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

📄 eap.c

📁 IEEE 802.11a/b/g 服务器端AP
💻 C
📖 第 1 页 / 共 3 页
字号:
					   (unsigned long) plen);				return;			}			sm->respVendor = WPA_GET_BE24(pos);			pos += 3;			sm->respVendorMethod = WPA_GET_BE32(pos);		}	}	wpa_printf(MSG_DEBUG, "EAP: parseEapResp: rxResp=%d respId=%d "		   "respMethod=%u respVendor=%u respVendorMethod=%u",		   sm->rxResp, sm->respId, sm->respMethod, sm->respVendor,		   sm->respVendorMethod);}static int eap_sm_getId(const struct wpabuf *data){	const struct eap_hdr *hdr;	if (data == NULL || wpabuf_len(data) < sizeof(*hdr))		return -1;	hdr = wpabuf_head(data);	wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier);	return hdr->identifier;}static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id){	struct wpabuf *msg;	struct eap_hdr *resp;	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id);	msg = wpabuf_alloc(sizeof(*resp));	if (msg == NULL)		return NULL;	resp = wpabuf_put(msg, sizeof(*resp));	resp->code = EAP_CODE_SUCCESS;	resp->identifier = id;	resp->length = host_to_be16(sizeof(*resp));	return msg;}static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id){	struct wpabuf *msg;	struct eap_hdr *resp;	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id);	msg = wpabuf_alloc(sizeof(*resp));	if (msg == NULL)		return NULL;	resp = wpabuf_put(msg, sizeof(*resp));	resp->code = EAP_CODE_FAILURE;	resp->identifier = id;	resp->length = host_to_be16(sizeof(*resp));	return msg;}static int eap_sm_nextId(struct eap_sm *sm, int id){	if (id < 0) {		/* RFC 3748 Ch 4.1: recommended to initialize Identifier with a		 * random number */		id = rand() & 0xff;		if (id != sm->lastId)			return id;	}	return (id + 1) & 0xff;}/** * eap_sm_process_nak - Process EAP-Response/Nak * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() * @nak_list: Nak list (allowed methods) from the supplicant * @len: Length of nak_list in bytes * * This function is called when EAP-Response/Nak is received from the * supplicant. This can happen for both phase 1 and phase 2 authentications. */void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len){	int i;	size_t j;	if (sm->user == NULL)		return;	wpa_printf(MSG_MSGDUMP, "EAP: processing NAK (current EAP method "		   "index %d)", sm->user_eap_method_index);	wpa_hexdump(MSG_MSGDUMP, "EAP: configured methods",		    (u8 *) sm->user->methods,		    EAP_MAX_METHODS * sizeof(sm->user->methods[0]));	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].vendor != EAP_VENDOR_IETF ||		sm->user->methods[i].method != EAP_TYPE_NONE)) {		if (sm->user->methods[i].vendor != EAP_VENDOR_IETF)			goto not_found;		for (j = 0; j < len; j++) {			if (nak_list[j] == sm->user->methods[i].method) {				break;			}		}		if (j < len) {			/* found */			i++;			continue;		}	not_found:		/* not found - remove from the list */		os_memmove(&sm->user->methods[i], &sm->user->methods[i + 1],			   (EAP_MAX_METHODS - i - 1) *			   sizeof(sm->user->methods[0]));		sm->user->methods[EAP_MAX_METHODS - 1].vendor =			EAP_VENDOR_IETF;		sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE;	}	wpa_hexdump(MSG_MSGDUMP, "EAP: new list of configured methods",		    (u8 *) sm->user->methods, EAP_MAX_METHODS *		    sizeof(sm->user->methods[0]));}static void eap_sm_Policy_update(struct eap_sm *sm, const 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, int *vendor){	EapType next;	int idx = sm->user_eap_method_index;	/* 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) {		*vendor = EAP_VENDOR_IETF;		next = EAP_TYPE_IDENTITY;		sm->update_user = TRUE;	} else if (sm->user && idx < EAP_MAX_METHODS &&		   (sm->user->methods[idx].vendor != EAP_VENDOR_IETF ||		    sm->user->methods[idx].method != EAP_TYPE_NONE)) {		*vendor = sm->user->methods[idx].vendor;		next = sm->user->methods[idx].method;		sm->user_eap_method_index++;	} else {		*vendor = EAP_VENDOR_IETF;		next = EAP_TYPE_NONE;	}	wpa_printf(MSG_DEBUG, "EAP: getNextMethod: vendor %d type %d",		   *vendor, next);	return next;}static int eap_sm_Policy_getDecision(struct eap_sm *sm){	if (!sm->eap_server && sm->identity) {		wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH");		return DECISION_PASSTHROUGH;	}	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].vendor !=	     EAP_VENDOR_IETF ||	     sm->user->methods[sm->user_eap_method_index].method !=	     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;}/** * eap_server_sm_step - Step EAP server state machine * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() * Returns: 1 if EAP state was changed or 0 if not * * This function advances EAP state machine to a new state to match with the * current variables. This should be called whenever variables used by the EAP * state machine have changed. */int eap_server_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;}static void eap_user_free(struct eap_user *user){	if (user == NULL)		return;	os_free(user->password);	user->password = NULL;	os_free(user);}/** * eap_server_sm_init - Allocate and initialize EAP server state machine * @eapol_ctx: Context data to be used with eapol_cb calls * @eapol_cb: Pointer to EAPOL callback functions * @conf: EAP configuration * Returns: Pointer to the allocated EAP state machine or %NULL on failure * * This function allocates and initializes an EAP state machine. */struct eap_sm * eap_server_sm_init(void *eapol_ctx,				   struct eapol_callbacks *eapol_cb,				   struct eap_config *conf){	struct eap_sm *sm;	sm = os_zalloc(sizeof(*sm));	if (sm == NULL)		return NULL;	sm->eapol_ctx = eapol_ctx;	sm->eapol_cb = eapol_cb;	sm->MaxRetrans = 10;	sm->ssl_ctx = conf->ssl_ctx;	sm->eap_sim_db_priv = conf->eap_sim_db_priv;	sm->backend_auth = conf->backend_auth;	sm->eap_server = conf->eap_server;	if (conf->pac_opaque_encr_key) {		sm->pac_opaque_encr_key = os_malloc(16);		if (sm->pac_opaque_encr_key) {			os_memcpy(sm->pac_opaque_encr_key,				  conf->pac_opaque_encr_key, 16);		}	}	if (conf->eap_fast_a_id)		sm->eap_fast_a_id = os_strdup(conf->eap_fast_a_id);	sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;	sm->tnc = conf->tnc;	wpa_printf(MSG_DEBUG, "EAP: Server state machine created");	return sm;}/** * eap_server_sm_deinit - Deinitialize and free an EAP server state machine * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() * * This function deinitializes EAP state machine and frees all allocated * resources. */void eap_server_sm_deinit(struct eap_sm *sm){	if (sm == NULL)		return;	wpa_printf(MSG_DEBUG, "EAP: Server state machine removed");	if (sm->m && sm->eap_method_priv)		sm->m->reset(sm, sm->eap_method_priv);	wpabuf_free(sm->eap_if.eapReqData);	os_free(sm->eap_if.eapKeyData);	os_free(sm->lastReqData);	wpabuf_free(sm->eap_if.eapRespData);	os_free(sm->identity);	os_free(sm->pac_opaque_encr_key);	os_free(sm->eap_fast_a_id);	wpabuf_free(sm->eap_if.aaaEapReqData);	wpabuf_free(sm->eap_if.aaaEapRespData);	os_free(sm->eap_if.aaaEapKeyData);	eap_user_free(sm->user);	os_free(sm);}/** * eap_sm_notify_cached - Notify EAP state machine of cached PMK * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() * * This function is called when PMKSA caching is used to skip EAP * authentication. */void eap_sm_notify_cached(struct eap_sm *sm){	if (sm == NULL)		return;	sm->EAP_state = EAP_SUCCESS;}/** * eap_sm_pending_cb - EAP state machine callback for a pending EAP request * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() * * This function is called when data for a pending EAP-Request is received. */void eap_sm_pending_cb(struct eap_sm *sm){	if (sm == NULL)		return;	wpa_printf(MSG_DEBUG, "EAP: Callback for pending request received");	if (sm->method_pending == METHOD_PENDING_WAIT)		sm->method_pending = METHOD_PENDING_CONT;}/** * eap_sm_method_pending - Query whether EAP method is waiting for pending data * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() * Returns: 1 if method is waiting for pending data or 0 if not */int eap_sm_method_pending(struct eap_sm *sm){	if (sm == NULL)		return 0;	return sm->method_pending == METHOD_PENDING_WAIT;}/** * eap_get_identity - Get the user identity (from EAP-Response/Identity) * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() * @len: Buffer for returning identity length * Returns: Pointer to the user identity or %NULL if not available */const u8 * eap_get_identity(struct eap_sm *sm, size_t *len){	*len = sm->identity_len;	return sm->identity;}/** * eap_get_interface - Get pointer to EAP-EAPOL interface data * @sm: Pointer to EAP state machine allocated with eap_server_sm_init() * Returns: Pointer to the EAP-EAPOL interface data */struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm){	return &sm->eap_if;}

⌨️ 快捷键说明

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