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

📄 eap_fast.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 4 页
字号:
		wpa_printf(MSG_INFO, "EAP-FAST: Failed to decrypt Phase 2 "			   "data");		os_free(in_decrypted);		return -1;	}	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Decrypted Phase 2 TLV(s)",		    in_decrypted, len_decrypted);	if (len_decrypted < 4) {		os_free(in_decrypted);		wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "			   "TLV frame (len=%d)", len_decrypted);		return -1;	}	pos = in_decrypted;	end = in_decrypted + len_decrypted;	stop = 0;	while (pos + 4 < end && !stop) {		mandatory = pos[0] & 0x80;		tlv_type = WPA_GET_BE16(pos) & 0x3fff;		pos += 2;		len = WPA_GET_BE16(pos);		pos += 2;		if (pos + len > end) {			os_free(in_decrypted);			wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow");			return 0;		}		wpa_printf(MSG_DEBUG, "EAP-FAST: received Phase 2: "			   "TLV type %d length %d%s",			   tlv_type, len, mandatory ? " (mandatory)" : "");		switch (tlv_type) {		case EAP_TLV_EAP_PAYLOAD_TLV:			wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: EAP Payload TLV",				    pos, len);			eap_payload_tlv = pos;			eap_payload_tlv_len = len;			break;		case EAP_TLV_RESULT_TLV:			wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Result TLV",				    pos, len);			if (len < 2) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "					   "Result TLV");				result = EAP_TLV_RESULT_FAILURE;				break;			}			result = WPA_GET_BE16(pos);			if (result != EAP_TLV_RESULT_SUCCESS &&			    result != EAP_TLV_RESULT_FAILURE) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown "					   "Result %d", result);				result = EAP_TLV_RESULT_FAILURE;			}			wpa_printf(MSG_DEBUG, "EAP-FAST: Result: %s",				   result == EAP_TLV_RESULT_SUCCESS ?				   "Success" : "Failure");			break;		case EAP_TLV_INTERMEDIATE_RESULT_TLV:			wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Intermediate "				    "Result TLV", pos, len);			if (len < 2) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "					   "Intermediate Result TLV");				iresult = EAP_TLV_RESULT_FAILURE;				break;			}			iresult = WPA_GET_BE16(pos);			if (iresult != EAP_TLV_RESULT_SUCCESS &&			    iresult != EAP_TLV_RESULT_FAILURE) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown "					   "Intermediate Result %d", iresult);				iresult = EAP_TLV_RESULT_FAILURE;			}			wpa_printf(MSG_DEBUG,				   "EAP-FAST: Intermediate Result: %s",				   iresult == EAP_TLV_RESULT_SUCCESS ?				   "Success" : "Failure");			break;		case EAP_TLV_CRYPTO_BINDING_TLV_:			wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding "				    "TLV", pos, len);			crypto_binding_len = sizeof(struct eap_tlv_hdr) + len;			if (crypto_binding_len < sizeof(*crypto_binding)) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "					   "Crypto-Binding TLV");				iresult = EAP_TLV_RESULT_FAILURE;				pos = end;				break;			}			crypto_binding =				(struct eap_tlv_crypto_binding__tlv *)				(pos - sizeof(struct eap_tlv_hdr));			break;		case EAP_TLV_PAC_TLV:			wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: PAC TLV",				    pos, len);			pac = pos;			pac_len = len;			break;		default:			if (mandatory) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown "					   "mandatory TLV type %d", tlv_type);				resp = eap_fast_tlv_nak(0, tlv_type,							&resp_len);				stop = 1;			} else {				wpa_printf(MSG_DEBUG, "EAP-FAST: ignored "					   "unknown optional TLV type %d",					   tlv_type);			}			break;		}		pos += len;	}	if (!resp && result == EAP_TLV_RESULT_FAILURE) {		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,					   &resp_len);		if (!resp) {			os_free(in_decrypted);			return 0;		}	}	if (!resp && iresult == EAP_TLV_RESULT_FAILURE) {		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,					   &resp_len);		if (!resp) {			os_free(in_decrypted);			return 0;		}	}	if (!resp && eap_payload_tlv) {		if (eap_payload_tlv_len < sizeof(*hdr)) {			wpa_printf(MSG_DEBUG, "EAP-FAST: too short EAP "				   "Payload TLV (len=%lu)",				   (unsigned long) eap_payload_tlv_len);			os_free(in_decrypted);			return 0;		}		hdr = (struct eap_hdr *) eap_payload_tlv;		if (be_to_host16(hdr->length) > eap_payload_tlv_len) {			wpa_printf(MSG_DEBUG, "EAP-FAST: EAP packet overflow "				   "in EAP Payload TLV");			os_free(in_decrypted);			return 0;		}		if (hdr->code == EAP_CODE_REQUEST) {			if (eap_fast_phase2_request(sm, data, ret, hdr,						    &resp, &resp_len)) {				os_free(in_decrypted);				wpa_printf(MSG_INFO, "EAP-FAST: Phase2 "					   "Request processing failed");				return 0;			}			resp = eap_fast_tlv_eap_payload(resp, &resp_len);			if (resp == NULL) {				os_free(in_decrypted);				return 0;			}		} else {			wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in "				   "Phase 2 EAP header", hdr->code);			os_free(in_decrypted);			return 0;		}	}	if (!resp && crypto_binding) {		int final = result == EAP_TLV_RESULT_SUCCESS;		resp = eap_fast_process_crypto_binding(sm, data, ret,						       crypto_binding,						       crypto_binding_len,						       &resp_len, final);		if (!resp) {			os_free(in_decrypted);			return 0;		}	}	if (!resp && pac && result != EAP_TLV_RESULT_SUCCESS) {		wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV without Result TLV "			   "acknowledging success");		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,					   &resp_len);		if (!resp) {			os_free(in_decrypted);			return 0;		}	}	if (!resp && pac && result == EAP_TLV_RESULT_SUCCESS) {		resp = eap_fast_process_pac(sm, data, ret, pac, pac_len,					    &resp_len);		if (!resp) {			os_free(in_decrypted);			return 0;		}	}	os_free(in_decrypted);	if (resp == NULL) {		wpa_printf(MSG_DEBUG, "EAP-FAST: No recognized TLVs - send "			   "empty response packet");		resp = os_malloc(1);		if (resp == NULL)			return 0;		resp_len = 0;	}	wpa_hexdump(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 data",		    resp, resp_len);	if (eap_fast_encrypt(sm, data, req->identifier, resp, resp_len,			     out_data, out_len)) {		wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt a Phase 2 "			   "frame");	}	os_free(resp);	return 0;}static u8 * eap_fast_process(struct eap_sm *sm, void *priv,			     struct eap_method_ret *ret,			     const u8 *reqData, size_t reqDataLen,			     size_t *respDataLen){	const struct eap_hdr *req;	size_t left;	int res;	u8 flags, *resp, id;	const u8 *pos;	struct eap_fast_data *data = priv;	pos = eap_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret,				   reqData, reqDataLen, &left, &flags);	if (pos == NULL)		return NULL;	req = (const struct eap_hdr *) reqData;	id = req->identifier;	if (flags & EAP_TLS_FLAGS_START) {		const u8 *a_id;		size_t a_id_len;		struct pac_tlv_hdr *hdr;		wpa_printf(MSG_DEBUG, "EAP-FAST: Start (server ver=%d, own "			   "ver=%d)", flags & EAP_PEAP_VERSION_MASK,			data->fast_version);		if ((flags & EAP_PEAP_VERSION_MASK) < data->fast_version)			data->fast_version = flags & EAP_PEAP_VERSION_MASK;		wpa_printf(MSG_DEBUG, "EAP-FAST: Using FAST version %d",			   data->fast_version);		a_id = pos;		a_id_len = left;		if (left > sizeof(*hdr)) {			int tlen;			hdr = (struct pac_tlv_hdr *) pos;			tlen = be_to_host16(hdr->len);			if (be_to_host16(hdr->type) == PAC_TYPE_A_ID &&			    sizeof(*hdr) + tlen <= left) {				a_id = (u8 *) (hdr + 1);				a_id_len = tlen;			}		}		wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: A-ID", a_id, a_id_len);		data->current_pac = eap_fast_get_pac(data, a_id, a_id_len);		if (data->current_pac) {			wpa_printf(MSG_DEBUG, "EAP-FAST: PAC found for this "				   "A-ID");			wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-FAST: A-ID-Info",					  data->current_pac->a_id_info,					  data->current_pac->a_id_info_len);		}		if (data->resuming && data->current_pac) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Trying to resume "				   "session - do not add PAC-Opaque to TLS "				   "ClientHello");			if (tls_connection_client_hello_ext(				    sm->ssl_ctx, data->ssl.conn,				    TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "					   "remove PAC-Opaque TLS extension");				return NULL;			}		} else if (data->current_pac) {			u8 *tlv;			size_t tlv_len, olen;			struct eap_tlv_hdr *ehdr;			olen = data->current_pac->pac_opaque_len;			tlv_len = sizeof(*ehdr) + olen;			tlv = os_malloc(tlv_len);			if (tlv) {				ehdr = (struct eap_tlv_hdr *) tlv;				ehdr->tlv_type =					host_to_be16(PAC_TYPE_PAC_OPAQUE);				ehdr->length = host_to_be16(olen);				os_memcpy(ehdr + 1,					  data->current_pac->pac_opaque, olen);			}			if (tlv == NULL ||			    tls_connection_client_hello_ext(				    sm->ssl_ctx, data->ssl.conn,				    TLS_EXT_PAC_OPAQUE, tlv, tlv_len) < 0) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "					   "add PAC-Opaque TLS extension");				os_free(tlv);				return NULL;			}			os_free(tlv);		} else {			u8 ciphers[2];			if (!data->provisioning_allowed) {				wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found "					   "and provisioning disabled");				return NULL;			}			wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found - "				   "starting provisioning");			ciphers[0] = TLS_CIPHER_ANON_DH_AES128_SHA;			ciphers[1] = TLS_CIPHER_NONE;			if (tls_connection_set_cipher_list(sm->ssl_ctx,							   data->ssl.conn,							   ciphers)) {				wpa_printf(MSG_INFO, "EAP-FAST: Could not "					   "configure anonymous DH for TLS "					   "connection");				return NULL;			}			if (tls_connection_client_hello_ext(				    sm->ssl_ctx, data->ssl.conn,				    TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "					   "remove PAC-Opaque TLS extension");				return NULL;			}			data->provisioning = 1;		}		left = 0; /* A-ID is not used in further packet processing */	}	resp = NULL;	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&	    !data->resuming) {		res = eap_fast_decrypt(sm, data, ret, req, pos, left,				       &resp, respDataLen);		if (res < 0) {			ret->methodState = METHOD_DONE;			ret->decision = DECISION_FAIL;			/* Ack possible Alert that may have caused failure in			 * decryption */			res = 1;		}	} else {		if (eap_fast_set_tls_master_secret(sm, data, pos, left) < 0) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to configure "				   "TLS master secret");			ret->methodState = METHOD_DONE;			ret->decision = DECISION_FAIL;			return NULL;		}		res = eap_tls_process_helper(sm, &data->ssl, EAP_TYPE_FAST,					     data->fast_version, id, pos, left,					     &resp, respDataLen);		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {			wpa_printf(MSG_DEBUG,				   "EAP-FAST: TLS done, proceed to Phase 2");			data->resuming = 0;			eap_fast_derive_keys(sm, data);		}	}	if (res == 1)		return eap_tls_build_ack(&data->ssl, respDataLen, id,					 EAP_TYPE_FAST, data->fast_version);	return resp;}#if 0 /* FIX */static Boolean eap_fast_has_reauth_data(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	return tls_connection_established(sm->ssl_ctx, data->ssl.conn);}static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	os_free(data->key_block_p);	data->key_block_p = NULL;}static void * eap_fast_init_for_reauth(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	if (eap_tls_reauth_init(sm, &data->ssl)) {		os_free(data);		return NULL;	}	if (data->phase2_priv && data->phase2_method &&	    data->phase2_method->init_for_reauth)		data->phase2_method->init_for_reauth(sm, data->phase2_priv);	data->phase2_success = 0;	data->resuming = 1;	data->provisioning = 0;	data->simck_idx = 0;	return priv;}#endifstatic int eap_fast_get_status(struct eap_sm *sm, void *priv, char *buf,			       size_t buflen, int verbose){	struct eap_fast_data *data = priv;	int len, ret;	len = eap_tls_status(sm, &data->ssl, buf, buflen, verbose);	if (data->phase2_method) {		ret = os_snprintf(buf + len, buflen - len,				  "EAP-FAST Phase2 method=%s\n",				  data->phase2_method->name);		if (ret < 0 || (size_t) ret >= buflen - len)			return len;		len += ret;	}	return len;}static Boolean eap_fast_isKeyAvailable(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	return data->success;}static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len){	struct eap_fast_data *data = priv;	u8 *key;	if (!data->success)		return NULL;	key = os_malloc(EAP_FAST_KEY_LEN);	if (key == NULL)		return NULL;	*len = EAP_FAST_KEY_LEN;	os_memcpy(key, data->key_data, EAP_FAST_KEY_LEN);	return key;}static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len){	struct eap_fast_data *data = priv;	u8 *key;	if (!data->success)		return NULL;	key = os_malloc(EAP_EMSK_LEN);	if (key == NULL)		return NULL;	*len = EAP_EMSK_LEN;	os_memcpy(key, data->emsk, EAP_EMSK_LEN);	return key;}int eap_peer_fast_register(void){	struct eap_method *eap;	int ret;	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,				    EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST");	if (eap == NULL)		return -1;	eap->init = eap_fast_init;	eap->deinit = eap_fast_deinit;	eap->process = eap_fast_process;	eap->isKeyAvailable = eap_fast_isKeyAvailable;	eap->getKey = eap_fast_getKey;	eap->get_status = eap_fast_get_status;#if 0	eap->has_reauth_data = eap_fast_has_reauth_data;	eap->deinit_for_reauth = eap_fast_deinit_for_reauth;	eap->init_for_reauth = eap_fast_init_for_reauth;#endif	eap->get_emsk = eap_fast_get_emsk;	ret = eap_peer_method_register(eap);	if (ret)		eap_peer_method_free(eap);	return ret;}

⌨️ 快捷键说明

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