]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
RSNO: Include all RSNE/RSNXE variants in EAPOL-Key message 3/4
authorJouni Malinen <quic_jouni@quicinc.com>
Mon, 29 Jul 2024 14:20:22 +0000 (17:20 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 30 Jul 2024 15:52:15 +0000 (18:52 +0300)
This allows all variants to be verified based on a protected frame to
achieve robust downgrade protection.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/ap/wpa_auth.c
src/common/wpa_common.c
src/common/wpa_common.h
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_i.h
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpas_glue.c

index 29d17f6845936b126ab0aebb907e75d9d3825c01..9a81402267ab187b2a53ffdef3002e764a2536bc 100644 (file)
@@ -4665,82 +4665,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
                        wpa_ie = wpa_ie + wpa_ie[1] + 2;
                wpa_ie_len = wpa_ie[1] + 2;
        }
-       if ((sm->rsn_override &&
-            get_vendor_ie(wpa_ie, wpa_ie_len, RSNE_OVERRIDE_IE_VENDOR_TYPE)) ||
-           (sm->rsn_override_2 &&
-            get_vendor_ie(wpa_ie, wpa_ie_len,
-                          RSNE_OVERRIDE_2_IE_VENDOR_TYPE))) {
-               const u8 *mde, *fte, *tie, *tie2 = NULL;
-               const u8 *override_rsne = NULL, *override_rsnxe = NULL;
-               const struct element *elem;
-
-               wpa_printf(MSG_DEBUG,
-                          "RSN: Use RSNE/RSNXE override element contents");
-               mde = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_MOBILITY_DOMAIN);
-               fte = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_FAST_BSS_TRANSITION);
-               tie = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_TIMEOUT_INTERVAL);
-               if (tie) {
-                       const u8 *next = tie + 2 + tie[1];
-
-                       tie2 = get_ie(next, wpa_ie + wpa_ie_len - next,
-                                     WLAN_EID_TIMEOUT_INTERVAL);
-               }
-               for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC,
-                                   wpa_ie, wpa_ie_len) {
-                       if (elem->datalen >= 4) {
-                               if (WPA_GET_BE32(elem->data) ==
-                                   (sm->rsn_override_2 ?
-                                    RSNE_OVERRIDE_2_IE_VENDOR_TYPE :
-                                    RSNE_OVERRIDE_IE_VENDOR_TYPE))
-                                       override_rsne = &elem->id;
-                               if (WPA_GET_BE32(elem->data) ==
-                                   RSNXE_OVERRIDE_IE_VENDOR_TYPE)
-                                       override_rsnxe = &elem->id;
-                       }
-               }
-               wpa_hexdump(MSG_DEBUG, "EAPOL-Key msg 3/4 IEs before edits",
-                           wpa_ie, wpa_ie_len);
-               wpa_ie_buf3 = os_malloc(wpa_ie_len);
-               if (!wpa_ie_buf3)
-                       goto done;
-               pos = wpa_ie_buf3;
-               if (override_rsne) {
-                       *pos++ = WLAN_EID_RSN;
-                       *pos++ = override_rsne[1] - 4;
-                       os_memcpy(pos, &override_rsne[2 + 4],
-                                 override_rsne[1] - 4);
-                       pos += override_rsne[1] - 4;
-               }
-               if (mde) {
-                       os_memcpy(pos, mde, 2 + mde[1]);
-                       pos += 2 + mde[1];
-               }
-               if (fte) {
-                       os_memcpy(pos, fte, 2 + fte[1]);
-                       pos += 2 + fte[1];
-               }
-               if (tie) {
-                       os_memcpy(pos, tie, 2 + tie[1]);
-                       pos += 2 + tie[1];
-               }
-               if (tie2) {
-                       os_memcpy(pos, tie2, 2 + tie2[1]);
-                       pos += 2 + tie2[1];
-               }
-               if (override_rsnxe) {
-                       *pos++ = WLAN_EID_RSNX;
-                       *pos++ = override_rsnxe[1] - 4;
-                       os_memcpy(pos, &override_rsnxe[2 + 4],
-                                 override_rsnxe[1] - 4);
-                       pos += override_rsnxe[1] - 4;
-               }
-               wpa_ie = wpa_ie_buf3;
-               wpa_ie_len = pos - wpa_ie_buf3;
-               wpa_hexdump(MSG_DEBUG, "EAPOL-Key msg 3/4 IEs after edits",
-                           wpa_ie, wpa_ie_len);
-       } else if ((conf->rsn_override_key_mgmt ||
-                   conf->rsn_override_key_mgmt_2) &&
-                  !sm->rsn_override && !sm->rsn_override_2) {
+       if ((conf->rsn_override_key_mgmt || conf->rsn_override_key_mgmt_2) &&
+           !rsn_is_snonce_cookie(sm->SNonce)) {
                u8 *ie;
                size_t ie_len;
                u32 ids[] = {
index 4f58f0737705c3088fbd78e9fca293c3ef50a5c2..8aa40606a2e40dc128792344ae2cd8fa1e031322 100644 (file)
@@ -3629,6 +3629,24 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
                return 0;
        }
 
+       if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
+               ie->rsne_override = pos;
+               ie->rsne_override_len = dlen;
+               return 0;
+       }
+
+       if (selector == RSNE_OVERRIDE_2_IE_VENDOR_TYPE) {
+               ie->rsne_override_2 = pos;
+               ie->rsne_override_2_len = dlen;
+               return 0;
+       }
+
+       if (selector == RSNXE_OVERRIDE_IE_VENDOR_TYPE) {
+               ie->rsnxe_override = pos;
+               ie->rsnxe_override_len = dlen;
+               return 0;
+       }
+
        if (selector == RSN_SELECTION_IE_VENDOR_TYPE) {
                ie->rsn_selection = p;
                ie->rsn_selection_len = left;
index 4cb5b8c602c50abf85ac4cca7a5d679332bae978..f3ee1d51e3e27eeb274b2bfcf455ebde7b098261 100644 (file)
@@ -714,6 +714,12 @@ struct wpa_eapol_ie_parse {
        size_t wmm_len;
        const u8 *rsn_selection;
        size_t rsn_selection_len;
+       const u8 *rsne_override;
+       size_t rsne_override_len;
+       const u8 *rsne_override_2;
+       size_t rsne_override_2_len;
+       const u8 *rsnxe_override;
+       size_t rsnxe_override_len;
        u16 valid_mlo_gtks; /* bitmap of valid link GTK KDEs */
        const u8 *mlo_gtk[MAX_NUM_MLD_LINKS];
        size_t mlo_gtk_len[MAX_NUM_MLD_LINKS];
index 0a1d4d07f35073c9d72af01bcabfbb22cfaf3e27..0aa98276c5d7c3cb74802e83186347bb807a3ffe 100644 (file)
@@ -2228,6 +2228,69 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
                return -1;
        }
 
+       if (sm->proto == WPA_PROTO_RSN &&
+           sm->rsn_override != RSN_OVERRIDE_NOT_USED) {
+               if ((sm->ap_rsne_override && !ie->rsne_override) ||
+                   (!sm->ap_rsne_override && ie->rsne_override) ||
+                   (sm->ap_rsne_override && ie->rsne_override &&
+                    (sm->ap_rsne_override_len != ie->rsne_override_len ||
+                     os_memcmp(sm->ap_rsne_override, ie->rsne_override,
+                               sm->ap_rsne_override_len) != 0))) {
+                       wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+                               "RSN: RSNE Override element mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
+                       wpa_hexdump(MSG_INFO,
+                                   "RSNE Override element in Beacon/ProbeResp",
+                                   sm->ap_rsne_override,
+                                   sm->ap_rsne_override_len);
+                       wpa_hexdump(MSG_INFO,
+                                   "RSNE Override element in EAPOL-Key msg 3/4",
+                                   ie->rsne_override, ie->rsne_override_len);
+                       wpa_sm_deauthenticate(sm,
+                                             WLAN_REASON_IE_IN_4WAY_DIFFERS);
+                       return -1;
+               }
+
+               if ((sm->ap_rsne_override_2 && !ie->rsne_override_2) ||
+                   (!sm->ap_rsne_override_2 && ie->rsne_override_2) ||
+                   (sm->ap_rsne_override_2 && ie->rsne_override_2 &&
+                    (sm->ap_rsne_override_2_len != ie->rsne_override_2_len ||
+                     os_memcmp(sm->ap_rsne_override_2, ie->rsne_override_2,
+                               sm->ap_rsne_override_2_len) != 0))) {
+                       wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+                               "RSN: RSNE Override 2 element mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
+                       wpa_hexdump(MSG_INFO,
+                                   "RSNE Override 2 element in Beacon/ProbeResp",
+                                   sm->ap_rsne_override_2,
+                                   sm->ap_rsne_override_2_len);
+                       wpa_hexdump(MSG_INFO,
+                                   "RSNE Override 2 element in EAPOL-Key msg 3/4",
+                                   ie->rsne_override_2, ie->rsne_override_2_len);
+                       wpa_sm_deauthenticate(sm,
+                                             WLAN_REASON_IE_IN_4WAY_DIFFERS);
+                       return -1;
+               }
+
+               if ((sm->ap_rsnxe_override && !ie->rsnxe_override) ||
+                   (!sm->ap_rsnxe_override && ie->rsnxe_override) ||
+                   (sm->ap_rsnxe_override && ie->rsnxe_override &&
+                    (sm->ap_rsnxe_override_len != ie->rsnxe_override_len ||
+                     os_memcmp(sm->ap_rsnxe_override, ie->rsnxe_override,
+                               sm->ap_rsnxe_override_len) != 0))) {
+                       wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+                               "RSN: RSNXE Override element mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
+                       wpa_hexdump(MSG_INFO,
+                                   "RSNXE Override element in Beacon/ProbeResp",
+                                   sm->ap_rsnxe_override,
+                                   sm->ap_rsnxe_override_len);
+                       wpa_hexdump(MSG_INFO,
+                                   "RSNXE Override element in EAPOL-Key msg 3/4",
+                                   ie->rsnxe_override, ie->rsnxe_override_len);
+                       wpa_sm_deauthenticate(sm,
+                                             WLAN_REASON_IE_IN_4WAY_DIFFERS);
+                       return -1;
+               }
+       }
+
 #ifdef CONFIG_IEEE80211R
        if (wpa_key_mgmt_ft(sm->key_mgmt) &&
            wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
@@ -4208,6 +4271,9 @@ void wpa_sm_deinit(struct wpa_sm *sm)
        os_free(sm->ap_wpa_ie);
        os_free(sm->ap_rsn_ie);
        os_free(sm->ap_rsnxe);
+       os_free(sm->ap_rsne_override);
+       os_free(sm->ap_rsne_override_2);
+       os_free(sm->ap_rsnxe_override);
        for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
                os_free(sm->mlo.links[i].ap_rsne);
                os_free(sm->mlo.links[i].ap_rsnxe);
@@ -4813,6 +4879,23 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
 }
 
 
+static const u8 * wpa_sm_get_ap_rsne(struct wpa_sm *sm, size_t *len)
+{
+       if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE) {
+               *len = sm->ap_rsne_override_len;
+               return sm->ap_rsne_override;
+       }
+
+       if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE_2) {
+               *len = sm->ap_rsne_override_2_len;
+               return sm->ap_rsne_override_2;
+       }
+
+       *len = sm->ap_rsn_ie_len;
+       return sm->ap_rsn_ie;
+}
+
+
 /**
  * wpa_sm_get_status - Get WPA state machine
  * @sm: Pointer to WPA state machine data from wpa_sm_init()
@@ -4830,6 +4913,10 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
 {
        char *pos = buf, *end = buf + buflen;
        int ret;
+       const u8 *rsne;
+       size_t rsne_len;
+
+       rsne = wpa_sm_get_ap_rsne(sm, &rsne_len);
 
        ret = os_snprintf(pos, end - pos,
                          "pairwise_cipher=%s\n"
@@ -4851,10 +4938,10 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
        }
 #endif /* CONFIG_DPP2 */
 
