diff options
Diffstat (limited to 'wpa_supplicant/sme.c')
-rw-r--r-- | wpa_supplicant/sme.c | 69 |
1 files changed, 56 insertions, 13 deletions
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index ea4023c8..8068f1ef 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -378,10 +378,12 @@ static void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s, } -static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) +static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, + struct wpa_ssid *ssid) { struct wpabuf *mlbuf; - const u8 *rnr_ie, *pos; + const u8 *rnr_ie, *pos, *rsn_ie; + struct wpa_ie_data ie; u8 ml_ie_len, rnr_ie_len; const struct ieee80211_eht_ml *eht_ml; const struct eht_ml_basic_common_info *ml_basic_common_info; @@ -402,6 +404,26 @@ static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) return false; } + rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN); + if (!rsn_ie || wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) { + wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RSN element"); + goto out; + } + + if (!(ie.capabilities & WPA_CAPABILITY_MFPC) || + wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION) { + wpa_dbg(wpa_s, MSG_DEBUG, + "MLD: No management frame protection"); + goto out; + } + + ie.key_mgmt &= ~(WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK | + WPA_KEY_MGMT_PSK_SHA256); + if (!(ie.key_mgmt & ssid->key_mgmt)) { + wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No valid key management"); + goto out; + } + ml_ie_len = wpabuf_len(mlbuf); /* control + common info len + MLD address + MLD link information */ @@ -525,20 +547,28 @@ 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; if (ieee802_11_parse_elems(data->auth.ies + ie_offset, data->auth.ies_len - ie_offset, - &elems, 0) != ParseOK) { + &elems, 0) == ParseFailed) { wpa_printf(MSG_DEBUG, "MLD: Failed parsing elements"); goto out; } 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); @@ -604,7 +634,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, params.ssid_len = bss->ssid_len; params.p2p = ssid->p2p_group; - if (wpas_ml_element(wpa_s, bss)) { + if (wpas_ml_element(wpa_s, bss, ssid)) { wpa_printf(MSG_DEBUG, "MLD: In authentication"); params.mld = true; params.mld_link_id = wpa_s->mlo_assoc_link_id; @@ -1596,20 +1626,28 @@ 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; if (ieee802_11_parse_elems(data + ie_offset, len - ie_offset, - &elems, 0) != ParseOK) { + &elems, 0) == ParseFailed) { wpa_printf(MSG_DEBUG, "MLD: Failed parsing elements"); return -1; } 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); @@ -1623,7 +1661,8 @@ static int sme_external_ml_auth(struct wpa_supplicant *wpa_s, if (os_memcmp(wpa_s->sme.ext_auth_ap_mld_addr, mld_addr, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, "MLD: Unexpected MLD address (expected " - MACSTR ")", MAC2STR(wpa_s->ap_mld_addr)); + MACSTR ")", + MAC2STR(wpa_s->sme.ext_auth_ap_mld_addr)); return -1; } @@ -1714,7 +1753,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( @@ -1741,7 +1781,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( @@ -1840,7 +1881,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); @@ -1856,7 +1898,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; |