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

📄 eap.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * hostapd / EAP Full Authenticator state machine (RFC 4137) * Copyright (c) 2004-2007, 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. * * This state machine is based on the full authenticator state machine defined * in RFC 4137. However, to support backend authentication in RADIUS * authentication server functionality, parts of backend authenticator (also * from RFC 4137) are mixed in. This functionality is enabled by setting * backend_auth configuration variable to TRUE. */#include "includes.h"#include "common.h"#include "eap_i.h"#include "state_machine.h"#define STATE_MACHINE_DATA struct eap_sm#define STATE_MACHINE_DEBUG_PREFIX "EAP"#define EAP_MAX_AUTH_ROUNDS 50static void eap_user_free(struct eap_user *user);/* EAP state machines are described in RFC 4137 */static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,				   int eapSRTT, int eapRTTVAR,				   int methodTimeout);static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp);static int eap_sm_getId(const struct wpabuf *data);static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id);static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id);static int eap_sm_nextId(struct eap_sm *sm, int id);static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list,				 size_t len);static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor);static int eap_sm_Policy_getDecision(struct eap_sm *sm);static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method);static int eap_copy_buf(struct wpabuf **dst, const struct wpabuf *src){	if (src == NULL)		return -1;	wpabuf_free(*dst);	*dst = wpabuf_dup(src);	return *dst ? 0 : -1;}static int eap_copy_data(u8 **dst, size_t *dst_len,			 const u8 *src, size_t src_len){	if (src == NULL)		return -1;	os_free(*dst);	*dst = os_malloc(src_len);	if (*dst) {		os_memcpy(*dst, src, src_len);		*dst_len = src_len;		return 0;	} else {		*dst_len = 0;		return -1;	}}#define EAP_COPY(dst, src) \	eap_copy_data((dst), (dst ## Len), (src), (src ## Len))/** * eap_user_get - Fetch user information from the database * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() * @identity: Identity (User-Name) of the user * @identity_len: Length of identity in bytes * @phase2: 0 = EAP phase1 user, 1 = EAP phase2 (tunneled) user * Returns: 0 on success, or -1 on failure * * This function is used to fetch user information for EAP. The user will be * selected based on the specified identity. sm->user and * sm->user_eap_method_index are updated for the new user when a matching user * is found. sm->user can be used to get user information (e.g., password). */int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,		 int phase2){	struct eap_user *user;	if (sm == NULL || sm->eapol_cb == NULL ||	    sm->eapol_cb->get_eap_user == NULL)		return -1;	eap_user_free(sm->user);	sm->user = NULL;	user = os_zalloc(sizeof(*user));	if (user == NULL)	    return -1;	if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity,				       identity_len, phase2, user) != 0) {		eap_user_free(user);		return -1;	}	sm->user = user;	sm->user_eap_method_index = 0;	return 0;}SM_STATE(EAP, DISABLED){	SM_ENTRY(EAP, DISABLED);	sm->num_rounds = 0;}SM_STATE(EAP, INITIALIZE){	SM_ENTRY(EAP, INITIALIZE);	sm->currentId = -1;	sm->eap_if.eapSuccess = FALSE;	sm->eap_if.eapFail = FALSE;	sm->eap_if.eapTimeout = FALSE;	os_free(sm->eap_if.eapKeyData);	sm->eap_if.eapKeyData = NULL;	sm->eap_if.eapKeyDataLen = 0;	sm->eap_if.eapKeyAvailable = FALSE;	sm->eap_if.eapRestart = FALSE;	/*	 * This is not defined in RFC 4137, but method state needs to be	 * reseted here so that it does not remain in success state when	 * re-authentication starts.	 */	if (sm->m && sm->eap_method_priv) {		sm->m->reset(sm, sm->eap_method_priv);		sm->eap_method_priv = NULL;	}	sm->m = NULL;	sm->user_eap_method_index = 0;	if (sm->backend_auth) {		sm->currentMethod = EAP_TYPE_NONE;		/* parse rxResp, respId, respMethod */		eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);		if (sm->rxResp) {			sm->currentId = sm->respId;		}	}	sm->num_rounds = 0;	sm->method_pending = METHOD_PENDING_NONE;}SM_STATE(EAP, PICK_UP_METHOD){	SM_ENTRY(EAP, PICK_UP_METHOD);	if (eap_sm_Policy_doPickUp(sm, sm->respMethod)) {		sm->currentMethod = sm->respMethod;		if (sm->m && sm->eap_method_priv) {			sm->m->reset(sm, sm->eap_method_priv);			sm->eap_method_priv = NULL;		}		sm->m = eap_server_get_eap_method(EAP_VENDOR_IETF,						  sm->currentMethod);		if (sm->m && sm->m->initPickUp) {			sm->eap_method_priv = sm->m->initPickUp(sm);			if (sm->eap_method_priv == NULL) {				wpa_printf(MSG_DEBUG, "EAP: Failed to "					   "initialize EAP method %d",					   sm->currentMethod);				sm->m = NULL;				sm->currentMethod = EAP_TYPE_NONE;			}		} else {			sm->m = NULL;			sm->currentMethod = EAP_TYPE_NONE;		}	}}SM_STATE(EAP, IDLE){	SM_ENTRY(EAP, IDLE);	sm->eap_if.retransWhile = eap_sm_calculateTimeout(		sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,		sm->methodTimeout);}SM_STATE(EAP, RETRANSMIT){	SM_ENTRY(EAP, RETRANSMIT);	sm->retransCount++;	if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {		if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0)			sm->eap_if.eapReq = TRUE;	}}SM_STATE(EAP, RECEIVED){	SM_ENTRY(EAP, RECEIVED);	/* parse rxResp, respId, respMethod */	eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);	sm->num_rounds++;}SM_STATE(EAP, DISCARD){	SM_ENTRY(EAP, DISCARD);	sm->eap_if.eapResp = FALSE;	sm->eap_if.eapNoReq = TRUE;}SM_STATE(EAP, SEND_REQUEST){	SM_ENTRY(EAP, SEND_REQUEST);	sm->retransCount = 0;	if (sm->eap_if.eapReqData) {		if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)		{			sm->eap_if.eapResp = FALSE;			sm->eap_if.eapReq = TRUE;		} else {			sm->eap_if.eapResp = FALSE;			sm->eap_if.eapReq = FALSE;		}	} else {		wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData");		sm->eap_if.eapResp = FALSE;		sm->eap_if.eapReq = FALSE;		sm->eap_if.eapNoReq = TRUE;	}}SM_STATE(EAP, INTEGRITY_CHECK){	SM_ENTRY(EAP, INTEGRITY_CHECK);	if (sm->m->check) {		sm->ignore = sm->m->check(sm, sm->eap_method_priv,					  sm->eap_if.eapRespData);	}}SM_STATE(EAP, METHOD_REQUEST){	SM_ENTRY(EAP, METHOD_REQUEST);	if (sm->m == NULL) {		wpa_printf(MSG_DEBUG, "EAP: method not initialized");		return;	}	sm->currentId = eap_sm_nextId(sm, sm->currentId);	wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d",		   sm->currentId);	sm->lastId = sm->currentId;	wpabuf_free(sm->eap_if.eapReqData);	sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv,						sm->currentId);	if (sm->m->getTimeout)		sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv);	else		sm->methodTimeout = 0;}SM_STATE(EAP, METHOD_RESPONSE){	SM_ENTRY(EAP, METHOD_RESPONSE);	sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData);	if (sm->m->isDone(sm, sm->eap_method_priv)) {		eap_sm_Policy_update(sm, NULL, 0);		os_free(sm->eap_if.eapKeyData);		if (sm->m->getKey) {			sm->eap_if.eapKeyData = sm->m->getKey(				sm, sm->eap_method_priv,				&sm->eap_if.eapKeyDataLen);		} else {			sm->eap_if.eapKeyData = NULL;			sm->eap_if.eapKeyDataLen = 0;		}		sm->methodState = METHOD_END;	} else {		sm->methodState = METHOD_CONTINUE;	}}SM_STATE(EAP, PROPOSE_METHOD){	int vendor;	EapType type;	SM_ENTRY(EAP, PROPOSE_METHOD);	type = eap_sm_Policy_getNextMethod(sm, &vendor);	if (vendor == EAP_VENDOR_IETF)		sm->currentMethod = type;	else		sm->currentMethod = EAP_TYPE_EXPANDED;	if (sm->m && sm->eap_method_priv) {		sm->m->reset(sm, sm->eap_method_priv);		sm->eap_method_priv = NULL;	}	sm->m = eap_server_get_eap_method(vendor, type);	if (sm->m) {		sm->eap_method_priv = sm->m->init(sm);		if (sm->eap_method_priv == NULL) {			wpa_printf(MSG_DEBUG, "EAP: Failed to initialize EAP "				   "method %d", sm->currentMethod);			sm->m = NULL;			sm->currentMethod = EAP_TYPE_NONE;		}	}	if (sm->currentMethod == EAP_TYPE_IDENTITY ||	    sm->currentMethod == EAP_TYPE_NOTIFICATION)		sm->methodState = METHOD_CONTINUE;	else		sm->methodState = METHOD_PROPOSED;}SM_STATE(EAP, NAK){	const struct eap_hdr *nak;	size_t len = 0;	const u8 *pos;	const u8 *nak_list = NULL;	SM_ENTRY(EAP, NAK);	if (sm->eap_method_priv) {		sm->m->reset(sm, sm->eap_method_priv);		sm->eap_method_priv = NULL;	}	sm->m = NULL;	nak = wpabuf_head(sm->eap_if.eapRespData);	if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) {		len = be_to_host16(nak->length);		if (len > wpabuf_len(sm->eap_if.eapRespData))			len = wpabuf_len(sm->eap_if.eapRespData);		pos = (const u8 *) (nak + 1);		len -= sizeof(*nak);		if (*pos == EAP_TYPE_NAK) {			pos++;			len--;			nak_list = pos;		}	}	eap_sm_Policy_update(sm, nak_list, len);}SM_STATE(EAP, SELECT_ACTION){	SM_ENTRY(EAP, SELECT_ACTION);	sm->decision = eap_sm_Policy_getDecision(sm);}SM_STATE(EAP, TIMEOUT_FAILURE){	SM_ENTRY(EAP, TIMEOUT_FAILURE);	sm->eap_if.eapTimeout = TRUE;}SM_STATE(EAP, FAILURE){	SM_ENTRY(EAP, FAILURE);	wpabuf_free(sm->eap_if.eapReqData);	sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId);	wpabuf_free(sm->lastReqData);	sm->lastReqData = NULL;	sm->eap_if.eapFail = TRUE;}SM_STATE(EAP, SUCCESS){	SM_ENTRY(EAP, SUCCESS);	wpabuf_free(sm->eap_if.eapReqData);	sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId);	wpabuf_free(sm->lastReqData);	sm->lastReqData = NULL;	if (sm->eap_if.eapKeyData)		sm->eap_if.eapKeyAvailable = TRUE;	sm->eap_if.eapSuccess = TRUE;}SM_STATE(EAP, INITIALIZE_PASSTHROUGH){	SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH);	wpabuf_free(sm->eap_if.aaaEapRespData);	sm->eap_if.aaaEapRespData = NULL;}SM_STATE(EAP, IDLE2){	SM_ENTRY(EAP, IDLE2);	sm->eap_if.retransWhile = eap_sm_calculateTimeout(		sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,		sm->methodTimeout);}SM_STATE(EAP, RETRANSMIT2)

⌨️ 快捷键说明

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