summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ap/ieee802_1x.c27
-rw-r--r--src/ap/sta_info.c9
-rw-r--r--src/ap/sta_info.h3
-rw-r--r--src/eapol_auth/eapol_auth_sm.c26
-rw-r--r--src/eapol_auth/eapol_auth_sm.h4
-rw-r--r--src/eapol_auth/eapol_auth_sm_i.h4
6 files changed, 49 insertions, 24 deletions
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 46a47d06e..8b67669bb 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -43,9 +43,9 @@
#ifdef CONFIG_HS20
static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx);
#endif /* CONFIG_HS20 */
-static void ieee802_1x_finished(struct hostapd_data *hapd,
+static bool ieee802_1x_finished(struct hostapd_data *hapd,
struct sta_info *sta, int success,
- int remediation);
+ int remediation, bool logoff);
static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta,
@@ -2287,16 +2287,18 @@ static void ieee802_1x_aaa_send(void *ctx, void *sta_ctx,
}
-static void _ieee802_1x_finished(void *ctx, void *sta_ctx, int success,
- int preauth, int remediation)
+static bool _ieee802_1x_finished(void *ctx, void *sta_ctx, int success,
+ int preauth, int remediation, bool logoff)
{
struct hostapd_data *hapd = ctx;
struct sta_info *sta = sta_ctx;
- if (preauth)
+ if (preauth) {
rsn_preauth_finished(hapd, sta, success);
- else
- ieee802_1x_finished(hapd, sta, success, remediation);
+ return false;
+ }
+
+ return ieee802_1x_finished(hapd, sta, success, remediation, logoff);
}
@@ -2977,9 +2979,9 @@ static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx)
#endif /* CONFIG_HS20 */
-static void ieee802_1x_finished(struct hostapd_data *hapd,
+static bool ieee802_1x_finished(struct hostapd_data *hapd,
struct sta_info *sta, int success,
- int remediation)
+ int remediation, bool logoff)
{
const u8 *key;
size_t len;
@@ -3039,6 +3041,11 @@ static void ieee802_1x_finished(struct hostapd_data *hapd,
* EAP-FAST with anonymous provisioning, may require another
* EAPOL authentication to be started to complete connection.
*/
- ap_sta_delayed_1x_auth_fail_disconnect(hapd, sta);
+ ap_sta_delayed_1x_auth_fail_disconnect(hapd, sta,
+ logoff ? 0 : 10);
+ if (logoff && sta->wpa_sm)
+ return true;
}
+
+ return false;
}
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 63f514c9e..0897bcda4 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -1536,11 +1536,12 @@ static void ap_sta_delayed_1x_auth_fail_cb(void *eloop_ctx, void *timeout_ctx)
void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
- struct sta_info *sta)
+ struct sta_info *sta,
+ unsigned timeout)
{
wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
"IEEE 802.1X: Force disconnection of " MACSTR
- " after EAP-Failure in 10 ms", MAC2STR(sta->addr));
+ " after EAP-Failure in %u ms", MAC2STR(sta->addr), timeout);
/*
* Add a small sleep to increase likelihood of previously requested
@@ -1548,8 +1549,8 @@ void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
* operations.
*/
eloop_cancel_timeout(ap_sta_delayed_1x_auth_fail_cb, hapd, sta);
- eloop_register_timeout(0, 10000, ap_sta_delayed_1x_auth_fail_cb,
- hapd, sta);
+ eloop_register_timeout(0, timeout * 1000,
+ ap_sta_delayed_1x_auth_fail_cb, hapd, sta);
}
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index b59b7584b..8433ff8d6 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -373,7 +373,8 @@ void ap_sta_clear_disconnect_timeouts(struct hostapd_data *hapd,
int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen);
void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
- struct sta_info *sta);
+ struct sta_info *sta,
+ unsigned timeout);
int ap_sta_pending_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
struct sta_info *sta);
int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta);
diff --git a/src/eapol_auth/eapol_auth_sm.c b/src/eapol_auth/eapol_auth_sm.c
index 1c11cb613..e1b82ebe3 100644
--- a/src/eapol_auth/eapol_auth_sm.c
+++ b/src/eapol_auth/eapol_auth_sm.c
@@ -217,6 +217,9 @@ SM_STATE(AUTH_PAE, INITIALIZE)
SM_STATE(AUTH_PAE, DISCONNECTED)
{
int from_initialize = sm->auth_pae_state == AUTH_PAE_INITIALIZE;
+ bool pre_auth_logoff = sm->auth_pae_state == AUTH_PAE_ABORTING &&
+ sm->eapolLogoff && !sm->authenticated;
+ bool logoff = sm->eapolLogoff;
if (sm->eapolLogoff) {
if (sm->auth_pae_state == AUTH_PAE_CONNECTING)
@@ -231,10 +234,14 @@ SM_STATE(AUTH_PAE, DISCONNECTED)
setPortUnauthorized();
sm->reAuthCount = 0;
sm->eapolLogoff = false;
- if (!from_initialize) {
- sm->eapol->cb.finished(sm->eapol->conf.ctx, sm->sta, 0,
- sm->flags & EAPOL_SM_PREAUTH,
- sm->remediation);
+ if (!from_initialize && !pre_auth_logoff) {
+ if (sm->eapol->cb.finished(sm->eapol->conf.ctx, sm->sta, 0,
+ sm->flags & EAPOL_SM_PREAUTH,
+ sm->remediation, logoff)) {
+ wpa_printf(MSG_DEBUG,
+ "EAPOL: Do not restart since lower layers will disconnect the port after EAPOL-Logoff");
+ sm->stopped = true;
+ }
}
}
@@ -291,7 +298,8 @@ SM_STATE(AUTH_PAE, HELD)
eap_server_get_name(0, sm->eap_type_supp));
}
sm->eapol->cb.finished(sm->eapol->conf.ctx, sm->sta, 0,
- sm->flags & EAPOL_SM_PREAUTH, sm->remediation);
+ sm->flags & EAPOL_SM_PREAUTH, sm->remediation,
+ false);
}
@@ -316,8 +324,11 @@ SM_STATE(AUTH_PAE, AUTHENTICATED)
sm->eap_type_authsrv,
eap_server_get_name(0, sm->eap_type_authsrv),
extra);
+ if (sm->authSuccess)
+ sm->authenticated++;
sm->eapol->cb.finished(sm->eapol->conf.ctx, sm->sta, 1,
- sm->flags & EAPOL_SM_PREAUTH, sm->remediation);
+ sm->flags & EAPOL_SM_PREAUTH, sm->remediation,
+ false);
}
@@ -397,7 +408,8 @@ SM_STEP(AUTH_PAE)
SM_ENTER(AUTH_PAE, DISCONNECTED);
break;
case AUTH_PAE_DISCONNECTED:
- SM_ENTER(AUTH_PAE, RESTART);
+ if (!sm->stopped)
+ SM_ENTER(AUTH_PAE, RESTART);
break;
case AUTH_PAE_RESTART:
if (!sm->eap_if->eapRestart)
diff --git a/src/eapol_auth/eapol_auth_sm.h b/src/eapol_auth/eapol_auth_sm.h
index 61b7039d6..7296a3aca 100644
--- a/src/eapol_auth/eapol_auth_sm.h
+++ b/src/eapol_auth/eapol_auth_sm.h
@@ -46,8 +46,8 @@ struct eapol_auth_cb {
size_t datalen);
void (*aaa_send)(void *ctx, void *sta_ctx, const u8 *data,
size_t datalen);
- void (*finished)(void *ctx, void *sta_ctx, int success, int preauth,
- int remediation);
+ bool (*finished)(void *ctx, void *sta_ctx, int success, int preauth,
+ int remediation, bool logoff);
int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
int phase2, struct eap_user *user);
int (*sta_entry_alive)(void *ctx, const u8 *addr);
diff --git a/src/eapol_auth/eapol_auth_sm_i.h b/src/eapol_auth/eapol_auth_sm_i.h
index 3c6898310..a0cef0f8e 100644
--- a/src/eapol_auth/eapol_auth_sm_i.h
+++ b/src/eapol_auth/eapol_auth_sm_i.h
@@ -171,6 +171,10 @@ struct eapol_state_machine {
int remediation;
u64 acct_multi_session_id;
+
+ unsigned int authenticated; /* The number of times authentication has
+ * been completed successfully. */
+ bool stopped;
};
#endif /* EAPOL_AUTH_SM_I_H */