]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - wpa_supplicant/events.c
OWE: Use shorter scan interval during transition mode search
[thirdparty/hostap.git] / wpa_supplicant / events.c
index 51e9d8a4ff47b798cf19395d8cb551dce27e9ca6..860b2792cc53d4650b5013c19210776369e4145f 100644 (file)
@@ -50,6 +50,9 @@
 #include "dpp_supplicant.h"
 
 
+#define MAX_OWE_TRANSITION_BSS_SELECT_COUNT 5
+
+
 #ifndef CONFIG_NO_SCAN_PROCESSING
 static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
                                              int new_scan, int own_request);
@@ -536,7 +539,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                 (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA));
 
        rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
-       while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
+       while ((ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) && rsn_ie) {
                proto_match++;
 
                if (wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
@@ -555,7 +558,8 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                        return 1;
                }
 
-               if (!(ie.proto & ssid->proto)) {
+               if (!(ie.proto & ssid->proto) &&
+                   !(ssid->proto & WPA_PROTO_OSEN)) {
                        if (debug_print)
                                wpa_dbg(wpa_s, MSG_DEBUG,
                                        "   skip RSN IE - proto mismatch");
@@ -702,6 +706,19 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_OWE
        if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) && !ssid->owe_only &&
            !wpa_ie && !rsn_ie) {
+               if (wpa_s->owe_transition_select &&
+                   wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE) &&
+                   ssid->owe_transition_bss_select_count + 1 <=
+                   MAX_OWE_TRANSITION_BSS_SELECT_COUNT) {
+                       ssid->owe_transition_bss_select_count++;
+                       if (debug_print)
+                               wpa_dbg(wpa_s, MSG_DEBUG,
+                                       "   skip OWE transition BSS (selection count %d does not exceed %d)",
+                                       ssid->owe_transition_bss_select_count,
+                                       MAX_OWE_TRANSITION_BSS_SELECT_COUNT);
+                       wpa_s->owe_transition_search = 1;
+                       return 0;
+               }
                if (debug_print)
                        wpa_dbg(wpa_s, MSG_DEBUG,
                                "   allow in OWE transition mode");
@@ -985,18 +1002,22 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
        struct wpa_blacklist *e;
        const u8 *ie;
        struct wpa_ssid *ssid;
-       int osen;
+       int osen, rsn_osen = 0;
 #ifdef CONFIG_MBO
        const u8 *assoc_disallow;
 #endif /* CONFIG_MBO */
        const u8 *match_ssid;
        size_t match_ssid_len;
+       struct wpa_ie_data data;
 
        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);
        rsn_ie_len = ie ? ie[1] : 0;
+       if (ie && wpa_parse_wpa_ie_rsn(ie, 2 + ie[1], &data) == 0 &&
+           (data.key_mgmt & WPA_KEY_MGMT_OSEN))
+               rsn_osen = 1;
 
        ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
        osen = ie != NULL;
@@ -1170,7 +1191,8 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
                        continue;
                }
 
-               if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) && !osen) {
+               if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) && !osen &&
+                   !rsn_osen) {
                        if (debug_print)
                                wpa_dbg(wpa_s, MSG_DEBUG,
                                        "   skip - non-OSEN network not allowed");
@@ -1381,8 +1403,11 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
 
        for (i = 0; i < wpa_s->last_scan_res_used; i++) {
                struct wpa_bss *bss = wpa_s->last_scan_res[i];
+
+               wpa_s->owe_transition_select = 1;
                *selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group,
                                                    only_first_ssid, 1);
+               wpa_s->owe_transition_select = 0;
                if (!*selected_ssid)
                        continue;
                wpa_dbg(wpa_s, MSG_DEBUG, "   selected BSS " MACSTR
@@ -1929,6 +1954,7 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
        if (wpa_s->p2p_mgmt)
                return 0; /* no normal connection on p2p_mgmt interface */
 
+       wpa_s->owe_transition_search = 0;
        selected = wpa_supplicant_pick_network(wpa_s, &ssid);
 
 #ifdef CONFIG_MESH
@@ -2030,6 +2056,17 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
                                return 0;
                        }
 #endif /* CONFIG_WPS */
+#ifdef CONFIG_OWE
+                       if (wpa_s->owe_transition_search) {
+                               wpa_dbg(wpa_s, MSG_DEBUG,
+                                       "OWE: Use shorter wait during transition mode search");
+                               timeout_sec = 0;
+                               timeout_usec = 500000;
+                               wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
+                                                           timeout_usec);
+                               return 0;
+                       }
+#endif /* CONFIG_OWE */
                        if (wpa_supplicant_req_sched_scan(wpa_s))
                                wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
                                                            timeout_usec);
@@ -3932,8 +3969,11 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
 
                if (!bss) {
                        bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
-                       if (!bss)
+                       if (!bss) {
+                               wpas_connection_failed(wpa_s, bssid);
+                               wpa_supplicant_mark_disassoc(wpa_s);
                                return;
+                       }
                }
                wpa_printf(MSG_DEBUG, "OWE: Try next supported DH group");
                wpas_connect_work_done(wpa_s);
@@ -3960,12 +4000,24 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_SAE */
 
+#ifdef CONFIG_DPP
+       if (wpa_s->current_ssid &&
+           wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_DPP &&
+           !data->assoc_reject.timed_out) {
+               wpa_dbg(wpa_s, MSG_DEBUG, "DPP: Drop PMKSA cache entry");
+               wpa_sm_aborted_cached(wpa_s->wpa);
+               wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid);
+       }
+#endif /* CONFIG_DPP */
+
 #ifdef CONFIG_FILS
        /* Update ERP next sequence number */
-       if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS)
+       if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS) {
                eapol_sm_update_erp_next_seq_num(
                        wpa_s->eapol,
                        data->assoc_reject.fils_erp_next_seq_num);
+               fils_connection_failure(wpa_s);
+       }
 #endif /* CONFIG_FILS */
 
        wpas_connection_failed(wpa_s, bssid);