#include "ap/hostapd.h"
#include "ap/wpa_auth.h"
#include "ap/sta_info.h"
+#include "ap/ieee802_11.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "wpas_glue.h"
#define MESH_AUTH_TIMEOUT 10
#define MESH_AUTH_RETRY 3
+#define MESH_AUTH_BLOCK_DURATION 3600
void mesh_auth_timer(void *eloop_ctx, void *user_data)
{
wpa_printf(MSG_DEBUG, "AUTH: Re-authenticate with " MACSTR
" (attempt %d) ",
MAC2STR(sta->addr), sta->sae_auth_retry);
+ wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_FAILURE "addr=" MACSTR,
+ MAC2STR(sta->addr));
if (sta->sae_auth_retry < MESH_AUTH_RETRY) {
mesh_rsn_auth_sae_sta(wpa_s, sta);
} else {
+ if (sta->sae_auth_retry > MESH_AUTH_RETRY) {
+ ap_free_sta(wpa_s->ifmsh->bss[0], sta);
+ return;
+ }
+
/* block the STA if exceeded the number of attempts */
- sta->plink_state = PLINK_BLOCKED;
+ wpa_mesh_set_plink_state(wpa_s, sta, PLINK_BLOCKED);
sta->sae->state = SAE_NOTHING;
+ if (wpa_s->mesh_auth_block_duration <
+ MESH_AUTH_BLOCK_DURATION)
+ wpa_s->mesh_auth_block_duration += 60;
+ eloop_register_timeout(wpa_s->mesh_auth_block_duration,
+ 0, mesh_auth_timer, wpa_s, sta);
+ wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_BLOCKED "addr="
+ MACSTR " duration=%d",
+ MAC2STR(sta->addr),
+ wpa_s->mesh_auth_block_duration);
}
sta->sae_auth_retry++;
}
static void mesh_rsn_deinit(struct mesh_rsn *rsn)
{
os_memset(rsn->mgtk, 0, sizeof(rsn->mgtk));
- wpa_deinit(rsn->auth);
+ if (rsn->auth)
+ wpa_deinit(rsn->auth);
}
bss->wpa_auth = mesh_rsn->auth;
ie = wpa_auth_get_wpa_ie(mesh_rsn->auth, &ie_len);
- conf->ies = (u8 *) ie;
- conf->ie_len = ie_len;
+ conf->rsn_ie = (u8 *) ie;
+ conf->rsn_ie_len = ie_len;
wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
}
-struct wpabuf *
-mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid, struct sta_info *sta)
+static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid,
+ struct sta_info *sta)
{
- struct wpabuf *buf;
- int len;
-
if (ssid->passphrase == NULL) {
wpa_msg(wpa_s, MSG_DEBUG, "SAE: No password available");
- return NULL;
+ return -1;
}
if (mesh_rsn_sae_group(wpa_s, sta->sae) < 0) {
wpa_msg(wpa_s, MSG_DEBUG, "SAE: Failed to select group");
- return NULL;
- }
-
- if (sae_prepare_commit(wpa_s->own_addr, sta->addr,
- (u8 *) ssid->passphrase,
- os_strlen(ssid->passphrase), sta->sae) < 0) {
- wpa_msg(wpa_s, MSG_DEBUG, "SAE: Could not pick PWE");
- return NULL;
+ return -1;
}
- len = wpa_s->mesh_rsn->sae_token ?
- wpabuf_len(wpa_s->mesh_rsn->sae_token) : 0;
- buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len);
- if (buf == NULL)
- return NULL;
-
- sae_write_commit(sta->sae, buf, wpa_s->mesh_rsn->sae_token);
-
- return buf;
-}
-
-
-static void mesh_rsn_send_auth(struct wpa_supplicant *wpa_s,
- const u8 *dst, const u8 *src,
- u16 auth_transaction, u16 resp,
- struct wpabuf *data)
-{
- struct ieee80211_mgmt *auth;
- u8 *buf;
- size_t len, ielen = 0;
-
- if (data)
- ielen = wpabuf_len(data);
- len = IEEE80211_HDRLEN + sizeof(auth->u.auth) + ielen;
- buf = os_zalloc(len);
- if (buf == NULL)
- return;
-
- auth = (struct ieee80211_mgmt *) buf;
- auth->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
- WLAN_FC_STYPE_AUTH);
- os_memcpy(auth->da, dst, ETH_ALEN);
- os_memcpy(auth->sa, src, ETH_ALEN);
- os_memcpy(auth->bssid, src, ETH_ALEN);
-
- auth->u.auth.auth_alg = host_to_le16(WLAN_AUTH_SAE);
- auth->u.auth.auth_transaction = host_to_le16(auth_transaction);
- auth->u.auth.status_code = host_to_le16(resp);
-
- if (data)
- os_memcpy(auth->u.auth.variable, wpabuf_head(data), ielen);
-
- wpa_msg(wpa_s, MSG_DEBUG, "authentication frame: STA=" MACSTR
- " auth_transaction=%d resp=%d (IE len=%lu)",
- MAC2STR(dst), auth_transaction, resp, (unsigned long) ielen);
- if (wpa_drv_send_mlme(wpa_s, buf, len, 0) < 0)
- perror("send_auth_reply: send");
-
- os_free(buf);
+ return sae_prepare_commit(wpa_s->own_addr, sta->addr,
+ (u8 *) ssid->passphrase,
+ os_strlen(ssid->passphrase), sta->sae);
}
int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
struct sta_info *sta)
{
+ struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
struct wpa_ssid *ssid = wpa_s->current_ssid;
- struct wpabuf *buf;
unsigned int rnd;
+ int ret;
if (!ssid) {
wpa_msg(wpa_s, MSG_DEBUG,
return -1;
}
- buf = mesh_rsn_build_sae_commit(wpa_s, ssid, sta);
- if (!buf)
+ if (mesh_rsn_build_sae_commit(wpa_s, ssid, sta))
return -1;
wpa_msg(wpa_s, MSG_DEBUG,
"AUTH: started authentication with SAE peer: " MACSTR,
MAC2STR(sta->addr));
- sta->sae->state = SAE_COMMITTED;
wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
+ ret = auth_sae_init_committed(hapd, sta);
+ if (ret)
+ return ret;
- mesh_rsn_send_auth(wpa_s, sta->addr, wpa_s->own_addr,
- 1, WLAN_STATUS_SUCCESS, buf);
-
+ eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta);
rnd = rand() % MESH_AUTH_TIMEOUT;
eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer,
wpa_s, sta);
- wpabuf_free(buf);
-
return 0;
}