[PATCH v2 12/20] mesh_rsn: add timer for SAE authentication
Bob Copeland
me
Sun Aug 31 21:23:31 PDT 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