]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Enable SA Query checks for WPS AP
authorDisha Das <dishad@codeaurora.org>
Tue, 6 Oct 2020 12:07:01 +0000 (17:37 +0530)
committerJouni Malinen <j@w1.fi>
Tue, 6 Oct 2020 19:44:43 +0000 (22:44 +0300)
Initiate SA Query for a WPS+MFP AP. STA flag checks for MFP added for
Association Request frames that use WPS IE without RSNE. This is needed
to avoid giving an opportunity to skip the protection against
disconnections when WPS is enabled.

Signed-off-by: Disha Das <dishad@codeaurora.org>
src/ap/drv_callbacks.c
src/ap/ieee802_11.c

index a8b339f58df7ae1dbdf0ade17ce8ec11b16868fd..9af5445e28ffc78cee67b788e00c8654f9e3e146 100644 (file)
@@ -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);
index 568ecacb06064df55540daaee6212f8fe4218a97..78c1b8c8cc17b0fcad5eeae4ddebba3c99c3c02f 100644 (file)
@@ -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;