From patchwork Sun Jun 10 22:44:30 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 164013 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) by ozlabs.org (Postfix) with ESMTP id 2F73CB6FD9 for ; Mon, 11 Jun 2012 08:44:26 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 6D0A79D1FE; Sun, 10 Jun 2012 18:44:24 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JFLAH68Ufc10; Sun, 10 Jun 2012 18:44:24 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id A75EB9C1BD; Sun, 10 Jun 2012 18:44:19 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id C26CB9C1BD for ; Sun, 10 Jun 2012 18:44:17 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FQUceVZ6Ro-L for ; Sun, 10 Jun 2012 18:44:12 -0400 (EDT) Received: from confino.investici.org (investici.nine.ch [217.150.252.179]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "smtp.autistici.org", Issuer "Autistici/Inventati Certification Authority" (not verified)) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id 43ED29C1BB for ; Sun, 10 Jun 2012 18:44:12 -0400 (EDT) Received: from [217.150.252.179] (confino [217.150.252.179]) (Authenticated sender: ordex@autistici.org) by localhost (Postfix) with ESMTPSA id 0FFA4C8691; Sun, 10 Jun 2012 22:44:07 +0000 (UTC) X-DKIM: Sendmail DKIM Filter v2.8.2 confino.investici.org 0FFA4C8691 From: Antonio Quartulli To: hostap Subject: [PATCHv2] hostapd: reload bss mac files on SIGUSR2 Date: Mon, 11 Jun 2012 00:44:30 +0200 Message-Id: <1339368270-11500-1-git-send-email-ordex@autistici.org> X-Mailer: git-send-email 1.7.9.4 In-Reply-To: <1339367661-6094-1-git-send-email-ordex@autistici.org> References: <1339367661-6094-1-git-send-email-ordex@autistici.org> X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com This patch allows the administrator to modify the provided MAC list for the BSS ACL mechanism at runtime. In the current implementation no runtime change is possible: if the MAC list is modified, hostapd has to be restart so disconnecting all the current clients. After manually modify the MAC files, the USR2 signal will make hostapd reload them and possibly disconnect new not allowed stations. Signed-hostap: Antonio Quartulli --- v2: fixed signed-hostap line hostapd/config_file.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ hostapd/config_file.h | 1 + hostapd/main.c | 14 +++++++ src/ap/ap_config.h | 3 +- src/ap/hostapd.c | 3 -- src/ap/sta_info.c | 32 ++++++++++++++++ src/ap/sta_info.h | 3 ++ 7 files changed, 150 insertions(+), 4 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index eab8ad4..a52309d 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -19,6 +19,9 @@ #include "radius/radius_client.h" #include "ap/wpa_auth.h" #include "ap/ap_config.h" +#include "ap/hostapd.h" +#include "ap/ap_drv_ops.h" +#include "ap/sta_info.h" #include "config_file.h" @@ -1391,8 +1394,12 @@ static int hostapd_config_fill(struct hostapd_config *conf, wpa_printf(MSG_ERROR, "Line %d: unknown " "macaddr_acl %d", line, bss->macaddr_acl); + bss->accept_mac_filename[0] = '\0'; + bss->deny_mac_filename[0] = '\0'; } } else if (os_strcmp(buf, "accept_mac_file") == 0) { + os_strncpy(bss->accept_mac_filename, pos, 256); + bss->accept_mac_filename[255] = '\0'; if (hostapd_config_read_maclist(pos, &bss->accept_mac, &bss->num_accept_mac)) { @@ -1402,6 +1409,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, errors++; } } else if (os_strcmp(buf, "deny_mac_file") == 0) { + os_strncpy(bss->deny_mac_filename, pos, 256); + bss->deny_mac_filename[255] = '\0'; if (hostapd_config_read_maclist(pos, &bss->deny_mac, &bss->num_deny_mac)) { wpa_printf(MSG_ERROR, "Line %d: Failed to " @@ -2495,3 +2504,92 @@ int hostapd_set_iface(struct hostapd_config *conf, return 0; } + +static void hostapd_deauth_station(struct hostapd_data *hapd, u8 *addr, + u16 reason) +{ + if (hostapd_drv_none(hapd)) + return; + + wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Deauthenticate " MACSTR, + MAC2STR(addr)); + + hostapd_drv_sta_deauth(hapd, addr, reason); + hostapd_free_sta(hapd, addr, reason); +} + +int hostapd_reload_macfile(struct hostapd_iface *iface) +{ + struct hostapd_bss_config *bss; + struct sta_info *sta, *prev, *next; + size_t i, j; + + wpa_printf(MSG_DEBUG, "Reloading macfiles"); + for (i = 0; i < iface->num_bss; i++) { + bss = iface->bss[i]->conf; + + /* reload accept mac file if any */ + if (bss->accept_mac_filename[0] != '\0') { + wpa_printf(MSG_DEBUG, "Reading %s", + bss->accept_mac_filename); + os_free(bss->accept_mac); + bss->accept_mac = NULL; + bss->num_accept_mac = 0; + if (hostapd_config_read_maclist( + bss->accept_mac_filename, + &bss->accept_mac, + &bss->num_accept_mac)) + wpa_printf(MSG_ERROR, "Failed to read " + "accept_mac_file '%s'", + bss->accept_mac_filename); + } + + /* reload deny mac file if any */ + if (bss->deny_mac_filename[0] != '\0') { + wpa_printf(MSG_DEBUG, "Reading %s", + bss->deny_mac_filename); + os_free(bss->deny_mac); + bss->deny_mac = NULL; + bss->num_deny_mac = 0; + if (hostapd_config_read_maclist(bss->deny_mac_filename, + &bss->deny_mac, + &bss->num_deny_mac)) + wpa_printf(MSG_ERROR, "Failed to read " + "deny_mac_file '%s'", + bss->deny_mac_filename); + } + + /* deauthenticate listed stations */ + if (bss->macaddr_acl == ACCEPT_UNLESS_DENIED) + for (j = 0; j < bss->num_deny_mac; j++) + hostapd_deauth_station(iface->bss[i], + bss->deny_mac[j].addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); + + /* deauthenticate all the stations that are not listed */ + if (bss->macaddr_acl == DENY_UNLESS_ACCEPTED) { + prev = sta = iface->bss[i]->sta_list; + while (sta) { + next = sta->next; + for (j = 0; j < bss->num_accept_mac; j++) + if (!memcmp(sta->addr, + bss->accept_mac[j].addr, + ETH_ALEN)) + break; + if (j == bss->num_accept_mac) { + if (iface->bss[i]->sta_list == sta) + iface->bss[i]->sta_list = + sta->next; + else + prev->next = sta->next; + hostapd_deauth_station(iface->bss[i], + sta->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); + } else + prev = sta; + sta = next; + } + } + } + return 0; +} diff --git a/hostapd/config_file.h b/hostapd/config_file.h index fba57b8..90a306b 100644 --- a/hostapd/config_file.h +++ b/hostapd/config_file.h @@ -13,5 +13,6 @@ struct hostapd_config * hostapd_config_read(const char *fname); int hostapd_set_iface(struct hostapd_config *conf, struct hostapd_bss_config *bss, char *field, char *value); +int hostapd_reload_macfile(struct hostapd_iface *iface); #endif /* CONFIG_FILE_H */ diff --git a/hostapd/main.c b/hostapd/main.c index d8c2776..85a376a 100644 --- a/hostapd/main.c +++ b/hostapd/main.c @@ -363,6 +363,10 @@ static void handle_reload(int sig, void *signal_ctx) hostapd_for_each_interface(interfaces, handle_reload_iface, NULL); } +int handle_reload_macfile_iface(struct hostapd_iface *iface, void *ctx) +{ + return hostapd_reload_macfile(iface); +} static void handle_dump_state(int sig, void *signal_ctx) { @@ -371,6 +375,15 @@ static void handle_dump_state(int sig, void *signal_ctx) hostapd_for_each_interface(interfaces, handle_dump_state_iface, NULL); #endif /* HOSTAPD_DUMP_STATE */ } + +static void handle_reload_macfile(int sig, void *signal_ctx) +{ + struct hapd_interfaces *interfaces = signal_ctx; + wpa_printf(MSG_DEBUG, "USR2 catched, reloading macfiles.."); + hostapd_for_each_interface(interfaces, handle_reload_macfile_iface, + NULL); +} + #endif /* CONFIG_NATIVE_WINDOWS */ @@ -398,6 +411,7 @@ static int hostapd_global_init(struct hapd_interfaces *interfaces, #ifndef CONFIG_NATIVE_WINDOWS eloop_register_signal(SIGHUP, handle_reload, interfaces); eloop_register_signal(SIGUSR1, handle_dump_state, interfaces); + eloop_register_signal(SIGUSR2, handle_reload_macfile, interfaces); #endif /* CONFIG_NATIVE_WINDOWS */ eloop_register_signal_terminate(handle_term, interfaces); diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 78c9068..8e23528 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -207,14 +207,15 @@ struct hostapd_bss_config { int ieee802_11f; /* use IEEE 802.11f (IAPP) */ char iapp_iface[IFNAMSIZ + 1]; /* interface used with IAPP broadcast * frames */ - enum { ACCEPT_UNLESS_DENIED = 0, DENY_UNLESS_ACCEPTED = 1, USE_EXTERNAL_RADIUS_AUTH = 2 } macaddr_acl; + char accept_mac_filename[256]; struct mac_acl_entry *accept_mac; int num_accept_mac; + char deny_mac_filename[256]; struct mac_acl_entry *deny_mac; int num_deny_mac; int wds_sta; diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 9d6fd7b..d17b231 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -106,7 +106,6 @@ static void hostapd_reload_bss(struct hostapd_data *hapd) wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface); } - int hostapd_reload_config(struct hostapd_iface *iface) { struct hostapd_data *hapd = iface->bss[0]; @@ -379,7 +378,6 @@ static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd) return 0; } - static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason) { int ret = 0; @@ -402,7 +400,6 @@ static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason) return ret; } - /** * hostapd_validate_bssid_configuration - Validate BSSID configuration * @iface: Pointer to interface data diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c index a7dffc7..0a4c673 100644 --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -239,6 +239,38 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) os_free(sta); } +void hostapd_free_sta_info(struct hostapd_data *hapd, struct sta_info *sta, + u16 reason) +{ + if (sta->flags & WLAN_STA_AUTH) { + mlme_deauthenticate_indication(hapd, sta, reason); + } + wpa_printf(MSG_DEBUG, "Removing station " MACSTR, MAC2STR(sta->addr)); + ap_free_sta(hapd, sta); +} + +void hostapd_free_sta(struct hostapd_data *hapd, u8 *addr, u16 reason) +{ + struct sta_info *sta, *prev; + + prev = sta = hapd->sta_list; + + while (sta && memcmp(sta->addr, addr, ETH_ALEN)) { + prev = sta; + sta = sta->next; + } + + /* station not found */ + if (!sta) + return; + + if (sta == hapd->sta_list) + hapd->sta_list = sta->next; + else + prev->next = sta->next; + + hostapd_free_sta_info(hapd, sta, reason); +} void hostapd_free_stas(struct hostapd_data *hapd) { diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h index cef428d..2ebe2db 100644 --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h @@ -144,6 +144,7 @@ int ap_for_each_sta(struct hostapd_data *hapd, struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta); void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta); void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta); +void hostapd_free_sta(struct hostapd_data *hapd, u8 *addr, u16 reason); void hostapd_free_stas(struct hostapd_data *hapd); void ap_handle_timer(void *eloop_ctx, void *timeout_ctx); void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta, @@ -174,6 +175,8 @@ static inline int ap_sta_is_authorized(struct sta_info *sta) return sta->flags & WLAN_STA_AUTHORIZED; } +void hostapd_free_sta_info(struct hostapd_data *hapd, struct sta_info *sta, + u16 reason); void ap_sta_deauth_cb(struct hostapd_data *hapd, struct sta_info *sta); void ap_sta_disassoc_cb(struct hostapd_data *hapd, struct sta_info *sta);