Patchwork [PATCH/RFC,12/18] mesh_rsn: add timer for SAE authentication

login
register
mail settings
Submitter Bob Copeland
Date July 14, 2014, 5:19 a.m.
Message ID <1405315163-9492-13-git-send-email-me@bobcopeland.com>
Download mbox | patch
Permalink /patch/369486/
State Superseded
Headers show

Comments

Bob Copeland - July 14, 2014, 5:19 a.m.
From: Chun-Yeow Yeoh <yeohchunyeow@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@gmail.com>
Signed-hostap: Bob Copeland <me@bobcopeland.com>
---
 src/ap/sta_info.c         |  8 ++++++++
 src/ap/sta_info.h         |  1 +
 wpa_supplicant/Makefile   |  4 ----
 wpa_supplicant/mesh_mpm.c |  7 +++++++
 wpa_supplicant/mesh_mpm.h |  2 ++
 wpa_supplicant/mesh_rsn.c | 36 +++++++++++++++++++++++++++++++++++-
 wpa_supplicant/mesh_rsn.h |  1 +
 7 files changed, 54 insertions(+), 5 deletions(-)

Patch

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/Makefile b/wpa_supplicant/Makefile
index b308de5..963b5cf 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -211,10 +211,6 @@  CFLAGS += -DCONFIG_MESH
 OBJS += mesh.o mesh_mpm.o mesh_rsn.o
 endif
 
-CFLAGS += -DCONFIG_MESH
-OBJS += mesh.o mesh_mpm.o
-endif
-
 ifdef CONFIG_SAE
 CFLAGS += -DCONFIG_SAE
 OBJS += ../src/common/sae.o
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index b32e12e..69ffba8 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -896,3 +896,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..7786a7d 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;
 }
@@ -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 */