]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SME: Fix order of WPA IE in association request
authorIlan Peer <ilan.peer@intel.com>
Thu, 23 Aug 2018 13:52:32 +0000 (16:52 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 20 Oct 2018 08:26:13 +0000 (11:26 +0300)
In case that the protocol used for association is WPA the WPA IE was
inserted before other (non vendor specific) IEs. This is not in
accordance to the standard that states that vendor IEs should be placed
after all the non vendor IEs are placed. In addition, this would cause
the low layers to fail to properly order information elements.

To fix this, if the protocol used is WPA, store the WPA IE and reinsert
it after all the non vendor specific IEs were placed.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
wpa_supplicant/sme.c

index 708a347a8332f35f76daf5f3e326907ca7ab0ece..d23dc06346c6294399b311948e556b29b805e37a 100644 (file)
@@ -240,6 +240,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
        u8 ext_capab[18];
        int ext_capab_len;
        int skip_auth;
+       u8 *wpa_ie;
+       size_t wpa_ie_len;
 #ifdef CONFIG_MBO
        const u8 *mbo_ie;
 #endif /* CONFIG_MBO */
@@ -391,6 +393,28 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
                wpa_s->sme.assoc_req_ie_len = 0;
        }
 
+       /* In case the WPA vendor IE is used, it should be placed after all the
+        * non-vendor IEs, as the lower layer expects the IEs to be ordered as
+        * defined in the standard. Store the WPA IE so it can later be
+        * inserted at the correct location.
+        */
+       wpa_ie = NULL;
+       wpa_ie_len = 0;
+       if (wpa_s->wpa_proto == WPA_PROTO_WPA) {
+               wpa_ie = os_memdup(wpa_s->sme.assoc_req_ie,
+                                  wpa_s->sme.assoc_req_ie_len);
+               if (wpa_ie) {
+                       wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Storing WPA IE");
+
+                       wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
+                       wpa_s->sme.assoc_req_ie_len = 0;
+               } else {
+                       wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed copy WPA IE");
+                       wpas_connect_work_done(wpa_s);
+                       return;
+               }
+       }
+
 #ifdef CONFIG_IEEE80211R
        ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
        if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
@@ -527,6 +551,26 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_HS20 */
 
+       if (wpa_ie) {
+               size_t len;
+
+               wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Reinsert WPA IE");
+
+               len = sizeof(wpa_s->sme.assoc_req_ie) -
+                       wpa_s->sme.assoc_req_ie_len;
+
+               if (len > wpa_ie_len) {
+                       os_memcpy(wpa_s->sme.assoc_req_ie +
+                                 wpa_s->sme.assoc_req_ie_len,
+                                 wpa_ie, wpa_ie_len);
+                       wpa_s->sme.assoc_req_ie_len += wpa_ie_len;
+               } else {
+                       wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Failed to add WPA IE");
+               }
+
+               os_free(wpa_ie);
+       }
+
        if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
                struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
                size_t len;