@@ -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;
+}
@@ -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 */
@@ -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);
@@ -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;
@@ -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
@@ -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)
{
@@ -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);
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-off-by: Antonio Quartulli <ordex@autistici.org> --- 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(-)