[wpa_supplicant] cumilative patch from commit 92374d59d
This merge is done mainly to support RSNE overriding for STA.
Bug: 348669010
Bug: 355076858
Test: Connect to open, WPA2, WPA3 and OWE
Test: Establish P2P connection
Test: Basic SoftAp tests
Test: Ran above tests on Pixel6
Test: Regression test (b/355078233)
BYPASS_INCLUSIVE_LANGUAGE_REASON=Merged from open source
92374d59d Enhance select_network() to trigger new scans in some cases
ff99012d8 RSNO: Use correct MLO capability while fetching RSNE/RSNXE
526ea193c Fallback to RSNXE when AP is not using valid RSN Overrding
4417b5ba8 Add QCA vendor interface to support Unsynchronized Service Discovery
765c48d5a RSNE/RSNXE overriding for STA
d0b55eb36 Make driver capabilities for AKM suites available within wpa_supplicant
5488e120d Use helper functions to access RSNE/RSNXE from BSS entries
341bcb2b5 nl80211: Add a capability flag for RSN overriding
6fad7224b Add QCA vendor feature flags to indicate RSN override elements support
157b01638 RSNE/RSNXE overriding for AP
b8a2d11ae Allow RSNXE Override element to override RSNXE contents during parsing
48ca68f6f Allow RSNE Override element to override RSNE contents during parsing
c16ac89be Add RSN overriding elements into IE parsing
6b0ce29d2 Define WFA vendor specific element types for RSNE/RSNXE overriding
e99cdfae4 The main branch is now used for v2.12 development
d945ddd36 Preparations for v2.11 release
aa2dfae5e dbus: Fix memory leak with Bonjour params for a P2P UPnP service
70e5bad56 dbus: Fix SignalChange property
ed5887a8c Move NULL check for driver private data (drv_priv)
c3d305d93 FT: Fix FTE MIC calculation with fragmented FTE
e7172e26d MLD STA: Find partner links by BSSID and SSID
816e22bba hostapd: Fix opclass during CSA with DFS channels
93a3c59ad Multi-AP: Honor wds_sta even with multi_ap
7d51bf2ab SAE: Drop default dot11RSNASAESync value from 5 to 3
5da59ff1c SAE: Disable protocol instance temporarily on sync error in mesh
7b8517d19 nl80211: Fix AP scan with STA fallback error path
6ad59779c nl80211: NAN: Register multicast action frames if possible
92829d8be NAN: Reject undefined publish type
44f20382c NAN: Fix a typo in USD doc
7c935eef3 nl80211: AP MLD: Reassign drv->ctx correctly to prevent hostapd crash
102365453 Make Beacon frame checks less frequent for SSID verification
fcf799c0d wpa_supplicant: Do not select a rejected SAE group
5f83f4db0 Add int_array_includes()
094e188f8 wpa_supplicant: Always clear SAE rejected groups on roaming to another BSS
627b67f29 ACS: Fix primary channel puncturing in ACS
be2ac9291 ACS: Fix ACS behavior for channel selection
83cfeb890 ACS: Update ACS documentation
cb91ef256 MLO: Swap Tx/Rx keys for GTK TKIP Michael MIC in MLO GTK KDE
7d314d6bd Fix channel switch without 'ht' for HE and EHT modes in 2.4 GHz band
99e82880e Fix mesh 6 GHz incorrect channel bandwidth
5452a4a30 SSID verification based on beacon protection
89b164138 BSS: Add wpa_bss_get_ie_beacon()
7436b5b01 Indicate if BIGTK has been set in STATUS output
c6f394b88 Indicate if SSID has been verified in STATUS output
b745cd33e PASN: Derive KDK on AP only when both ends support SecureLTF
e5f76b915 dbus: Fix error path in scan request handling
58b275955 trace: Only permit explicit prefix matching for functions
49344db09 trace: Use strncmp() to match function names
ac15b79fe PMKSA: Guard against NULL KCK for memcpy()
7bcede06e MLD: Ensure link_bssid array has space for sentinel
cf3883f3d MLD: Ensure link BSSIDs remain on stack for ignore
9f0429c9e dbus: Make sure ServiceDiscoveryRequest/Result does not override pointers
d22401d89 dbus: Fix memory leak in case dbus provides 'tlvs' in invalid P2P SD response
0c2d8417c dbus: Fix memory leak in case dbus provides tlv in P2P UPnP SD request
3b4f12708 nl80211: Use actual number of supported AKMs for AP setup
8f69e538a SecureLTF: Work around misbehaving STAs for PTK derivation without KDK
438a27b36 Do not derive SAE PT if the network profile does not include SAE
61eb89d5f nl80211: AP MLD: Parse link ID to determine the BSS for color event
5d16ad9ab nl80211: Refactor color collision related nl80211 commands handling
22a592d11 hostapd: Fix updating Beacon frames during association handling
9716bf116 SAE: Reject invalid Rejected Groups element in the parser
593a7c2f8 SAE: Check for invalid Rejected Groups element length explicitly on STA
5f98c853e nl80211: Send link ID with NL80211_CMD_TDLS_MGMT to enable TDLS with MLO
f302d9f96 RADIUS: Check Message-Authenticator if it is present even if not required
58097123e RADIUS: Require Message-Authenticator attribute in MAC ACL cases
934b0c3a4 Require Message-Authenticator in Access-Reject even without EAP-Message
f54157077 RADIUS DAS: Move Message-Authenticator attribute to be the first one
37fe8e48a hostapd: Move Message-Authenticator attribute to be the first one in req
689a24826 eapol_test: Move Message-Authenticator attribute to be the first one
54abb0d3c RADIUS server: Place Message-Authenticator attribute as the first one
adac846bd RADIUS: Allow Message-Authenticator attribute as the first attribute
d944ef1c0 SAE: Clear rejected groups list on completing authentication
0ab009db3 SAE: Clear rejected groups list on continuous failures
21fe04281 SAE: Clear peer_rejected_groups when no element is included
364c2da87 SAE: Check for invalid Rejected Groups element length explicitly
c9db4925f Vendor attribute to configure STA to follow AP preference for candidates
0cb42655f Vendor command extension for Responder PM Mode bit in TWT SET Request
9832f1324 Add vendor flag to indicate unavailability mode in TWT responder mode
761041b18 SAE: Free password identifier if SAE commit is rejected due to it
d97b5c649 Define Link Id attribute for secure ranging context vendor command
2097de2a6 Define Link Id attribute for QCA_NL80211_VENDOR_SUBCMD_PASN
c6e55fb96 Add Link ID for External ACS vendor command
37a289f8b SSID protection in 4-way handshake on AP
dab7549d6 SSID protection in 4-way handshake on STA
9a022cdc7 STA: Update scan results when BSS entry with current SSID is not found
320c4c8f8 AP MLD: Send link id to the driver during color change
ecfe2aa61 Update Beacon frames after color change
5913d1a18 Remove double "on" from debug prints in CCA event callbacks
d8e1a353a hostapd: Add support to change BSS color from the control interface
3e52a90d3 ACS: Handle scan start request failure with error code -EBUSY
3cf7bf68f AP MLD: Fix deferred first link BSS's authentication server init
2829f1c43 wlantest: Initial support for Multiple BSSID procedure
1b96745f1 Add a new QCA vendor attribute to set interface offload type
ffcb7392f Add vendor attributes to detect data stall for consecutive TX no ack
a5ee11e02 Add new traffic type values for flow report vendor attribute
2c89b56d6 WNM: Include BSS max idle period in STATUS command output
58ac46baf WNM: AP configuration to allow BSS max idle period requests
6594ea9ef WNM: Allow a specific BSS max idle period to be requested
6cd023111 WNM: Group rekeying skipping with BSS max idle period management
846b1d618 WNM: Configurable BSS Max Idle Period management on AP
7566370a9 Add QCA vendor attribute to get number of TX/RX packets for each NSS
4c0ea8270 Add vendor attributes to configure TX/RX NSS and chains per band
c484a0fca Add kernel documentation for nss and chain configuration vendor command
cb40986a7 Add QCA vendor attribute for uplink delay jitter
ed56dfc33 P2P: Fix fast IP address allocation for invitation of a persistent group
0ae087994 Add a new QCA vendor attribute to set reduced power scan mode
bd36dc90f AP MLD: Remove unused get_ml_rsn_info callback definition
51b5b9512 Update Probe Response template on BSS color change
6f1fbebeb Update Probe Response template on channel switch
7d0c08910 More generic unsolicited broadcast Probe Response template setup
195cc3d91 Make selection of current opclass more generic for 20 MHz UNI-III channels
b9113105a FILS: Add Operating Class and Primary Channel in FD for non-PSC chan
5929b4eb1 Define QCA vendor commands for flow stats/classification
5308029f8 nl80211: Update link bandwidth when receiving channel switch event
11dfdf64c AP MLD: Set link_id field in hostapd_freq_params when setting up AP
df14f1e2b Add QCA vendor subcommand to suspend/resume AP interface
df5988004 AP MLD: Add MLO Link KDE for each affiliated link in EAPOL-Key 3/4
b26971774 AP MLD: Do not store per-supplicant AP RSNE/RSNXE information
20872d525 AP MLD: Do not store per-supplicant AP link MAC address information
3b68eef7d AP MLD: Do not store per-supplicant AP MLD MAC address information
ed78f56dc Add a vendor attribute value to set aggressive roaming mode
e6ec62aa2 Allow Session-Timeout with PSK RADIUS during 4-way handshake
f44a07d5c wpa_cli: Make WPA_EVENT_CHANNEL_SWITCH events accessible to action scripts
2e1f7d091 Fix center segment indexes in channel switch fallback to non-5 GHz cases
7cf3ceada P2P: Call normal SD query callback on RX/TX race
9b1e0ab4e dbus: Use correct values for persistent group
cf36ffd43 wpa_supplicant: Do not allow fast associate before scanning 6 GHz
ff798fbb8 ctrl_iface: Allow sending ML probe without AP MLD ID
4d2f76fab MLD: Use AP MLD MAC address with deauthenticate
5d9b4a1a1 SME: MLD: Clear MLD state only after the deauthentication
39fefeada SME: MLD: Deauthenticate when failing to parse ML element
6f3e7c5d3 wpa_supplicant: Do not roam to an associated link
2bbe4822a Clear connect_without_scan on network profile removal
b3ad54e46 Check whether to skip a BSS in RNR with a shared helper
de1bfda64 Fix RNR building for co-location and MLO
8d434bf65 AP MLD: Add link details in STATUS command
b1e463374 AP MLD: Link-specific flushing of stations
5e3c2b489 AP MLD: Run authenticator state machine for all links
12acda633 AP MLD: Support group rekeying for MLO
62a8f96e5 AP MLD: Calculate ML KDE length separately for each link
78adbf2c0 AP MLD: Mark GKeyDone completed for STAs in a helper function
e5b49876a AP MLD: Debug print of MLO KDE lengths
84d2a36da AP MLD: Require same AKM and pairwise cipher for all links
8891ebdc1 Use defined values for RSN PN length
3ea7cf11d AP MLD: Enhance authenticator state machine
19fdcf511 AP MLD: Skip association link processing in ML info
4a1197acd AP MLD: Update all partner links' beacons
a51881032 AP MLD: Handle link_id in EAPOL RX handler
eea52c4b5 AP MLD: Handle link_id in EAPOL TX status handler
636530bc2 hostapd: Make hostapd_eapol_tx_status() function static
93d204b1e nl80211: Move control port TX status to per BSS handling
efb484bbc nl80211: Move Management frame TX status to per BSS handling
80864d011 AP MLD/nl80211: Pass ctx in mlme_event_mgmt()
c36ad1150 AP MLD: Use link_id in the get_hapd_bssid() helper function
d9c5d601f AP NLD: Extend support for cohosted ML BSS
3d0cc612f AP MLD: Support cohosted ML BSS
9098535ef AP MLD: Reset authenticator state machine's ML info
866ed6324 Remove the bssid argument from send_auth_reply()
fd1a35e14 AP MLD: Handle authentication and association on link address
e4e772456 AP MLD: Use if/else/endif comments more consistently
9fcc636da nl80211: Restore libnl3-route inclusion for full VLAN support with netlink
61c8cc94f Add a vendor attribute to configure custom keep-alive interval for STA
47d1307d2 Add QCA vendor interface for reporting station info in unicast event
3c79173c3 Add TWT responder support for AP in HT and VHT modes
54b1df85c Add QCA vendor feature flag for TWT responder support in HT and VHT modes
85ea5f349 nl80211: Send link_id on sta_deauth()
62e0c1019 nl80211: Print the interface name in debug during link add
e8764518b nl80211: Generate link add command on per-BSS basis for AP MLD
16aea07e5 AP MLD: Simplify for_each_mld_link() macro
d43eb71da hostapd: Add support for testing Probe Response frame elements
Change-Id: I445ef0fed93ec7d4443ed33751318a46899e61e7
Signed-off-by: Sunil Ravi <sunilravi@google.com>
diff --git a/wpa_supplicant/ChangeLog b/wpa_supplicant/ChangeLog
index efcc6cd..3f4162e 100644
--- a/wpa_supplicant/ChangeLog
+++ b/wpa_supplicant/ChangeLog
@@ -1,5 +1,55 @@
ChangeLog for wpa_supplicant
+2024-07-20 - v2.11
+ * Wi-Fi Easy Connect
+ - add support for DPP release 3
+ - allow Configurator parameters to be provided during config exchange
+ * MACsec
+ - add support for GCM-AES-256 cipher suite
+ - remove incorrect EAP Session-Id length constraint
+ - add hardware offload support for additional drivers
+ * HE/IEEE 802.11ax/Wi-Fi 6
+ - support BSS color updates
+ - various fixes
+ * EHT/IEEE 802.11be/Wi-Fi 7
+ - add preliminary support
+ * support OpenSSL 3.0 API changes
+ * improve EAP-TLS support for TLSv1.3
+ * EAP-SIM/AKA: support IMSI privacy
+ * improve mitigation against DoS attacks when PMF is used
+ * improve 4-way handshake operations
+ - discard unencrypted EAPOL frames in additional cases
+ - use Secure=1 in message 2 during PTK rekeying
+ * OCV: do not check Frequency Segment 1 Channel Number for 160 MHz cases
+ to avoid interoperability issues
+ * support new SAE AKM suites with variable length keys
+ * support new AKM for 802.1X/EAP with SHA384
+ * improve cross-AKM roaming with driver-based SME/BSS selection
+ * PASN
+ - extend support for secure ranging
+ - allow PASN implementation to be used with external programs for
+ Wi-Fi Aware
+ * FT: Use SHA256 to derive PMKID for AKM 00-0F-AC:3 (FT-EAP)
+ - this is based on additional details being added in the IEEE 802.11
+ standard
+ - the new implementation is not backwards compatible, but PMKSA
+ caching with FT-EAP was, and still is, disabled by default
+ * support a pregenerated MAC (mac_addr=3) as an alternative mechanism
+ for using per-network random MAC addresses
+ * EAP-PEAP: require Phase 2 authentication by default (phase2_auth=1)
+ to improve security for still unfortunately common invalid
+ configurations that do not set ca_cert
+ * extend SCS support for QoS Characteristics
+ * extend MSCS support
+ * support unsynchronized service discovery (USD)
+ * add support for explicit SSID protection in 4-way handshake
+ (a mitigation for CVE-2023-52424; disabled by default for now, can be
+ enabled with ssid_protection=1)
+ - in addition, verify SSID after key setup when beacon protection is
+ used
+ * fix SAE H2E rejected groups validation to avoid downgrade attacks
+ * a large number of other fixes, cleanup, and extensions
+
2022-01-16 - v2.10
* SAE changes
- improved protection against side channel attacks
diff --git a/wpa_supplicant/README b/wpa_supplicant/README
index f8da781..49e971e 100644
--- a/wpa_supplicant/README
+++ b/wpa_supplicant/README
@@ -1,7 +1,7 @@
wpa_supplicant
==============
-Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi> and contributors
All Rights Reserved.
This program is licensed under the BSD license (the one with
diff --git a/wpa_supplicant/README-NAN-USD b/wpa_supplicant/README-NAN-USD
index 5dfe6ee..72c379f 100644
--- a/wpa_supplicant/README-NAN-USD
+++ b/wpa_supplicant/README-NAN-USD
@@ -75,7 +75,7 @@
This command maps to the CancelSubscribe() method in the NAN Discovery Engine.
-NAN_TRANSMIT handle=<id from NAN_PUBLISH or NAN_SUBSCRIBE> req_instance=<peer's id> address=<peer's MAC address> [ssi=<service specific information (hexdump)>]
+NAN_TRANSMIT handle=<id from NAN_PUBLISH or NAN_SUBSCRIBE> req_instance_id=<peer's id> address=<peer's MAC address> [ssi=<service specific information (hexdump)>]
This command maps to the Transmit() method in the NAN Discovery Engine.
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 2890353..cf94d4b 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -1226,6 +1226,31 @@
/**
+ * wpa_bss_get_ie_beacon - Fetch a specified information element from a BSS entry
+ * @bss: BSS table entry
+ * @ie: Information element identitifier (WLAN_EID_*)
+ * Returns: Pointer to the information element (id field) or %NULL if not found
+ *
+ * This function returns the first matching information element in the BSS
+ * entry.
+ *
+ * This function is like wpa_bss_get_ie(), but uses IE buffer only from Beacon
+ * frames instead of either Beacon or Probe Response frames.
+ */
+const u8 * wpa_bss_get_ie_beacon(const struct wpa_bss *bss, u8 ie)
+{
+ const u8 *ies;
+
+ if (bss->beacon_ie_len == 0)
+ return NULL;
+
+ ies = wpa_bss_ie_ptr(bss);
+ ies += bss->ie_len;
+ return get_ie(ies, bss->beacon_ie_len, ie);
+}
+
+
+/**
* wpa_bss_get_ie_ext - Fetch a specified extended IE from a BSS entry
* @bss: BSS table entry
* @ext: Information element extension identifier (WLAN_EID_EXT_*)
@@ -1529,8 +1554,14 @@
wpa_printf(MSG_DEBUG,
"MLD: Reported link not part of MLD");
} else if (!(BIT(link_id) & *seen)) {
- struct wpa_bss *neigh_bss =
- wpa_bss_get_bssid(wpa_s, pos + 1);
+ struct wpa_bss *neigh_bss;
+
+ if (ssid && ssid->ssid_len)
+ neigh_bss = wpa_bss_get(wpa_s, pos + 1,
+ ssid->ssid,
+ ssid->ssid_len);
+ else
+ neigh_bss = wpa_bss_get_bssid(wpa_s, pos + 1);
*seen |= BIT(link_id);
wpa_printf(MSG_DEBUG, "MLD: mld ID=%u, link ID=%u",
@@ -1626,10 +1657,22 @@
if (ssid) {
struct wpa_ie_data ie;
+ const u8 *rsne;
+ size_t rsne_len;
- if (!elems.rsn_ie ||
- wpa_parse_wpa_ie(elems.rsn_ie - 2, 2 + elems.rsn_ie_len,
- &ie)) {
+ if (elems.rsne_override_2 && wpas_rsn_overriding(wpa_s)) {
+ rsne = elems.rsne_override_2;
+ rsne_len = elems.rsne_override_2_len;
+ } else if (elems.rsne_override &&
+ wpas_rsn_overriding(wpa_s)) {
+ rsne = elems.rsne_override;
+ rsne_len = elems.rsne_override_len;
+ } else {
+ rsne = elems.rsn_ie;
+ rsne_len = elems.rsn_ie_len;
+ }
+ if (!rsne ||
+ wpa_parse_wpa_ie(rsne - 2, 2 + rsne_len, &ie)) {
wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RSN element");
goto out;
}
@@ -1835,3 +1878,201 @@
wpabuf_free(mlbuf);
return removed_links;
}
+
+
+static bool wpa_bss_supported_cipher(struct wpa_supplicant *wpa_s,
+ int pairwise_cipher)
+{
+ if (!wpa_s->drv_enc)
+ return true;
+
+ if ((pairwise_cipher & WPA_CIPHER_CCMP) &&
+ (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP))
+ return true;
+
+ if ((pairwise_cipher & WPA_CIPHER_GCMP) &&
+ (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP))
+ return true;
+
+ if ((pairwise_cipher & WPA_CIPHER_CCMP_256) &&
+ (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP_256))
+ return true;
+
+ if ((pairwise_cipher & WPA_CIPHER_GCMP_256) &&
+ (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP_256))
+ return true;
+
+ return false;
+}
+
+
+static bool wpa_bss_supported_key_mgmt(struct wpa_supplicant *wpa_s,
+ int key_mgmt)
+{
+ if (!wpa_s->drv_key_mgmt)
+ return true;
+
+ if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA2))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_802_1X_SHA256))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_802_1X_SHA384))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_PSK) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_FT_PSK) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_PSK_SHA256) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_SAE) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_FT_SAE) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE_EXT_KEY))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_OWE) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_DPP) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_FILS_SHA256) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_FILS_SHA384) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256))
+ return true;
+ if ((key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) &&
+ (wpa_s->drv_key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384))
+ return true;
+
+ return false;
+}
+
+
+static bool wpa_bss_supported_rsne(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid, const u8 *ie)
+{
+ struct wpa_ie_data data;
+
+ if (wpa_parse_wpa_ie_rsn(ie, 2 + ie[1], &data) < 0)
+ return false;
+
+ /* Check that there is a supported AKM and pairwise cipher based on
+ * overall capabilities */
+ if (!data.pairwise_cipher || !data.key_mgmt)
+ return false;
+
+ if (wpa_s->drv_capa_known) {
+ if (!wpa_bss_supported_cipher(wpa_s, data.pairwise_cipher) ||
+ !wpa_bss_supported_key_mgmt(wpa_s, data.key_mgmt))
+ return false;
+ }
+
+ if (ssid) {
+ /* Check that there is a supported AKM and pairwise cipher
+ * based on the specific network profile. */
+ if ((ssid->pairwise_cipher & data.pairwise_cipher) == 0)
+ return false;
+ if ((ssid->key_mgmt & data.key_mgmt) == 0)
+ return false;
+ }
+
+ return true;
+}
+
+
+const u8 * wpa_bss_get_rsne(struct wpa_supplicant *wpa_s,
+ const struct wpa_bss *bss, struct wpa_ssid *ssid,
+ bool mlo)
+{
+ const u8 *ie;
+
+ if (wpas_rsn_overriding(wpa_s)) {
+ if (!ssid)
+ ssid = wpa_s->current_ssid;
+
+ /* MLO cases for RSN overriding are required to use RSNE
+ * Override 2 element and RSNXE Override element together. */
+ ie = wpa_bss_get_vendor_ie(bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
+ if (mlo && ie &&
+ !wpa_bss_get_vendor_ie(bss,
+ RSNXE_OVERRIDE_IE_VENDOR_TYPE)) {
+ wpa_printf(MSG_DEBUG, "BSS " MACSTR
+ " advertises RSNE Override 2 element without RSNXE Override element - ignore RSNE Override 2 element for MLO",
+ MAC2STR(bss->bssid));
+ } else if (ie && wpa_bss_supported_rsne(wpa_s, ssid, ie)) {
+ return ie;
+ }
+
+ if (!mlo) {
+ ie = wpa_bss_get_vendor_ie(
+ bss, RSNE_OVERRIDE_IE_VENDOR_TYPE);
+ if (ie && wpa_bss_supported_rsne(wpa_s, ssid, ie))
+ return ie;
+ }
+ }
+
+ return wpa_bss_get_ie(bss, WLAN_EID_RSN);
+}
+
+
+const u8 * wpa_bss_get_rsnxe(struct wpa_supplicant *wpa_s,
+ const struct wpa_bss *bss, struct wpa_ssid *ssid,
+ bool mlo)
+{
+ const u8 *ie;
+
+ if (wpas_rsn_overriding(wpa_s)) {
+ ie = wpa_bss_get_vendor_ie(bss, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
+ if (ie) {
+ const u8 *tmp;
+
+ tmp = wpa_bss_get_rsne(wpa_s, bss, ssid, mlo);
+ if (!tmp || tmp[0] == WLAN_EID_RSN) {
+ /* An acceptable RSNE override element was not
+ * found, so need to ignore RSNXE overriding. */
+ goto out;
+ }
+
+ return ie;
+ }
+
+ /* MLO cases for RSN overriding are required to use RSNE
+ * Override 2 element and RSNXE Override element together. */
+ if (mlo && wpa_bss_get_vendor_ie(
+ bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE)) {
+ wpa_printf(MSG_DEBUG, "BSS " MACSTR
+ " advertises RSNXE Override element without RSNE Override 2 element - ignore RSNXE Override element for MLO",
+ MAC2STR(bss->bssid));
+ goto out;
+ }
+ }
+
+out:
+ return wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+}
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
index cc04963..508129c 100644
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -175,6 +175,7 @@
struct wpa_bss * wpa_bss_get_id_range(struct wpa_supplicant *wpa_s,
unsigned int idf, unsigned int idl);
const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie);
+const u8 * wpa_bss_get_ie_beacon(const struct wpa_bss *bss, u8 ie);
const u8 * wpa_bss_get_ie_ext(const struct wpa_bss *bss, u8 ext);
const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type);
const u8 * wpa_bss_get_vendor_ie_beacon(const struct wpa_bss *bss,
@@ -225,4 +226,11 @@
u16 wpa_bss_parse_reconf_ml_element(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss);
+const u8 * wpa_bss_get_rsne(struct wpa_supplicant *wpa_s,
+ const struct wpa_bss *bss, struct wpa_ssid *ssid,
+ bool mlo);
+const u8 * wpa_bss_get_rsnxe(struct wpa_supplicant *wpa_s,
+ const struct wpa_bss *bss, struct wpa_ssid *ssid,
+ bool mlo);
+
#endif /* BSS_H */
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index c949bab..0f98f77 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2755,6 +2755,8 @@
{ INT_RANGE(sae_pk, 0, 2) },
{ INT_RANGE(disable_eht, 0, 1)},
{ INT_RANGE(enable_4addr_mode, 0, 1)},
+ { INT_RANGE(max_idle, 0, 65535)},
+ { INT_RANGE(ssid_protection, 0, 1)},
};
#undef OFFSET
@@ -5589,6 +5591,7 @@
{ INT_RANGE(extended_key_id, 0, 1), 0 },
#endif /* CONFIG_WNM */
{ INT_RANGE(wowlan_disconnect_on_deinit, 0, 1), 0},
+ { INT_RANGE(rsn_overriding, 0, 2), 0},
#ifdef CONFIG_PASN
#ifdef CONFIG_TESTING_OPTIONS
{ INT_RANGE(force_kdk_derivation, 0, 1), 0 },
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 56d5c61..7ea43a6 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1803,6 +1803,19 @@
*/
int wowlan_disconnect_on_deinit;
+ /**
+ * rsn_overriding - RSN overriding
+ *
+ * 0 = Disabled
+ * 1 = Enabled automatically if the driver indicates support
+ * 2 = Forced to be enabled even without driver capability indication
+ */
+ enum rsn_overriding {
+ RSN_OVERRIDING_DISABLED = 0,
+ RSN_OVERRIDING_AUTO = 1,
+ RSN_OVERRIDING_ENABLED = 2,
+ } rsn_overriding;
+
#ifdef CONFIG_PASN
#ifdef CONFIG_TESTING_OPTIONS
/*
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 414ed22..fa829eb 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -893,6 +893,8 @@
#endif /* CONFIG_HE_OVERRIDES */
INT(disable_eht);
INT(enable_4addr_mode);
+ INT(max_idle);
+ INT(ssid_protection);
#undef STR
#undef INT
@@ -1619,6 +1621,8 @@
if (config->wowlan_disconnect_on_deinit)
fprintf(f, "wowlan_disconnect_on_deinit=%d\n",
config->wowlan_disconnect_on_deinit);
+ if (config->rsn_overriding)
+ fprintf(f, "rsn_overriding=%d\n", config->rsn_overriding);
#ifdef CONFIG_TESTING_OPTIONS
if (config->mld_force_single_link)
fprintf(f, "mld_force_single_link=1\n");
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 2043a80..3d1bc5e 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -1269,6 +1269,19 @@
* to use the interface in a bridge.
*/
int enable_4addr_mode;
+
+ /**
+ * max_idle - BSS max idle period to request
+ *
+ * If nonzero, request the specified number of 1000 TU (i.e., 1.024 s)
+ * as the maximum idle period for the STA during association.
+ */
+ int max_idle;
+
+ /**
+ * ssid_protection - Whether to use SSID protection in 4-way handshake
+ */
+ bool ssid_protection;
};
#endif /* CONFIG_SSID_H */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index d0fda4c..d245531 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -2558,6 +2558,30 @@
pos += ret;
}
+#ifdef CONFIG_SME
+ if (wpa_s->sme.bss_max_idle_period) {
+ ret = os_snprintf(pos, end - pos, "bss_max_idle_period=%d\n",
+ wpa_s->sme.bss_max_idle_period);
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+#endif /* CONFIG_SME */
+
+ if (wpa_s->ssid_verified) {
+ ret = os_snprintf(pos, end - pos, "ssid_verified=1\n");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+
+ if (wpa_s->bigtk_set) {
+ ret = os_snprintf(pos, end - pos, "bigtk_set=1\n");
+ if (os_snprintf_error(end - pos, ret))
+ return pos - buf;
+ pos += ret;
+ }
+
#ifdef ANDROID
/*
* Allow using the STATUS command with default behavior, say for debug,
@@ -3095,12 +3119,12 @@
ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
if (ie)
pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
- ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ ie2 = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
if (ie2) {
pos = wpa_supplicant_ie_txt(pos, end, mesh ? "RSN" : "WPA2",
ie2, 2 + ie2[1]);
}
- rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
if (os_snprintf_error(end - pos, ret))
@@ -5420,12 +5444,12 @@
if (ie)
pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie,
2 + ie[1]);
- ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ ie2 = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
if (ie2)
pos = wpa_supplicant_ie_txt(pos, end,
mesh ? "RSN" : "WPA2", ie2,
2 + ie2[1]);
- rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
if (os_snprintf_error(end - pos, ret))
@@ -6716,6 +6740,7 @@
char *pos;
size_t len;
struct wpabuf *query, *resp;
+ int ret;
pos = os_strchr(cmd, ' ');
if (pos == NULL)
@@ -6729,34 +6754,28 @@
query = wpabuf_alloc(len);
if (query == NULL)
return -1;
- if (hexstr2bin(cmd, wpabuf_put(query, len), len) < 0) {
- wpabuf_free(query);
- return -1;
- }
-
+ ret = hexstr2bin(cmd, wpabuf_put(query, len), len);
+ if (ret < 0)
+ goto err_query;
+ ret = -1;
len = os_strlen(pos);
- if (len & 1) {
- wpabuf_free(query);
- return -1;
- }
+ if (len & 1)
+ goto err_query;
len /= 2;
resp = wpabuf_alloc(len);
- if (resp == NULL) {
- wpabuf_free(query);
- return -1;
- }
- if (hexstr2bin(pos, wpabuf_put(resp, len), len) < 0) {
- wpabuf_free(query);
- wpabuf_free(resp);
- return -1;
- }
+ if (!resp)
+ goto err_query;
+ ret = hexstr2bin(pos, wpabuf_put(resp, len), len);
+ if (ret < 0)
+ goto err_resp;
- if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0) {
- wpabuf_free(query);
- wpabuf_free(resp);
- return -1;
- }
- return 0;
+ ret = wpas_p2p_service_add_bonjour(wpa_s, query, resp);
+
+err_resp:
+ wpabuf_free(resp);
+err_query:
+ wpabuf_free(query);
+ return ret;
}
@@ -12118,7 +12137,7 @@
}
}
- if (mld_id < 0 || is_zero_ether_addr(bssid)) {
+ if (is_zero_ether_addr(bssid)) {
wpa_printf(MSG_DEBUG,
"MLD: Failed parsing ML probe request arguments");
return -1;
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 8bd6a9a..76e42ff 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -1663,7 +1663,8 @@
wpa_s->dbus_new_path) ||
!wpa_dbus_dict_append_string(&dict_iter, "role",
client ? "client" : "GO") ||
- !wpa_dbus_dict_append_bool(&dict_iter, "persistent", persistent) ||
+ !wpa_dbus_dict_append_bool(&dict_iter, "persistent",
+ !!persistent) ||
!wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
wpa_s->dbus_groupobj_path) ||
(ip &&
@@ -4022,6 +4023,11 @@
NULL,
NULL,
},
+ { "SignalChange", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
+ wpas_dbus_getter_signal_change,
+ NULL,
+ NULL
+ },
{ NULL, NULL, NULL, NULL, NULL, NULL }
};
@@ -4619,11 +4625,6 @@
NULL,
NULL
},
- { "SignalChange", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
- wpas_dbus_getter_signal_change,
- NULL,
- NULL
- },
{ NULL, NULL, NULL, NULL, NULL, NULL }
};
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 3897d98..960b306 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1731,6 +1731,7 @@
reply = wpas_dbus_error_scan_error(
message,
"Scan request rejected");
+ goto out;
}
} else {
wpa_s->scan_req = MANUAL_SCAN_REQ;
@@ -1757,6 +1758,7 @@
false)) {
reply = wpas_dbus_error_scan_error(
message, "Scan request rejected");
+ goto out;
}
} else {
wpa_printf(MSG_DEBUG, "%s[dbus]: Unknown scan type: %s",
@@ -5633,7 +5635,7 @@
return FALSE;
os_memset(&wpa_data, 0, sizeof(wpa_data));
- ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
+ ie = wpa_bss_get_rsne(args->wpa_s, res, NULL, false);
if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
dbus_set_error_const(error, DBUS_ERROR_FAILED,
"failed to parse RSN IE");
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 16b2caa..418a8fd 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -2778,20 +2778,20 @@
if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0)
goto error;
- query = NULL;
- resp = NULL;
} else
goto error;
+out:
os_free(service);
+ wpabuf_free(query);
+ wpabuf_free(resp);
+
return reply;
error_clear:
wpa_dbus_dict_entry_clear(&entry);
error:
- os_free(service);
- wpabuf_free(query);
- wpabuf_free(resp);
- return wpas_dbus_error_invalid_args(message, NULL);
+ reply = wpas_dbus_error_invalid_args(message, NULL);
+ goto out;
}
@@ -2925,6 +2925,7 @@
if (entry.type != DBUS_TYPE_ARRAY ||
entry.array_type != DBUS_TYPE_BYTE)
goto error_clear;
+ wpabuf_free(tlv);
tlv = wpabuf_alloc_copy(entry.bytearray_value,
entry.array_len);
} else
@@ -2952,7 +2953,6 @@
if (tlv == NULL)
goto error;
ref = wpas_p2p_sd_request(wpa_s, addr, tlv);
- wpabuf_free(tlv);
}
if (ref != 0) {
@@ -2964,14 +2964,13 @@
message, "Unable to send SD request");
}
out:
+ wpabuf_free(tlv);
os_free(service);
os_free(peer_object_path);
return reply;
error_clear:
wpa_dbus_dict_entry_clear(&entry);
error:
- if (tlv)
- wpabuf_free(tlv);
reply = wpas_dbus_error_invalid_args(message, NULL);
goto out;
}
@@ -3013,6 +3012,7 @@
if (entry.type != DBUS_TYPE_ARRAY ||
entry.array_type != DBUS_TYPE_BYTE)
goto error_clear;
+ wpabuf_free(tlv);
tlv = wpabuf_alloc_copy(entry.bytearray_value,
entry.array_len);
} else
@@ -3026,8 +3026,8 @@
goto error;
wpas_p2p_sd_response(wpa_s, freq, addr, (u8) dlg_tok, tlv);
- wpabuf_free(tlv);
out:
+ wpabuf_free(tlv);
os_free(peer_object_path);
return reply;
error_clear:
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index e223450..216224f 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -4538,7 +4538,7 @@
if (!(ssid->key_mgmt & WPA_KEY_MGMT_DPP) || !bss)
return 0; /* Not using DPP AKM - continue */
- rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
!(ied.key_mgmt & WPA_KEY_MGMT_DPP))
return 0; /* AP does not support DPP AKM - continue */
diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c
index 95953de..0c17aae 100644
--- a/wpa_supplicant/eapol_test.c
+++ b/wpa_supplicant/eapol_test.c
@@ -195,6 +195,9 @@
return;
}
+ if (!radius_msg_add_msg_auth(msg))
+ goto fail;
+
radius_msg_make_authenticator(msg);
hdr = (const struct eap_hdr *) eap;
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index ff18543..09a2bbb 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -138,6 +138,33 @@
}
+static struct wpa_bss * __wpa_supplicant_get_new_bss(
+ struct wpa_supplicant *wpa_s, const u8 *bssid, const u8 *ssid,
+ size_t ssid_len)
+{
+ if (ssid && ssid_len > 0)
+ return wpa_bss_get(wpa_s, bssid, ssid, ssid_len);
+ else
+ return wpa_bss_get_bssid(wpa_s, bssid);
+}
+
+
+static struct wpa_bss * _wpa_supplicant_get_new_bss(
+ struct wpa_supplicant *wpa_s, const u8 *bssid, const u8 *ssid,
+ size_t ssid_len, bool try_update_scan_results)
+{
+ struct wpa_bss *bss = __wpa_supplicant_get_new_bss(wpa_s, bssid, ssid,
+ ssid_len);
+
+ if (bss || !try_update_scan_results)
+ return bss;
+
+ wpa_supplicant_update_scan_results(wpa_s, bssid);
+
+ return __wpa_supplicant_get_new_bss(wpa_s, bssid, ssid, ssid_len);
+}
+
+
static struct wpa_bss * wpa_supplicant_get_new_bss(
struct wpa_supplicant *wpa_s, const u8 *bssid)
{
@@ -145,14 +172,23 @@
struct wpa_ssid *ssid = wpa_s->current_ssid;
u8 drv_ssid[SSID_MAX_LEN];
int res;
+ bool try_update_scan_results = true;
res = wpa_drv_get_ssid(wpa_s, drv_ssid);
- if (res > 0)
- bss = wpa_bss_get(wpa_s, bssid, drv_ssid, res);
- if (!bss && ssid && ssid->ssid_len > 0)
- bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len);
+ if (res > 0) {
+ bss = _wpa_supplicant_get_new_bss(wpa_s, bssid, drv_ssid, res,
+ try_update_scan_results);
+ try_update_scan_results = false;
+ }
+ if (!bss && ssid && ssid->ssid_len > 0) {
+ bss = _wpa_supplicant_get_new_bss(wpa_s, bssid, ssid->ssid,
+ ssid->ssid_len,
+ try_update_scan_results);
+ try_update_scan_results = false;
+ }
if (!bss)
- bss = wpa_bss_get_bssid(wpa_s, bssid);
+ bss = _wpa_supplicant_get_new_bss(wpa_s, bssid, NULL, 0,
+ try_update_scan_results);
return bss;
}
@@ -163,13 +199,6 @@
{
struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
- if (!bss) {
- wpa_supplicant_update_scan_results(wpa_s, bssid);
-
- /* Get the BSS from the new scan results */
- bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
- }
-
if (bss)
wpa_s->current_bss = bss;
@@ -182,11 +211,6 @@
{
struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
- if (!bss) {
- wpa_supplicant_update_scan_results(wpa_s, bssid);
- bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
- }
-
if (bss)
wpa_s->links[link_id].bss = bss;
}
@@ -405,6 +429,13 @@
wpa_s->wps_scan_done = false;
wpas_reset_mlo_info(wpa_s);
+
+#ifdef CONFIG_SME
+ wpa_s->sme.bss_max_idle_period = 0;
+#endif /* CONFIG_SME */
+
+ wpa_s->ssid_verified = false;
+ wpa_s->bigtk_set = false;
}
@@ -640,7 +671,7 @@
(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA));
#endif /* CONFIG_WEP */
- rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ rsn_ie = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
if (is_6ghz_bss && !rsn_ie) {
if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG,
@@ -1113,7 +1144,7 @@
u8 ssid_len;
owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
- if (!owe || !wpa_bss_get_ie(bss, WLAN_EID_RSN))
+ if (!owe || !wpa_bss_get_rsne(wpa_s, bss, NULL, false))
return;
pos = owe + 6;
@@ -1217,7 +1248,7 @@
if (bss == orig_bss)
continue;
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ ie = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
if (!(ieee802_11_rsnx_capab(ie, WLAN_RSNX_CAPAB_SAE_PK)))
continue;
@@ -1256,7 +1287,7 @@
ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
wpa = ie && ie[1];
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ ie = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
wpa |= ie && ie[1];
if (ie && wpa_parse_wpa_ie_rsn(ie, 2 + ie[1], &data) == 0 &&
(data.key_mgmt & WPA_KEY_MGMT_OSEN))
@@ -1265,8 +1296,10 @@
osen = ie != NULL;
#ifdef CONFIG_SAE
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
- if (ie && ie[1] >= 1)
+ ie = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
+ if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4 + 1)
+ rsnxe_capa = ie[4 + 2];
+ else if (ie && ie[1] >= 1)
rsnxe_capa = ie[2];
#endif /* CONFIG_SAE */
@@ -1623,7 +1656,7 @@
ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
wpa_ie_len = ie ? ie[1] : 0;
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ ie = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
rsn_ie_len = ie ? ie[1] : 0;
ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
@@ -2090,7 +2123,7 @@
if (ssid == NULL)
continue;
- rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ rsn = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
if (rsn == NULL)
continue;
@@ -2171,6 +2204,11 @@
MAC2STR(selected->bssid), selected->freq, selected->level,
selected->snr, selected->est_throughput);
+ if (wpas_ap_link_address(wpa_s, selected->bssid)) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "MLD: associated to selected BSS");
+ return 0;
+ }
+
if (wpa_s->current_ssid->bssid_set &&
ether_addr_equal(selected->bssid, wpa_s->current_ssid->bssid)) {
wpa_dbg(wpa_s, MSG_DEBUG, "Allow reassociation - selected BSS "
@@ -2449,6 +2487,8 @@
}
#endif /* CONFIG_NO_RANDOM_POOL */
+ wpa_s->last_scan_external = data && data->scan_info.external_scan;
+
if (update_only) {
ret = 1;
goto scan_work_done;
@@ -2843,6 +2883,9 @@
wpa_s->conf->scan_res_valid_for_connect)) {
wpa_printf(MSG_DEBUG, "Fast associate: Old scan results");
return -1;
+ } else if (wpa_s->crossed_6ghz_dom) {
+ wpa_printf(MSG_DEBUG, "Fast associate: Crossed 6 GHz domain");
+ return -1;
}
return wpas_select_network_from_last_scan(wpa_s, 0, 1, false, NULL);
@@ -2925,6 +2968,8 @@
wnm_bss_keep_alive, wpa_s,
NULL);
}
+ } else {
+ wpa_s->sme.bss_max_idle_period = 0;
}
#endif /* CONFIG_SME */
}
@@ -3231,7 +3276,8 @@
if (wpa_s->wpa_proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) {
const u8 *bss_rsn;
- bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ bss_rsn = wpa_bss_get_rsne(wpa_s, bss, ssid,
+ wpa_s->valid_links);
if (bss_rsn) {
p = bss_rsn;
len = 2 + bss_rsn[1];
@@ -3338,6 +3384,16 @@
#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
+ wpa_s->ssid_verified = false;
+ wpa_s->bigtk_set = false;
+#ifdef CONFIG_SAE
+#ifdef CONFIG_SME
+ /* SAE H2E binds the SSID into PT and that verifies the SSID
+ * implicitly. */
+ if (wpa_s->sme.sae.state == SAE_ACCEPTED && wpa_s->sme.sae.h2e)
+ wpa_s->ssid_verified = true;
+#endif /* CONFIG_SME */
+#endif /* CONFIG_SAE */
bssid_known = wpa_drv_get_bssid(wpa_s, bssid) == 0;
if (data->assoc_info.req_ies)
wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
@@ -3515,14 +3571,22 @@
#ifdef CONFIG_FILS
#ifdef CONFIG_SME
- if ((wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
- wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) &&
- (!data->assoc_info.resp_frame ||
- fils_process_assoc_resp(wpa_s->wpa,
- data->assoc_info.resp_frame,
- data->assoc_info.resp_frame_len) < 0)) {
- wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED);
- return -1;
+ if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
+ wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) {
+ if (!data->assoc_info.resp_frame ||
+ fils_process_assoc_resp(wpa_s->wpa,
+ data->assoc_info.resp_frame,
+ data->assoc_info.resp_frame_len) <
+ 0) {
+ wpa_supplicant_deauthenticate(wpa_s,
+ WLAN_REASON_UNSPECIFIED);
+ return -1;
+ }
+
+ /* FILS use of an AEAD cipher include the SSID element in
+ * (Re)Association Request frame in the AAD and since the AP
+ * accepted that, the SSID was verified. */
+ wpa_s->ssid_verified = true;
}
#endif /* CONFIG_SME */
@@ -3583,6 +3647,9 @@
wpa_s, WLAN_REASON_INVALID_IE);
return -1;
}
+ /* SSID is included in PMK-R0 derivation, so it is verified
+ * implicitly. */
+ wpa_s->ssid_verified = true;
}
p = data->assoc_info.resp_ies;
@@ -3654,6 +3721,9 @@
return -1;
}
wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done");
+ /* SSID is included in PMK-R0 derivation, so it is verified
+ * implicitly. */
+ wpa_s->ssid_verified = true;
}
wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
@@ -3694,9 +3764,29 @@
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
}
+ if (wpas_rsn_overriding(wpa_s) &&
+ p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
+ WPA_GET_BE32(&p[2]) == RSNE_OVERRIDE_2_IE_VENDOR_TYPE) {
+ rsn_found = 1;
+ wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
+ }
+
+ if (!rsn_found &&
+ wpas_rsn_overriding(wpa_s) &&
+ p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
+ WPA_GET_BE32(&p[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
+ rsn_found = 1;
+ wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
+ }
+
if (p[0] == WLAN_EID_RSNX && p[1] >= 1)
wpa_sm_set_ap_rsnxe(wpa_s->wpa, p, len);
+ if (wpas_rsn_overriding(wpa_s) &&
+ p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
+ WPA_GET_BE32(&p[2]) == RSNXE_OVERRIDE_IE_VENDOR_TYPE)
+ wpa_sm_set_ap_rsnxe(wpa_s->wpa, p, len);
+
l -= len;
p += len;
}
@@ -3750,8 +3840,10 @@
bss_wpa = wpa_bss_get_vendor_ie(wpa_s->current_bss,
WPA_IE_VENDOR_TYPE);
- bss_rsn = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSN);
- bss_rsnx = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSNX);
+ bss_rsn = wpa_bss_get_rsne(wpa_s, wpa_s->current_bss, NULL,
+ wpa_s->valid_links);
+ bss_rsnx = wpa_bss_get_rsnxe(wpa_s, wpa_s->current_bss, NULL,
+ wpa_s->valid_links);
if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
bss_wpa ? 2 + bss_wpa[1] : 0) ||
@@ -4134,20 +4226,13 @@
bss = wpa_supplicant_get_new_bss(wpa_s, drv_mlo.links[i].bssid);
if (!bss) {
- wpa_supplicant_update_scan_results(
- wpa_s, drv_mlo.links[i].bssid);
- bss = wpa_supplicant_get_new_bss(
- wpa_s, drv_mlo.links[i].bssid);
- }
-
- if (!bss) {
wpa_dbg(wpa_s, MSG_INFO,
"Failed to get MLO link %d BSS", i);
return -1;
}
- bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ bss_rsn = wpa_bss_get_rsne(wpa_s, bss, NULL, true);
+ bss_rsnx = wpa_bss_get_rsnxe(wpa_s, bss, NULL, true);
wpa_mlo.links[i].ap_rsne = bss_rsn ? (u8 *) bss_rsn : NULL;
wpa_mlo.links[i].ap_rsne_len = bss_rsn ? 2 + bss_rsn[1] : 0;
@@ -5365,11 +5450,10 @@
wpa_dbg(ifs, MSG_DEBUG,
"Channel list changed - restart sched_scan");
wpas_scan_restart_sched_scan(ifs);
- } else if (ifs->scanning && !was_6ghz_enabled &&
- ifs->is_6ghz_enabled) {
- /* Look for APs in the 6 GHz band */
+ } else if (!was_6ghz_enabled && ifs->is_6ghz_enabled) {
wpa_dbg(ifs, MSG_INFO,
- "Channel list changed - trigger 6 GHz-only scan");
+ "Channel list changed: 6 GHz was enabled");
+
ifs->crossed_6ghz_dom = true;
}
}
@@ -5757,7 +5841,8 @@
{
const u8 *bssid = data->assoc_reject.bssid;
struct ieee802_11_elems elems;
- const u8 *link_bssids[MAX_NUM_MLD_LINKS];
+ struct ml_sta_link_info ml_info[MAX_NUM_MLD_LINKS];
+ const u8 *link_bssids[MAX_NUM_MLD_LINKS + 1];
#ifdef CONFIG_MBO
struct wpa_bss *reject_bss;
#endif /* CONFIG_MBO */
@@ -5890,7 +5975,6 @@
if (ieee802_11_parse_elems(data->assoc_reject.resp_ies,
data->assoc_reject.resp_ies_len,
&elems, 1) != ParseFailed) {
- struct ml_sta_link_info ml_info[MAX_NUM_MLD_LINKS];
unsigned int n_links, i, idx;
idx = 0;
diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c
index c68167f..f14e6cb 100644
--- a/wpa_supplicant/hs20_supplicant.c
+++ b/wpa_supplicant/hs20_supplicant.c
@@ -1101,7 +1101,7 @@
prov_anqp = bss->anqp->hs20_osu_providers_list;
if (prov_anqp == NULL)
continue;
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ ie = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &data) == 0 &&
(data.key_mgmt & WPA_KEY_MGMT_OSEN)) {
osu_ssid2 = bss->ssid;
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index 554268a..25039a0 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -484,8 +484,8 @@
"\x00\x0f\xac\x04"
"\x01\x00\x00\x0f\xac\x04"
"\x01\x00\x00\x0f\xac\x02"
- "\x00\x00", 22, NULL, 0, NULL, 0, NULL, 0) !=
- WPA_IE_OK) {
+ "\x00\x00", 22, NULL, 0, NULL, 0, NULL, 0,
+ NULL) != WPA_IE_OK) {
wpa_printf(MSG_DEBUG, "AUTH: wpa_validate_wpa_ie() failed");
return -1;
}
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 5676f38..651907b 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -1734,7 +1734,7 @@
" for connection",
MAC2STR(bss->bssid));
- if (!wpa_bss_get_ie(bss, WLAN_EID_RSN)) {
+ if (!wpa_bss_get_rsne(wpa_s, bss, NULL, false)) {
/*
* We currently support only HS 2.0 networks and those are
* required to use WPA2-Enterprise.
@@ -2467,7 +2467,7 @@
cred2 = interworking_credentials_available(wpa_s, bss, NULL);
if (!cred2)
continue;
- if (!wpa_bss_get_ie(bss, WLAN_EID_RSN))
+ if (!wpa_bss_get_rsne(wpa_s, bss, NULL, false))
continue;
prio = roaming_prio(wpa_s, cred2, bss);
wpa_printf(MSG_DEBUG, "Interworking: roaming_prio=%u for BSS "
@@ -2519,7 +2519,7 @@
if (!cred)
continue;
- if (!wpa_bss_get_ie(bss, WLAN_EID_RSN)) {
+ if (!wpa_bss_get_rsne(wpa_s, bss, NULL, false)) {
/*
* We currently support only HS 2.0 networks and those
* are required to use WPA2-Enterprise.
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index 31d0fce..80fbe01 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -115,7 +115,7 @@
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);
+ rsne = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
if (!rsne || wpa_parse_wpa_ie(rsne, 2 + rsne[1], &ie) < 0)
return; /* AP is not using RSN */
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index c930651..d53ae56 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -467,6 +467,8 @@
wpa_s->ml_connect_probe_ssid = NULL;
wpa_s->ml_connect_probe_bss = NULL;
}
+ if (wpa_s->connect_without_scan == ssid)
+ wpa_s->connect_without_scan = NULL;
#if defined(CONFIG_SME) && defined(CONFIG_SAE)
if (wpa_s->sme.ext_auth_wpa_ssid == ssid)
wpa_s->sme.ext_auth_wpa_ssid = NULL;
diff --git a/wpa_supplicant/p2p_supplicant_sd.c b/wpa_supplicant/p2p_supplicant_sd.c
index 312f46b..576180d 100644
--- a/wpa_supplicant/p2p_supplicant_sd.c
+++ b/wpa_supplicant/p2p_supplicant_sd.c
@@ -1222,12 +1222,22 @@
bsrv = os_zalloc(sizeof(*bsrv));
if (bsrv == NULL)
return -1;
- bsrv->query = query;
- bsrv->resp = resp;
+ bsrv->query = wpabuf_dup(query);
+ if (!bsrv->query)
+ goto error_bsrv;
+ bsrv->resp = wpabuf_dup(resp);
+ if (!bsrv->resp)
+ goto error_query;
dl_list_add(&wpa_s->global->p2p_srv_bonjour, &bsrv->list);
wpas_p2p_sd_service_update(wpa_s);
return 0;
+
+error_query:
+ wpabuf_free(bsrv->query);
+error_bsrv:
+ os_free(bsrv);
+ return -1;
}
diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c
index 1bb38f7..89edad4 100644
--- a/wpa_supplicant/pasn_supplicant.c
+++ b/wpa_supplicant/pasn_supplicant.c
@@ -174,7 +174,7 @@
}
}
- rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
if (!rsne) {
wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
return -1;
@@ -186,7 +186,7 @@
return -1;
}
- rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
ssid_str_len = bss->ssid_len;
ssid_str = bss->ssid;
@@ -480,7 +480,7 @@
return NULL;
}
- rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
if (!rsne) {
wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
return NULL;
@@ -544,13 +544,13 @@
goto fail;
}
- rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
if (!rsne) {
wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
goto fail;
}
- rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
derive_kdk = (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA) &&
ieee802_11_rsnx_capab(rsnxe,
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index ccd694b..8b59e40 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -322,6 +322,12 @@
}
wpa_s->last_scan_all_chan = !params->freqs;
wpa_s->last_scan_non_coloc_6ghz = params->non_coloc_6ghz;
+
+ if (wpa_s->crossed_6ghz_dom) {
+ wpa_printf(MSG_DEBUG, "First scan after crossing 6 GHz domain");
+ wpa_s->crossed_6ghz_dom = false;
+ }
+
if (!ctx ||
radio_add_work(wpa_s, 0, "scan", next, wpas_trigger_scan_cb,
ctx) < 0) {
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index be0bc0d..57c9b38 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -71,7 +71,9 @@
int group = groups[wpa_s->sme.sae_group_index];
if (group <= 0)
break;
- if (sae_set_group(&wpa_s->sme.sae, group) == 0) {
+ if (!int_array_includes(wpa_s->sme.sae_rejected_groups,
+ group) &&
+ sae_set_group(&wpa_s->sme.sae, group) == 0) {
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d",
wpa_s->sme.sae.group);
wpa_s->sme.sae.akmp = external ?
@@ -188,8 +190,11 @@
if (bss) {
const u8 *rsnxe;
- rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
- if (rsnxe && rsnxe[1] >= 1)
+ rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
+ if (rsnxe && rsnxe[0] == WLAN_EID_VENDOR_SPECIFIC &&
+ rsnxe[1] >= 1 + 4)
+ rsnxe_capa = rsnxe[2 + 4];
+ else if (rsnxe && rsnxe[1] >= 1)
rsnxe_capa = rsnxe[2];
}
@@ -390,7 +395,8 @@
#ifdef CONFIG_TESTING_OPTIONS
static struct wpa_bss * wpas_ml_connect_pref(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss)
+ struct wpa_bss *bss,
+ struct wpa_ssid *ssid)
{
unsigned int low, high, i;
@@ -456,7 +462,11 @@
MAC2STR(wpa_s->links[i].bssid));
/* Get the BSS entry and do the switch */
- bss = wpa_bss_get_bssid(wpa_s, wpa_s->links[i].bssid);
+ if (ssid && ssid->ssid_len)
+ bss = wpa_bss_get(wpa_s, wpa_s->links[i].bssid, ssid->ssid,
+ ssid->ssid_len);
+ else
+ bss = wpa_bss_get_bssid(wpa_s, wpa_s->links[i].bssid);
wpa_s->mlo_assoc_link_id = i;
return bss;
@@ -479,7 +489,7 @@
data->auth.ies_len - ie_offset,
&elems, 0) == ParseFailed) {
wpa_printf(MSG_DEBUG, "MLD: Failed parsing elements");
- goto out;
+ return -1;
}
if (!elems.basic_mle || !elems.basic_mle_len) {
@@ -488,7 +498,7 @@
status_code == WLAN_STATUS_SUCCESS ||
status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
status_code == WLAN_STATUS_SAE_PK)
- goto out;
+ return -1;
/* Accept missing Multi-Link element in failed authentication
* cases. */
return 0;
@@ -496,26 +506,22 @@
mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
if (!mld_addr)
- goto out;
+ return -1;
wpa_printf(MSG_DEBUG, "MLD: mld_address=" MACSTR, MAC2STR(mld_addr));
if (!ether_addr_equal(wpa_s->ap_mld_addr, mld_addr)) {
wpa_printf(MSG_DEBUG, "MLD: Unexpected MLD address (expected "
MACSTR ")", MAC2STR(wpa_s->ap_mld_addr));
- goto out;
+ return -1;
}
return 0;
-out:
- wpa_printf(MSG_DEBUG, "MLD: Authentication - clearing MLD state");
- wpas_reset_mlo_info(wpa_s);
- return -1;
}
static void wpas_sme_set_mlo_links(struct wpa_supplicant *wpa_s,
- struct wpa_bss *bss)
+ struct wpa_bss *bss, struct wpa_ssid *ssid)
{
u8 i;
@@ -532,6 +538,10 @@
if (bss->mld_link_id == i)
wpa_s->links[i].bss = bss;
+ else if (ssid && ssid->ssid_len)
+ wpa_s->links[i].bss = wpa_bss_get(wpa_s, bssid,
+ ssid->ssid,
+ ssid->ssid_len);
else
wpa_s->links[i].bss = wpa_bss_get_bssid(wpa_s, bssid);
}
@@ -576,10 +586,10 @@
NULL, ssid, NULL) &&
bss->valid_links) {
wpa_printf(MSG_DEBUG, "MLD: In authentication");
- wpas_sme_set_mlo_links(wpa_s, bss);
+ wpas_sme_set_mlo_links(wpa_s, bss, ssid);
#ifdef CONFIG_TESTING_OPTIONS
- bss = wpas_ml_connect_pref(wpa_s, bss);
+ bss = wpas_ml_connect_pref(wpa_s, bss, ssid);
if (wpa_s->conf->mld_force_single_link) {
wpa_printf(MSG_DEBUG, "MLD: Force single link");
@@ -636,7 +646,7 @@
const u8 *rsn;
struct wpa_ie_data ied;
- rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
if (!rsn) {
wpa_dbg(wpa_s, MSG_DEBUG,
"SAE enabled, but target BSS does not advertise RSN");
@@ -676,7 +686,7 @@
#endif /* CONFIG_WEP */
if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
- wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
+ wpa_bss_get_rsne(wpa_s, bss, ssid, false)) &&
wpa_key_mgmt_wpa(ssid->key_mgmt)) {
int try_opportunistic;
const u8 *cache_id = NULL;
@@ -800,7 +810,7 @@
wpa_dbg(wpa_s, MSG_DEBUG, "SME: FT mobility domain %02x%02x",
md[0], md[1]);
- omit_rsnxe = !wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ omit_rsnxe = !wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
if (wpa_s->sme.assoc_req_ie_len + 5 <
sizeof(wpa_s->sme.assoc_req_ie)) {
struct rsn_mdie *mdie;
@@ -829,7 +839,7 @@
wpa_s->sme.mfp = wpas_get_ssid_pmf(wpa_s, ssid);
if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) {
- const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ const u8 *rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
struct wpa_ie_data _ie;
if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 &&
_ie.capabilities &
@@ -897,6 +907,18 @@
os_memcpy(pos, ext_capab, ext_capab_len);
}
+ if (ssid->max_idle && wpa_s->sme.assoc_req_ie_len + 5 <=
+ sizeof(wpa_s->sme.assoc_req_ie)) {
+ u8 *pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
+
+ *pos++ = WLAN_EID_BSS_MAX_IDLE_PERIOD;
+ *pos++ = 3;
+ WPA_PUT_LE16(pos, ssid->max_idle);
+ pos += 2;
+ *pos = 0; /* Idle Options */
+ wpa_s->sme.assoc_req_ie_len += 5;
+ }
+
#ifdef CONFIG_TESTING_OPTIONS
if (wpa_s->rsnxe_override_assoc &&
wpabuf_len(wpa_s->rsnxe_override_assoc) <=
@@ -1044,6 +1066,7 @@
old_ssid = wpa_s->current_ssid;
wpa_s->current_ssid = ssid;
wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
+ wpa_sm_set_ssid(wpa_s->wpa, bss->ssid, bss->ssid_len);
wpa_supplicant_initiate_eapol(wpa_s);
#ifdef CONFIG_FILS
@@ -1565,14 +1588,21 @@
static int sme_check_sae_rejected_groups(struct wpa_supplicant *wpa_s,
const struct wpabuf *groups)
{
- size_t i, count;
+ size_t i, count, len;
const u8 *pos;
if (!groups)
return 0;
pos = wpabuf_head(groups);
- count = wpabuf_len(groups) / 2;
+ len = wpabuf_len(groups);
+ if (len & 1) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Invalid length of the Rejected Groups element payload: %zu",
+ len);
+ return 1;
+ }
+ count = len / 2;
for (i = 0; i < count; i++) {
int enabled;
u16 group;
@@ -1868,6 +1898,7 @@
wpa_s->sme.sae.state = SAE_ACCEPTED;
sae_clear_temp_data(&wpa_s->sme.sae);
+ wpa_s_clear_sae_rejected(wpa_s);
if (external) {
/* Report success to driver */
@@ -2010,6 +2041,12 @@
NULL);
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+ if (wpa_s->sme.sae_rejected_groups &&
+ ssid->disabled_until.sec) {
+ wpa_printf(MSG_DEBUG,
+ "SME: Clear SAE state with rejected groups due to continuous failures");
+ wpa_s_clear_sae_rejected(wpa_s);
+ }
}
if (res != 1)
return;
@@ -2160,7 +2197,11 @@
MAC2STR(wpa_s->pending_bssid),
WLAN_REASON_DEAUTH_LEAVING);
wpas_connection_failed(wpa_s, wpa_s->pending_bssid, NULL);
- wpa_supplicant_mark_disassoc(wpa_s);
+ wpa_supplicant_deauthenticate(wpa_s,
+ WLAN_REASON_DEAUTH_LEAVING);
+ wpa_printf(MSG_DEBUG,
+ "MLD: Authentication - clearing MLD state");
+ wpas_reset_mlo_info(wpa_s);
return;
}
@@ -2430,6 +2471,28 @@
wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
}
+ if (wpas_rsn_overriding(wpa_s) &&
+ wpas_ap_supports_rsn_overriding(wpa_s, wpa_s->current_bss) &&
+ wpa_s->sme.assoc_req_ie_len + 2 + 4 <=
+ sizeof(wpa_s->sme.assoc_req_ie)) {
+ u8 *pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
+ u32 type = 0;
+ const u8 *ie;
+
+ ie = wpa_bss_get_rsne(wpa_s, wpa_s->current_bss, ssid,
+ wpa_s->valid_links);
+ if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4)
+ type = WPA_GET_BE32(&ie[2]);
+
+ if (type) {
+ /* Indicate support for RSN overriding */
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+ *pos++ = 4;
+ WPA_PUT_BE32(pos, type);
+ wpa_s->sme.assoc_req_ie_len += 2 + 4;
+ }
+ }
+
params.bssid = bssid;
params.ssid = wpa_s->sme.ssid;
params.ssid_len = wpa_s->sme.ssid_len;
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 60f8562..af00e79 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -29,7 +29,7 @@
static const char *const wpa_cli_version =
"wpa_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2004-2024, Jouni Malinen <j@w1.fi> and contributors";
#define VENDOR_ELEM_FRAME_ID \
" 0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \
@@ -4380,6 +4380,8 @@
}
} else if (str_starts(pos, WPA_EVENT_CHANNEL_SWITCH_STARTED)) {
wpa_cli_exec(action_file, ctrl_ifname, pos);
+ } else if (str_starts(pos, WPA_EVENT_CHANNEL_SWITCH)) {
+ wpa_cli_exec(action_file, ctrl_ifname, pos);
} else if (str_starts(pos, AP_EVENT_ENABLED)) {
wpa_cli_exec(action_file, ctrl_ifname, pos);
} else if (str_starts(pos, AP_EVENT_DISABLED)) {
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 3fde0a8..15a859f 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -74,7 +74,7 @@
const char *const wpa_supplicant_version =
"wpa_supplicant v" VERSION_STR "\n"
-"Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2003-2024, Jouni Malinen <j@w1.fi> and contributors";
const char *const wpa_supplicant_license =
"This software may be distributed under the terms of the BSD license.\n"
@@ -126,6 +126,7 @@
static void wpa_bss_tmp_disallow_timeout(void *eloop_ctx, void *timeout_ctx);
+static void wpas_verify_ssid_beacon(void *eloop_ctx, void *timeout_ctx);
#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
static void wpas_update_fils_connect_params(struct wpa_supplicant *wpa_s);
#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
@@ -445,6 +446,7 @@
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
wpa_s->mgmt_group_cipher);
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SSID_PROTECTION, 0);
pmksa_cache_clear_current(wpa_s->wpa);
os_memset(&mlo, 0, sizeof(mlo));
@@ -612,6 +614,7 @@
eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
eloop_cancel_timeout(wpas_clear_disabled_interface, wpa_s, NULL);
+ eloop_cancel_timeout(wpas_verify_ssid_beacon, wpa_s, NULL);
wpas_wps_deinit(wpa_s);
@@ -928,6 +931,91 @@
}
+static void wpas_verify_ssid_beacon(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ struct wpa_bss *bss;
+ const u8 *ssid;
+ size_t ssid_len;
+
+ if (!wpa_s->current_ssid || !wpa_s->current_bss)
+ return;
+
+ ssid = wpa_s->current_bss->ssid;
+ ssid_len = wpa_s->current_bss->ssid_len;
+
+ if (wpa_s->current_ssid->ssid_len &&
+ (wpa_s->current_ssid->ssid_len != ssid_len ||
+ os_memcmp(wpa_s->current_ssid->ssid, ssid, ssid_len) != 0))
+ return;
+
+ if (wpa_s->wpa_state < WPA_4WAY_HANDSHAKE ||
+ !wpa_s->bigtk_set || wpa_s->ssid_verified)
+ return;
+
+ wpa_printf(MSG_DEBUG,
+ "SSID not yet verified; check if the driver has received a verified Beacon frame");
+ if (wpa_supplicant_update_scan_results(wpa_s, wpa_s->bssid) < 0)
+ return;
+
+ bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->bssid);
+ if (!bss)
+ return;
+ wpa_printf(MSG_DEBUG, "The current beacon time stamp: 0x%llx",
+ (long long unsigned int) bss->tsf);
+ if (bss->tsf > wpa_s->first_beacon_tsf) {
+ const u8 *ie;
+
+ wpa_printf(MSG_DEBUG,
+ "Verified Beacon frame has been received");
+ wpa_s->beacons_checked++;
+
+ ie = wpa_bss_get_ie_beacon(bss, WLAN_EID_SSID);
+ if (ie && ie[1] == ssid_len &&
+ os_memcmp(&ie[2], ssid, ssid_len) == 0) {
+ wpa_printf(MSG_DEBUG,
+ "SSID verified based on a Beacon frame and beacon protection");
+ wpa_s->ssid_verified = true;
+ return;
+ }
+
+ /* TODO: Multiple BSSID element */
+ }
+
+ if (wpa_s->beacons_checked < 16) {
+ eloop_register_timeout(wpa_s->next_beacon_check, 0,
+ wpas_verify_ssid_beacon, wpa_s, NULL);
+ wpa_s->next_beacon_check++;
+ }
+}
+
+
+static void wpas_verify_ssid_beacon_prot(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_bss *bss;
+
+ wpa_printf(MSG_DEBUG,
+ "SSID not yet verified; try to verify using beacon protection");
+ /* Fetch the current scan result which is likely based on not yet
+ * verified payload since the current BIGTK was just received. Any
+ * newer update in the future with a larger timestamp value is an
+ * indication that a verified Beacon frame has been received. */
+ if (wpa_supplicant_update_scan_results(wpa_s, wpa_s->bssid) < 0)
+ return;
+
+ bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->bssid);
+ if (!bss)
+ return;
+ wpa_printf(MSG_DEBUG, "The initial beacon time stamp: 0x%llx",
+ (long long unsigned int) bss->tsf);
+ wpa_s->first_beacon_tsf = bss->tsf;
+ wpa_s->beacons_checked = 0;
+ wpa_s->next_beacon_check = 1;
+ eloop_cancel_timeout(wpas_verify_ssid_beacon, wpa_s, NULL);
+ eloop_register_timeout(1, 0, wpas_verify_ssid_beacon, wpa_s, NULL);
+}
+
+
/**
* wpa_supplicant_set_state - Set current connection state
* @wpa_s: Pointer to wpa_supplicant data
@@ -1104,6 +1192,10 @@
if (wpa_s->wpa_state == WPA_COMPLETED)
wpas_dpp_connected(wpa_s);
#endif /* CONFIG_DPP2 */
+
+ if (wpa_s->wpa_state == WPA_COMPLETED &&
+ wpa_s->bigtk_set && !wpa_s->ssid_verified)
+ wpas_verify_ssid_beacon_prot(wpa_s);
}
#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
if (update_fils_connect_params)
@@ -1613,8 +1705,8 @@
if (bss) {
bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
- bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+ bss_rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
+ bss_rsnx = wpa_bss_get_rsnxe(wpa_s, bss, ssid, false);
bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
} else {
bss_wpa = bss_rsn = bss_rsnx = bss_osen = NULL;
@@ -2029,6 +2121,22 @@
wmm = !!wpa_bss_get_vendor_ie(bss, WMM_IE_VENDOR_TYPE);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_WMM_ENABLED, wmm);
+ if (ssid->ssid_protection && proto == WPA_PROTO_RSN) {
+ bool ssid_prot;
+
+ /* Enable SSID protection based on the AP advertising support
+ * for it to avoid potential interoperability issues with
+ * incorrect AP behavior if we were to send an "unexpected"
+ * RSNXE with multiple octets of payload. */
+ ssid_prot = ieee802_11_rsnx_capab(
+ bss_rsnx, WLAN_RSNX_CAPAB_SSID_PROTECTION);
+ if (!skip_default_rsne)
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SSID_PROTECTION,
+ proto == WPA_PROTO_RSN && ssid_prot);
+ } else {
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SSID_PROTECTION, false);
+ }
+
if (!skip_default_rsne) {
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie,
wpa_ie_len)) {
@@ -2426,6 +2534,7 @@
password = ssid->passphrase;
if (!password ||
+ !wpa_key_mgmt_sae(ssid->key_mgmt) ||
(conf->sae_pwe == SAE_PWE_HUNT_AND_PECK && !ssid->sae_password_id &&
!wpa_key_mgmt_sae_ext_key(ssid->key_mgmt) &&
!force &&
@@ -2446,7 +2555,7 @@
}
-static void wpa_s_clear_sae_rejected(struct wpa_supplicant *wpa_s)
+void wpa_s_clear_sae_rejected(struct wpa_supplicant *wpa_s)
{
#if defined(CONFIG_SAE) && defined(CONFIG_SME)
os_free(wpa_s->sme.sae_rejected_groups);
@@ -2499,6 +2608,7 @@
void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss, struct wpa_ssid *ssid)
{
+ bool clear_rejected = true;
struct wpa_connect_work *cwork;
enum wpas_mac_addr_style rand_style;
@@ -2540,14 +2650,15 @@
wmm_ac_save_tspecs(wpa_s);
#endif /* CONFIG_NO_WMM_AC */
wpa_s->reassoc_same_bss = 1;
+ clear_rejected = false;
} else if (wpa_s->current_bss && wpa_s->current_bss != bss) {
os_get_reltime(&wpa_s->roam_start);
}
- } else {
-#ifdef CONFIG_SAE
- wpa_s_clear_sae_rejected(wpa_s);
-#endif /* CONFIG_SAE */
}
+
+ if (clear_rejected)
+ wpa_s_clear_sae_rejected(wpa_s);
+
#ifdef CONFIG_SAE
wpa_s_setup_sae_pt(wpa_s->conf, ssid, false);
#endif /* CONFIG_SAE */
@@ -3105,7 +3216,7 @@
int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode);
enum hostapd_hw_mode hw_mode;
struct hostapd_hw_modes *mode = NULL;
- int i, obss_scan = 1;
+ int obss_scan = 1;
u8 channel;
bool is_6ghz, is_24ghz;
@@ -3124,14 +3235,8 @@
}
hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
- for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].mode == hw_mode &&
- hw_mode_get_channel(&wpa_s->hw.modes[i], freq->freq,
- NULL) != NULL) {
- mode = &wpa_s->hw.modes[i];
- break;
- }
- }
+ mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+ hw_mode, is_6ghz_freq(ssid->frequency));
if (!mode)
return;
@@ -3373,7 +3478,7 @@
}
if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
- wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
+ wpa_bss_get_rsne(wpa_s, bss, ssid, false)) &&
wpa_key_mgmt_wpa(ssid->key_mgmt)) {
int try_opportunistic;
const u8 *cache_id = NULL;
@@ -3598,6 +3703,17 @@
}
}
+ if (ssid->max_idle && wpa_ie_len + 5 <= max_wpa_ie_len) {
+ u8 *pos = wpa_ie;
+
+ *pos++ = WLAN_EID_BSS_MAX_IDLE_PERIOD;
+ *pos++ = 3;
+ WPA_PUT_LE16(pos, ssid->max_idle);
+ pos += 2;
+ *pos = 0; /* Idle Options */
+ wpa_ie_len += 5;
+ }
+
#ifdef CONFIG_HS20
if (is_hs20_network(wpa_s, ssid, bss)
#ifndef ANDROID /* Android does not use the native HS 2.0 config */
@@ -3852,6 +3968,57 @@
wpa_ie_len += multi_ap_ie_len;
}
+ if (!wpas_driver_bss_selection(wpa_s) &&
+ wpas_rsn_overriding(wpa_s) &&
+ wpas_ap_supports_rsn_overriding(wpa_s, bss) &&
+ wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
+ u8 *pos = wpa_ie + wpa_ie_len;
+ u32 type = 0;
+ const u8 *ie;
+
+ ie = wpa_bss_get_rsne(wpa_s, bss, ssid, wpa_s->valid_links);
+ if (ie && ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] >= 4)
+ type = WPA_GET_BE32(&ie[2]);
+
+ if (type) {
+ /* Indicate support for RSN overriding */
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+ *pos++ = 4;
+ WPA_PUT_BE32(pos, type);
+ pos += 4;
+ wpa_hexdump(MSG_MSGDUMP, "RSNE Override", wpa_ie,
+ pos - wpa_ie);
+ wpa_ie_len += 2 + 4;
+ }
+ }
+
+ if (wpas_driver_bss_selection(wpa_s) &&
+ wpas_rsn_overriding(wpa_s)) {
+ if (wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
+ u8 *pos = wpa_ie + wpa_ie_len;
+
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+ *pos++ = 4;
+ WPA_PUT_BE32(pos, RSNE_OVERRIDE_IE_VENDOR_TYPE);
+ pos += 4;
+ wpa_hexdump(MSG_MSGDUMP, "RSNE Override", wpa_ie,
+ pos - wpa_ie);
+ wpa_ie_len += 2 + 4;
+ }
+
+ if (wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
+ u8 *pos = wpa_ie + wpa_ie_len;
+
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+ *pos++ = 4;
+ WPA_PUT_BE32(pos, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
+ pos += 4;
+ wpa_hexdump(MSG_MSGDUMP, "RSNE Override 2",
+ wpa_ie, pos - wpa_ie);
+ wpa_ie_len += 2 + 4;
+ }
+ }
+
params->wpa_ie = wpa_ie;
params->wpa_ie_len = wpa_ie_len;
params->auth_alg = algs;
@@ -4076,6 +4243,7 @@
#ifdef CONFIG_WNM
wpa_s->bss_trans_mgmt_in_progress = false;
#endif /* CONFIG_WNM */
+ wpa_s->no_suitable_network = 0;
if (deinit) {
if (work->started) {
@@ -4427,7 +4595,7 @@
params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
- const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ const u8 *rsn = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
struct wpa_ie_data ie;
if (!wpas_driver_bss_selection(wpa_s) && rsn &&
wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
@@ -4587,6 +4755,8 @@
}
wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
+ if (bss)
+ wpa_sm_set_ssid(wpa_s->wpa, bss->ssid, bss->ssid_len);
wpa_supplicant_initiate_eapol(wpa_s);
if (old_ssid != wpa_s->current_ssid)
wpas_notify_network_changed(wpa_s);
@@ -4635,14 +4805,18 @@
int zero_addr = 0;
wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
- " pending_bssid=" MACSTR " reason=%d (%s) state=%s",
+ " pending_bssid=" MACSTR
+ " reason=%d (%s) state=%s valid_links=0x%x ap_mld_addr=" MACSTR,
MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
reason_code, reason2str(reason_code),
- wpa_supplicant_state_txt(wpa_s->wpa_state));
+ wpa_supplicant_state_txt(wpa_s->wpa_state), wpa_s->valid_links,
+ MAC2STR(wpa_s->ap_mld_addr));
- if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
- (wpa_s->wpa_state == WPA_AUTHENTICATING ||
- wpa_s->wpa_state == WPA_ASSOCIATING))
+ if (wpa_s->valid_links && !is_zero_ether_addr(wpa_s->ap_mld_addr))
+ addr = wpa_s->ap_mld_addr;
+ else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
+ (wpa_s->wpa_state == WPA_AUTHENTICATING ||
+ wpa_s->wpa_state == WPA_ASSOCIATING))
addr = wpa_s->pending_bssid;
else if (!is_zero_ether_addr(wpa_s->bssid))
addr = wpa_s->bssid;
@@ -4960,6 +5134,7 @@
struct wpa_ssid *other_ssid;
int disconnected = 0;
+ bool request_new_scan = false;
if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
@@ -5005,6 +5180,18 @@
(ssid->mode == WPAS_MODE_MESH ||
ssid->mode == WPAS_MODE_AP) ? ssid : NULL;
+ if (ssid->scan_ssid &&
+ (wpa_s->no_suitable_network || wpa_s->last_scan_external)) {
+ wpa_printf(MSG_DEBUG,
+ "Request a new scan for hidden network");
+ request_new_scan = true;
+ } else if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
+ !ssid->owe_only) {
+ wpa_printf(MSG_DEBUG,
+ "Request a new scan for OWE transition SSID");
+ request_new_scan = true;
+ }
+
/*
* Don't optimize next scan freqs since a new ESS has been
* selected.
@@ -5024,7 +5211,7 @@
wpa_s_setup_sae_pt(wpa_s->conf, ssid, false);
}
- if (wpa_s->connect_without_scan ||
+ if (wpa_s->connect_without_scan || request_new_scan ||
wpa_supplicant_fast_associate(wpa_s) != 1) {
wpa_s->scan_req = NORMAL_SCAN_REQ;
wpas_scan_reset_sched_scan(wpa_s);
@@ -7289,6 +7476,7 @@
wpa_s->drv_flags = capa.flags;
wpa_s->drv_flags2 = capa.flags2;
wpa_s->drv_enc = capa.enc;
+ wpa_s->drv_key_mgmt = capa.key_mgmt;
wpa_s->drv_rrm_flags = capa.rrm_flags;
wpa_s->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs;
wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
@@ -8502,6 +8690,28 @@
}
+static bool wpas_driver_rsn_override(struct wpa_supplicant *wpa_s)
+{
+ return !!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_RSN_OVERRIDE_STA);
+}
+
+
+bool wpas_rsn_overriding(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->conf->rsn_overriding == RSN_OVERRIDING_DISABLED)
+ return false;
+
+ if (wpa_s->conf->rsn_overriding == RSN_OVERRIDING_ENABLED)
+ return true;
+
+ if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
+ wpas_driver_bss_selection(wpa_s))
+ return wpas_driver_rsn_override(wpa_s);
+
+ return true;
+}
+
+
#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW) || defined (CONFIG_CTRL_IFACE_AIDL)
int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
@@ -9522,3 +9732,58 @@
return false;
}
+
+
+bool wpas_ap_supports_rsn_overriding(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss)
+{
+ int i;
+
+ if (!bss)
+ return false;
+ if (wpa_bss_get_vendor_ie(bss, RSNE_OVERRIDE_IE_VENDOR_TYPE) ||
+ wpa_bss_get_vendor_ie(bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE))
+ return true;
+
+ if (!wpa_s->valid_links)
+ return false;
+
+ for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+ if (!(wpa_s->valid_links & BIT(i)))
+ continue;
+ if (wpa_s->links[i].bss &&
+ (wpa_bss_get_vendor_ie(wpa_s->links[i].bss,
+ RSNE_OVERRIDE_IE_VENDOR_TYPE) ||
+ wpa_bss_get_vendor_ie(wpa_s->links[i].bss,
+ RSNE_OVERRIDE_2_IE_VENDOR_TYPE)))
+ return true;
+ }
+
+ return false;
+}
+
+
+bool wpas_ap_supports_rsn_overriding_2(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss)
+{
+ int i;
+
+ if (!bss)
+ return false;
+ if (wpa_bss_get_vendor_ie(bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE))
+ return true;
+
+ if (!wpa_s->valid_links)
+ return false;
+
+ for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+ if (!(wpa_s->valid_links & BIT(i)))
+ continue;
+ if (wpa_s->links[i].bss &&
+ wpa_bss_get_vendor_ie(wpa_s->links[i].bss,
+ RSNE_OVERRIDE_2_IE_VENDOR_TYPE))
+ return true;
+ }
+
+ return false;
+}
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 89c5d03..abbe7d7 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -878,6 +878,15 @@
# 1 = auto: Activate Extended Key ID support if the driver supports it
#extended_key_id=0
+# RSN overriding
+# NOTE: The protocol used for this mechanism is still subject to change and as
+# such, this should not yet be enabled for production uses to avoid issues if
+# something were to change.
+# 0 = Disabled (default)
+# 1 = Enabled automatically if the driver indicates support
+# 2 = Forced to be enabled even without driver capability indication
+#rsn_overriding=0
+
# network block
#
# Each network (usually AP's sharing the same SSID) is configured as a separate
@@ -1771,6 +1780,11 @@
# In STA mode it defines the EDMG channel for connection (if supported by AP).
#edmg_channel=9
+# BSS max idle period to request
+# If nonzero, request the specified number of 1000 TU (i.e., 1.024 s)
+# as the maximum idle period for the STA during association.
+#max_idle=600
+
# Example blocks:
# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 0fea5cc..245ac93 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -822,6 +822,7 @@
size_t last_scan_res_used;
size_t last_scan_res_size;
struct os_reltime last_scan;
+ bool last_scan_external;
const struct wpa_driver_ops *driver;
int interface_removed; /* whether the network interface has been
@@ -937,6 +938,7 @@
u64 drv_flags;
u64 drv_flags2;
unsigned int drv_enc;
+ unsigned int drv_key_mgmt;
unsigned int drv_rrm_flags;
unsigned int drv_max_acl_mac_addrs;
@@ -1635,6 +1637,12 @@
struct wpa_radio_work *nan_usd_listen_work;
struct wpa_radio_work *nan_usd_tx_work;
#endif /* CONFIG_NAN_USD */
+
+ bool ssid_verified;
+ bool bigtk_set;
+ u64 first_beacon_tsf;
+ unsigned int beacons_checked;
+ unsigned int next_beacon_check;
};
@@ -1746,6 +1754,7 @@
void fils_connection_failure(struct wpa_supplicant *wpa_s);
void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
+bool wpas_rsn_overriding(struct wpa_supplicant *wpa_s);
int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s);
void wpas_auth_failed(struct wpa_supplicant *wpa_s, const char *reason,
const u8 *bssid);
@@ -1932,6 +1941,7 @@
int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr);
void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid,
bool force);
+void wpa_s_clear_sae_rejected(struct wpa_supplicant *wpa_s);
bool wpas_is_sae_avoided(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
@@ -2043,5 +2053,9 @@
bool wpa_is_non_eht_scs_traffic_desc_supported(struct wpa_bss *bss);
bool wpas_ap_link_address(struct wpa_supplicant *wpa_s, const u8 *addr);
+bool wpas_ap_supports_rsn_overriding(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss);
+bool wpas_ap_supports_rsn_overriding_2(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss);
#endif /* WPA_SUPPLICANT_I_H */
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 2fea640..de216d2 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -441,11 +441,11 @@
if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
ret = -1;
- ie = wpa_bss_get_ie(curr, WLAN_EID_RSN);
+ ie = wpa_bss_get_rsne(wpa_s, curr, ssid, false);
if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
ret = -1;
- ie = wpa_bss_get_ie(curr, WLAN_EID_RSNX);
+ ie = wpa_bss_get_rsnxe(wpa_s, curr, ssid, false);
if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
ret = -1;
} else {
@@ -550,6 +550,8 @@
enum key_flag key_flag)
{
struct wpa_supplicant *wpa_s = _wpa_s;
+ int ret;
+
if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) {
/* Clear the MIC error counter when setting a new PTK. */
wpa_s->mic_errors_seen = 0;
@@ -572,8 +574,14 @@
wpa_s->last_tk_len = key_len;
}
#endif /* CONFIG_TESTING_OPTIONS */
- return wpa_drv_set_key(wpa_s, link_id, alg, addr, key_idx, set_tx, seq,
- seq_len, key, key_len, key_flag);
+
+ ret = wpa_drv_set_key(wpa_s, link_id, alg, addr, key_idx, set_tx, seq,
+ seq_len, key, key_len, key_flag);
+ if (ret == 0 && (key_idx == 6 || key_idx == 7) &&
+ alg != WPA_ALG_NONE && key_len > 0)
+ wpa_s->bigtk_set = true;
+
+ return ret;
}
@@ -1470,6 +1478,15 @@
}
+static void wpa_supplicant_ssid_verified(void *_wpa_s)
+{
+ struct wpa_supplicant *wpa_s = _wpa_s;
+
+ wpa_s->ssid_verified = true;
+ wpa_msg(wpa_s, MSG_INFO, "RSN: SSID matched expected value");
+}
+
+
int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
{
#ifndef CONFIG_NO_WPA
@@ -1536,6 +1553,7 @@
ctx->set_ltf_keyseed = wpa_supplicant_set_ltf_keyseed;
#endif /* CONFIG_PASN */
ctx->notify_pmksa_cache_entry = wpa_supplicant_notify_pmksa_cache_entry;
+ ctx->ssid_verified = wpa_supplicant_ssid_verified;
wpa_s->wpa = wpa_sm_init(ctx);
if (wpa_s->wpa == NULL) {
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index f103237..f3a8c9c 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -226,7 +226,7 @@
wpa_printf(MSG_DEBUG, "WPS: AP found from BSS table");
- ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ ie = wpa_bss_get_rsne(wpa_s, bss, ssid, false);
if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0) {
wpa2 = 1;
if (adv.pairwise_cipher & WPA_CIPHER_CCMP)