]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
MLD STA: Allow auth frames without ML IE for failure status codes
authorVeerendranath Jakkam <quic_vjakkam@quicinc.com>
Tue, 9 May 2023 13:53:21 +0000 (19:23 +0530)
committerJouni Malinen <j@w1.fi>
Thu, 25 May 2023 15:03:58 +0000 (18:03 +0300)
In some cases like unknown-group rejection, AP MLD can't parse the
received Authentication frame to the point of the Multi-Link element if
the group used by the peer is unknown to the AP MLD.

In such cases, AP MLD not including Multi-Link element in rejection
Authentication frames can be considered as standard compliant since AP
MLD doesn't know whether the received Authentication frame has
Multi-Link element or not.

To avoid connection issues in such cases, don't reject Authentication
frames without Multi-Link element when status code is other than
WLAN_STATUS_SUCCESS, WLAN_STATUS_SAE_HASH_TO_ELEMENT,
WLAN_STATUS_SAE_PK, and WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
wpa_supplicant/sme.c

index 51bc44246e3a14afc43c8517dc7a232a5ac8a785..4ed0a3003ff42f324208ee5d9568ee5e3d2585f8 100644 (file)
@@ -547,6 +547,7 @@ static void wpas_sme_ml_auth(struct wpa_supplicant *wpa_s,
 {
        struct ieee802_11_elems elems;
        const u8 *mld_addr;
+       u16 status_code = data->auth.status_code;
 
        if (!wpa_s->valid_links)
                return;
@@ -560,7 +561,14 @@ static void wpas_sme_ml_auth(struct wpa_supplicant *wpa_s,
 
        if (!elems.basic_mle || !elems.basic_mle_len) {
                wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
-               goto out;
+               if (status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ ||
+                   status_code == WLAN_STATUS_SUCCESS ||
+                   status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
+                   status_code == WLAN_STATUS_SAE_PK)
+                       goto out;
+               /* Accept missing Multi-Link element in failed authentication
+                * cases. */
+               return;
        }
 
        mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
@@ -1614,7 +1622,8 @@ static int sme_check_sae_rejected_groups(struct wpa_supplicant *wpa_s,
 
 
 static int sme_external_ml_auth(struct wpa_supplicant *wpa_s,
-                               const u8 *data, size_t len, int ie_offset)
+                               const u8 *data, size_t len, int ie_offset,
+                               u16 status_code)
 {
        struct ieee802_11_elems elems;
        const u8 *mld_addr;
@@ -1627,7 +1636,14 @@ static int sme_external_ml_auth(struct wpa_supplicant *wpa_s,
 
        if (!elems.basic_mle || !elems.basic_mle_len) {
                wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
-               return -1;
+               if (status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ ||
+                   status_code == WLAN_STATUS_SUCCESS ||
+                   status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
+                   status_code == WLAN_STATUS_SAE_PK)
+                       return -1;
+               /* Accept missing Multi-Link element in failed authentication
+                * cases. */
+               return 0;
        }
 
        mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
@@ -1733,7 +1749,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
                                                wpa_s->current_ssid, 2);
                } else {
                        if (wpa_s->sme.ext_ml_auth &&
-                           sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+                           sme_external_ml_auth(wpa_s, data, len, *ie_offset,
+                                                status_code))
                                return -1;
 
                        sme_external_auth_send_sae_commit(
@@ -1760,7 +1777,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
                                                wpa_s->current_ssid, 1);
                } else {
                        if (wpa_s->sme.ext_ml_auth &&
-                           sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+                           sme_external_ml_auth(wpa_s, data, len, *ie_offset,
+                                                status_code))
                                return -1;
 
                        sme_external_auth_send_sae_commit(
@@ -1859,7 +1877,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
                                                wpa_s->current_ssid, 0);
                } else {
                        if (wpa_s->sme.ext_ml_auth &&
-                           sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+                           sme_external_ml_auth(wpa_s, data, len, *ie_offset,
+                                                status_code))
                                return -1;
 
                        sme_external_auth_send_sae_confirm(wpa_s, sa);
@@ -1875,7 +1894,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
                                      ie_offset) < 0)
                        return -1;
                if (external && wpa_s->sme.ext_ml_auth &&
-                   sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+                   sme_external_ml_auth(wpa_s, data, len, *ie_offset,
+                                        status_code))
                        return -1;
 
                wpa_s->sme.sae.state = SAE_ACCEPTED;