hostapd: Process MAC ACLs on a station association event (SME in driver)

Now hostapd will use station MAC-based permissions according to the
macaddr_acl policy also for drivers which use AP SME offload, but do not
support NL80211_CMD_SET_MAC_ACL for offloading MAC ACL processing. It
should be noted that in this type of case the association goes through
and the station gets disconnected immediately after that.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Anton Nayshtut 2015-10-22 19:48:04 +03:00 committed by Jouni Malinen
parent 89a11ad38f
commit 0603bcb7fe
3 changed files with 44 additions and 16 deletions

View file

@ -22,6 +22,7 @@
#include "wnm_ap.h" #include "wnm_ap.h"
#include "hostapd.h" #include "hostapd.h"
#include "ieee802_11.h" #include "ieee802_11.h"
#include "ieee802_11_auth.h"
#include "sta_info.h" #include "sta_info.h"
#include "accounting.h" #include "accounting.h"
#include "tkip_countermeasures.h" #include "tkip_countermeasures.h"
@ -114,6 +115,14 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
} }
sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2); sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
res = hostapd_check_acl(hapd, addr, NULL);
if (res != HOSTAPD_ACL_ACCEPT) {
wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect",
MAC2STR(addr));
reason = WLAN_REASON_UNSPECIFIED;
goto fail;
}
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (elems.p2p) { if (elems.p2p) {
wpabuf_free(sta->p2p_ie); wpabuf_free(sta->p2p_ie);

View file

@ -212,6 +212,32 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
#endif /* CONFIG_NO_RADIUS */ #endif /* CONFIG_NO_RADIUS */
/**
* hostapd_check_acl - Check a specified STA against accept/deny ACLs
* @hapd: hostapd BSS data
* @addr: MAC address of the STA
* @vlan_id: Buffer for returning VLAN ID
* Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING
*/
int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr, int *vlan_id)
{
if (hostapd_maclist_found(hapd->conf->accept_mac,
hapd->conf->num_accept_mac, addr, vlan_id))
return HOSTAPD_ACL_ACCEPT;
if (hostapd_maclist_found(hapd->conf->deny_mac,
hapd->conf->num_deny_mac, addr, vlan_id))
return HOSTAPD_ACL_REJECT;
if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED)
return HOSTAPD_ACL_ACCEPT;
if (hapd->conf->macaddr_acl == DENY_UNLESS_ACCEPTED)
return HOSTAPD_ACL_REJECT;
return HOSTAPD_ACL_PENDING;
}
/** /**
* hostapd_allowed_address - Check whether a specified STA can be authenticated * hostapd_allowed_address - Check whether a specified STA can be authenticated
* @hapd: hostapd BSS data * @hapd: hostapd BSS data
@ -235,6 +261,8 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
struct hostapd_sta_wpa_psk_short **psk, struct hostapd_sta_wpa_psk_short **psk,
char **identity, char **radius_cui) char **identity, char **radius_cui)
{ {
int res;
if (session_timeout) if (session_timeout)
*session_timeout = 0; *session_timeout = 0;
if (acct_interim_interval) if (acct_interim_interval)
@ -248,18 +276,9 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
if (radius_cui) if (radius_cui)
*radius_cui = NULL; *radius_cui = NULL;
if (hostapd_maclist_found(hapd->conf->accept_mac, res = hostapd_check_acl(hapd, addr, vlan_id);
hapd->conf->num_accept_mac, addr, vlan_id)) if (res != HOSTAPD_ACL_PENDING)
return HOSTAPD_ACL_ACCEPT; return res;
if (hostapd_maclist_found(hapd->conf->deny_mac,
hapd->conf->num_deny_mac, addr, vlan_id))
return HOSTAPD_ACL_REJECT;
if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED)
return HOSTAPD_ACL_ACCEPT;
if (hapd->conf->macaddr_acl == DENY_UNLESS_ACCEPTED)
return HOSTAPD_ACL_REJECT;
if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) { if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) {
#ifdef CONFIG_NO_RADIUS #ifdef CONFIG_NO_RADIUS
@ -268,10 +287,9 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
struct hostapd_acl_query_data *query; struct hostapd_acl_query_data *query;
/* Check whether ACL cache has an entry for this station */ /* Check whether ACL cache has an entry for this station */
int res = hostapd_acl_cache_get(hapd, addr, session_timeout, res = hostapd_acl_cache_get(hapd, addr, session_timeout,
acct_interim_interval, acct_interim_interval, vlan_id, psk,
vlan_id, psk, identity, radius_cui);
identity, radius_cui);
if (res == HOSTAPD_ACL_ACCEPT || if (res == HOSTAPD_ACL_ACCEPT ||
res == HOSTAPD_ACL_ACCEPT_TIMEOUT) res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
return res; return res;

View file

@ -16,6 +16,7 @@ enum {
HOSTAPD_ACL_ACCEPT_TIMEOUT = 3 HOSTAPD_ACL_ACCEPT_TIMEOUT = 3
}; };
int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr, int *vlan_id);
int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
const u8 *msg, size_t len, u32 *session_timeout, const u8 *msg, size_t len, u32 *session_timeout,
u32 *acct_interim_interval, int *vlan_id, u32 *acct_interim_interval, int *vlan_id,