]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Allow a lower priority BSS to be tried after network disabling
authorJouni Malinen <quic_jouni@quicinc.com>
Thu, 24 Nov 2022 10:03:01 +0000 (12:03 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 24 Nov 2022 10:03:01 +0000 (12:03 +0200)
If a higher priority BSS has invalid security parameters, e.g., an
invalid SAE password, and a lower priority BSS is discovered only after
the local network profile has been temporarily disabled, the BSSID
ignoring mechanism is not sufficient to allow the lower priority BSS to
be tried and all consecutive attempts will continue to use the higher
priority BSS. This might prevent connection in some unexpected cases
with invalid network configuration.

Extend BSSID ignoring mechanism to work in this type of a case by
ignoring the BSSID that resulted in disabling the SSID temporarily
during the first connection attempt after having re-enabled the SSID.
This allows a lower priority BSS, if any is available in scan results,
to be tried next to see if it might have working security parameters.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
wpa_supplicant/config_ssid.h
wpa_supplicant/events.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index a8a81d79b3eeaeaa90065cdee479438f18c0b02d..c77ffa11a92acf3286b8a0e6501ee8c6df91014d 100644 (file)
@@ -837,6 +837,14 @@ struct wpa_ssid {
         */
        struct os_reltime disabled_until;
 
+       /**
+        * disabled_due_to - BSSID of the disabling failure
+        *
+        * This identifies the BSS that failed the connection attempt that
+        * resulted in the network being temporarily disabled.
+        */
+       u8 disabled_due_to[ETH_ALEN];
+
        /**
         * parent_cred - Pointer to parent wpa_cred entry
         *
index 5af3b61770dd1265216c9b36656859823c53ccab..35f3694a0be26a64dc5fe18cb1ba3e6ea6e4e59d 100644 (file)
@@ -2845,7 +2845,7 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s,
                if (!ssid->psk_set) {
                        wpa_dbg(wpa_s, MSG_INFO,
                                "No PSK available for association");
-                       wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE");
+                       wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE", NULL);
                        return -1;
                }
 
@@ -3895,7 +3895,7 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
                        "pre-shared key may be incorrect");
                if (wpas_p2p_4way_hs_failed(wpa_s) > 0)
                        return; /* P2P group removed */
-               wpas_auth_failed(wpa_s, "WRONG_KEY");
+               wpas_auth_failed(wpa_s, "WRONG_KEY", prev_pending_bssid);
 #ifdef CONFIG_DPP2
                wpas_dpp_send_conn_status_result(wpa_s,
                                                 DPP_STATUS_AUTH_FAILURE);
@@ -4399,7 +4399,7 @@ static void wpas_event_disconnect(struct wpa_supplicant *wpa_s, const u8 *addr,
                (wpa_s->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) &&
               eapol_sm_failed(wpa_s->eapol))) &&
             !wpa_s->eap_expected_failure))
-               wpas_auth_failed(wpa_s, "AUTH_FAILED");
+               wpas_auth_failed(wpa_s, "AUTH_FAILED", addr);
 
 #ifdef CONFIG_P2P
        if (deauth && reason_code > 0) {
index f9409f56a829a8168f65d5ce3e123071f4079338..ab2e70b5d5d3322ecada543a9355bd4218bfc709 100644 (file)
@@ -2011,7 +2011,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
                if (!psk_set) {
                        wpa_msg(wpa_s, MSG_INFO,
                                "No PSK available for association");
-                       wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE");
+                       wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE", NULL);
                        return -1;
                }
 #ifdef CONFIG_OWE
@@ -7919,7 +7919,7 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
        if (wpa_s->consecutive_conn_failures > 3 && wpa_s->current_ssid) {
                wpa_printf(MSG_DEBUG, "Continuous association failures - "
                           "consider temporary network disabling");
-               wpas_auth_failed(wpa_s, "CONN_FAILED");
+               wpas_auth_failed(wpa_s, "CONN_FAILED", bssid);
        }
        /*
         * Multiple consecutive connection failures mean that other APs are
@@ -8266,7 +8266,8 @@ int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
 }
 
 
-void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
+void wpas_auth_failed(struct wpa_supplicant *wpa_s, const char *reason,
+                     const u8 *bssid)
 {
        struct wpa_ssid *ssid = wpa_s->current_ssid;
        int dur;
@@ -8323,6 +8324,9 @@ void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
                "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
                ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
                ssid->auth_failures, dur, reason);
+
+       if (bssid)
+               os_memcpy(ssid->disabled_due_to, bssid, ETH_ALEN);
 }
 
 
@@ -8339,8 +8343,15 @@ void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
        }
        ssid->disabled_until.sec = 0;
        ssid->disabled_until.usec = 0;
-       if (clear_failures)
+       if (clear_failures) {
                ssid->auth_failures = 0;
+       } else if (!is_zero_ether_addr(ssid->disabled_due_to)) {
+               wpa_printf(MSG_DEBUG, "Mark BSSID " MACSTR
+                          " ignored to allow a lower priority BSS, if any, to be tried next",
+                          MAC2STR(ssid->disabled_due_to));
+               wpa_bssid_ignore_add(wpa_s, ssid->disabled_due_to);
+               os_memset(ssid->disabled_due_to, 0, ETH_ALEN);
+       }
 }
 
 
index 3e35b9ca847053157b8726f96a87cab78f33fd9d..add24f07dfe76551c2947d9c73608c3511dc8351 100644 (file)
@@ -1629,7 +1629,8 @@ 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);
 int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s);
-void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason);
+void wpas_auth_failed(struct wpa_supplicant *wpa_s, const char *reason,
+                     const u8 *bssid);
 void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
                              struct wpa_ssid *ssid, int clear_failures);
 int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid);