mesh: Fix remaining BLOCKED state after SAE auth failure

When SAE authentication fails, wpa_supplicant retries four times. If all
the retries result in failure, SAE state machine enters BLOCKED state.
Once it enters this state, wpa_supplicant doesn't retry connection. This
commit allow connection retries even if the state machine entered
BLOCKED state.

There could be an opinion "Is this patch needed? User could know the SAE
state machine is in the BLOCKED mode by MESH-SAE-AUTH-BLOCKED event.
Then user can retry connection. By user action, SAE state machine can
change the state from BLOCKED to another.". Yes, this is a true at the
joining mesh STA. However, a STA that is already a member of existing
mesh BSS should not retry connection because if the joining mesh STA
used wrong password, all the existing STA should do something from UI to
retry connection.

Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
This commit is contained in:
Masashi Honma 2015-02-05 23:00:01 +09:00 committed by Jouni Malinen
parent 79ddb2062e
commit bf51f4f82b
2 changed files with 16 additions and 2 deletions

View file

@ -27,6 +27,7 @@
#define MESH_AUTH_TIMEOUT 10 #define MESH_AUTH_TIMEOUT 10
#define MESH_AUTH_RETRY 3 #define MESH_AUTH_RETRY 3
#define MESH_AUTH_BLOCK_DURATION 3600
void mesh_auth_timer(void *eloop_ctx, void *user_data) void mesh_auth_timer(void *eloop_ctx, void *user_data)
{ {
@ -42,12 +43,23 @@ void mesh_auth_timer(void *eloop_ctx, void *user_data)
if (sta->sae_auth_retry < MESH_AUTH_RETRY) { if (sta->sae_auth_retry < MESH_AUTH_RETRY) {
mesh_rsn_auth_sae_sta(wpa_s, sta); mesh_rsn_auth_sae_sta(wpa_s, sta);
} else { } 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 */ /* block the STA if exceeded the number of attempts */
wpa_mesh_set_plink_state(wpa_s, sta, PLINK_BLOCKED); wpa_mesh_set_plink_state(wpa_s, sta, PLINK_BLOCKED);
sta->sae->state = SAE_NOTHING; 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=" wpa_msg(wpa_s, MSG_INFO, MESH_SAE_AUTH_BLOCKED "addr="
MACSTR, MACSTR " duration=%d",
MAC2STR(sta->addr)); MAC2STR(sta->addr),
wpa_s->mesh_auth_block_duration);
} }
sta->sae_auth_retry++; sta->sae_auth_retry++;
} }
@ -304,6 +316,7 @@ int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
if (ret) if (ret)
return ret; return ret;
eloop_cancel_timeout(mesh_auth_timer, wpa_s, sta);
rnd = rand() % MESH_AUTH_TIMEOUT; rnd = rand() % MESH_AUTH_TIMEOUT;
eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer, eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer,
wpa_s, sta); wpa_s, sta);

View file

@ -712,6 +712,7 @@ struct wpa_supplicant {
int mesh_if_idx; int mesh_if_idx;
unsigned int mesh_if_created:1; unsigned int mesh_if_created:1;
unsigned int mesh_ht_enabled:1; unsigned int mesh_ht_enabled:1;
int mesh_auth_block_duration; /* sec */
#endif /* CONFIG_MESH */ #endif /* CONFIG_MESH */
unsigned int off_channel_freq; unsigned int off_channel_freq;