diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 2e083fe4e..ba9a5ac2e 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -327,6 +327,7 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) wpas_rrm_reset(wpa_s); wpa_s->wnmsleep_used = 0; wnm_clear_coloc_intf_reporting(wpa_s); + wpa_s->disable_mbo_oce = 0; #ifdef CONFIG_TESTING_OPTIONS wpa_s->last_tk_alg = WPA_ALG_NONE; @@ -540,9 +541,6 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, const u8 *rsn_ie, *wpa_ie; int ret; int wep_ok; -#ifdef CONFIG_MBO - const u8 *oce_capa_attr; -#endif /* CONFIG_MBO */ ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss); if (ret >= 0) @@ -631,21 +629,6 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, " skip RSN IE - no mgmt frame protection enabled but AP requires it"); break; } -#ifdef CONFIG_MBO - oce_capa_attr = wpas_mbo_get_bss_attr(bss, - OCE_ATTR_ID_CAPA_IND); - if (!(ie.capabilities & WPA_CAPABILITY_MFPC) && - (wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_AP_CAPA_IND) || - (oce_capa_attr && oce_capa_attr[1] >= 1 && - !(oce_capa_attr[2] & OCE_IS_STA_CFON))) && - wpas_get_ssid_pmf(wpa_s, ssid) != - NO_MGMT_FRAME_PROTECTION) { - if (debug_print) - wpa_dbg(wpa_s, MSG_DEBUG, - " skip RSN IE - no mgmt frame protection enabled on MBO/OCE AP"); - break; - } -#endif /* CONFIG_MBO */ if (debug_print) wpa_dbg(wpa_s, MSG_DEBUG, diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c index 43b1fa7be..3df86ef07 100644 --- a/wpa_supplicant/mbo.c +++ b/wpa_supplicant/mbo.c @@ -15,6 +15,7 @@ #include "utils/common.h" #include "common/ieee802_11_defs.h" #include "common/gas.h" +#include "rsn_supp/wpa.h" #include "config.h" #include "wpa_supplicant_i.h" #include "driver_i.h" @@ -82,6 +83,35 @@ const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr) } +void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, + struct wpa_ssid *ssid) +{ + const u8 *rsne, *mbo, *oce; + struct wpa_ie_data ie; + + wpa_s->disable_mbo_oce = 0; + if (!bss) + return; + mbo = wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_AP_CAPA_IND); + oce = wpas_mbo_get_bss_attr(bss, OCE_ATTR_ID_CAPA_IND); + if (!mbo && !oce) + return; + if (oce && oce[1] >= 1 && (oce[2] & OCE_IS_STA_CFON)) + return; /* STA-CFON is not required to enable PMF */ + rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN); + if (!rsne || wpa_parse_wpa_ie(rsne, 2 + rsne[1], &ie) < 0) + return; /* AP is not using RSN */ + + if (!(ie.capabilities & WPA_CAPABILITY_MFPC)) + wpa_s->disable_mbo_oce = 1; /* AP uses RSN without PMF */ + if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION) + wpa_s->disable_mbo_oce = 1; /* STA uses RSN without PMF */ + if (wpa_s->disable_mbo_oce) + wpa_printf(MSG_INFO, + "MBO: Disable MBO/OCE due to misbehaving AP not having enabled PMF"); +} + + static void wpas_mbo_non_pref_chan_attr_body(struct wpa_supplicant *wpa_s, struct wpabuf *mbo, u8 start, u8 end) diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 8003d2c39..ad533a148 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -619,7 +619,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, #ifdef CONFIG_MBO mbo_ie = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE); - if (mbo_ie) { + if (!wpa_s->disable_mbo_oce && mbo_ie) { int len; len = wpas_mbo_ie(wpa_s, wpa_s->sme.assoc_req_ie + diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index 92dbdbab5..270be9e2e 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -1369,7 +1369,7 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s, const u8 *vendor; #endif /* CONFIG_MBO */ - if (wpa_s->conf->disable_btm) + if (wpa_s->disable_mbo_oce || wpa_s->conf->disable_btm) return; if (end - pos < 5) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 6fb4efb5f..e7ddaa1d0 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1720,7 +1720,7 @@ static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx) case 2: /* Bits 16-23 */ #ifdef CONFIG_WNM *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */ - if (!wpa_s->conf->disable_btm) + if (!wpa_s->disable_mbo_oce && !wpa_s->conf->disable_btm) *pos |= 0x08; /* Bit 19 - BSS Transition */ #endif /* CONFIG_WNM */ break; @@ -2074,6 +2074,10 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, bss->ie_len); #endif /* CONFIG_TDLS */ +#ifdef CONFIG_MBO + wpas_mbo_check_pmf(wpa_s, bss, ssid); +#endif /* CONFIG_MBO */ + if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) && ssid->mode == WPAS_MODE_INFRA) { sme_authenticate(wpa_s, bss, ssid); @@ -2832,7 +2836,7 @@ static u8 * wpas_populate_assoc_ies( #ifdef CONFIG_MBO mbo_ie = bss ? wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE) : NULL; - if (mbo_ie) { + if (!wpa_s->disable_mbo_oce && mbo_ie) { int len; len = wpas_mbo_ie(wpa_s, wpa_ie + wpa_ie_len, @@ -5985,7 +5989,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, hs20_init(wpa_s); #endif /* CONFIG_HS20 */ #ifdef CONFIG_MBO - if (wpa_s->conf->oce) { + if (!wpa_s->disable_mbo_oce && wpa_s->conf->oce) { if ((wpa_s->conf->oce & OCE_STA) && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OCE_STA)) wpa_s->enable_oce = OCE_STA; diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 63f2f5960..af938064b 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -756,6 +756,7 @@ struct wpa_supplicant { unsigned int connection_ht:1; unsigned int connection_vht:1; unsigned int connection_he:1; + unsigned int disable_mbo_oce:1; struct os_reltime last_mac_addr_change; int last_mac_addr_style; @@ -1396,6 +1397,8 @@ int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len, int add_oce_capa); const u8 * mbo_attr_from_mbo_ie(const u8 *mbo_ie, enum mbo_attr_id attr); const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr); +void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, + struct wpa_ssid *ssid); const u8 * mbo_get_attr_from_ies(const u8 *ies, size_t ies_len, enum mbo_attr_id attr); int wpas_mbo_update_non_pref_chan(struct wpa_supplicant *wpa_s,