From: Jouni Malinen Date: Mon, 21 Nov 2022 20:53:07 +0000 (+0200) Subject: HS 2.0: Deauthenticate STA on deauth-imminent more quickly if no URL X-Git-Tag: hostap_2_11~1510 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=34d93b0c9da2bd7d6a4f53767e2ae77bd27e328f;p=thirdparty%2Fhostap.git HS 2.0: Deauthenticate STA on deauth-imminent more quickly if no URL When the RADIUS server requests a STA to be deauthenticated imminently without providing a reason URL, there is no need to allow the STA spend any additional time associated. Deauthenticate the STA immediately after it has ACK'ed the WNM-Notification frame indicating imminent deauthentication or at latest two seconds after having processes the Access-Accept message. Signed-off-by: Jouni Malinen --- diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index ea67aa100..01abd585e 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -2799,7 +2799,12 @@ own_ip_addr=127.0.0.1 # If the RADIUS server indicates that the station is not allowed to connect to # the BSS/ESS, the AP can allow the station some time to download a # notification page (URL included in the message). This parameter sets that -# timeout in seconds. +# timeout in seconds. If the RADIUS server provides no URL, this value is +# reduced to two seconds with an additional trigger for immediate +# deauthentication when the STA acknowledges reception of the deauthentication +# imminent indication. Note that setting this value to 0 will prevent delivery +# of the notification to the STA, so a value of at least 1 should be used here +# for normal use cases. #hs20_deauth_req_timeout=60 # Operator Friendly Name diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index e771b069d..56914dc5b 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -5838,6 +5838,19 @@ static void handle_action_cb(struct hostapd_data *hapd, return; } +#ifdef CONFIG_HS20 + if (ok && len >= IEEE80211_HDRLEN + 2 && + mgmt->u.action.category == WLAN_ACTION_WNM && + mgmt->u.action.u.vs_public_action.action == WNM_NOTIFICATION_REQ && + sta->hs20_deauth_on_ack) { + wpa_printf(MSG_DEBUG, "HS 2.0: Deauthenticate STA " MACSTR + " on acknowledging the WNM-Notification", + MAC2STR(sta->addr)); + ap_sta_session_timeout(hapd, sta, 0); + return; + } +#endif /* CONFIG_HS20 */ + if (len < 24 + 5 + sizeof(*report)) return; report = (const struct rrm_measurement_report_element *) diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index d90792c78..46a47d06e 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -1709,23 +1709,35 @@ static void ieee802_1x_hs20_sub_rem(struct sta_info *sta, u8 *pos, size_t len) static void ieee802_1x_hs20_deauth_req(struct hostapd_data *hapd, - struct sta_info *sta, u8 *pos, + struct sta_info *sta, const u8 *pos, size_t len) { + size_t url_len; + unsigned int timeout; + if (len < 3) return; /* Malformed information */ + url_len = len - 3; sta->hs20_deauth_requested = 1; + sta->hs20_deauth_on_ack = url_len == 0; wpa_printf(MSG_DEBUG, - "HS 2.0: Deauthentication request - Code %u Re-auth Delay %u", - *pos, WPA_GET_LE16(pos + 1)); + "HS 2.0: Deauthentication request - Code %u Re-auth Delay %u URL length %zu", + *pos, WPA_GET_LE16(pos + 1), url_len); wpabuf_free(sta->hs20_deauth_req); sta->hs20_deauth_req = wpabuf_alloc(len + 1); if (sta->hs20_deauth_req) { wpabuf_put_data(sta->hs20_deauth_req, pos, 3); - wpabuf_put_u8(sta->hs20_deauth_req, len - 3); - wpabuf_put_data(sta->hs20_deauth_req, pos + 3, len - 3); + wpabuf_put_u8(sta->hs20_deauth_req, url_len); + wpabuf_put_data(sta->hs20_deauth_req, pos + 3, url_len); } - ap_sta_session_timeout(hapd, sta, hapd->conf->hs20_deauth_req_timeout); + timeout = hapd->conf->hs20_deauth_req_timeout; + /* If there is no URL, no need to provide time to fetch it. Use a short + * timeout here to allow maximum time for completing 4-way handshake and + * WNM-Notification delivery. Acknowledgement of the frame will result + * in cutting this wait further. */ + if (!url_len && timeout > 2) + timeout = 2; + ap_sta_session_timeout(hapd, sta, timeout); } @@ -1813,6 +1825,7 @@ static void ieee802_1x_check_hs20(struct hostapd_data *hapd, buf = NULL; sta->remediation = 0; sta->hs20_deauth_requested = 0; + sta->hs20_deauth_on_ack = 0; for (;;) { if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_VENDOR_SPECIFIC, diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h index 1dc442531..6911bc5fb 100644 --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h @@ -118,6 +118,7 @@ struct sta_info { unsigned int qos_map_enabled:1; unsigned int remediation:1; unsigned int hs20_deauth_requested:1; + unsigned int hs20_deauth_on_ack:1; unsigned int session_timeout_set:1; unsigned int radius_das_match:1; unsigned int ecsa_supported:1;