⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eapol_sm.c

📁 802.1x 源码,基于linux平台开发
💻 C
📖 第 1 页 / 共 2 页
字号:
				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 + -