-       if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) {
+       if (sm->mfp != NO_MGMT_FRAME_PROTECTION && rsne) {
                struct wpa_ie_data rsn;
-               if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
-                   >= 0 &&
+
+               if (wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) >= 0 &&
                    rsn.capabilities & (WPA_CAPABILITY_MFPR |
                                        WPA_CAPABILITY_MFPC)) {
                        ret = os_snprintf(pos, end - pos, "pmf=%d\n"
@@ -4876,11 +4963,15 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
 int wpa_sm_pmf_enabled(struct wpa_sm *sm)
 {
        struct wpa_ie_data rsn;
+       const u8 *rsne;
+       size_t rsne_len;
+
+       rsne = wpa_sm_get_ap_rsne(sm, &rsne_len);
 
-       if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie)
+       if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !rsne)
                return 0;
 
-       if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 &&
+       if (wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) >= 0 &&
            rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
                return 1;
 
@@ -4903,12 +4994,14 @@ int wpa_sm_ext_key_id_active(struct wpa_sm *sm)
 int wpa_sm_ocv_enabled(struct wpa_sm *sm)
 {
        struct wpa_ie_data rsn;
+       const u8 *rsne;
+       size_t rsne_len;
 
-       if (!sm->ocv || !sm->ap_rsn_ie)
+       rsne = wpa_sm_get_ap_rsne(sm, &rsne_len);
+       if (!sm->ocv || !rsne)
                return 0;
 
-       return wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len,
-                                   &rsn) >= 0 &&
+       return wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) >= 0 &&
                (rsn.capabilities & WPA_CAPABILITY_OCVC);
 }
 
