]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mesh: Add timer for SAE authentication in RSN mesh
authorChun-Yeow Yeoh <yeohchunyeow@gmail.com>
Mon, 1 Sep 2014 04:23:31 +0000 (00:23 -0400)
committerJouni Malinen <j@w1.fi>
Sun, 16 Nov 2014 17:43:11 +0000 (19:43 +0200)
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-off-by: Bob Copeland <me@bobcopeland.com>
src/ap/hostapd.h
src/ap/sta_info.c
src/ap/sta_info.h
wpa_supplicant/mesh.c
wpa_supplicant/mesh_mpm.c
wpa_supplicant/mesh_mpm.h
wpa_supplicant/mesh_rsn.c
wpa_supplicant/mesh_rsn.h

index 49f0ddf54830729ddd6145e7e37f54de5c6e3597..7ee3c8771fe8eebecda7026fd287b8e7da677a74 100644 (file)
@@ -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
index ec0e493c37aa9521c390bc4fe3c2bae6e5a9e9ba..c48222e40a33861fd990a0bc7b76d7a18cad8054 100644 (file)
@@ -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);
 
index 8ba3ff23c251568e8f883e6a8cc896e670d9d5e9..76e34e4052074ac345c758e10e85a3a36b6d3780 100644 (file)
@@ -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;
index 1ad4bf67460cf85fc9e1ff0262674357240d329d..6439d645c5f86603ecd48c5cf9b80661dbe85f8d 100644 (file)
@@ -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;
 
index de6c3ebb9afd5d1db033546c62316f0220b51b5c..e440d4ffb02aabeed0fc213b2a70a090efa0a960 100644 (file)
@@ -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);
+}
index 056cedd5db70d6f9f7a4d035ee5e2e993e2258d8..2f7f6a7833bb36383e60b42792d361fc264fdfe4 100644 (file)
@@ -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
 
index ecc6393124d3ebbc6f8f41c942253a12b8ddb40f..4ee3431dc74545d695d340e76f2605db626d99f1 100644 (file)
@@ -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"
 #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;
index 2dcf76dbaf89c09fe88f8e9bf96f548ad5938efa..b1471b2de8ae918180719780bd9f1f31caf63d06 100644 (file)
@@ -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 */