diff mbox series

Display error on SAE connection with incorrect key

Message ID 20231108134432.11121-1-jianling.fu@mediatek.com
State Changes Requested
Headers show
Series Display error on SAE connection with incorrect key | expand

Commit Message

Jianling.Fu Nov. 8, 2023, 1:44 p.m. UTC
If the status code is not 'success' during the SAE 'auth confirm' step,
or if the auth confirm check encounters a mismatch, this would be
related to the key. In such cases, we would trigger an
'association reject' event, which is used to prompt the
upper layer to process the event as a 'WRONG_PASSWORD' event

Signed-off-by: Jianling.Fu <jianling.fu@mediatek.com>
---
 wpa_supplicant/config_ssid.h    |  5 +++++
 wpa_supplicant/sme.c            | 23 ++++++++++++++++++++++-
 wpa_supplicant/wpa_supplicant.c |  3 ++-
 3 files changed, 29 insertions(+), 2 deletions(-)

Comments

Jouni Malinen Nov. 10, 2023, 3:02 p.m. UTC | #1
On Wed, Nov 08, 2023 at 09:44:32PM +0800, Jianling.Fu wrote:
> If the status code is not 'success' during the SAE 'auth confirm' step,
> or if the auth confirm check encounters a mismatch, this would be
> related to the key. In such cases, we would trigger an
> 'association reject' event, which is used to prompt the
> upper layer to process the event as a 'WRONG_PASSWORD' event

This is not an association rejection and should not be claimed to be
that. I'm not sure what 'WRONG_PASSWORD' event means in this context.
There is no such string in this patch or baseline implementation.

For the case where the SAE Confirm is sent first by the STA, the status
code from the AP is already reported with this:

CTRL-EVENT-AUTH-REJECT 02:00:00:00:03:00 auth_type=3 auth_transaction=2 status_code=15

For the case where the SAE Confirm is sent first by the AP, an
additional indication about the SAE Confirm message validation failing
might be of some use. However, that should not be reporting association
failure since association was not even attempted in this case. Instead,
a new indication should be used for this specific case instead of trying
to use an existing association related event.

This patch did not result in WRONG_PASSWORD being indicated in my test.
Instead, this looked as follows:
SME: Authentication response: peer=02:00:00:00:03:00 auth_type=3 auth_transaction=2 status_code=0
SAE: Confirm mismatch
SME: SAE Authentication failure indicate assoc reject
SME: Association with 02:00:00:00:03:00 failed: status code 1
wpa_driver_nl80211_deauthenticate(addr=02:00:00:00:03:00 reason_code=3)

This is quite confusing since there was no association failure and there
was no status code 1 anywhere either. Furthermore, there was this extra
deauthentication.

> diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
> @@ -1265,6 +1265,11 @@ struct wpa_ssid {
> +	/**
> +	 * New variable to track if the network
> +	 * has been successfully connected
> +	 */
> +	int had_been_connected;

This would not be maintained over restarting of a wpa_supplicant
process. It would be better to not to try to reuse some existing
mechanism for indicating potential password failures. Instead, a new
event that could be indicated on all local verification failures for
received SAE confirm messages could be used without having to try to
track success within wpa_supplicant if this is targeting a case where an
external component is adding a network profile and observing what
happens during the first connection attempt.
diff mbox series

Patch

diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index ff045380e..5c237d56a 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -1265,6 +1265,11 @@  struct wpa_ssid {
 	 * to use the interface in a bridge.
 	 */
 	int enable_4addr_mode;
+	/**
+	 * New variable to track if the network
+	 * has been successfully connected
+	 */
+	int had_been_connected;
 };
 
 #endif /* CONFIG_SSID_H */
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index bb04652f5..02baa1c0d 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -1892,7 +1892,7 @@  static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
 			return -1;
 		if (sae_check_confirm(&wpa_s->sme.sae, data, len,
 				      ie_offset) < 0)
-			return -1;
+			return -2;
 		if (external && wpa_s->sme.ext_ml_auth &&
 		    sme_external_ml_auth(wpa_s, data, len, *ie_offset,
 					 status_code))
@@ -2038,6 +2038,27 @@  void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
 				   data->auth.ies_len, 0, data->auth.peer,
 				   &ie_offset);
 		if (res < 0) {
+			if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME
+					&& data->auth.auth_transaction == 2
+					&& ssid->had_been_connected == 0
+					&& (data->auth.status_code ==
+						WLAN_STATUS_UNSPECIFIED_FAILURE
+						|| res == -2)) {
+				union wpa_event_data event;
+
+				os_memset(&event, 0, sizeof(event));
+				event.assoc_reject.bssid = wpa_s->pending_bssid;
+				event.assoc_reject.status_code =
+					WLAN_STATUS_UNSPECIFIED_FAILURE;
+				wpa_s->assoc_status_code =
+					event.assoc_reject.status_code;
+				wpas_notify_assoc_status_code(wpa_s);
+				wpa_dbg(wpa_s, MSG_DEBUG,
+					"SME: SAE Authentication failure indicate assoc reject");
+				sme_event_assoc_reject(wpa_s, &event);
+
+				return;
+			}
 			wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
 			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index ba68e8198..a21fd5891 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1063,7 +1063,8 @@  void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
 
 	if (wpa_s->wpa_state != old_state) {
 		wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
-
+		if (wpa_s->wpa_state == WPA_COMPLETED)
+			wpa_s->current_ssid->had_been_connected = 1;
 		/*
 		 * Notify the P2P Device interface about a state change in one
 		 * of the interfaces.