@@ -5145,24 +5238,11 @@ int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
                sm->ap_rsn_ie_len = 0;
        } else {
                wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
-               if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) {
-                       sm->ap_rsn_ie = os_malloc(len - 4);
-                       if (!sm->ap_rsn_ie)
-                               return -1;
-                       sm->ap_rsn_ie[0] = WLAN_EID_RSN;
-                       sm->ap_rsn_ie[1] = len - 2 - 4;
-                       os_memcpy(&sm->ap_rsn_ie[2], ie + 2 + 4, len - 2 - 4);
-                       sm->ap_rsn_ie_len = len - 4;
-                       wpa_hexdump(MSG_DEBUG,
-                                   "RSN: Converted RSNE override to RSNE",
-                                   sm->ap_rsn_ie, sm->ap_rsn_ie_len);
-               } else {
-                       sm->ap_rsn_ie = os_memdup(ie, len);
-                       if (sm->ap_rsn_ie == NULL)
-                               return -1;
+               sm->ap_rsn_ie = os_memdup(ie, len);
+               if (sm->ap_rsn_ie == NULL)
+                       return -1;
 
-                       sm->ap_rsn_ie_len = len;
-               }
+               sm->ap_rsn_ie_len = len;
        }
 
        return 0;
@@ -5191,24 +5271,86 @@ int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)
                sm->ap_rsnxe_len = 0;
        } else {
                wpa_hexdump(MSG_DEBUG, "WPA: set AP RSNXE", ie, len);
-               if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) {
-                       sm->ap_rsnxe = os_malloc(len - 4);
-                       if (!sm->ap_rsnxe)
-                               return -1;
-                       sm->ap_rsnxe[0] = WLAN_EID_RSNX;
-                       sm->ap_rsnxe[1] = len - 2 - 4;
-                       os_memcpy(&sm->ap_rsnxe[2], ie + 2 + 4, len - 2 - 4);
-                       sm->ap_rsnxe_len = len - 4;
-                       wpa_hexdump(MSG_DEBUG,
-                                   "RSN: Converted RSNXE override to RSNXE",
-                                   sm->ap_rsnxe, sm->ap_rsnxe_len);
-               } else {
-                       sm->ap_rsnxe = os_memdup(ie, len);
-                       if (!sm->ap_rsnxe)
-                               return -1;
+               sm->ap_rsnxe = os_memdup(ie, len);
+               if (!sm->ap_rsnxe)
+                       return -1;
 
-                       sm->ap_rsnxe_len = len;
-               }
+               sm->ap_rsnxe_len = len;
+       }
+
+       return 0;
+}
+
+
+int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len)
+{
+       if (!sm)
+               return -1;
+
+       os_free(sm->ap_rsne_override);
+       if (!ie || len == 0) {
+               wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+                       "RSN: Clearing AP RSNE Override element");
+               sm->ap_rsne_override = NULL;
+               sm->ap_rsne_override_len = 0;
+       } else {
+               wpa_hexdump(MSG_DEBUG, "RSN: Set AP RSNE Override element",
+                           ie, len);
+               sm->ap_rsne_override = os_memdup(ie, len);
+               if (!sm->ap_rsne_override)
+                       return -1;
+
+               sm->ap_rsne_override_len = len;
+       }
+
+       return 0;
+}
+
+
+int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie, size_t len)
+{
+       if (!sm)
+               return -1;
+
+       os_free(sm->ap_rsne_override_2);
+       if (!ie || len == 0) {
+               wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+                       "RSN: Clearing AP RSNE Override 2 element");
+               sm->ap_rsne_override_2 = NULL;
+               sm->ap_rsne_override_2_len = 0;
+       } else {
+               wpa_hexdump(MSG_DEBUG, "RSN: Set AP RSNE Override 2 element",
+                           ie, len);
+               sm->ap_rsne_override_2 = os_memdup(ie, len);
+               if (!sm->ap_rsne_override_2)
+                       return -1;
+
+               sm->ap_rsne_override_2_len = len;
+       }
+
+       return 0;
+}
+
+
+int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len)
+{
+       if (!sm)
+               return -1;
+
+       os_free(sm->ap_rsnxe_override);
+       if (!ie || len == 0) {
+               wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+                       "RSN: Clearing AP RSNXE Override element");
+               sm->ap_rsnxe_override = NULL;
+               sm->ap_rsnxe_override_len = 0;
+       } else {
+               wpa_hexdump(MSG_DEBUG, "RSN: Set AP RSNXE Override element",
+                           ie, len);
+               sm->ap_rsnxe_override = os_memdup(ie, len);
+               if (!sm->ap_rsnxe_override)
+                       return -1;
+
+               sm->ap_rsnxe_override_len = len;
        }
 
        return 0;
