From 05ec485688e63ee06159cfb45e99b480efb43661 Mon Sep 17 00:00:00 2001 From: Sai Pratyusha Magam Date: Sun, 21 Aug 2022 20:35:50 +0530 Subject: [PATCH] WPS: Pick WPS AP based on latest received WPS IE 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 --- wpa_supplicant/wps_supplicant.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 11f0b3d49..02111ea91 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -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))