aboutsummaryrefslogtreecommitdiff
path: root/wpa_supplicant/sme.c
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant/sme.c')
-rw-r--r--wpa_supplicant/sme.c69
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;