aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ap/hostapd.h1
-rw-r--r--src/ap/sta_info.c5
-rw-r--r--src/ap/sta_info.h1
-rw-r--r--wpa_supplicant/mesh.c1
-rw-r--r--wpa_supplicant/mesh_mpm.c8
-rw-r--r--wpa_supplicant/mesh_mpm.h1
-rw-r--r--wpa_supplicant/mesh_rsn.c35
-rw-r--r--wpa_supplicant/mesh_rsn.h1
8 files changed, 53 insertions, 0 deletions
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 49f0ddf..7ee3c87 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -247,6 +247,7 @@ struct hostapd_data {
#ifdef CONFIG_MESH
int num_plinks;
int max_plinks;
+ void (*mesh_sta_free_cb)(struct sta_info *sta);
#endif /* CONFIG_MESH */
#ifdef CONFIG_SQLITE
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index ec0e493..c48222e 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -227,6 +227,11 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
set_beacon++;
#endif /* NEED_AP_MLME && CONFIG_IEEE80211N */
+#ifdef CONFIG_MESH
+ if (hapd->mesh_sta_free_cb)
+ hapd->mesh_sta_free_cb(sta);
+#endif /* CONFIG_MESH */
+
if (set_beacon)
ieee802_11_set_beacons(hapd->iface);
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 8ba3ff2..76e34e4 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -66,6 +66,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.c b/wpa_supplicant/mesh.c
index 1ad4bf6..6439d64 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -147,6 +147,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
bss->driver = wpa_s->driver;
bss->drv_priv = wpa_s->drv_priv;
bss->iface = ifmsh;
+ bss->mesh_sta_free_cb = mesh_mpm_free_sta;
wpa_s->assoc_freq = ssid->frequency;
wpa_s->current_ssid = ssid;
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index de6c3eb..e440d4f 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -908,3 +908,11 @@ 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 056cedd..2f7f6a7 100644
--- a/wpa_supplicant/mesh_mpm.h
+++ b/wpa_supplicant/mesh_mpm.h
@@ -14,6 +14,7 @@ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
struct ieee802_11_elems *elems);
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);
#ifdef CONFIG_MESH
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index ecc6393..4ee3431 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -9,6 +9,7 @@
#include "utils/includes.h"
#include "utils/common.h"
+#include "utils/eloop.h"
#include "crypto/sha256.h"
#include "crypto/random.h"
#include "crypto/aes.h"
@@ -23,6 +24,29 @@
#include "mesh_mpm.h"
#include "mesh_rsn.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)
@@ -81,10 +105,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;
}
@@ -296,6 +327,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));
@@ -317,6 +349,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 2dcf76d..b1471b2 100644
--- a/wpa_supplicant/mesh_rsn.h
+++ b/wpa_supplicant/mesh_rsn.h
@@ -31,5 +31,6 @@ int mesh_rsn_protect_frame(struct mesh_rsn *rsn, struct sta_info *sta,
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 */