index f8346e1ef494f4598b9aca36ea39e25b6502e985..9337ea001ec27947eaa0679f1c09dd6c4ed635e5 100644 (file)
@@ -212,6 +212,9 @@ int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
 int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
 int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
 int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
+int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len);
+int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie, size_t len);
+int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len);
 int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen);
 
 int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
@@ -356,6 +359,24 @@ static inline int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie,
        return -1;
 }
 
+static inline int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie,
+                                             size_t len)
+{
+       return -1;
+}
+
+static inline int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie,
+                                               size_t len)
+{
+       return -1;
+}
+
+static inline int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie,
+                                              size_t len)
+{
+       return -1;
+}
+
 static inline int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
 {
        return 0;
index 6e47975771908617a27325328cbf249e1cd8bef6..8ac4fe1eb80af65bcc035849bcdde56d26deb61b 100644 (file)
@@ -120,6 +120,9 @@ struct wpa_sm {
        size_t assoc_rsnxe_len;
        u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe;
        size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len;
+       u8 *ap_rsne_override, *ap_rsne_override_2, *ap_rsnxe_override;
+       size_t ap_rsne_override_len, ap_rsne_override_2_len,
+               ap_rsnxe_override_len;
 
 #ifdef CONFIG_TDLS
        struct wpa_tdls_peer *tdls;
index acb8f0168c7d887fb89d9c6b2887145b16b64c5d..1e77493ef229e82f2687b8c56e02177ad40340cc 100644 (file)
@@ -416,6 +416,9 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
        wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
        wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
        wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0);
+       wpa_sm_set_ap_rsne_override(wpa_s->wpa, NULL, 0);
+       wpa_sm_set_ap_rsne_override_2(wpa_s->wpa, NULL, 0);
+       wpa_sm_set_ap_rsnxe_override(wpa_s->wpa, NULL, 0);
        wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
        wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
        wpa_s->rsnxe_len = 0;
@@ -1833,12 +1836,31 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
                         !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
 
        if (bss || !wpa_s->ap_ies_from_associnfo) {
+               const u8 *rsnoe = NULL, *rsno2e = NULL, *rsnxoe = NULL;
+
+               if (bss) {
+                       bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+                       bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+                       rsnoe = wpa_bss_get_vendor_ie(
+                               bss, RSNE_OVERRIDE_IE_VENDOR_TYPE);
+                       rsno2e = wpa_bss_get_vendor_ie(
+                               bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
+                       rsnxoe = wpa_bss_get_vendor_ie(
+                               bss, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
+               }
+
                if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
                                         bss_wpa ? 2 + bss_wpa[1] : 0) ||
                    wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
                                         bss_rsn ? 2 + bss_rsn[1] : 0) ||
                    wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx,
-                                       bss_rsnx ? 2 + bss_rsnx[1] : 0))
+                                       bss_rsnx ? 2 + bss_rsnx[1] : 0) ||
+                   wpa_sm_set_ap_rsne_override(wpa_s->wpa, rsnoe,
+                                               rsnoe ? 2 + rsnoe[1] : 0) ||
+                   wpa_sm_set_ap_rsne_override_2(wpa_s->wpa, rsno2e,
+                                                 rsno2e ? 2 + rsno2e[1] : 0) ||
+                   wpa_sm_set_ap_rsnxe_override(wpa_s->wpa, rsnxoe,
+                                                rsnxoe ? 2 + rsnxoe[1] : 0))
                        return -1;
        }
 
