summaryrefslogtreecommitdiffstats
path: root/contrib/hostapd/eapol_sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/hostapd/eapol_sm.c')
-rw-r--r--contrib/hostapd/eapol_sm.c457
1 files changed, 231 insertions, 226 deletions
diff --git a/contrib/hostapd/eapol_sm.c b/contrib/hostapd/eapol_sm.c
index f2d5ec7..f4f5752 100644
--- a/contrib/hostapd/eapol_sm.c
+++ b/contrib/hostapd/eapol_sm.c
@@ -1,7 +1,6 @@
/*
- * Host AP (software wireless LAN access point) user space daemon for
- * Host AP kernel driver / IEEE 802.1X Authenticator - EAPOL state machine
- * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ * hostapd / IEEE 802.1X Authenticator - EAPOL state machine
+ * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,20 +12,21 @@
* See README and COPYING for more details.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/socket.h>
+#include "includes.h"
#include "hostapd.h"
#include "ieee802_1x.h"
#include "eapol_sm.h"
#include "eloop.h"
#include "wpa.h"
+#include "preauth.h"
#include "sta_info.h"
#include "eap.h"
+#include "state_machine.h"
+
+#define STATE_MACHINE_DATA struct eapol_state_machine
+#define STATE_MACHINE_DEBUG_PREFIX "IEEE 802.1X"
+#define STATE_MACHINE_ADDR sm->addr
static struct eapol_callbacks eapol_cb;
@@ -47,25 +47,6 @@ ieee802_1x_set_sta_authorized(sm->hapd, sm->sta, 0)
#define processKey() do { } while (0)
-/* Definitions for clarifying state machine implementation */
-#define SM_STATE(machine, state) \
-static void sm_ ## machine ## _ ## state ## _Enter(struct eapol_state_machine \
-*sm)
-
-#define SM_ENTRY(machine, _state, _data) \
-sm->_data.state = machine ## _ ## _state; \
-if (sm->hapd->conf->debug >= HOSTAPD_DEBUG_MINIMAL) \
- printf("IEEE 802.1X: " MACSTR " " #machine " entering state " #_state \
- "\n", MAC2STR(sm->addr));
-
-#define SM_ENTER(machine, state) sm_ ## machine ## _ ## state ## _Enter(sm)
-
-#define SM_STEP(machine) \
-static void sm_ ## machine ## _Step(struct eapol_state_machine *sm)
-
-#define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm)
-
-
static void eapol_sm_step_run(struct eapol_state_machine *sm);
static void eapol_sm_step_cb(void *eloop_ctx, void *timeout_ctx);
@@ -115,8 +96,8 @@ static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx)
SM_STATE(AUTH_PAE, INITIALIZE)
{
- SM_ENTRY(AUTH_PAE, INITIALIZE, auth_pae);
- sm->auth_pae.portMode = Auto;
+ SM_ENTRY_MA(AUTH_PAE, INITIALIZE, auth_pae);
+ sm->portMode = Auto;
sm->currentId = 255;
}
@@ -124,21 +105,21 @@ SM_STATE(AUTH_PAE, INITIALIZE)
SM_STATE(AUTH_PAE, DISCONNECTED)
{
- int from_initialize = sm->auth_pae.state == AUTH_PAE_INITIALIZE;
+ int from_initialize = sm->auth_pae_state == AUTH_PAE_INITIALIZE;
- if (sm->auth_pae.eapolLogoff) {
- if (sm->auth_pae.state == AUTH_PAE_CONNECTING)
- sm->auth_pae.authEapLogoffsWhileConnecting++;
- else if (sm->auth_pae.state == AUTH_PAE_AUTHENTICATED)
- sm->auth_pae.authAuthEapLogoffWhileAuthenticated++;
+ if (sm->eapolLogoff) {
+ if (sm->auth_pae_state == AUTH_PAE_CONNECTING)
+ sm->authEapLogoffsWhileConnecting++;
+ else if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATED)
+ sm->authAuthEapLogoffWhileAuthenticated++;
}
- SM_ENTRY(AUTH_PAE, DISCONNECTED, auth_pae);
+ SM_ENTRY_MA(AUTH_PAE, DISCONNECTED, auth_pae);
sm->authPortStatus = Unauthorized;
setPortUnauthorized();
- sm->auth_pae.reAuthCount = 0;
- sm->auth_pae.eapolLogoff = FALSE;
+ sm->reAuthCount = 0;
+ sm->eapolLogoff = FALSE;
if (!from_initialize) {
if (sm->flags & EAPOL_SM_PREAUTH)
rsn_preauth_finished(sm->hapd, sm->sta, 0);
@@ -150,48 +131,58 @@ SM_STATE(AUTH_PAE, DISCONNECTED)
SM_STATE(AUTH_PAE, RESTART)
{
- if (sm->auth_pae.state == AUTH_PAE_AUTHENTICATED) {
+ if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATED) {
if (sm->reAuthenticate)
- sm->auth_pae.authAuthReauthsWhileAuthenticated++;
- if (sm->auth_pae.eapolStart)
- sm->auth_pae.authAuthEapStartsWhileAuthenticated++;
- if (sm->auth_pae.eapolLogoff)
- sm->auth_pae.authAuthEapLogoffWhileAuthenticated++;
+ sm->authAuthReauthsWhileAuthenticated++;
+ if (sm->eapolStart)
+ sm->authAuthEapStartsWhileAuthenticated++;
+ if (sm->eapolLogoff)
+ sm->authAuthEapLogoffWhileAuthenticated++;
}
- SM_ENTRY(AUTH_PAE, RESTART, auth_pae);
+ SM_ENTRY_MA(AUTH_PAE, RESTART, auth_pae);
- sm->auth_pae.eapRestart = TRUE;
+ sm->eapRestart = TRUE;
ieee802_1x_request_identity(sm->hapd, sm->sta);
}
SM_STATE(AUTH_PAE, CONNECTING)
{
- if (sm->auth_pae.state != AUTH_PAE_CONNECTING)
- sm->auth_pae.authEntersConnecting++;
+ if (sm->auth_pae_state != AUTH_PAE_CONNECTING)
+ sm->authEntersConnecting++;
- SM_ENTRY(AUTH_PAE, CONNECTING, auth_pae);
+ SM_ENTRY_MA(AUTH_PAE, CONNECTING, auth_pae);
sm->reAuthenticate = FALSE;
- sm->auth_pae.reAuthCount++;
+ sm->reAuthCount++;
}
SM_STATE(AUTH_PAE, HELD)
{
- if (sm->auth_pae.state == AUTH_PAE_AUTHENTICATING && sm->authFail)
- sm->auth_pae.authAuthFailWhileAuthenticating++;
+ if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATING && sm->authFail)
+ sm->authAuthFailWhileAuthenticating++;
- SM_ENTRY(AUTH_PAE, HELD, auth_pae);
+ SM_ENTRY_MA(AUTH_PAE, HELD, auth_pae);
sm->authPortStatus = Unauthorized;
setPortUnauthorized();
- sm->quietWhile = sm->auth_pae.quietPeriod;
- sm->auth_pae.eapolLogoff = FALSE;
+ sm->quietWhile = sm->quietPeriod;
+ sm->eapolLogoff = FALSE;
hostapd_logger(sm->hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
- HOSTAPD_LEVEL_WARNING, "authentication failed");
+ HOSTAPD_LEVEL_WARNING, "authentication failed - "
+ "EAP type: %d (%s)",
+ sm->eap_type_authsrv,
+ eap_type_text(sm->eap_type_authsrv));
+ if (sm->eap_type_authsrv != sm->eap_type_supp) {
+ hostapd_logger(sm->hapd, sm->addr,
+ HOSTAPD_MODULE_IEEE8021X, HOSTAPD_LEVEL_INFO,
+ "Supplicant used different EAP type: %d (%s)",
+ sm->eap_type_supp,
+ eap_type_text(sm->eap_type_supp));
+ }
if (sm->flags & EAPOL_SM_PREAUTH)
rsn_preauth_finished(sm->hapd, sm->sta, 0);
else
@@ -201,16 +192,24 @@ SM_STATE(AUTH_PAE, HELD)
SM_STATE(AUTH_PAE, AUTHENTICATED)
{
- if (sm->auth_pae.state == AUTH_PAE_AUTHENTICATING && sm->authSuccess)
- sm->auth_pae.authAuthSuccessesWhileAuthenticating++;
+ char *extra = "";
+
+ if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATING && sm->authSuccess)
+ sm->authAuthSuccessesWhileAuthenticating++;
- SM_ENTRY(AUTH_PAE, AUTHENTICATED, auth_pae);
+ SM_ENTRY_MA(AUTH_PAE, AUTHENTICATED, auth_pae);
sm->authPortStatus = Authorized;
setPortAuthorized();
- sm->auth_pae.reAuthCount = 0;
+ sm->reAuthCount = 0;
+ if (sm->flags & EAPOL_SM_PREAUTH)
+ extra = " (pre-authentication)";
+ else if (wpa_auth_sta_get_pmksa(sm->sta->wpa_sm))
+ extra = " (PMKSA cache)";
hostapd_logger(sm->hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
- HOSTAPD_LEVEL_INFO, "authenticated");
+ HOSTAPD_LEVEL_INFO, "authenticated - EAP type: %d (%s)"
+ "%s", sm->eap_type_authsrv,
+ eap_type_text(sm->eap_type_authsrv), extra);
if (sm->flags & EAPOL_SM_PREAUTH)
rsn_preauth_finished(sm->hapd, sm->sta, 1);
else
@@ -220,14 +219,14 @@ SM_STATE(AUTH_PAE, AUTHENTICATED)
SM_STATE(AUTH_PAE, AUTHENTICATING)
{
- if (sm->auth_pae.state == AUTH_PAE_CONNECTING && sm->rx_identity) {
- sm->auth_pae.authEntersAuthenticating++;
+ if (sm->auth_pae_state == AUTH_PAE_CONNECTING && sm->rx_identity) {
+ sm->authEntersAuthenticating++;
sm->rx_identity = FALSE;
}
- SM_ENTRY(AUTH_PAE, AUTHENTICATING, auth_pae);
+ SM_ENTRY_MA(AUTH_PAE, AUTHENTICATING, auth_pae);
- sm->auth_pae.eapolStart = FALSE;
+ sm->eapolStart = FALSE;
sm->authSuccess = FALSE;
sm->authFail = FALSE;
sm->authTimeout = FALSE;
@@ -239,16 +238,16 @@ SM_STATE(AUTH_PAE, AUTHENTICATING)
SM_STATE(AUTH_PAE, ABORTING)
{
- if (sm->auth_pae.state == AUTH_PAE_AUTHENTICATING) {
+ if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATING) {
if (sm->authTimeout)
- sm->auth_pae.authAuthTimeoutsWhileAuthenticating++;
- if (sm->auth_pae.eapolStart)
- sm->auth_pae.authAuthEapStartsWhileAuthenticating++;
- if (sm->auth_pae.eapolLogoff)
- sm->auth_pae.authAuthEapLogoffWhileAuthenticating++;
+ sm->authAuthTimeoutsWhileAuthenticating++;
+ if (sm->eapolStart)
+ sm->authAuthEapStartsWhileAuthenticating++;
+ if (sm->eapolLogoff)
+ sm->authAuthEapLogoffWhileAuthenticating++;
}
- SM_ENTRY(AUTH_PAE, ABORTING, auth_pae);
+ SM_ENTRY_MA(AUTH_PAE, ABORTING, auth_pae);
sm->authAbort = TRUE;
sm->keyRun = FALSE;
@@ -258,44 +257,43 @@ SM_STATE(AUTH_PAE, ABORTING)
SM_STATE(AUTH_PAE, FORCE_AUTH)
{
- SM_ENTRY(AUTH_PAE, FORCE_AUTH, auth_pae);
+ SM_ENTRY_MA(AUTH_PAE, FORCE_AUTH, auth_pae);
sm->authPortStatus = Authorized;
setPortAuthorized();
- sm->auth_pae.portMode = ForceAuthorized;
- sm->auth_pae.eapolStart = FALSE;
+ sm->portMode = ForceAuthorized;
+ sm->eapolStart = FALSE;
txCannedSuccess();
}
SM_STATE(AUTH_PAE, FORCE_UNAUTH)
{
- SM_ENTRY(AUTH_PAE, FORCE_UNAUTH, auth_pae);
+ SM_ENTRY_MA(AUTH_PAE, FORCE_UNAUTH, auth_pae);
sm->authPortStatus = Unauthorized;
setPortUnauthorized();
- sm->auth_pae.portMode = ForceUnauthorized;
- sm->auth_pae.eapolStart = FALSE;
+ sm->portMode = ForceUnauthorized;
+ sm->eapolStart = FALSE;
txCannedFail();
}
SM_STEP(AUTH_PAE)
{
- if ((sm->portControl == Auto &&
- sm->auth_pae.portMode != sm->portControl) ||
+ if ((sm->portControl == Auto && sm->portMode != sm->portControl) ||
sm->initialize || !sm->portEnabled)
SM_ENTER(AUTH_PAE, INITIALIZE);
else if (sm->portControl == ForceAuthorized &&
- sm->auth_pae.portMode != sm->portControl &&
+ sm->portMode != sm->portControl &&
!(sm->initialize || !sm->portEnabled))
SM_ENTER(AUTH_PAE, FORCE_AUTH);
else if (sm->portControl == ForceUnauthorized &&
- sm->auth_pae.portMode != sm->portControl &&
+ sm->portMode != sm->portControl &&
!(sm->initialize || !sm->portEnabled))
SM_ENTER(AUTH_PAE, FORCE_UNAUTH);
else {
- switch (sm->auth_pae.state) {
+ switch (sm->auth_pae_state) {
case AUTH_PAE_INITIALIZE:
SM_ENTER(AUTH_PAE, DISCONNECTED);
break;
@@ -303,7 +301,7 @@ SM_STEP(AUTH_PAE)
SM_ENTER(AUTH_PAE, RESTART);
break;
case AUTH_PAE_RESTART:
- if (!sm->auth_pae.eapRestart)
+ if (!sm->eapRestart)
SM_ENTER(AUTH_PAE, CONNECTING);
break;
case AUTH_PAE_HELD:
@@ -311,19 +309,17 @@ SM_STEP(AUTH_PAE)
SM_ENTER(AUTH_PAE, RESTART);
break;
case AUTH_PAE_CONNECTING:
- if (sm->auth_pae.eapolLogoff ||
- sm->auth_pae.reAuthCount > sm->auth_pae.reAuthMax)
+ if (sm->eapolLogoff || sm->reAuthCount > sm->reAuthMax)
SM_ENTER(AUTH_PAE, DISCONNECTED);
- else if ((sm->be_auth.eapReq &&
- sm->auth_pae.reAuthCount <=
- sm->auth_pae.reAuthMax) ||
+ else if ((sm->eapReq &&
+ sm->reAuthCount <= sm->reAuthMax) ||
sm->eapSuccess || sm->eapFail)
SM_ENTER(AUTH_PAE, AUTHENTICATING);
break;
case AUTH_PAE_AUTHENTICATED:
- if (sm->auth_pae.eapolStart || sm->reAuthenticate)
+ if (sm->eapolStart || sm->reAuthenticate)
SM_ENTER(AUTH_PAE, RESTART);
- else if (sm->auth_pae.eapolLogoff || !sm->portValid)
+ else if (sm->eapolLogoff || !sm->portValid)
SM_ENTER(AUTH_PAE, DISCONNECTED);
break;
case AUTH_PAE_AUTHENTICATING:
@@ -332,22 +328,22 @@ SM_STEP(AUTH_PAE)
else if (sm->authFail ||
(sm->keyDone && !sm->portValid))
SM_ENTER(AUTH_PAE, HELD);
- else if (sm->auth_pae.eapolStart ||
- sm->auth_pae.eapolLogoff || sm->authTimeout)
+ else if (sm->eapolStart || sm->eapolLogoff ||
+ sm->authTimeout)
SM_ENTER(AUTH_PAE, ABORTING);
break;
case AUTH_PAE_ABORTING:
- if (sm->auth_pae.eapolLogoff && !sm->authAbort)
+ if (sm->eapolLogoff && !sm->authAbort)
SM_ENTER(AUTH_PAE, DISCONNECTED);
- else if (!sm->auth_pae.eapolLogoff && !sm->authAbort)
+ else if (!sm->eapolLogoff && !sm->authAbort)
SM_ENTER(AUTH_PAE, RESTART);
break;
case AUTH_PAE_FORCE_AUTH:
- if (sm->auth_pae.eapolStart)
+ if (sm->eapolStart)
SM_ENTER(AUTH_PAE, FORCE_AUTH);
break;
case AUTH_PAE_FORCE_UNAUTH:
- if (sm->auth_pae.eapolStart)
+ if (sm->eapolStart)
SM_ENTER(AUTH_PAE, FORCE_UNAUTH);
break;
}
@@ -360,21 +356,21 @@ SM_STEP(AUTH_PAE)
SM_STATE(BE_AUTH, INITIALIZE)
{
- SM_ENTRY(BE_AUTH, INITIALIZE, be_auth);
+ SM_ENTRY_MA(BE_AUTH, INITIALIZE, be_auth);
abortAuth();
- sm->be_auth.eapNoReq = FALSE;
+ sm->eapNoReq = FALSE;
sm->authAbort = FALSE;
}
SM_STATE(BE_AUTH, REQUEST)
{
- SM_ENTRY(BE_AUTH, REQUEST, be_auth);
+ SM_ENTRY_MA(BE_AUTH, REQUEST, be_auth);
txReq();
- sm->be_auth.eapReq = FALSE;
- sm->be_auth.backendOtherRequestsToSupplicant++;
+ sm->eapReq = FALSE;
+ sm->backendOtherRequestsToSupplicant++;
/*
* Clearing eapolEap here is not specified in IEEE Std 802.1X-2004, but
@@ -393,21 +389,21 @@ SM_STATE(BE_AUTH, REQUEST)
SM_STATE(BE_AUTH, RESPONSE)
{
- SM_ENTRY(BE_AUTH, RESPONSE, be_auth);
+ SM_ENTRY_MA(BE_AUTH, RESPONSE, be_auth);
sm->authTimeout = FALSE;
sm->eapolEap = FALSE;
- sm->be_auth.eapNoReq = FALSE;
- sm->aWhile = sm->be_auth.serverTimeout;
- sm->be_auth.eapResp = TRUE;
+ sm->eapNoReq = FALSE;
+ sm->aWhile = sm->serverTimeout;
+ sm->eapResp = TRUE;
sendRespToServer();
- sm->be_auth.backendResponses++;
+ sm->backendResponses++;
}
SM_STATE(BE_AUTH, SUCCESS)
{
- SM_ENTRY(BE_AUTH, SUCCESS, be_auth);
+ SM_ENTRY_MA(BE_AUTH, SUCCESS, be_auth);
txReq();
sm->authSuccess = TRUE;
@@ -417,7 +413,7 @@ SM_STATE(BE_AUTH, SUCCESS)
SM_STATE(BE_AUTH, FAIL)
{
- SM_ENTRY(BE_AUTH, FAIL, be_auth);
+ SM_ENTRY_MA(BE_AUTH, FAIL, be_auth);
/* Note: IEEE 802.1X-REV-d11 has unconditional txReq() here.
* txCannelFail() is used as a workaround for the case where
@@ -433,7 +429,7 @@ SM_STATE(BE_AUTH, FAIL)
SM_STATE(BE_AUTH, TIMEOUT)
{
- SM_ENTRY(BE_AUTH, TIMEOUT, be_auth);
+ SM_ENTRY_MA(BE_AUTH, TIMEOUT, be_auth);
sm->authTimeout = TRUE;
}
@@ -441,7 +437,7 @@ SM_STATE(BE_AUTH, TIMEOUT)
SM_STATE(BE_AUTH, IDLE)
{
- SM_ENTRY(BE_AUTH, IDLE, be_auth);
+ SM_ENTRY_MA(BE_AUTH, IDLE, be_auth);
sm->authStart = FALSE;
}
@@ -449,9 +445,9 @@ SM_STATE(BE_AUTH, IDLE)
SM_STATE(BE_AUTH, IGNORE)
{
- SM_ENTRY(BE_AUTH, IGNORE, be_auth);
+ SM_ENTRY_MA(BE_AUTH, IGNORE, be_auth);
- sm->be_auth.eapNoReq = FALSE;
+ sm->eapNoReq = FALSE;
}
@@ -462,31 +458,31 @@ SM_STEP(BE_AUTH)
return;
}
- switch (sm->be_auth.state) {
+ switch (sm->be_auth_state) {
case BE_AUTH_INITIALIZE:
SM_ENTER(BE_AUTH, IDLE);
break;
case BE_AUTH_REQUEST:
if (sm->eapolEap)
SM_ENTER(BE_AUTH, RESPONSE);
- else if (sm->be_auth.eapReq)
+ else if (sm->eapReq)
SM_ENTER(BE_AUTH, REQUEST);
else if (sm->eapTimeout)
SM_ENTER(BE_AUTH, TIMEOUT);
break;
case BE_AUTH_RESPONSE:
- if (sm->be_auth.eapNoReq)
+ if (sm->eapNoReq)
SM_ENTER(BE_AUTH, IGNORE);
- if (sm->be_auth.eapReq) {
- sm->be_auth.backendAccessChallenges++;
+ if (sm->eapReq) {
+ sm->backendAccessChallenges++;
SM_ENTER(BE_AUTH, REQUEST);
} else if (sm->aWhile == 0)
SM_ENTER(BE_AUTH, TIMEOUT);
else if (sm->eapFail) {
- sm->be_auth.backendAuthFails++;
+ sm->backendAuthFails++;
SM_ENTER(BE_AUTH, FAIL);
} else if (sm->eapSuccess) {
- sm->be_auth.backendAuthSuccesses++;
+ sm->backendAuthSuccesses++;
SM_ENTER(BE_AUTH, SUCCESS);
}
break;
@@ -502,7 +498,7 @@ SM_STEP(BE_AUTH)
case BE_AUTH_IDLE:
if (sm->eapFail && sm->authStart)
SM_ENTER(BE_AUTH, FAIL);
- else if (sm->be_auth.eapReq && sm->authStart)
+ else if (sm->eapReq && sm->authStart)
SM_ENTER(BE_AUTH, REQUEST);
else if (sm->eapSuccess && sm->authStart)
SM_ENTER(BE_AUTH, SUCCESS);
@@ -510,7 +506,7 @@ SM_STEP(BE_AUTH)
case BE_AUTH_IGNORE:
if (sm->eapolEap)
SM_ENTER(BE_AUTH, RESPONSE);
- else if (sm->be_auth.eapReq)
+ else if (sm->eapReq)
SM_ENTER(BE_AUTH, REQUEST);
else if (sm->eapTimeout)
SM_ENTER(BE_AUTH, TIMEOUT);
@@ -524,31 +520,30 @@ SM_STEP(BE_AUTH)
SM_STATE(REAUTH_TIMER, INITIALIZE)
{
- SM_ENTRY(REAUTH_TIMER, INITIALIZE, reauth_timer);
+ SM_ENTRY_MA(REAUTH_TIMER, INITIALIZE, reauth_timer);
- sm->reAuthWhen = sm->reauth_timer.reAuthPeriod;
+ sm->reAuthWhen = sm->reAuthPeriod;
}
SM_STATE(REAUTH_TIMER, REAUTHENTICATE)
{
- SM_ENTRY(REAUTH_TIMER, REAUTHENTICATE, reauth_timer);
+ SM_ENTRY_MA(REAUTH_TIMER, REAUTHENTICATE, reauth_timer);
sm->reAuthenticate = TRUE;
- wpa_sm_event(sm->hapd, sm->sta, WPA_REAUTH_EAPOL);
+ wpa_auth_sm_event(sm->sta->wpa_sm, WPA_REAUTH_EAPOL);
}
SM_STEP(REAUTH_TIMER)
{
if (sm->portControl != Auto || sm->initialize ||
- sm->authPortStatus == Unauthorized ||
- !sm->reauth_timer.reAuthEnabled) {
+ sm->authPortStatus == Unauthorized || !sm->reAuthEnabled) {
SM_ENTER(REAUTH_TIMER, INITIALIZE);
return;
}
- switch (sm->reauth_timer.state) {
+ switch (sm->reauth_timer_state) {
case REAUTH_TIMER_INITIALIZE:
if (sm->reAuthWhen == 0)
SM_ENTER(REAUTH_TIMER, REAUTHENTICATE);
@@ -565,13 +560,13 @@ SM_STEP(REAUTH_TIMER)
SM_STATE(AUTH_KEY_TX, NO_KEY_TRANSMIT)
{
- SM_ENTRY(AUTH_KEY_TX, NO_KEY_TRANSMIT, auth_key_tx);
+ SM_ENTRY_MA(AUTH_KEY_TX, NO_KEY_TRANSMIT, auth_key_tx);
}
SM_STATE(AUTH_KEY_TX, KEY_TRANSMIT)
{
- SM_ENTRY(AUTH_KEY_TX, KEY_TRANSMIT, auth_key_tx);
+ SM_ENTRY_MA(AUTH_KEY_TX, KEY_TRANSMIT, auth_key_tx);
txKey();
sm->keyAvailable = FALSE;
@@ -586,10 +581,10 @@ SM_STEP(AUTH_KEY_TX)
return;
}
- switch (sm->auth_key_tx.state) {
+ switch (sm->auth_key_tx_state) {
case AUTH_KEY_TX_NO_KEY_TRANSMIT:
if (sm->keyTxEnabled && sm->keyAvailable && sm->keyRun &&
- !sm->sta->wpa)
+ !wpa_auth_sta_wpa_version(sm->sta->wpa_sm))
SM_ENTER(AUTH_KEY_TX, KEY_TRANSMIT);
break;
case AUTH_KEY_TX_KEY_TRANSMIT:
@@ -607,16 +602,16 @@ SM_STEP(AUTH_KEY_TX)
SM_STATE(KEY_RX, NO_KEY_RECEIVE)
{
- SM_ENTRY(KEY_RX, NO_KEY_RECEIVE, key_rx);
+ SM_ENTRY_MA(KEY_RX, NO_KEY_RECEIVE, key_rx);
}
SM_STATE(KEY_RX, KEY_RECEIVE)
{
- SM_ENTRY(KEY_RX, KEY_RECEIVE, key_rx);
+ SM_ENTRY_MA(KEY_RX, KEY_RECEIVE, key_rx);
processKey();
- sm->key_rx.rxKey = FALSE;
+ sm->rxKey = FALSE;
}
@@ -627,13 +622,13 @@ SM_STEP(KEY_RX)
return;
}
- switch (sm->key_rx.state) {
+ switch (sm->key_rx_state) {
case KEY_RX_NO_KEY_RECEIVE:
- if (sm->key_rx.rxKey)
+ if (sm->rxKey)
SM_ENTER(KEY_RX, KEY_RECEIVE);
break;
case KEY_RX_KEY_RECEIVE:
- if (sm->key_rx.rxKey)
+ if (sm->rxKey)
SM_ENTER(KEY_RX, KEY_RECEIVE);
break;
}
@@ -645,16 +640,15 @@ SM_STEP(KEY_RX)
SM_STATE(CTRL_DIR, FORCE_BOTH)
{
- SM_ENTRY(CTRL_DIR, FORCE_BOTH, ctrl_dir);
- sm->ctrl_dir.operControlledDirections = Both;
+ SM_ENTRY_MA(CTRL_DIR, FORCE_BOTH, ctrl_dir);
+ sm->operControlledDirections = Both;
}
SM_STATE(CTRL_DIR, IN_OR_BOTH)
{
- SM_ENTRY(CTRL_DIR, IN_OR_BOTH, ctrl_dir);
- sm->ctrl_dir.operControlledDirections =
- sm->ctrl_dir.adminControlledDirections;
+ SM_ENTRY_MA(CTRL_DIR, IN_OR_BOTH, ctrl_dir);
+ sm->operControlledDirections = sm->adminControlledDirections;
}
@@ -665,16 +659,16 @@ SM_STEP(CTRL_DIR)
return;
}
- switch (sm->ctrl_dir.state) {
+ switch (sm->ctrl_dir_state) {
case CTRL_DIR_FORCE_BOTH:
- if (sm->portEnabled && sm->ctrl_dir.operEdge)
+ if (sm->portEnabled && sm->operEdge)
SM_ENTER(CTRL_DIR, IN_OR_BOTH);
break;
case CTRL_DIR_IN_OR_BOTH:
- if (sm->ctrl_dir.operControlledDirections !=
- sm->ctrl_dir.adminControlledDirections)
+ if (sm->operControlledDirections !=
+ sm->adminControlledDirections)
SM_ENTER(CTRL_DIR, IN_OR_BOTH);
- if (!sm->portEnabled || !sm->ctrl_dir.operEdge)
+ if (!sm->portEnabled || !sm->operEdge)
SM_ENTER(CTRL_DIR, FORCE_BOTH);
break;
}
@@ -683,16 +677,15 @@ SM_STEP(CTRL_DIR)
struct eapol_state_machine *
-eapol_sm_alloc(hostapd *hapd, struct sta_info *sta)
+eapol_sm_alloc(struct hostapd_data *hapd, struct sta_info *sta)
{
struct eapol_state_machine *sm;
- sm = (struct eapol_state_machine *) malloc(sizeof(*sm));
+ sm = wpa_zalloc(sizeof(*sm));
if (sm == NULL) {
printf("IEEE 802.1X port state allocation failed\n");
return NULL;
}
- memset(sm, 0, sizeof(*sm));
sm->radius_identifier = -1;
memcpy(sm->addr, sta->addr, ETH_ALEN);
if (sta->flags & WLAN_STA_PREAUTH)
@@ -702,23 +695,22 @@ eapol_sm_alloc(hostapd *hapd, struct sta_info *sta)
sm->sta = sta;
/* Set default values for state machine constants */
- sm->auth_pae.state = AUTH_PAE_INITIALIZE;
- sm->auth_pae.quietPeriod = AUTH_PAE_DEFAULT_quietPeriod;
- sm->auth_pae.reAuthMax = AUTH_PAE_DEFAULT_reAuthMax;
+ sm->auth_pae_state = AUTH_PAE_INITIALIZE;
+ sm->quietPeriod = AUTH_PAE_DEFAULT_quietPeriod;
+ sm->reAuthMax = AUTH_PAE_DEFAULT_reAuthMax;
- sm->be_auth.state = BE_AUTH_INITIALIZE;
- sm->be_auth.serverTimeout = BE_AUTH_DEFAULT_serverTimeout;
+ sm->be_auth_state = BE_AUTH_INITIALIZE;
+ sm->serverTimeout = BE_AUTH_DEFAULT_serverTimeout;
- sm->reauth_timer.state = REAUTH_TIMER_INITIALIZE;
- sm->reauth_timer.reAuthPeriod = hapd->conf->eap_reauth_period;
- sm->reauth_timer.reAuthEnabled = hapd->conf->eap_reauth_period > 0 ?
- TRUE : FALSE;
+ sm->reauth_timer_state = REAUTH_TIMER_INITIALIZE;
+ sm->reAuthPeriod = hapd->conf->eap_reauth_period;
+ sm->reAuthEnabled = hapd->conf->eap_reauth_period > 0 ? TRUE : FALSE;
- sm->auth_key_tx.state = AUTH_KEY_TX_NO_KEY_TRANSMIT;
+ sm->auth_key_tx_state = AUTH_KEY_TX_NO_KEY_TRANSMIT;
- sm->key_rx.state = KEY_RX_NO_KEY_RECEIVE;
+ sm->key_rx_state = KEY_RX_NO_KEY_RECEIVE;
- sm->ctrl_dir.state = CTRL_DIR_IN_OR_BOTH;
+ sm->ctrl_dir_state = CTRL_DIR_IN_OR_BOTH;
sm->portEnabled = FALSE;
sm->portControl = Auto;
@@ -779,8 +771,8 @@ static void eapol_sm_step_run(struct eapol_state_machine *sm)
{
struct hostapd_data *hapd = sm->hapd;
u8 addr[ETH_ALEN];
- int prev_auth_pae, prev_be_auth, prev_reauth_timer, prev_auth_key_tx,
- prev_key_rx, prev_ctrl_dir;
+ unsigned int prev_auth_pae, prev_be_auth, prev_reauth_timer,
+ prev_auth_key_tx, prev_key_rx, prev_ctrl_dir;
int max_steps = 100;
memcpy(addr, sm->sta->addr, ETH_ALEN);
@@ -792,12 +784,12 @@ static void eapol_sm_step_run(struct eapol_state_machine *sm)
* eloop callback.
*/
restart:
- prev_auth_pae = sm->auth_pae.state;
- prev_be_auth = sm->be_auth.state;
- prev_reauth_timer = sm->reauth_timer.state;
- prev_auth_key_tx = sm->auth_key_tx.state;
- prev_key_rx = sm->key_rx.state;
- prev_ctrl_dir = sm->ctrl_dir.state;
+ prev_auth_pae = sm->auth_pae_state;
+ prev_be_auth = sm->be_auth_state;
+ prev_reauth_timer = sm->reauth_timer_state;
+ prev_auth_key_tx = sm->auth_key_tx_state;
+ prev_key_rx = sm->key_rx_state;
+ prev_ctrl_dir = sm->ctrl_dir_state;
SM_STEP_RUN(AUTH_PAE);
if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
@@ -811,12 +803,12 @@ restart:
if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
SM_STEP_RUN(CTRL_DIR);
- if (prev_auth_pae != sm->auth_pae.state ||
- prev_be_auth != sm->be_auth.state ||
- prev_reauth_timer != sm->reauth_timer.state ||
- prev_auth_key_tx != sm->auth_key_tx.state ||
- prev_key_rx != sm->key_rx.state ||
- prev_ctrl_dir != sm->ctrl_dir.state) {
+ if (prev_auth_pae != sm->auth_pae_state ||
+ prev_be_auth != sm->be_auth_state ||
+ prev_reauth_timer != sm->reauth_timer_state ||
+ prev_auth_key_tx != sm->auth_key_tx_state ||
+ prev_key_rx != sm->key_rx_state ||
+ prev_ctrl_dir != sm->ctrl_dir_state) {
if (--max_steps > 0)
goto restart;
/* Re-run from eloop timeout */
@@ -835,7 +827,7 @@ restart:
}
if (eapol_sm_sta_entry_alive(hapd, addr))
- wpa_sm_notify(sm->hapd, sm->sta);
+ wpa_auth_sm_notify(sm->sta->wpa_sm);
}
@@ -1022,22 +1014,21 @@ void eapol_sm_dump_state(FILE *f, const char *prefix,
"%s authAuthReauthsWhileAuthenticated=%d\n"
"%s authAuthEapStartsWhileAuthenticated=%d\n"
"%s authAuthEapLogoffWhileAuthenticated=%d\n",
- prefix, prefix, auth_pae_state_txt(sm->auth_pae.state), prefix,
- _SB(sm->auth_pae.eapolLogoff), _SB(sm->auth_pae.eapolStart),
- _SB(sm->auth_pae.eapRestart), prefix,
- port_type_txt(sm->auth_pae.portMode), sm->auth_pae.reAuthCount,
- prefix, sm->auth_pae.quietPeriod, sm->auth_pae.reAuthMax,
- prefix, sm->auth_pae.authEntersConnecting,
- prefix, sm->auth_pae.authEapLogoffsWhileConnecting,
- prefix, sm->auth_pae.authEntersAuthenticating,
- prefix, sm->auth_pae.authAuthSuccessesWhileAuthenticating,
- prefix, sm->auth_pae.authAuthTimeoutsWhileAuthenticating,
- prefix, sm->auth_pae.authAuthFailWhileAuthenticating,
- prefix, sm->auth_pae.authAuthEapStartsWhileAuthenticating,
- prefix, sm->auth_pae.authAuthEapLogoffWhileAuthenticating,
- prefix, sm->auth_pae.authAuthReauthsWhileAuthenticated,
- prefix, sm->auth_pae.authAuthEapStartsWhileAuthenticated,
- prefix, sm->auth_pae.authAuthEapLogoffWhileAuthenticated);
+ prefix, prefix, auth_pae_state_txt(sm->auth_pae_state), prefix,
+ _SB(sm->eapolLogoff), _SB(sm->eapolStart), _SB(sm->eapRestart),
+ prefix, port_type_txt(sm->portMode), sm->reAuthCount,
+ prefix, sm->quietPeriod, sm->reAuthMax,
+ prefix, sm->authEntersConnecting,
+ prefix, sm->authEapLogoffsWhileConnecting,
+ prefix, sm->authEntersAuthenticating,
+ prefix, sm->authAuthSuccessesWhileAuthenticating,
+ prefix, sm->authAuthTimeoutsWhileAuthenticating,
+ prefix, sm->authAuthFailWhileAuthenticating,
+ prefix, sm->authAuthEapStartsWhileAuthenticating,
+ prefix, sm->authAuthEapLogoffWhileAuthenticating,
+ prefix, sm->authAuthReauthsWhileAuthenticated,
+ prefix, sm->authAuthEapStartsWhileAuthenticated,
+ prefix, sm->authAuthEapLogoffWhileAuthenticated);
fprintf(f, "%s Backend Authentication:\n"
"%s state=%s\n"
@@ -1049,42 +1040,39 @@ void eapol_sm_dump_state(FILE *f, const char *prefix,
"%s backendAuthSuccesses=%d\n"
"%s backendAuthFails=%d\n",
prefix, prefix,
- be_auth_state_txt(sm->be_auth.state),
- prefix, _SB(sm->be_auth.eapNoReq), _SB(sm->be_auth.eapReq),
- _SB(sm->be_auth.eapResp),
- prefix, sm->be_auth.serverTimeout,
- prefix, sm->be_auth.backendResponses,
- prefix, sm->be_auth.backendAccessChallenges,
- prefix, sm->be_auth.backendOtherRequestsToSupplicant,
- prefix, sm->be_auth.backendAuthSuccesses,
- prefix, sm->be_auth.backendAuthFails);
+ be_auth_state_txt(sm->be_auth_state),
+ prefix, _SB(sm->eapNoReq), _SB(sm->eapReq), _SB(sm->eapResp),
+ prefix, sm->serverTimeout,
+ prefix, sm->backendResponses,
+ prefix, sm->backendAccessChallenges,
+ prefix, sm->backendOtherRequestsToSupplicant,
+ prefix, sm->backendAuthSuccesses,
+ prefix, sm->backendAuthFails);
fprintf(f, "%s Reauthentication Timer:\n"
"%s state=%s\n"
"%s reAuthPeriod=%d reAuthEnabled=%s\n", prefix, prefix,
- reauth_timer_state_txt(sm->reauth_timer.state), prefix,
- sm->reauth_timer.reAuthPeriod,
- _SB(sm->reauth_timer.reAuthEnabled));
+ reauth_timer_state_txt(sm->reauth_timer_state), prefix,
+ sm->reAuthPeriod, _SB(sm->reAuthEnabled));
fprintf(f, "%s Authenticator Key Transmit:\n"
"%s state=%s\n", prefix, prefix,
- auth_key_tx_state_txt(sm->auth_key_tx.state));
+ auth_key_tx_state_txt(sm->auth_key_tx_state));
fprintf(f, "%s Key Receive:\n"
"%s state=%s\n"
"%s rxKey=%s\n", prefix, prefix,
- key_rx_state_txt(sm->key_rx.state),
- prefix, _SB(sm->key_rx.rxKey));
+ key_rx_state_txt(sm->key_rx_state), prefix, _SB(sm->rxKey));
fprintf(f, "%s Controlled Directions:\n"
"%s state=%s\n"
"%s adminControlledDirections=%s "
"operControlledDirections=%s\n"
"%s operEdge=%s\n", prefix, prefix,
- ctrl_dir_state_txt(sm->ctrl_dir.state),
- prefix, ctrl_dir_txt(sm->ctrl_dir.adminControlledDirections),
- ctrl_dir_txt(sm->ctrl_dir.operControlledDirections),
- prefix, _SB(sm->ctrl_dir.operEdge));
+ ctrl_dir_state_txt(sm->ctrl_dir_state),
+ prefix, ctrl_dir_txt(sm->adminControlledDirections),
+ ctrl_dir_txt(sm->operControlledDirections),
+ prefix, _SB(sm->operEdge));
#undef _SB
}
#endif /* HOSTAPD_DUMP_STATE */
@@ -1099,15 +1087,15 @@ static Boolean eapol_sm_get_bool(void *ctx, enum eapol_bool_var variable)
case EAPOL_eapSuccess:
return sm->eapSuccess;
case EAPOL_eapRestart:
- return sm->auth_pae.eapRestart;
+ return sm->eapRestart;
case EAPOL_eapFail:
return sm->eapFail;
case EAPOL_eapResp:
- return sm->be_auth.eapResp;
+ return sm->eapResp;
case EAPOL_eapReq:
- return sm->be_auth.eapReq;
+ return sm->eapReq;
case EAPOL_eapNoReq:
- return sm->be_auth.eapNoReq;
+ return sm->eapNoReq;
case EAPOL_portEnabled:
return sm->portEnabled;
case EAPOL_eapTimeout:
@@ -1128,19 +1116,19 @@ static void eapol_sm_set_bool(void *ctx, enum eapol_bool_var variable,
sm->eapSuccess = value;
break;
case EAPOL_eapRestart:
- sm->auth_pae.eapRestart = value;
+ sm->eapRestart = value;
break;
case EAPOL_eapFail:
sm->eapFail = value;
break;
case EAPOL_eapResp:
- sm->be_auth.eapResp = value;
+ sm->eapResp = value;
break;
case EAPOL_eapReq:
- sm->be_auth.eapReq = value;
+ sm->eapReq = value;
break;
case EAPOL_eapNoReq:
- sm->be_auth.eapNoReq = value;
+ sm->eapNoReq = value;
break;
case EAPOL_portEnabled:
sm->portEnabled = value;
@@ -1214,6 +1202,7 @@ static int eapol_sm_get_eap_user(void *ctx, const u8 *identity,
{
struct eapol_state_machine *sm = ctx;
const struct hostapd_eap_user *eap_user;
+ int i, count;
eap_user = hostapd_get_eap_user(sm->hapd->conf, identity,
identity_len, phase2);
@@ -1222,9 +1211,13 @@ static int eapol_sm_get_eap_user(void *ctx, const u8 *identity,
memset(user, 0, sizeof(*user));
user->phase2 = phase2;
- memcpy(user->methods, eap_user->methods,
- EAP_USER_MAX_METHODS > EAP_MAX_METHODS ?
- EAP_USER_MAX_METHODS : EAP_MAX_METHODS);
+ count = EAP_USER_MAX_METHODS;
+ if (count > EAP_MAX_METHODS)
+ count = EAP_MAX_METHODS;
+ for (i = 0; i < count; i++) {
+ user->methods[i].vendor = eap_user->methods[i].vendor;
+ user->methods[i].method = eap_user->methods[i].method;
+ }
if (eap_user->password) {
user->password = malloc(eap_user->password_len);
@@ -1257,3 +1250,15 @@ static struct eapol_callbacks eapol_cb =
.get_eap_user = eapol_sm_get_eap_user,
.get_eap_req_id_text = eapol_sm_get_eap_req_id_text,
};
+
+
+int eapol_sm_eap_pending_cb(struct eapol_state_machine *sm, void *ctx)
+{
+ if (sm == NULL || ctx != sm->eap)
+ return -1;
+
+ eap_sm_pending_cb(sm->eap);
+ eapol_sm_step(sm);
+
+ return 0;
+}
OpenPOWER on IntegriCloud