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

📄 eap.c

📁 hostapd无线AP工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	sm->eapReqData = eap_sm_buildFailure(sm, sm->currentId,					     &sm->eapReqDataLen);	if (sm->eapReqData) {		eapol_set_eapReqData(sm, sm->eapReqData, sm->eapReqDataLen);		free(sm->eapReqData);		sm->eapReqData = NULL;		sm->eapReqDataLen = 0;	}	free(sm->lastReqData);	sm->lastReqData = NULL;	sm->lastReqDataLen = 0;	eapol_set_bool(sm, EAPOL_eapFail, TRUE);}SM_STATE(EAP, SUCCESS){	SM_ENTRY(EAP, SUCCESS);	free(sm->eapReqData);	sm->eapReqData = eap_sm_buildSuccess(sm, sm->currentId,					     &sm->eapReqDataLen);	if (sm->eapReqData) {		eapol_set_eapReqData(sm, sm->eapReqData, sm->eapReqDataLen);		free(sm->eapReqData);		sm->eapReqData = NULL;		sm->eapReqDataLen = 0;	}	free(sm->lastReqData);	sm->lastReqData = NULL;	sm->lastReqDataLen = 0;	if (sm->eapKeyData) {		eapol_set_eapKeyData(sm, sm->eapKeyData, sm->eapKeyDataLen);	}	eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);}SM_STEP(EAP){	if (eapol_get_bool(sm, EAPOL_eapRestart) &&	    eapol_get_bool(sm, EAPOL_portEnabled))		SM_ENTER_GLOBAL(EAP, INITIALIZE);	else if (!eapol_get_bool(sm, EAPOL_portEnabled))		SM_ENTER_GLOBAL(EAP, DISABLED);	else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {		if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {			wpa_printf(MSG_DEBUG, "EAP: more than %d "				   "authentication rounds - abort",				   EAP_MAX_AUTH_ROUNDS);			sm->num_rounds++;			SM_ENTER_GLOBAL(EAP, FAILURE);		}	} else switch (sm->EAP_state) {	case EAP_INITIALIZE:		if (sm->backend_auth) {			if (!sm->rxResp)				SM_ENTER(EAP, SELECT_ACTION);			else if (sm->rxResp &&				 (sm->respMethod == EAP_TYPE_NAK ||				  sm->respMethod == EAP_TYPE_EXPANDED_NAK))				SM_ENTER(EAP, NAK);			else				SM_ENTER(EAP, PICK_UP_METHOD);		} else {			SM_ENTER(EAP, SELECT_ACTION);		}		break;	case EAP_PICK_UP_METHOD:		if (sm->currentMethod == EAP_TYPE_NONE) {			SM_ENTER(EAP, SELECT_ACTION);		} else {			SM_ENTER(EAP, METHOD_RESPONSE);		}		break;	case EAP_DISABLED:		if (eapol_get_bool(sm, EAPOL_portEnabled))			SM_ENTER(EAP, INITIALIZE);		break;	case EAP_IDLE:		if (sm->retransWhile == 0)			SM_ENTER(EAP, RETRANSMIT);		else if (eapol_get_bool(sm, EAPOL_eapResp))			SM_ENTER(EAP, RECEIVED);		break;	case EAP_RETRANSMIT:		if (sm->retransCount > sm->MaxRetrans)			SM_ENTER(EAP, TIMEOUT_FAILURE);		else			SM_ENTER(EAP, IDLE);		break;	case EAP_RECEIVED:		if (sm->rxResp && (sm->respId == sm->currentId) &&		    (sm->respMethod == EAP_TYPE_NAK ||		     sm->respMethod == EAP_TYPE_EXPANDED_NAK)		    && (sm->methodState == METHOD_PROPOSED))			SM_ENTER(EAP, NAK);		else if (sm->rxResp && (sm->respId == sm->currentId) &&			 (sm->respMethod == sm->currentMethod))			SM_ENTER(EAP, INTEGRITY_CHECK);		else			SM_ENTER(EAP, DISCARD);		break;	case EAP_DISCARD:		SM_ENTER(EAP, IDLE);		break;	case EAP_SEND_REQUEST:		SM_ENTER(EAP, IDLE);		break;	case EAP_INTEGRITY_CHECK:		if (sm->ignore)			SM_ENTER(EAP, DISCARD);		else			SM_ENTER(EAP, METHOD_RESPONSE);		break;	case EAP_METHOD_REQUEST:		SM_ENTER(EAP, SEND_REQUEST);		break;	case EAP_METHOD_RESPONSE:		if (sm->methodState == METHOD_END)			SM_ENTER(EAP, SELECT_ACTION);		else			SM_ENTER(EAP, METHOD_REQUEST);		break;	case EAP_PROPOSE_METHOD:		SM_ENTER(EAP, METHOD_REQUEST);		break;	case EAP_NAK:		SM_ENTER(EAP, SELECT_ACTION);		break;	case EAP_SELECT_ACTION:		if (sm->decision == DECISION_FAILURE)			SM_ENTER(EAP, FAILURE);		else if (sm->decision == DECISION_SUCCESS)			SM_ENTER(EAP, SUCCESS);		else			SM_ENTER(EAP, PROPOSE_METHOD);		break;	case EAP_TIMEOUT_FAILURE:		break;	case EAP_FAILURE:		break;	case EAP_SUCCESS:		break;	}}static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,				   int eapSRTT, int eapRTTVAR,				   int methodTimeout){	/* For now, retransmission is done in EAPOL state machines, so make	 * sure EAP state machine does not end up trying to retransmit packets.	 */	return 1;}static void eap_sm_parseEapResp(struct eap_sm *sm, u8 *resp, size_t len){	struct eap_hdr *hdr;	size_t plen;	/* parse rxResp, respId, respMethod */	sm->rxResp = FALSE;	sm->respId = -1;	sm->respMethod = EAP_TYPE_NONE;	if (resp == NULL || len < sizeof(*hdr))		return;	hdr = (struct eap_hdr *) resp;	plen = ntohs(hdr->length);	if (plen > len) {		wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "			   "(len=%lu plen=%lu)", (unsigned long) len,			   (unsigned long) plen);		return;	}	sm->respId = hdr->identifier;	if (hdr->code == EAP_CODE_RESPONSE)		sm->rxResp = TRUE;	if (len > sizeof(*hdr))		sm->respMethod = *((u8 *) (hdr + 1));	wpa_printf(MSG_DEBUG, "EAP: parseEapResp: rxResp=%d respId=%d "		   "respMethod=%d", sm->rxResp, sm->respId, sm->respMethod);}static u8 * eap_sm_buildSuccess(struct eap_sm *sm, int id, size_t *len){	struct eap_hdr *resp;	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id);	*len = sizeof(*resp);	resp = malloc(*len);	if (resp == NULL)		return NULL;	resp->code = EAP_CODE_SUCCESS;	resp->identifier = id;	resp->length = htons(*len);	return (u8 *) resp;}static u8 * eap_sm_buildFailure(struct eap_sm *sm, int id, size_t *len){	struct eap_hdr *resp;	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id);	*len = sizeof(*resp);	resp = malloc(*len);	if (resp == NULL)		return NULL;	resp->code = EAP_CODE_FAILURE;	resp->identifier = id;	resp->length = htons(*len);	return (u8 *) resp;}static int eap_sm_nextId(struct eap_sm *sm, int id){	if (id < 0) {		/* RFC 3748 Ch 4.1: recommended to initalize Identifier with a		 * random number */		id = rand() & 0xff;		if (id != sm->lastId)			return id;	}	return (id + 1) & 0xff;}void eap_sm_process_nak(struct eap_sm *sm, u8 *nak_list, size_t len){	int i, j;	wpa_printf(MSG_MSGDUMP, "EAP: processing NAK (current EAP method "		   "index %d)", sm->user_eap_method_index);	wpa_hexdump(MSG_MSGDUMP, "EAP: configured methods",		    sm->user->methods, EAP_MAX_METHODS);	wpa_hexdump(MSG_MSGDUMP, "EAP: list of methods supported by the peer",		    nak_list, len);	i = sm->user_eap_method_index;	while (i < EAP_MAX_METHODS && sm->user->methods[i] != EAP_TYPE_NONE) {		for (j = 0; j < len; j++) {			if (nak_list[j] == sm->user->methods[i]) {				break;			}		}		if (j < len) {			/* found */			i++;			continue;		}		/* not found - remove from the list */		memmove(&sm->user->methods[i], &sm->user->methods[i + 1],			EAP_MAX_METHODS - i - 1);		sm->user->methods[EAP_MAX_METHODS - 1] = EAP_TYPE_NONE;	}	wpa_hexdump(MSG_MSGDUMP, "EAP: new list of configured methods",		    sm->user->methods, EAP_MAX_METHODS);}static void eap_sm_Policy_update(struct eap_sm *sm, u8 *nak_list, size_t len){	if (nak_list == NULL || sm == NULL || sm->user == NULL)		return;	if (sm->user->phase2) {		wpa_printf(MSG_DEBUG, "EAP: EAP-Nak received after Phase2 user"			   " info was selected - reject");		sm->decision = DECISION_FAILURE;		return;	}	eap_sm_process_nak(sm, nak_list, len);}static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm){	EapType next;	/* In theory, there should be no problems with starting	 * re-authentication with something else than EAP-Request/Identity and	 * this does indeed work with wpa_supplicant. However, at least Funk	 * Supplicant seemed to ignore re-auth if it skipped	 * EAP-Request/Identity.	 * Re-auth sets currentId == -1, so that can be used here to select	 * whether Identity needs to be requested again. */	if (sm->identity == NULL || sm->currentId == -1) {		next = EAP_TYPE_IDENTITY;		sm->update_user = TRUE;	} else if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&		   sm->user->methods[sm->user_eap_method_index] !=		   EAP_TYPE_NONE) {		next = sm->user->methods[sm->user_eap_method_index++];	} else {		next = EAP_TYPE_NONE;	}	wpa_printf(MSG_DEBUG, "EAP: getNextMethod: type %d", next);	return next;}static int eap_sm_Policy_getDecision(struct eap_sm *sm){	if (sm->m && sm->currentMethod != EAP_TYPE_IDENTITY &&	    sm->m->isSuccess(sm, sm->eap_method_priv)) {		wpa_printf(MSG_DEBUG, "EAP: getDecision: method succeeded -> "			   "SUCCESS");		sm->update_user = TRUE;		return DECISION_SUCCESS;	}	if (sm->m && sm->m->isDone(sm, sm->eap_method_priv) &&	    !sm->m->isSuccess(sm, sm->eap_method_priv)) {		wpa_printf(MSG_DEBUG, "EAP: getDecision: method failed -> "			   "FAILURE");		sm->update_user = TRUE;		return DECISION_FAILURE;	}	if ((sm->user == NULL || sm->update_user) && sm->identity) {		if (eap_user_get(sm, sm->identity, sm->identity_len, 0) != 0) {			wpa_printf(MSG_DEBUG, "EAP: getDecision: user not "				   "found from database -> FAILURE");			return DECISION_FAILURE;		}		sm->update_user = FALSE;	}	if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&	    sm->user->methods[sm->user_eap_method_index] != EAP_TYPE_NONE) {		wpa_printf(MSG_DEBUG, "EAP: getDecision: another method "			   "available -> CONTINUE");		return DECISION_CONTINUE;	}	if (sm->identity == NULL || sm->currentId == -1) {		wpa_printf(MSG_DEBUG, "EAP: getDecision: no identity known "			   "yet -> CONTINUE");		return DECISION_CONTINUE;	}	wpa_printf(MSG_DEBUG, "EAP: getDecision: no more methods available -> "		   "FAILURE");	return DECISION_FAILURE;}static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method){	return method == EAP_TYPE_IDENTITY ? TRUE : FALSE;}int eap_sm_step(struct eap_sm *sm){	int res = 0;	do {		sm->changed = FALSE;		SM_STEP_RUN(EAP);		if (sm->changed)			res = 1;	} while (sm->changed);	return res;}u8 eap_get_type(const char *name){	int i;	for (i = 0; i < NUM_EAP_METHODS; i++) {		if (strcmp(eap_methods[i]->name, name) == 0)			return eap_methods[i]->method;	}	return EAP_TYPE_NONE;}void eap_set_eapRespData(struct eap_sm *sm, const u8 *eapRespData,			 size_t eapRespDataLen){	if (sm == NULL)		return;	free(sm->eapRespData);	sm->eapRespData = malloc(eapRespDataLen);	if (sm->eapRespData == NULL)		return;	memcpy(sm->eapRespData, eapRespData, eapRespDataLen);	sm->eapRespDataLen = eapRespDataLen;	wpa_hexdump(MSG_MSGDUMP, "EAP: EAP-Response received",		    eapRespData, eapRespDataLen);}static void eap_user_free(struct eap_user *user){	if (user == NULL)		return;	free(user->password);	user->password = NULL;	free(user);}struct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,			    struct eap_config *eap_conf){	struct eap_sm *sm;	sm = malloc(sizeof(*sm));	if (sm == NULL)		return NULL;	memset(sm, 0, sizeof(*sm));	sm->eapol_ctx = eapol_ctx;	sm->eapol_cb = eapol_cb;	sm->MaxRetrans = 10;	sm->ssl_ctx = eap_conf->ssl_ctx;	sm->eap_sim_db_priv = eap_conf->eap_sim_db_priv;	sm->backend_auth = eap_conf->backend_auth;	wpa_printf(MSG_DEBUG, "EAP: State machine created");	return sm;}void eap_sm_deinit(struct eap_sm *sm){	if (sm == NULL)		return;	wpa_printf(MSG_DEBUG, "EAP: State machine removed");	if (sm->m && sm->eap_method_priv)		sm->m->reset(sm, sm->eap_method_priv);	free(sm->eapReqData);	free(sm->eapKeyData);	free(sm->lastReqData);	free(sm->eapRespData);	free(sm->identity);	eap_user_free(sm->user);	free(sm);}void eap_sm_notify_cached(struct eap_sm *sm){	if (sm == NULL)		return;	sm->EAP_state = EAP_SUCCESS;}

⌨️ 快捷键说明

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