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

📄 eap_peap.c

📁 IEEE 802.11a/b/g 服务器端AP
💻 C
📖 第 1 页 / 共 3 页
字号:
	encr_req = eap_server_tls_encrypt(sm, &data->ssl, (u8 *) hdr, req_len);	os_free(hdr);	return encr_req;}static struct wpabuf * eap_peap_buildReq(struct eap_sm *sm, void *priv, u8 id){	struct eap_peap_data *data = priv;	if (data->ssl.state == FRAG_ACK) {		return eap_server_tls_build_ack(id, EAP_TYPE_PEAP,						data->peap_version);	}	if (data->ssl.state == WAIT_FRAG_ACK) {		return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_PEAP,						data->peap_version, id);	}	switch (data->state) {	case START:		return eap_peap_build_start(sm, data, id);	case PHASE1:	case PHASE1_ID2:		if (data->peap_version < 2 &&		    tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {			wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase1 done, "				   "starting Phase2");			eap_peap_state(data, PHASE2_START);		}		break;	case PHASE2_ID:	case PHASE2_METHOD:		wpabuf_free(data->ssl.out_buf);		data->ssl.out_used = 0;		data->ssl.out_buf = eap_peap_build_phase2_req(sm, data, id);		break;#ifdef EAP_TNC	case PHASE2_SOH:		wpabuf_free(data->ssl.out_buf);		data->ssl.out_used = 0;		data->ssl.out_buf = eap_peap_build_phase2_soh(sm, data, id);		break;#endif /* EAP_TNC */	case PHASE2_TLV:		wpabuf_free(data->ssl.out_buf);		data->ssl.out_used = 0;		data->ssl.out_buf = eap_peap_build_phase2_tlv(sm, data, id);		break;	case SUCCESS_REQ:		wpabuf_free(data->ssl.out_buf);		data->ssl.out_used = 0;		data->ssl.out_buf = eap_peap_build_phase2_term(sm, data, id,							       1);		break;	case FAILURE_REQ:		wpabuf_free(data->ssl.out_buf);		data->ssl.out_used = 0;		data->ssl.out_buf = eap_peap_build_phase2_term(sm, data, id,							       0);		break;	default:		wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d",			   __func__, data->state);		return NULL;	}	return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_PEAP,					data->peap_version, id);}static Boolean eap_peap_check(struct eap_sm *sm, void *priv,			      struct wpabuf *respData){	const u8 *pos;	size_t len;	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PEAP, respData, &len);	if (pos == NULL || len < 1) {		wpa_printf(MSG_INFO, "EAP-PEAP: Invalid frame");		return TRUE;	}	return FALSE;}static int eap_peap_phase2_init(struct eap_sm *sm, struct eap_peap_data *data,				EapType eap_type){	if (data->phase2_priv && data->phase2_method) {		data->phase2_method->reset(sm, data->phase2_priv);		data->phase2_method = NULL;		data->phase2_priv = NULL;	}	data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,							eap_type);	if (!data->phase2_method)		return -1;	sm->init_phase2 = 1;	data->phase2_priv = data->phase2_method->init(sm);	sm->init_phase2 = 0;	return 0;}static int eap_tlv_validate_cryptobinding(struct eap_sm *sm,					  struct eap_peap_data *data,					  const u8 *crypto_tlv,					  size_t crypto_tlv_len){	u8 buf[61], mac[SHA1_MAC_LEN];	const u8 *pos;	if (crypto_tlv_len != 4 + 56) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid cryptobinding TLV "			   "length %d", (int) crypto_tlv_len);		return -1;	}	pos = crypto_tlv;	pos += 4; /* TLV header */	if (pos[1] != data->peap_version) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Cryptobinding TLV Version "			   "mismatch (was %d; expected %d)",			   pos[1], data->peap_version);		return -1;	}	if (pos[3] != 1) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Unexpected Cryptobinding TLV "			   "SubType %d", pos[3]);		return -1;	}	pos += 4;	pos += 32; /* Nonce */	/* Compound_MAC: HMAC-SHA1-160(cryptobinding TLV | EAP type) */	os_memcpy(buf, crypto_tlv, 60);	os_memset(buf + 4 + 4 + 32, 0, 20); /* Compound_MAC */	buf[60] = EAP_TYPE_PEAP;	hmac_sha1(data->cmk, 20, buf, sizeof(buf), mac);	if (os_memcmp(mac, pos, SHA1_MAC_LEN) != 0) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid Compound_MAC in "			   "cryptobinding TLV");		wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK", data->cmk, 20);		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Cryptobinding seed data",			    buf, 61);		return -1;	}	wpa_printf(MSG_DEBUG, "EAP-PEAP: Valid cryptobinding TLV received");	return 0;}static void eap_peap_process_phase2_tlv(struct eap_sm *sm,					struct eap_peap_data *data,					struct wpabuf *in_data){	const u8 *pos;	size_t left;	const u8 *result_tlv = NULL, *crypto_tlv = NULL;	size_t result_tlv_len = 0, crypto_tlv_len = 0;	int tlv_type, mandatory, tlv_len;	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TLV, in_data, &left);	if (pos == NULL) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid EAP-TLV header");		return;	}	/* Parse TLVs */	wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Received TLVs", pos, left);	while (left >= 4) {		mandatory = !!(pos[0] & 0x80);		tlv_type = pos[0] & 0x3f;		tlv_type = (tlv_type << 8) | pos[1];		tlv_len = ((int) pos[2] << 8) | pos[3];		pos += 4;		left -= 4;		if ((size_t) tlv_len > left) {			wpa_printf(MSG_DEBUG, "EAP-PEAP: TLV underrun "				   "(tlv_len=%d left=%lu)", tlv_len,				   (unsigned long) left);			eap_peap_state(data, FAILURE);			return;		}		switch (tlv_type) {		case EAP_TLV_RESULT_TLV:			result_tlv = pos;			result_tlv_len = tlv_len;			break;		case EAP_TLV_CRYPTO_BINDING_TLV:			crypto_tlv = pos;			crypto_tlv_len = tlv_len;			break;		default:			wpa_printf(MSG_DEBUG, "EAP-PEAP: Unsupported TLV Type "				   "%d%s", tlv_type,				   mandatory ? " (mandatory)" : "");			if (mandatory) {				eap_peap_state(data, FAILURE);				return;			}			/* Ignore this TLV, but process other TLVs */			break;		}		pos += tlv_len;		left -= tlv_len;	}	if (left) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Last TLV too short in "			   "Request (left=%lu)", (unsigned long) left);		eap_peap_state(data, FAILURE);		return;	}	/* Process supported TLVs */	if (crypto_tlv && data->crypto_binding_sent) {		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Cryptobinding TLV",			    crypto_tlv, crypto_tlv_len);		if (eap_tlv_validate_cryptobinding(sm, data, crypto_tlv - 4,						   crypto_tlv_len + 4) < 0) {			eap_peap_state(data, FAILURE);			return;		}		data->crypto_binding_used = 1;	} else if (!crypto_tlv && data->crypto_binding_sent &&		   data->crypto_binding == REQUIRE_BINDING) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: No cryptobinding TLV");		eap_peap_state(data, FAILURE);		return;	}	if (result_tlv) {		int status;		const char *requested;		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Result TLV",			    result_tlv, result_tlv_len);		if (result_tlv_len < 2) {			wpa_printf(MSG_INFO, "EAP-PEAP: Too short Result TLV "				   "(len=%lu)",				   (unsigned long) result_tlv_len);			eap_peap_state(data, FAILURE);			return;		}		requested = data->tlv_request == TLV_REQ_SUCCESS ? "Success" :			"Failure";		status = WPA_GET_BE16(result_tlv);		if (status == EAP_TLV_RESULT_SUCCESS) {			wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Success "				   "- requested %s", requested);			if (data->tlv_request == TLV_REQ_SUCCESS)				eap_peap_state(data, SUCCESS);			else				eap_peap_state(data, FAILURE);					} else if (status == EAP_TLV_RESULT_FAILURE) {			wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Failure "				   "- requested %s", requested);			eap_peap_state(data, FAILURE);		} else {			wpa_printf(MSG_INFO, "EAP-PEAP: Unknown TLV Result "				   "Status %d", status);			eap_peap_state(data, FAILURE);		}	}}#ifdef EAP_TNCstatic void eap_peap_process_phase2_soh(struct eap_sm *sm,					struct eap_peap_data *data,					struct wpabuf *in_data){	const u8 *pos, *vpos;	size_t left;	const u8 *soh_tlv = NULL;	size_t soh_tlv_len = 0;	int tlv_type, mandatory, tlv_len, vtlv_len;	u8 next_type;	u32 vendor_id;	pos = eap_hdr_validate(EAP_VENDOR_MICROSOFT, 0x21, in_data, &left);	if (pos == NULL) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Not a valid SoH EAP "			   "Extensions Method header - skip TNC");		goto auth_method;	}	/* Parse TLVs */	wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Received TLVs (SoH)", pos, left);	while (left >= 4) {		mandatory = !!(pos[0] & 0x80);		tlv_type = pos[0] & 0x3f;		tlv_type = (tlv_type << 8) | pos[1];		tlv_len = ((int) pos[2] << 8) | pos[3];		pos += 4;		left -= 4;		if ((size_t) tlv_len > left) {			wpa_printf(MSG_DEBUG, "EAP-PEAP: TLV underrun "				   "(tlv_len=%d left=%lu)", tlv_len,				   (unsigned long) left);			eap_peap_state(data, FAILURE);			return;		}		switch (tlv_type) {		case EAP_TLV_VENDOR_SPECIFIC_TLV:			if (tlv_len < 4) {				wpa_printf(MSG_DEBUG, "EAP-PEAP: Too short "					   "vendor specific TLV (len=%d)",					   (int) tlv_len);				eap_peap_state(data, FAILURE);				return;			}			vendor_id = WPA_GET_BE32(pos);			if (vendor_id != EAP_VENDOR_MICROSOFT) {				if (mandatory) {					eap_peap_state(data, FAILURE);					return;				}				break;			}			vpos = pos + 4;			mandatory = !!(vpos[0] & 0x80);			tlv_type = vpos[0] & 0x3f;			tlv_type = (tlv_type << 8) | vpos[1];			vtlv_len = ((int) vpos[2] << 8) | vpos[3];			vpos += 4;			if (vpos + vtlv_len > pos + left) {				wpa_printf(MSG_DEBUG, "EAP-PEAP: Vendor TLV "					   "underrun");				eap_peap_state(data, FAILURE);				return;			}			if (tlv_type == 1) {				soh_tlv = vpos;				soh_tlv_len = vtlv_len;				break;			}			wpa_printf(MSG_DEBUG, "EAP-PEAP: Unsupported MS-TLV "				   "Type %d%s", tlv_type,				   mandatory ? " (mandatory)" : "");			if (mandatory) {				eap_peap_state(data, FAILURE);				return;			}			/* Ignore this TLV, but process other TLVs */			break;		default:			wpa_printf(MSG_DEBUG, "EAP-PEAP: Unsupported TLV Type "				   "%d%s", tlv_type,				   mandatory ? " (mandatory)" : "");			if (mandatory) {				eap_peap_state(data, FAILURE);				return;			}			/* Ignore this TLV, but process other TLVs */			break;		}		pos += tlv_len;		left -= tlv_len;	}	if (left) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Last TLV too short in "			   "Request (left=%lu)", (unsigned long) left);		eap_peap_state(data, FAILURE);		return;	}	/* Process supported TLVs */	if (soh_tlv) {		int failure = 0;		wpabuf_free(data->soh_response);		data->soh_response = tncs_process_soh(soh_tlv, soh_tlv_len,						      &failure);		if (failure) {			eap_peap_state(data, FAILURE);			return;		}	} else {		wpa_printf(MSG_DEBUG, "EAP-PEAP: No SoH TLV received");		eap_peap_state(data, FAILURE);		return;	}auth_method:	eap_peap_state(data, PHASE2_METHOD);	next_type = sm->user->methods[0].method;	sm->user_eap_method_index = 1;	wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d", next_type);	eap_peap_phase2_init(sm, data, next_type);}#endif /* EAP_TNC */static void eap_peap_process_phase2_response(struct eap_sm *sm,					     struct eap_peap_data *data,					     struct wpabuf *in_data){	u8 next_type = EAP_TYPE_NONE;	const struct eap_hdr *hdr;	const u8 *pos;	size_t left;	if (data->state == PHASE2_TLV) {		eap_peap_process_phase2_tlv(sm, data, in_data);		return;	}#ifdef EAP_TNC	if (data->state == PHASE2_SOH) {		eap_peap_process_phase2_soh(sm, data, in_data);		return;	}#endif /* EAP_TNC */	if (data->phase2_priv == NULL) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - Phase2 not "			   "initialized?!", __func__);		return;	}	hdr = wpabuf_head(in_data);	pos = (const u8 *) (hdr + 1);	if (wpabuf_len(in_data) > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {		left = wpabuf_len(in_data) - sizeof(*hdr);		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Phase2 type Nak'ed; "			    "allowed types", pos + 1, left - 1);		eap_sm_process_nak(sm, pos + 1, left - 1);		if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&		    sm->user->methods[sm->user_eap_method_index].method !=		    EAP_TYPE_NONE) {			next_type = sm->user->methods[				sm->user_eap_method_index++].method;			wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d",				   next_type);		} else {			eap_peap_req_failure(sm, data);			next_type = EAP_TYPE_NONE;		}		eap_peap_phase2_init(sm, data, next_type);		return;	}	if (data->phase2_method->check(sm, data->phase2_priv, in_data)) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 check() asked to "			   "ignore the packet");		return;	}	data->phase2_method->process(sm, data->phase2_priv, in_data);	if (sm->method_pending == METHOD_PENDING_WAIT) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method is in "			   "pending wait state - save decrypted response");		wpabuf_free(data->pending_phase2_resp);		data->pending_phase2_resp = wpabuf_dup(in_data);	}	if (!data->phase2_method->isDone(sm, data->phase2_priv))		return;

⌨️ 快捷键说明

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