mesh: Add timer for SAE authentication in RSN mesh
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>
This commit is contained in:
parent
c50d94f1f8
commit
c596f3f083
8 changed files with 53 additions and 0 deletions
|
@ -247,6 +247,7 @@ struct hostapd_data {
|
||||||
#ifdef CONFIG_MESH
|
#ifdef CONFIG_MESH
|
||||||
int num_plinks;
|
int num_plinks;
|
||||||
int max_plinks;
|
int max_plinks;
|
||||||
|
void (*mesh_sta_free_cb)(struct sta_info *sta);
|
||||||
#endif /* CONFIG_MESH */
|
#endif /* CONFIG_MESH */
|
||||||
|
|
||||||
#ifdef CONFIG_SQLITE
|
#ifdef CONFIG_SQLITE
|
||||||
|
|
|
@ -227,6 +227,11 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
||||||
set_beacon++;
|
set_beacon++;
|
||||||
#endif /* NEED_AP_MLME && CONFIG_IEEE80211N */
|
#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)
|
if (set_beacon)
|
||||||
ieee802_11_set_beacons(hapd->iface);
|
ieee802_11_set_beacons(hapd->iface);
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ struct sta_info {
|
||||||
u8 aek[32]; /* SHA256 digest length */
|
u8 aek[32]; /* SHA256 digest length */
|
||||||
u8 mtk[16];
|
u8 mtk[16];
|
||||||
u8 mgtk[16];
|
u8 mgtk[16];
|
||||||
|
u8 sae_auth_retry;
|
||||||
#endif /* CONFIG_MESH */
|
#endif /* CONFIG_MESH */
|
||||||
|
|
||||||
unsigned int nonerp_set:1;
|
unsigned int nonerp_set:1;
|
||||||
|
|
|
@ -147,6 +147,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
|
||||||
bss->driver = wpa_s->driver;
|
bss->driver = wpa_s->driver;
|
||||||
bss->drv_priv = wpa_s->drv_priv;
|
bss->drv_priv = wpa_s->drv_priv;
|
||||||
bss->iface = ifmsh;
|
bss->iface = ifmsh;
|
||||||
|
bss->mesh_sta_free_cb = mesh_mpm_free_sta;
|
||||||
wpa_s->assoc_freq = ssid->frequency;
|
wpa_s->assoc_freq = ssid->frequency;
|
||||||
wpa_s->current_ssid = ssid;
|
wpa_s->current_ssid = ssid;
|
||||||
|
|
||||||
|
|
|
@ -908,3 +908,11 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
mesh_mpm_fsm(wpa_s, sta, event);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
|
||||||
struct ieee802_11_elems *elems);
|
struct ieee802_11_elems *elems);
|
||||||
void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh);
|
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_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
|
||||||
|
void mesh_mpm_free_sta(struct sta_info *sta);
|
||||||
|
|
||||||
#ifdef CONFIG_MESH
|
#ifdef CONFIG_MESH
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
|
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
|
#include "utils/eloop.h"
|
||||||
#include "crypto/sha256.h"
|
#include "crypto/sha256.h"
|
||||||
#include "crypto/random.h"
|
#include "crypto/random.h"
|
||||||
#include "crypto/aes.h"
|
#include "crypto/aes.h"
|
||||||
|
@ -23,6 +24,29 @@
|
||||||
#include "mesh_mpm.h"
|
#include "mesh_mpm.h"
|
||||||
#include "mesh_rsn.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,
|
static void auth_logger(void *ctx, const u8 *addr, logger_level level,
|
||||||
const char *txt)
|
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)
|
static int auth_start_ampe(void *ctx, const u8 *addr)
|
||||||
{
|
{
|
||||||
struct mesh_rsn *mesh_rsn = ctx;
|
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)
|
if (mesh_rsn->wpa_s->current_ssid->mode != WPAS_MODE_MESH)
|
||||||
return -1;
|
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);
|
mesh_mpm_auth_peer(mesh_rsn->wpa_s, addr);
|
||||||
return 0;
|
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 wpa_ssid *ssid = wpa_s->current_ssid;
|
||||||
struct wpabuf *buf;
|
struct wpabuf *buf;
|
||||||
|
unsigned int rnd;
|
||||||
|
|
||||||
if (!sta->sae) {
|
if (!sta->sae) {
|
||||||
sta->sae = os_zalloc(sizeof(*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,
|
mesh_rsn_send_auth(wpa_s, sta->addr, wpa_s->own_addr,
|
||||||
1, WLAN_STATUS_SUCCESS, buf);
|
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);
|
wpabuf_free(buf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -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,
|
int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
|
||||||
struct ieee802_11_elems *elems, const u8 *cat,
|
struct ieee802_11_elems *elems, const u8 *cat,
|
||||||
const u8 *start, size_t elems_len);
|
const u8 *start, size_t elems_len);
|
||||||
|
void mesh_auth_timer(void *eloop_ctx, void *user_data);
|
||||||
|
|
||||||
#endif /* MESH_RSN_H */
|
#endif /* MESH_RSN_H */
|
||||||
|
|
Loading…
Reference in a new issue