diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index a8b339f58..9af5445e2 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -105,6 +105,32 @@ void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd, #endif /* CONFIG_FILS */ +static bool check_sa_query_need(struct hostapd_data *hapd, struct sta_info *sta) +{ + if ((sta->flags & + (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) != + (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) + return false; + + if (!sta->sa_query_timed_out && sta->sa_query_count > 0) + ap_check_sa_query_timeout(hapd, sta); + + if (!sta->sa_query_timed_out && (sta->auth_alg != WLAN_AUTH_FT)) { + /* + * STA has already been associated with MFP and SA Query timeout + * has not been reached. Reject the association attempt + * temporarily and start SA Query, if one is not pending. + */ + if (sta->sa_query_count == 0) + ap_sta_start_sa_query(hapd, sta); + + return true; + } + + return false; +} + + int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, const u8 *req_ies, size_t req_ies_len, int reassoc) { @@ -293,6 +319,17 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) { struct wpabuf *wps; + if (check_sa_query_need(hapd, sta)) { + status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; + + p = hostapd_eid_assoc_comeback_time(hapd, sta, + p); + + hostapd_sta_assoc(hapd, addr, reassoc, status, + buf, p - buf); + return 0; + } + sta->flags |= WLAN_STA_WPS; wps = ieee802_11_vendor_ie_concat(ie, ielen, WPS_IE_VENDOR_TYPE); @@ -388,27 +425,7 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, goto fail; } - if ((sta->flags & - (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) == - (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED) && - !sta->sa_query_timed_out && - sta->sa_query_count > 0) - ap_check_sa_query_timeout(hapd, sta); - if ((sta->flags & - (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) == - (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED) && - !sta->sa_query_timed_out && - (sta->auth_alg != WLAN_AUTH_FT)) { - /* - * STA has already been associated with MFP and SA - * Query timeout has not been reached. Reject the - * association attempt temporarily and start SA Query, - * if one is not pending. - */ - - if (sta->sa_query_count == 0) - ap_sta_start_sa_query(hapd, sta); - + if (check_sa_query_need(hapd, sta)) { status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; p = hostapd_eid_assoc_comeback_time(hapd, sta, p); diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 568ecacb0..78c1b8c8c 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3152,6 +3152,34 @@ end: #endif /* CONFIG_OWE */ +static bool check_sa_query(struct hostapd_data *hapd, struct sta_info *sta, + int reassoc) +{ + if ((sta->flags & + (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) != + (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) + return false; + + if (!sta->sa_query_timed_out && sta->sa_query_count > 0) + ap_check_sa_query_timeout(hapd, sta); + + if (!sta->sa_query_timed_out && + (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) { + /* + * STA has already been associated with MFP and SA Query timeout + * has not been reached. Reject the association attempt + * temporarily and start SA Query, if one is not pending. + */ + if (sta->sa_query_count == 0) + ap_sta_start_sa_query(hapd, sta); + + return true; + } + + return false; +} + + static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, const u8 *ies, size_t ies_len, int reassoc) { @@ -3275,6 +3303,8 @@ static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, if (hapd->conf->wps_state && elems.wps_ie) { wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association " "Request - assume WPS is used"); + if (check_sa_query(hapd, sta, reassoc)) + return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; sta->flags |= WLAN_STA_WPS; wpabuf_free(sta->wps_ie); sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len, @@ -3328,29 +3358,9 @@ static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, resp = wpa_res_to_status_code(res); if (resp != WLAN_STATUS_SUCCESS) return resp; - if ((sta->flags & - (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) == - (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED) && - !sta->sa_query_timed_out && - sta->sa_query_count > 0) - ap_check_sa_query_timeout(hapd, sta); - if ((sta->flags & - (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) == - (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED) && - !sta->sa_query_timed_out && - (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) { - /* - * STA has already been associated with MFP and SA - * Query timeout has not been reached. Reject the - * association attempt temporarily and start SA Query, - * if one is not pending. - */ - - if (sta->sa_query_count == 0) - ap_sta_start_sa_query(hapd, sta); + if (check_sa_query(hapd, sta, reassoc)) return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; - } if (wpa_auth_uses_mfp(sta->wpa_sm)) sta->flags |= WLAN_STA_MFP;