index 9100bee0541f8f63077c6e219b27759cf3631506..30e4876eefb0ee3cb66b7fbac4b41e7b7d2021fe 100644 (file)
@@ -425,13 +425,29 @@ static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
                if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
                        ret = -1;
 
-               ie = wpa_bss_get_rsne(wpa_s, curr, ssid, false);
+               ie = wpa_bss_get_ie(curr, WLAN_EID_RSN);
                if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
                        ret = -1;
 
-               ie = wpa_bss_get_rsnxe(wpa_s, curr, ssid, false);
+               ie = wpa_bss_get_ie(curr, WLAN_EID_RSNX);
                if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
                        ret = -1;
+
+               ie = wpa_bss_get_vendor_ie(curr, RSNE_OVERRIDE_IE_VENDOR_TYPE);
+               if (wpa_sm_set_ap_rsne_override(wpa_s->wpa, ie,
+                                               ie ? 2 + ie[1] : 0))
+                       ret = -1;
+
+               ie = wpa_bss_get_vendor_ie(curr,
+                                          RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
+               if (wpa_sm_set_ap_rsne_override_2(wpa_s->wpa, ie,
+                                                 ie ? 2 + ie[1] : 0))
+                       ret = -1;
+
+               ie = wpa_bss_get_vendor_ie(curr, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
+               if (wpa_sm_set_ap_rsnxe_override(wpa_s->wpa, ie,
+                                                ie ? 2 + ie[1] : 0))
+                       ret = -1;
        } else {
                ret = -1;
        }