[PATCH v2 12/20] mesh_rsn: add timer for SAE authentication

Bob Copeland me at bobcopeland.com
Mon Sep 1 00:23:31 EDT 2014


From: Chun-Yeow Yeoh <yeohchunyeow at gmail.com>

Add timer to do SAE re-authentication with number of tries defined
by MESH_AUTH_RETRY and timeout defined by MESH_AUTH_TIMEOUT.

Ignoring the sending of reply message on "SAE confirm before commit"
to avoid "ping-pong" issues with other mesh nodes. This is obvious when
number of mesh nodes in MBSS reaching 6.

Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow at gmail.com>
Signed-off-by: Bob Copeland <me at bobcopeland.com>
---
 src/ap/sta_info.c         |  8 ++++++++
 src/ap/sta_info.h         |  1 +
 wpa_supplicant/mesh_mpm.c |  7 +++++++
 wpa_supplicant/mesh_mpm.h |  2 ++
 wpa_supplicant/mesh_rsn.c | 38 ++++++++++++++++++++++++++++++++++++--
 wpa_supplicant/mesh_rsn.h |  1 +
 6 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 60f0768..2c01826 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -33,6 +33,10 @@
 #include "wnm_ap.h"
 #include "sta_info.h"
 
+#ifdef CONFIG_MESH
+#include "../../wpa_supplicant/mesh_mpm.h"
+#endif
+
 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
 				       struct sta_info *sta);
 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx);
@@ -224,6 +228,10 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 		set_beacon++;
 #endif /* NEED_AP_MLME && CONFIG_IEEE80211N */
 
+#ifdef CONFIG_MESH
+	mesh_mpm_free_sta(sta);
+#endif
+
 	if (set_beacon)
 		ieee802_11_set_beacons(hapd->iface);
 
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index a1a8ed1..3fe38b0 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -65,6 +65,7 @@ struct sta_info {
 	u8 aek[32];	/* SHA256 digest length */
 	u8 mtk[16];
 	u8 mgtk[16];
+	u8 sae_auth_retry;
 #endif /* CONFIG_MESH */
 
 	unsigned int nonerp_set:1;
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index b6e4c96..25ea5e8 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -900,3 +900,10 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
 	}
 	mesh_mpm_fsm(wpa_s, sta, event);
 }
+
+/* called by ap_free_sta */
+void mesh_mpm_free_sta(struct sta_info *sta)
+{
+	eloop_cancel_timeout(plink_timer, ELOOP_ALL_CTX, sta);
+	eloop_cancel_timeout(mesh_auth_timer, ELOOP_ALL_CTX, sta);
+}
diff --git a/wpa_supplicant/mesh_mpm.h b/wpa_supplicant/mesh_mpm.h
index f890ad6..0cba7ad 100644
--- a/wpa_supplicant/mesh_mpm.h
+++ b/wpa_supplicant/mesh_mpm.h
@@ -23,4 +23,6 @@ void mesh_mpm_deinit(struct wpa_supplicant *wpa_s,
 		     struct hostapd_iface *ifmsh);
 void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
 
+void mesh_mpm_free_sta(struct sta_info *sta);
+
 #endif /* MESH_MPM_H */
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index dacb1f3..bf1ebb4 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -18,6 +18,30 @@
 #include "crypto/aes_siv.h"
 #include "wpas_glue.h"
 
+#define MESH_AUTH_TIMEOUT 10
+#define MESH_AUTH_RETRY 3
+
+void mesh_auth_timer(void *eloop_ctx, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+	struct sta_info *sta = user_data;
+
+	if (sta->sae->state != SAE_ACCEPTED) {
+		wpa_printf(MSG_DEBUG, "AUTH: Re-authenticate with "
+			   MACSTR " (attempt %d) ", MAC2STR(sta->addr),
+			   sta->sae_auth_retry);
+		if (sta->sae_auth_retry < MESH_AUTH_RETRY) {
+			mesh_rsn_auth_sae_sta(wpa_s, sta);
+		} else {
+			/* block the STA if exceeded the number of attempts */
+			sta->plink_state = PLINK_BLOCKED;
+			sta->sae->state = SAE_NOTHING;
+		}
+		sta->sae_auth_retry++;
+	}
+
+}
+
 static void auth_logger(void *ctx, const u8 *addr, logger_level level,
 			const char *txt)
 {
@@ -28,7 +52,6 @@ static void auth_logger(void *ctx, const u8 *addr, logger_level level,
 		wpa_printf(MSG_DEBUG, "AUTH: %s", txt);
 }
 
-
 static const u8 *auth_get_psk(void *ctx, const u8 *addr,
 			      const u8 *p2p_dev_addr, const u8 *prev_psk)
 {
@@ -72,10 +95,17 @@ static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
 static int auth_start_ampe(void *ctx, const u8 *addr)
 {
 	struct mesh_rsn *mesh_rsn = ctx;
+	struct hostapd_data *hapd;
+	struct sta_info *sta;
 
 	if (mesh_rsn->wpa_s->current_ssid->mode != WPAS_MODE_MESH)
 		return -1;
 
+	hapd = mesh_rsn->wpa_s->ifmsh->bss[0];
+	sta = ap_get_sta(hapd, addr);
+	if (sta)
+		eloop_cancel_timeout(mesh_auth_timer, mesh_rsn->wpa_s, sta);
+
 	mesh_mpm_auth_peer(mesh_rsn->wpa_s, addr);
 	return 0;
 }
@@ -178,7 +208,7 @@ static int mesh_rsn_sae_group(struct wpa_supplicant *wpa_s,
 
 	for (;;) {
 		int group = groups[wpa_s->mesh_rsn->sae_group_index];
-		if (group < 0)
+		if (group <= 0)
 			break;
 		if (sae_set_group(sae, group) == 0) {
 			wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d",
@@ -271,6 +301,7 @@ int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
 {
 	struct wpa_ssid *ssid = wpa_s->current_ssid;
 	struct wpabuf *buf;
+	unsigned int rnd;
 
 	if (!sta->sae) {
 		sta->sae = os_zalloc(sizeof(*sta->sae));
@@ -292,6 +323,9 @@ int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
 	mesh_rsn_send_auth(wpa_s, sta->addr, wpa_s->own_addr,
 			   1, WLAN_STATUS_SUCCESS, buf);
 
+	rnd = rand() % MESH_AUTH_TIMEOUT;
+	eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer,
+			       wpa_s, sta);
 	wpabuf_free(buf);
 	return 0;
 }
diff --git a/wpa_supplicant/mesh_rsn.h b/wpa_supplicant/mesh_rsn.h
index 7b95637..2b60b99 100644
--- a/wpa_supplicant/mesh_rsn.h
+++ b/wpa_supplicant/mesh_rsn.h
@@ -35,4 +35,5 @@ int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s,
 			  struct sta_info *sta,
 			  struct ieee802_11_elems *elems, const u8 *cat,
 			  const u8 *start, size_t elems_len);
+void mesh_auth_timer(void *eloop_ctx, void *user_data);
 #endif /* MESH_RSN_H */
-- 
2.1.0.rc1



More information about the HostAP mailing list