From 0e14818d3e4f9185d30638cb748c396c0f2b1efe Mon Sep 17 00:00:00 2001 From: Nadim Zubidat Date: Mon, 5 Nov 2012 11:18:26 +0800 Subject: hostapd: enable dynamic modification of acl policy add APIs for dynamically changing the macaddr_acl policy and mac addresses lists. once changed, hostapd will deauth stations which do not pass the new policy. Signed-off-by: Nadim Zubidat --- hostapd/config_file.c | 4 ++-- hostapd/config_file.h | 2 ++ hostapd/ctrl_iface.c | 42 ++++++++++++++++++++++++++++++++++++++ src/ap/hostapd.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/ap/hostapd.h | 3 +++ 5 files changed, 105 insertions(+), 2 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 59745fa..41dd242 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -116,8 +116,8 @@ static int hostapd_acl_comp(const void *a, const void *b) } -static int hostapd_config_read_maclist(const char *fname, - struct mac_acl_entry **acl, int *num) +int hostapd_config_read_maclist(const char *fname, + struct mac_acl_entry **acl, int *num) { FILE *f; char buf[128], *pos; diff --git a/hostapd/config_file.h b/hostapd/config_file.h index fba57b8..61759f3 100644 --- a/hostapd/config_file.h +++ b/hostapd/config_file.h @@ -13,5 +13,7 @@ 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_config_read_maclist(const char *fname, + struct mac_acl_entry **acl, int *num); #endif /* CONFIG_FILE_H */ diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 8f42f90..e6a8ced 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -514,6 +514,42 @@ static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd, } +static int hostapd_ctrl_iface_set_accept_mac(struct hostapd_data *hapd, + char *fname) +{ + hapd->conf->num_accept_mac = 0; + + if (hostapd_config_read_maclist(fname, &hapd->conf->accept_mac, + &hapd->conf->num_accept_mac)) { + wpa_printf(MSG_ERROR, "Reading mac list from file failed"); + return -1; + } + + /* Accept mac list changed, check if need to deauth stations*/ + hostapd_macaddr_acl_accept_sta(hapd); + + return 0; +} + + +static int hostapd_ctrl_iface_set_deny_mac(struct hostapd_data *hapd, + char *fname) +{ + hapd->conf->num_deny_mac = 0; + + if (hostapd_config_read_maclist(fname, &hapd->conf->deny_mac, + &hapd->conf->num_deny_mac)) { + wpa_printf(MSG_ERROR, "Reading mac list from file failed"); + return -1; + } + + /* Deny mac list changed, check if need to deauth stations*/ + hostapd_macaddr_acl_deny_sta(hapd); + + return 0; +} + + static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd, char *buf, size_t buflen) { @@ -723,6 +759,12 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) else hapd->gas_frag_limit = val; #endif /* CONFIG_INTERWORKING */ + } else if (os_strcasecmp(cmd, "macaddr_acl") == 0) { + ret = hostapd_macaddr_acl_command(hapd, value); + } else if (os_strcasecmp(cmd, "accept_mac_file") == 0) { + ret = hostapd_ctrl_iface_set_accept_mac(hapd, value); + } else if (os_strcasecmp(cmd, "deny_mac_file") == 0) { + ret = hostapd_ctrl_iface_set_deny_mac(hapd, value); } else { ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value); } diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 4e06808..ac9ef26 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1137,3 +1137,59 @@ hostapd_channel_data *hostapd_get_valid_channel(struct hostapd_data *hapd, wpa_printf(MSG_WARNING, "Could't get requested channel"); return NULL; } + +void hostapd_macaddr_acl_accept_sta(struct hostapd_data *hapd) +{ + struct sta_info *sta = NULL; + + if (hapd->conf->macaddr_acl != DENY_UNLESS_ACCEPTED) + return; + + for (sta = hapd->sta_list; sta; sta = sta->next) { + if (!hostapd_maclist_found(hapd->conf->accept_mac, + hapd->conf->num_accept_mac, sta->addr, NULL)) { + hostapd_drv_sta_deauth(hapd, sta->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); + ap_sta_deauthenticate(hapd, sta, + WLAN_REASON_PREV_AUTH_NOT_VALID); + } + } +} + +void hostapd_macaddr_acl_deny_sta(struct hostapd_data *hapd) +{ + struct sta_info *sta = NULL; + + if (hapd->conf->macaddr_acl != ACCEPT_UNLESS_DENIED) + return; + + for (sta = hapd->sta_list; sta; sta = sta->next) { + if (hostapd_maclist_found(hapd->conf->deny_mac, + hapd->conf->num_deny_mac, sta->addr, NULL)) { + hostapd_drv_sta_deauth(hapd, sta->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); + ap_sta_deauthenticate(hapd, sta, + WLAN_REASON_PREV_AUTH_NOT_VALID); + } + } +} + +int hostapd_macaddr_acl_command(struct hostapd_data *hapd, char *cmd) +{ + int ret = 0; + + if (os_strcasecmp(cmd, "accept") == 0) { + wpa_printf(MSG_DEBUG, "Changing to access control accept list"); + hapd->conf->macaddr_acl = DENY_UNLESS_ACCEPTED; + hostapd_macaddr_acl_accept_sta(hapd); + } else if (os_strcasecmp(cmd, "deny") == 0) { + wpa_printf(MSG_DEBUG, "Changing to accees control deny list"); + hapd->conf->macaddr_acl = ACCEPT_UNLESS_DENIED; + hostapd_macaddr_acl_deny_sta(hapd); + } else { + wpa_printf(MSG_ERROR, "Unknown acl command"); + ret = -1; + } + + return ret; +} diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index feea42d..6193200 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -276,6 +276,9 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, struct hostapd_channel_data *hostapd_get_valid_channel(struct hostapd_data *hapd, int req_freq); +void hostapd_macaddr_acl_accept_sta(struct hostapd_data *hapd); +void hostapd_macaddr_acl_deny_sta(struct hostapd_data *hapd); +int hostapd_macaddr_acl_command(struct hostapd_data *hapd, char *cmd); /* utils.c */ int hostapd_register_probereq_cb(struct hostapd_data *hapd, -- cgit v1.1