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

📄 eapol_sm.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * hostapd / IEEE 802.1X-2004 Authenticator - EAPOL state machine * Copyright (c) 2002-2008, 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 * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#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_server/eap.h"#include "state_machine.h"#include "eap_common/eap_common.h"#define STATE_MACHINE_DATA struct eapol_state_machine#define STATE_MACHINE_DEBUG_PREFIX "IEEE 802.1X"#define STATE_MACHINE_ADDR sm->addrstatic struct eapol_callbacks eapol_cb;/* EAPOL state machines are described in IEEE Std 802.1X-2004, Chap. 8.2 */#define setPortAuthorized() \sm->eapol->cb.set_port_authorized(sm->hapd, sm->sta, 1)#define setPortUnauthorized() \sm->eapol->cb.set_port_authorized(sm->hapd, sm->sta, 0)/* procedures */#define txCannedFail() eapol_auth_tx_canned_eap(sm, 0)#define txCannedSuccess() eapol_auth_tx_canned_eap(sm, 1)#define txReq() eapol_auth_tx_req(sm)#define abortAuth() sm->eapol->cb.abort_auth(sm->hapd, sm->sta)#define txKey() sm->eapol->cb.tx_key(sm->hapd, sm->sta)#define processKey() do { } while (0)static void eapol_sm_step_run(struct eapol_state_machine *sm);static void eapol_sm_step_cb(void *eloop_ctx, void *timeout_ctx);static void eapol_auth_logger(struct eapol_authenticator *eapol,			      const u8 *addr, logger_level level,			      const char *txt){	if (eapol->cb.logger == NULL)		return;	eapol->cb.logger(eapol->conf.hapd, addr, level, txt);}static void eapol_auth_vlogger(struct eapol_authenticator *eapol,			       const u8 *addr, logger_level level,			       const char *fmt, ...){	char *format;	int maxlen;	va_list ap;	if (eapol->cb.logger == NULL)		return;	maxlen = os_strlen(fmt) + 100;	format = os_malloc(maxlen);	if (!format)		return;	va_start(ap, fmt);	vsnprintf(format, maxlen, fmt, ap);	va_end(ap);	eapol_auth_logger(eapol, addr, level, format);	os_free(format);}static void eapol_auth_tx_canned_eap(struct eapol_state_machine *sm,				     int success){	struct eap_hdr eap;	os_memset(&eap, 0, sizeof(eap));	eap.code = success ? EAP_CODE_SUCCESS : EAP_CODE_FAILURE;	eap.identifier = ++sm->last_eap_id;	eap.length = host_to_be16(sizeof(eap));	eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_DEBUG,			   "Sending canned EAP packet %s (identifier %d)",			   success ? "SUCCESS" : "FAILURE", eap.identifier);	sm->eapol->cb.eapol_send(sm->hapd, sm->sta, IEEE802_1X_TYPE_EAP_PACKET,				 (u8 *) &eap, sizeof(eap));	sm->dot1xAuthEapolFramesTx++;}static void eapol_auth_tx_req(struct eapol_state_machine *sm){	if (sm->eap_if->eapReqData == NULL ||	    wpabuf_len(sm->eap_if->eapReqData) < sizeof(struct eap_hdr)) {		eapol_auth_logger(sm->eapol, sm->addr,				  EAPOL_LOGGER_DEBUG,				  "TxReq called, but there is no EAP request "				  "from authentication server");		return;	}	if (sm->flags & EAPOL_SM_WAIT_START) {		wpa_printf(MSG_DEBUG, "EAPOL: Drop EAPOL TX to " MACSTR			   " while waiting for EAPOL-Start",			   MAC2STR(sm->addr));		return;	}	sm->last_eap_id = eap_get_id(sm->eap_if->eapReqData);	eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_DEBUG,			   "Sending EAP Packet (identifier %d)",			   sm->last_eap_id);	sm->eapol->cb.eapol_send(sm->hapd, sm->sta, IEEE802_1X_TYPE_EAP_PACKET,				 wpabuf_head(sm->eap_if->eapReqData),				 wpabuf_len(sm->eap_if->eapReqData));	sm->dot1xAuthEapolFramesTx++;	if (eap_get_type(sm->eap_if->eapReqData) == EAP_TYPE_IDENTITY)		sm->dot1xAuthEapolReqIdFramesTx++;	else		sm->dot1xAuthEapolReqFramesTx++;}/** * eapol_port_timers_tick - Port Timers state machine * @eloop_ctx: struct eapol_state_machine * * @timeout_ctx: Not used * * This statemachine is implemented as a function that will be called * once a second as a registered event loop timeout. */static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx){	struct eapol_state_machine *state = timeout_ctx;	if (state->aWhile > 0) {		state->aWhile--;		if (state->aWhile == 0) {			wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR				   " - aWhile --> 0",				   MAC2STR(state->addr));		}	}	if (state->quietWhile > 0) {		state->quietWhile--;		if (state->quietWhile == 0) {			wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR				   " - quietWhile --> 0",				   MAC2STR(state->addr));		}	}	if (state->reAuthWhen > 0) {		state->reAuthWhen--;		if (state->reAuthWhen == 0) {			wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR				   " - reAuthWhen --> 0",				   MAC2STR(state->addr));		}	}	if (state->eap_if->retransWhile > 0) {		state->eap_if->retransWhile--;		if (state->eap_if->retransWhile == 0) {			wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR				   " - (EAP) retransWhile --> 0",				   MAC2STR(state->addr));		}	}	eapol_sm_step_run(state);	eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx, state);}/* Authenticator PAE state machine */SM_STATE(AUTH_PAE, INITIALIZE){	SM_ENTRY_MA(AUTH_PAE, INITIALIZE, auth_pae);	sm->portMode = Auto;}SM_STATE(AUTH_PAE, DISCONNECTED){	int from_initialize = sm->auth_pae_state == AUTH_PAE_INITIALIZE;	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_MA(AUTH_PAE, DISCONNECTED, auth_pae);	sm->authPortStatus = Unauthorized;	setPortUnauthorized();	sm->reAuthCount = 0;	sm->eapolLogoff = FALSE;	if (!from_initialize) {		sm->eapol->cb.finished(sm->hapd, sm->sta, 0,				       sm->flags & EAPOL_SM_PREAUTH);	}}SM_STATE(AUTH_PAE, RESTART){	if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATED) {		if (sm->reAuthenticate)			sm->authAuthReauthsWhileAuthenticated++;		if (sm->eapolStart)			sm->authAuthEapStartsWhileAuthenticated++;		if (sm->eapolLogoff)			sm->authAuthEapLogoffWhileAuthenticated++;	}	SM_ENTRY_MA(AUTH_PAE, RESTART, auth_pae);	sm->eap_if->eapRestart = TRUE;}SM_STATE(AUTH_PAE, CONNECTING){	if (sm->auth_pae_state != AUTH_PAE_CONNECTING)		sm->authEntersConnecting++;	SM_ENTRY_MA(AUTH_PAE, CONNECTING, auth_pae);	sm->reAuthenticate = FALSE;	sm->reAuthCount++;}SM_STATE(AUTH_PAE, HELD){	if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATING && sm->authFail)		sm->authAuthFailWhileAuthenticating++;	SM_ENTRY_MA(AUTH_PAE, HELD, auth_pae);	sm->authPortStatus = Unauthorized;	setPortUnauthorized();	sm->quietWhile = sm->quietPeriod;	sm->eapolLogoff = FALSE;	eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_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) {		eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_INFO,				   "Supplicant used different EAP type: "				   "%d (%s)", sm->eap_type_supp,				   eap_type_text(sm->eap_type_supp));	}	sm->eapol->cb.finished(sm->hapd, sm->sta, 0,			       sm->flags & EAPOL_SM_PREAUTH);}SM_STATE(AUTH_PAE, AUTHENTICATED){	char *extra = "";	if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATING && sm->authSuccess)		sm->authAuthSuccessesWhileAuthenticating++;								SM_ENTRY_MA(AUTH_PAE, AUTHENTICATED, auth_pae);	sm->authPortStatus = Authorized;	setPortAuthorized();	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)";	eapol_auth_vlogger(sm->eapol, sm->addr, EAPOL_LOGGER_INFO,			   "authenticated - EAP type: %d (%s)%s",			   sm->eap_type_authsrv,			   eap_type_text(sm->eap_type_authsrv), extra);	sm->eapol->cb.finished(sm->hapd, sm->sta, 1,			       sm->flags & EAPOL_SM_PREAUTH);}SM_STATE(AUTH_PAE, AUTHENTICATING){	SM_ENTRY_MA(AUTH_PAE, AUTHENTICATING, auth_pae);	sm->eapolStart = FALSE;	sm->authSuccess = FALSE;	sm->authFail = FALSE;	sm->authTimeout = FALSE;	sm->authStart = TRUE;	sm->keyRun = FALSE;	sm->keyDone = FALSE;}SM_STATE(AUTH_PAE, ABORTING){	if (sm->auth_pae_state == AUTH_PAE_AUTHENTICATING) {		if (sm->authTimeout)			sm->authAuthTimeoutsWhileAuthenticating++;		if (sm->eapolStart)			sm->authAuthEapStartsWhileAuthenticating++;		if (sm->eapolLogoff)			sm->authAuthEapLogoffWhileAuthenticating++;	}	SM_ENTRY_MA(AUTH_PAE, ABORTING, auth_pae);	sm->authAbort = TRUE;	sm->keyRun = FALSE;	sm->keyDone = FALSE;}SM_STATE(AUTH_PAE, FORCE_AUTH){	SM_ENTRY_MA(AUTH_PAE, FORCE_AUTH, auth_pae);	sm->authPortStatus = Authorized;	setPortAuthorized();	sm->portMode = ForceAuthorized;	sm->eapolStart = FALSE;	txCannedSuccess();}SM_STATE(AUTH_PAE, FORCE_UNAUTH){	SM_ENTRY_MA(AUTH_PAE, FORCE_UNAUTH, auth_pae);	sm->authPortStatus = Unauthorized;	setPortUnauthorized();	sm->portMode = ForceUnauthorized;	sm->eapolStart = FALSE;	txCannedFail();}SM_STEP(AUTH_PAE){	if ((sm->portControl == Auto && sm->portMode != sm->portControl) ||	    sm->initialize || !sm->eap_if->portEnabled)		SM_ENTER_GLOBAL(AUTH_PAE, INITIALIZE);	else if (sm->portControl == ForceAuthorized &&		 sm->portMode != sm->portControl &&		 !(sm->initialize || !sm->eap_if->portEnabled))		SM_ENTER_GLOBAL(AUTH_PAE, FORCE_AUTH);	else if (sm->portControl == ForceUnauthorized &&		 sm->portMode != sm->portControl &&		 !(sm->initialize || !sm->eap_if->portEnabled))		SM_ENTER_GLOBAL(AUTH_PAE, FORCE_UNAUTH);	else {		switch (sm->auth_pae_state) {		case AUTH_PAE_INITIALIZE:			SM_ENTER(AUTH_PAE, DISCONNECTED);			break;		case AUTH_PAE_DISCONNECTED:			SM_ENTER(AUTH_PAE, RESTART);			break;		case AUTH_PAE_RESTART:			if (!sm->eap_if->eapRestart)				SM_ENTER(AUTH_PAE, CONNECTING);			break;		case AUTH_PAE_HELD:			if (sm->quietWhile == 0)				SM_ENTER(AUTH_PAE, RESTART);			break;		case AUTH_PAE_CONNECTING:			if (sm->eapolLogoff || sm->reAuthCount > sm->reAuthMax)				SM_ENTER(AUTH_PAE, DISCONNECTED);			else if ((sm->eap_if->eapReq &&				  sm->reAuthCount <= sm->reAuthMax) ||				 sm->eap_if->eapSuccess || sm->eap_if->eapFail)				SM_ENTER(AUTH_PAE, AUTHENTICATING);			break;		case AUTH_PAE_AUTHENTICATED:			if (sm->eapolStart || sm->reAuthenticate)				SM_ENTER(AUTH_PAE, RESTART);			else if (sm->eapolLogoff || !sm->portValid)				SM_ENTER(AUTH_PAE, DISCONNECTED);			break;		case AUTH_PAE_AUTHENTICATING:			if (sm->authSuccess && sm->portValid)				SM_ENTER(AUTH_PAE, AUTHENTICATED);			else if (sm->authFail ||				 (sm->keyDone && !sm->portValid))				SM_ENTER(AUTH_PAE, HELD);			else if (sm->eapolStart || sm->eapolLogoff ||				 sm->authTimeout)				SM_ENTER(AUTH_PAE, ABORTING);			break;		case AUTH_PAE_ABORTING:			if (sm->eapolLogoff && !sm->authAbort)				SM_ENTER(AUTH_PAE, DISCONNECTED);			else if (!sm->eapolLogoff && !sm->authAbort)				SM_ENTER(AUTH_PAE, RESTART);			break;		case AUTH_PAE_FORCE_AUTH:			if (sm->eapolStart)				SM_ENTER(AUTH_PAE, FORCE_AUTH);			break;		case AUTH_PAE_FORCE_UNAUTH:			if (sm->eapolStart)				SM_ENTER(AUTH_PAE, FORCE_UNAUTH);			break;		}	}}/* Backend Authentication state machine */SM_STATE(BE_AUTH, INITIALIZE){	SM_ENTRY_MA(BE_AUTH, INITIALIZE, be_auth);	abortAuth();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -