]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Pick WPS AP based on latest received WPS IE
authorSai Pratyusha Magam <quic_smagam@quicinc.com>
Sun, 21 Aug 2022 15:05:50 +0000 (20:35 +0530)
committerJouni Malinen <j@w1.fi>
Thu, 24 Nov 2022 16:50:44 +0000 (18:50 +0200)
wpa_supplicant used the WPS IE from a Probe Response frame, if one was
received, even if there might have been a more recent Beacon frame with
an updated WPS IE. This could result in using stale information about
active WPS registrar, e.g., when operating on the 6 GHz band.

Prefer WPS IE from a Beacon frame over the default selection of Probe
Response frame (if one has been received) in cases where the Beacon
frame is received more recently than the Probe Response frame and active
WPS Registrar information is being checked. Skip this for the case where
UUID-E is needed since that is not available in the Beacon frame.

Signed-off-by: Sai Pratyusha Magam <quic_smagam@quicinc.com>
wpa_supplicant/wps_supplicant.c

index 11f0b3d49751f9396bad869c4da7052e87cf22e4..02111ea91100bf9dc46b7966418c22649b6759d1 100644 (file)
@@ -79,6 +79,18 @@ static void wpas_wps_assoc_with_cred_cancel(struct wpa_supplicant *wpa_s)
 }
 
 
+static struct wpabuf * wpas_wps_get_wps_ie(struct wpa_bss *bss)
+{
+       /* Return the latest receive WPS IE from the AP regardless of whether
+        * it was from a Beacon frame or Probe Response frame to avoid using
+        * stale information. */
+       if (bss->beacon_newer)
+               return wpa_bss_get_vendor_ie_multi_beacon(bss,
+                                                         WPS_IE_VENDOR_TYPE);
+       return wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
+}
+
+
 int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
 {
        if (wpas_p2p_wps_eapol_cb(wpa_s) > 0)
@@ -141,8 +153,7 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
                        struct wpabuf *wps;
                        struct wps_parse_attr attr;
 
-                       wps = wpa_bss_get_vendor_ie_multi(bss,
-                                                         WPS_IE_VENDOR_TYPE);
+                       wps = wpas_wps_get_wps_ie(bss);
                        if (wps && wps_parse_msg(wps, &attr) == 0 &&
                            attr.wps_state &&
                            *attr.wps_state == WPS_STATE_CONFIGURED)
@@ -1705,7 +1716,7 @@ int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
        if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
                return -1;
 
-       wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
+       wps_ie = wpas_wps_get_wps_ie(bss);
        if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
                if (!wps_ie) {
                        wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
@@ -1779,13 +1790,13 @@ int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
        int ret = 0;
 
        if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
-               wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
+               wps_ie = wpas_wps_get_wps_ie(bss);
                if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) {
                        /* allow wildcard SSID for WPS PBC */
                        ret = 1;
                }
        } else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
-               wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
+               wps_ie = wpas_wps_get_wps_ie(bss);
                if (wps_ie &&
                    (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) ||
                     wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
@@ -1907,7 +1918,8 @@ void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s)
 
        dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
                struct wpabuf *ie;
-               ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
+
+               ie = wpas_wps_get_wps_ie(bss);
                if (!ie)
                        continue;
                if (wps_is_selected_pbc_registrar(ie))