From 92eb00aec2a05413a3b5da4982c488889d7f3bae Mon Sep 17 00:00:00 2001 From: Tamizh chelvam Date: Wed, 14 Feb 2018 19:13:56 +0530 Subject: [PATCH] Extend ACL check for Probe Request frames Extend ACL check to deny Probe Request frames for the client which does not pass ACL check. Skip this check for the case where RADIUS ACL is used to avoid excessive load on the RADIUS authentication server due to Probe Request frames. This patch add wpa_msg event for auth and assoc rejection due to acl reject. Signed-off-by: Tamizh chelvam --- src/ap/beacon.c | 17 +++++++++++++++++ src/ap/ieee802_11.c | 19 ++++++++++++++----- src/ap/ieee802_11.h | 9 +++++++++ src/ap/ieee802_11_auth.c | 10 +++++++++- src/ap/ieee802_11_auth.h | 3 ++- 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 711464977..7d079d261 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -31,6 +31,7 @@ #include "hs20.h" #include "dfs.h" #include "taxonomy.h" +#include "ieee802_11_auth.h" #ifdef NEED_AP_MLME @@ -731,6 +732,11 @@ void handle_probe_req(struct hostapd_data *hapd, int ret; u16 csa_offs[2]; size_t csa_offs_len; + u32 session_timeout, acct_interim_interval; + struct vlan_description vlan_id; + struct hostapd_sta_wpa_psk_short *psk = NULL; + char *identity = NULL; + char *radius_cui = NULL; if (len < IEEE80211_HDRLEN) return; @@ -739,6 +745,17 @@ void handle_probe_req(struct hostapd_data *hapd, sta_track_add(hapd->iface, mgmt->sa, ssi_signal); ie_len = len - IEEE80211_HDRLEN; + ret = ieee802_11_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len, + &session_timeout, + &acct_interim_interval, &vlan_id, + &psk, &identity, &radius_cui, 1); + if (ret == HOSTAPD_ACL_REJECT) { + wpa_msg(hapd->msg_ctx, MSG_DEBUG, + "Ignore Probe Request frame from " MACSTR + " due to ACL reject ", MAC2STR(mgmt->sa)); + return; + } + for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, mgmt->sa, mgmt->da, mgmt->bssid, diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 8c0de4d67..fcfe33621 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1577,20 +1577,21 @@ void ieee802_11_finish_fils_auth(struct hostapd_data *hapd, #endif /* CONFIG_FILS */ -static int +int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr, const u8 *msg, size_t len, u32 *session_timeout, u32 *acct_interim_interval, struct vlan_description *vlan_id, struct hostapd_sta_wpa_psk_short **psk, - char **identity, char **radius_cui) + char **identity, char **radius_cui, int is_probe_req) { int res; os_memset(vlan_id, 0, sizeof(*vlan_id)); res = hostapd_allowed_address(hapd, addr, msg, len, session_timeout, acct_interim_interval, - vlan_id, psk, identity, radius_cui); + vlan_id, psk, identity, radius_cui, + is_probe_req); if (res == HOSTAPD_ACL_REJECT) { wpa_printf(MSG_INFO, @@ -1826,8 +1827,12 @@ static void handle_auth(struct hostapd_data *hapd, res = ieee802_11_allowed_address( hapd, mgmt->sa, (const u8 *) mgmt, len, &session_timeout, - &acct_interim_interval, &vlan_id, &psk, &identity, &radius_cui); + &acct_interim_interval, &vlan_id, &psk, &identity, &radius_cui, + 0); if (res == HOSTAPD_ACL_REJECT) { + wpa_msg(hapd->msg_ctx, MSG_DEBUG, + "Ignore Authentication frame from " MACSTR + " due to ACL reject", MAC2STR(mgmt->sa)); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } @@ -3189,8 +3194,12 @@ static void handle_assoc(struct hostapd_data *hapd, acl_res = ieee802_11_allowed_address( hapd, mgmt->sa, (const u8 *) mgmt, len, &session_timeout, &acct_interim_interval, - &vlan_id, &psk, &identity, &radius_cui); + &vlan_id, &psk, &identity, &radius_cui, 0); if (acl_res == HOSTAPD_ACL_REJECT) { + wpa_msg(hapd->msg_ctx, MSG_DEBUG, + "Ignore Association Request frame from " + MACSTR " due to ACL reject", + MAC2STR(mgmt->sa)); resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index 9fa09ca41..2f3b4da8e 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -16,6 +16,8 @@ struct hostapd_frame_info; struct ieee80211_ht_capabilities; struct ieee80211_vht_capabilities; struct ieee80211_mgmt; +struct vlan_description; +struct hostapd_sta_wpa_psk_short; int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, struct hostapd_frame_info *fi); @@ -156,5 +158,12 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta, size_t hostapd_eid_owe_trans_len(struct hostapd_data *hapd); u8 * hostapd_eid_owe_trans(struct hostapd_data *hapd, u8 *eid, size_t len); +int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr, + const u8 *msg, size_t len, u32 *session_timeout, + u32 *acct_interim_interval, + struct vlan_description *vlan_id, + struct hostapd_sta_wpa_psk_short **psk, + char **identity, char **radius_cui, + int is_probe_req); #endif /* IEEE802_11_H */ diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c index 3308398d1..5cb7fb145 100644 --- a/src/ap/ieee802_11_auth.c +++ b/src/ap/ieee802_11_auth.c @@ -244,6 +244,7 @@ int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr, * @psk: Linked list buffer for returning WPA PSK * @identity: Buffer for returning identity (from RADIUS) * @radius_cui: Buffer for returning CUI (from RADIUS) + * @is_probe_req: Whether this query for a Probe Request frame * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING * * The caller is responsible for freeing the returned *identity and *radius_cui @@ -254,7 +255,8 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, u32 *acct_interim_interval, struct vlan_description *vlan_id, struct hostapd_sta_wpa_psk_short **psk, - char **identity, char **radius_cui) + char **identity, char **radius_cui, + int is_probe_req) { int res; @@ -281,6 +283,12 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, #else /* CONFIG_NO_RADIUS */ struct hostapd_acl_query_data *query; + if (is_probe_req) { + /* Skip RADIUS queries for Probe Request frames to avoid + * excessive load on the authentication server. */ + return HOSTAPD_ACL_ACCEPT; + }; + /* Check whether ACL cache has an entry for this station */ res = hostapd_acl_cache_get(hapd, addr, session_timeout, acct_interim_interval, vlan_id, psk, diff --git a/src/ap/ieee802_11_auth.h b/src/ap/ieee802_11_auth.h index 71f53b961..5aece5183 100644 --- a/src/ap/ieee802_11_auth.h +++ b/src/ap/ieee802_11_auth.h @@ -23,7 +23,8 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, u32 *acct_interim_interval, struct vlan_description *vlan_id, struct hostapd_sta_wpa_psk_short **psk, - char **identity, char **radius_cui); + char **identity, char **radius_cui, + int is_probe_req); int hostapd_acl_init(struct hostapd_data *hapd); void hostapd_acl_deinit(struct hostapd_data *hapd); void hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk);