📄 eapol_sm.c
字号:
SM_ENTER(AUTH_PAE, CONNECTING);
break;
case AUTH_PAE_FORCE_AUTH:
if (sm->auth_pae.eapStart)
SM_ENTER(AUTH_PAE, FORCE_AUTH);
break;
case AUTH_PAE_FORCE_UNAUTH:
if (sm->auth_pae.eapStart)
SM_ENTER(AUTH_PAE, FORCE_UNAUTH);
break;
}
}
}
/* Backend Authentication state machine */
SM_STATE(BE_AUTH, INITIALIZE)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, BE_AUTH, INITIALIZE\n");
SM_ENTRY(BE_AUTH, INITIALIZE, be_auth);
abortAuth;
sm->authAbort = FALSE;
}
SM_STATE(BE_AUTH, REQUEST)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, BE_AUTH, INITIALIZE\n");
SM_ENTRY(BE_AUTH, REQUEST, be_auth);
sm->currentId = sm->be_auth.idFromServer;
txReq(sm->currentId);
sm->be_auth.backendOtherRequestsToSupplicant++;
sm->aWhile = sm->be_auth.suppTimeout;
sm->be_auth.reqCount++;
}
SM_STATE(BE_AUTH, RESPONSE)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, BE_AUTH, INITIALIZE\n");
SM_ENTRY(BE_AUTH, RESPONSE, be_auth);
sm->be_auth.aReq = sm->be_auth.aSuccess = FALSE;
sm->authTimeout = FALSE;
sm->be_auth.rxResp = sm->be_auth.aFail = FALSE;
sm->aWhile = sm->be_auth.serverTimeout;
sm->be_auth.reqCount = 0;
sendRespToServer;
sm->be_auth.backendResponses++;
}
SM_STATE(BE_AUTH, SUCCESS)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, BE_AUTH, INITIALIZE\n");
SM_ENTRY(BE_AUTH, SUCCESS, be_auth);
sm->currentId = sm->be_auth.idFromServer;
txReq(sm->currentId);
sm->authSuccess = TRUE;
}
SM_STATE(BE_AUTH, FAIL)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, BE_AUTH, INITIALIZE\n");
SM_ENTRY(BE_AUTH, FAIL, be_auth);
sm->currentId = sm->be_auth.idFromServer;
txReq(sm->currentId);
sm->authFail = TRUE;
}
SM_STATE(BE_AUTH, TIMEOUT)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, BE_AUTH, INITIALIZE\n");
SM_ENTRY(BE_AUTH, TIMEOUT, be_auth);
if (sm->portStatus == Unauthorized)
txCannedFail(sm->currentId);
sm->authTimeout = TRUE;
}
SM_STATE(BE_AUTH, IDLE)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, BE_AUTH, INITIALIZE\n");
SM_ENTRY(BE_AUTH, IDLE, be_auth);
sm->authStart = FALSE;
sm->be_auth.reqCount = 0;
}
SM_STEP(BE_AUTH)
{
if (sm->portControl != Auto || sm->initialize || sm->authAbort) {
SM_ENTER(BE_AUTH, INITIALIZE);
return;
}
switch (sm->be_auth.state) {
case BE_AUTH_INITIALIZE:
SM_ENTER(BE_AUTH, IDLE);
break;
case BE_AUTH_REQUEST:
if (sm->aWhile == 0 &&
sm->be_auth.reqCount != sm->be_auth.maxReq)
SM_ENTER(BE_AUTH, REQUEST);
else if (sm->be_auth.rxResp)
SM_ENTER(BE_AUTH, RESPONSE);
else if (sm->aWhile == 0 &&
sm->be_auth.reqCount >= sm->be_auth.maxReq)
SM_ENTER(BE_AUTH, TIMEOUT);
break;
case BE_AUTH_RESPONSE:
if (sm->be_auth.aReq) {
sm->be_auth.backendAccessChallenges++;
SM_ENTER(BE_AUTH, REQUEST);
} else if (sm->aWhile == 0)
SM_ENTER(BE_AUTH, TIMEOUT);
else if (sm->be_auth.aFail) {
sm->be_auth.backendAuthFails++;
SM_ENTER(BE_AUTH, FAIL);
} else if (sm->be_auth.aSuccess) {
sm->be_auth.backendAuthSuccesses++;
SM_ENTER(BE_AUTH, SUCCESS);
}
break;
case BE_AUTH_SUCCESS:
SM_ENTER(BE_AUTH, IDLE);
break;
case BE_AUTH_FAIL:
SM_ENTER(BE_AUTH, IDLE);
break;
case BE_AUTH_TIMEOUT:
SM_ENTER(BE_AUTH, IDLE);
break;
case BE_AUTH_IDLE:
if (sm->authStart)
SM_ENTER(BE_AUTH, RESPONSE);
break;
}
}
/* Reauthentication Timer state machine */
SM_STATE(REAUTH_TIMER, INITIALIZE)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, REAUTH_TIMER, INITIALIZE\n");
SM_ENTRY(REAUTH_TIMER, INITIALIZE, reauth_timer);
sm->reAuthWhen = sm->reauth_timer.reAuthPeriod;
}
SM_STATE(REAUTH_TIMER, REAUTHENTICATE)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, REAUTH_TIMER, INITIALIZE\n");
SM_ENTRY(REAUTH_TIMER, REAUTHENTICATE, reauth_timer);
sm->reAuthenticate = TRUE;
}
SM_STEP(REAUTH_TIMER)
{
if (sm->portControl != Auto || sm->initialize ||
sm->portStatus == Unauthorized ||
!sm->reauth_timer.reAuthEnabled) {
SM_ENTER(REAUTH_TIMER, INITIALIZE);
return;
}
switch (sm->reauth_timer.state) {
case REAUTH_TIMER_INITIALIZE:
if ((sm->reAuthWhen == 0) )
SM_ENTER(REAUTH_TIMER, REAUTHENTICATE);
break;
case REAUTH_TIMER_REAUTHENTICATE:
SM_ENTER(REAUTH_TIMER, INITIALIZE);
break;
}
}
/* Authenticator Key Transmit state machine */
SM_STATE(AUTH_KEY_TX, NO_KEY_TRANSMIT)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, AUTH_KEY_TX, NO_KEY_TRANSMIT\n");
DBGPRINT(RT_DEBUG_INFO,"AUTH_KEY_TX, NO_KEY_TRANSMIT\n");
SM_ENTRY(AUTH_KEY_TX, NO_KEY_TRANSMIT, auth_key_tx);
}
SM_STATE(AUTH_KEY_TX, KEY_TRANSMIT)
{
DBGPRINT(RT_DEBUG_INFO," SM_STATE, AUTH_KEY_TX, NO_KEY_TRANSMIT\n");
DBGPRINT(RT_DEBUG_INFO,"(AUTH_KEY_TX, KEY_TRANSMIT)\n");
SM_ENTRY(AUTH_KEY_TX, KEY_TRANSMIT, auth_key_tx);
//txKey(sm->currentId);
sm->keyAvailable = FALSE;
}
SM_STEP(AUTH_KEY_TX)
{
if (sm->initialize || sm->portControl != Auto) {
SM_ENTER(AUTH_KEY_TX, NO_KEY_TRANSMIT);
return;
}
switch (sm->auth_key_tx.state) {
case AUTH_KEY_TX_NO_KEY_TRANSMIT:
/* NOTE! IEEE 802.1aa/D4 does has this requirement as
* keyTxEnabled && keyAvailable && authSuccess. However, this
* seems to be conflicting with BE_AUTH sm, since authSuccess
* is now set only if keyTxEnabled is true and there are no
* keys to be sent.. I think the purpose is to sent the keys
* first and report authSuccess only after this and adding OR
* be_auth.aSuccess does this. */
if (sm->keyTxEnabled && sm->keyAvailable &&
(sm->authSuccess /* || sm->be_auth.aSuccess */))
SM_ENTER(AUTH_KEY_TX, KEY_TRANSMIT);
break;
case AUTH_KEY_TX_KEY_TRANSMIT:
if (!sm->keyTxEnabled || sm->authFail ||
sm->auth_pae.eapLogoff)
SM_ENTER(AUTH_KEY_TX, NO_KEY_TRANSMIT);
else if (sm->keyAvailable)
SM_ENTER(AUTH_KEY_TX, KEY_TRANSMIT);
break;
}
}
struct eapol_state_machine *
eapol_sm_alloc(rtapd *rtapd, struct sta_info *sta)
{
struct eapol_state_machine *sm;
sm = (struct eapol_state_machine *) malloc(sizeof(*sm));
if (sm == NULL) {
DBGPRINT(RT_DEBUG_ERROR,"IEEE 802.1X port state allocation failed\n");
return NULL;
}
memset(sm, 0, sizeof(*sm));
sm->rtapd = rtapd;
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.initialEAPMsg = AUTH_PAE_DEFAULT_initialEAPMsg;
sm->auth_pae.reAuthMax = AUTH_PAE_DEFAULT_reAuthMax;
sm->auth_pae.txPeriod = AUTH_PAE_DEFAULT_txPeriod;
sm->be_auth.state = BE_AUTH_INITIALIZE;
sm->be_auth.suppTimeout = BE_AUTH_DEFAULT_suppTimeout;
sm->be_auth.serverTimeout = BE_AUTH_DEFAULT_serverTimeout;
sm->be_auth.maxReq = BE_AUTH_DEFAULT_maxReq;
sm->reauth_timer.state = REAUTH_TIMER_INITIALIZE;
sm->reauth_timer.reAuthEnabled = REAUTH_TIMER_DEFAULT_reAuthEnabled;
if (rtapd->conf->session_timeout_set == 1)
{
sm->reauth_timer.reAuthPeriod = rtapd->conf->session_timeout_interval;
sm->reauth_timer.reAuthEnabled = TRUE;
DBGPRINT(RT_DEBUG_INFO,"Set This Session Timeout Interval %d Seconds. \n",sm->reauth_timer.reAuthPeriod );
}
else
{
/* didn't set reauth , or set to not reauth */
sm->reauth_timer.reAuthPeriod = REAUTH_TIMER_DEFAULT_reAuthPeriod;
}
sm->portEnabled = FALSE;
sm->portControl = Auto;
sm->currentId = 1;
/* IEEE 802.1aa/D4 */
sm->keyAvailable = FALSE;
sm->keyTxEnabled =TRUE ;
sm->portValid = TRUE; /* TODO: should this be FALSE sometimes? */
eapol_sm_initialize(sm);
return sm;
}
void eapol_sm_free(struct eapol_state_machine *sm)
{
if (sm == NULL)
return;
eloop_cancel_timeout(eapol_port_timers_tick, sm->rtapd, sm);
free(sm);
}
void eapol_sm_step(struct eapol_state_machine *sm)
{
int prev_auth_pae, prev_be_auth, prev_reauth_timer, prev_auth_key_tx;
/* FIX: could re-run eapol_sm_step from registered timeout (after
* 0 sec) to make sure that other possible timeouts/events are
* processed */
do {
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;
DBGPRINT(RT_DEBUG_INFO,"\n Handle eapol_sm_step AUTH_PAE\n");
SM_STEP_RUN(AUTH_PAE);
DBGPRINT(RT_DEBUG_INFO,"Handle eapol_sm_step BE_AUTH\n");
SM_STEP_RUN(BE_AUTH);
DBGPRINT(RT_DEBUG_INFO,"Handle eapol_sm_step REAUTH_TIMER sm=%d\n",sm);
SM_STEP_RUN(REAUTH_TIMER);
DBGPRINT(RT_DEBUG_INFO,"Handle eapol_sm_step AUTH_KEY_TX\n");
SM_STEP_RUN(AUTH_KEY_TX);
DBGPRINT(RT_DEBUG_INFO,"Handle eapol_sm_step completed\n");
DBGPRINT(RT_DEBUG_INFO,"-----------------\n");
DBGPRINT(RT_DEBUG_INFO,"prev_auth_pae(%d) ->auth_pae.state(%d) \n",prev_auth_pae,sm->auth_pae.state);
DBGPRINT(RT_DEBUG_INFO,"prev_be_auth(%d) ->auth_pae.state(%d) \n",prev_auth_pae,sm->be_auth.state);
DBGPRINT(RT_DEBUG_INFO,"prev_reauth_timer(%d) ->auth_pae.state(%d) \n",prev_auth_pae,sm->reauth_timer.state);
DBGPRINT(RT_DEBUG_INFO,"prev_auth_key_tx(%d) ->auth_pae.state(%d) \n",prev_auth_pae,sm->auth_key_tx.state);
DBGPRINT(RT_DEBUG_INFO,"-----------------\n");
} while (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);
}
void eapol_sm_initialize(struct eapol_state_machine *sm)
{
/* Initialize the state machines by asserting initialize and then
* deasserting it after one step */
sm->initialize = TRUE;
DBGPRINT(RT_DEBUG_INFO," eapol_sm_initialize call eapol_sm_step\n");
eapol_sm_step(sm);
sm->initialize = FALSE;
DBGPRINT(RT_DEBUG_INFO," eapol_sm_initialize call eapol_sm_step\n");
eapol_sm_step(sm);
/* Start one second tick for port timers state machine */
eloop_cancel_timeout(eapol_port_timers_tick, sm->rtapd, sm);
eloop_register_timeout(1, 0, eapol_port_timers_tick, sm->rtapd, sm);
}
void eapol_sm_reinit_port_timer(struct eapol_state_machine *sm)
{
eloop_cancel_timeout(eapol_port_timers_tick, sm->rtapd, sm);
eloop_register_timeout(1, 0, eapol_port_timers_tick, sm->rtapd, sm);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -