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

📄 eap_ttls.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	switch (phase2_type) {	case EAP_TTLS_PHASE2_EAP:		res = eap_ttls_phase2_request_eap(sm, data, ret, hdr, resp);		break;	case EAP_TTLS_PHASE2_MSCHAPV2:		res = eap_ttls_phase2_request_mschapv2(sm, data, ret, resp);		break;	case EAP_TTLS_PHASE2_MSCHAP:		res = eap_ttls_phase2_request_mschap(sm, data, ret, resp);		break;	case EAP_TTLS_PHASE2_PAP:		res = eap_ttls_phase2_request_pap(sm, data, ret, resp);		break;	case EAP_TTLS_PHASE2_CHAP:		res = eap_ttls_phase2_request_chap(sm, data, ret, resp);		break;	default:		wpa_printf(MSG_ERROR, "EAP-TTLS: Phase 2 - Unknown");		res = -1;		break;	}	if (res < 0) {		ret->methodState = METHOD_DONE;		ret->decision = DECISION_FAIL;	}	return res;}#if EAP_TTLS_VERSION > 0static struct wpabuf * eap_ttls_build_phase_finished(	struct eap_sm *sm, struct eap_ttls_data *data, int id, int final){	int len;	struct wpabuf *req;	u8 *pos;	const int max_len = 300;	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1 + max_len,			    EAP_CODE_RESPONSE, id);	if (req == NULL)		return NULL;	wpabuf_put_u8(req, data->ttls_version);	pos = wpabuf_put(req, 0);	len = tls_connection_ia_send_phase_finished(sm->ssl_ctx,						    data->ssl.conn,						    final, pos, max_len);	if (len < 0) {		wpabuf_free(req);		return NULL;	}	wpabuf_put(req, len);	eap_update_len(req);	return req;}#endif /* EAP_TTLS_VERSION */struct ttls_parse_avp {	u8 *mschapv2;	u8 *eapdata;	size_t eap_len;	int mschapv2_error;};static int eap_ttls_parse_attr_eap(const u8 *dpos, size_t dlen,				   struct ttls_parse_avp *parse){	wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");	if (parse->eapdata == NULL) {		parse->eapdata = os_malloc(dlen);		if (parse->eapdata == NULL) {			wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "				   "memory for Phase 2 EAP data");			return -1;		}		os_memcpy(parse->eapdata, dpos, dlen);		parse->eap_len = dlen;	} else {		u8 *neweap = os_realloc(parse->eapdata, parse->eap_len + dlen);		if (neweap == NULL) {			wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "				   "memory for Phase 2 EAP data");			return -1;		}		os_memcpy(neweap + parse->eap_len, dpos, dlen);		parse->eapdata = neweap;		parse->eap_len += dlen;	}	return 0;}static int eap_ttls_parse_avp(u8 *pos, size_t left,			      struct ttls_parse_avp *parse){	struct ttls_avp *avp;	u32 avp_code, avp_length, vendor_id = 0;	u8 avp_flags, *dpos;	size_t dlen;	avp = (struct ttls_avp *) pos;	avp_code = be_to_host32(avp->avp_code);	avp_length = be_to_host32(avp->avp_length);	avp_flags = (avp_length >> 24) & 0xff;	avp_length &= 0xffffff;	wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "		   "length=%d", (int) avp_code, avp_flags,		   (int) avp_length);	if (avp_length > left) {		wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "			   "(len=%d, left=%lu) - dropped",			   (int) avp_length, (unsigned long) left);		return -1;	}	if (avp_length < sizeof(*avp)) {		wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length %d",			   avp_length);		return -1;	}	dpos = (u8 *) (avp + 1);	dlen = avp_length - sizeof(*avp);	if (avp_flags & AVP_FLAGS_VENDOR) {		if (dlen < 4) {			wpa_printf(MSG_WARNING, "EAP-TTLS: Vendor AVP "				   "underflow");			return -1;		}		vendor_id = WPA_GET_BE32(dpos);		wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",			   (int) vendor_id);		dpos += 4;		dlen -= 4;	}	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);	if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {		if (eap_ttls_parse_attr_eap(dpos, dlen, parse) < 0)			return -1;	} else if (vendor_id == 0 && avp_code == RADIUS_ATTR_REPLY_MESSAGE) {		/* This is an optional message that can be displayed to		 * the user. */		wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: AVP - Reply-Message",				  dpos, dlen);	} else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&		   avp_code == RADIUS_ATTR_MS_CHAP2_SUCCESS) {		wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP2-Success",				  dpos, dlen);		if (dlen != 43) {			wpa_printf(MSG_WARNING, "EAP-TTLS: Unexpected "				   "MS-CHAP2-Success length "				   "(len=%lu, expected 43)",				   (unsigned long) dlen);			return -1;		}		parse->mschapv2 = dpos;	} else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&		   avp_code == RADIUS_ATTR_MS_CHAP_ERROR) {		wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP-Error",				  dpos, dlen);		parse->mschapv2_error = 1;	} else if (avp_flags & AVP_FLAGS_MANDATORY) {		wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported mandatory AVP "			   "code %d vendor_id %d - dropped",			   (int) avp_code, (int) vendor_id);		return -1;	} else {		wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported AVP "			   "code %d vendor_id %d",			   (int) avp_code, (int) vendor_id);	}	return avp_length;}static int eap_ttls_parse_avps(struct wpabuf *in_decrypted,			       struct ttls_parse_avp *parse){	u8 *pos;	size_t left, pad;	int avp_length;	pos = wpabuf_mhead(in_decrypted);	left = wpabuf_len(in_decrypted);	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs", pos, left);	if (left < sizeof(struct ttls_avp)) {		wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 AVP frame"			   " len=%lu expected %lu or more - dropped",			   (unsigned long) left,			   (unsigned long) sizeof(struct ttls_avp));		return -1;	}	/* Parse AVPs */	os_memset(parse, 0, sizeof(*parse));	while (left > 0) {		avp_length = eap_ttls_parse_avp(pos, left, parse);		if (avp_length < 0)			return -1;		pad = (4 - (avp_length & 3)) & 3;		pos += avp_length + pad;		if (left < avp_length + pad)			left = 0;		else			left -= avp_length + pad;	}	return 0;}static u8 * eap_ttls_fake_identity_request(void){	struct eap_hdr *hdr;	u8 *buf;	wpa_printf(MSG_DEBUG, "EAP-TTLS: empty data in beginning of "		   "Phase 2 - use fake EAP-Request Identity");	buf = os_malloc(sizeof(*hdr) + 1);	if (buf == NULL) {		wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate "			   "memory for fake EAP-Identity Request");		return NULL;	}	hdr = (struct eap_hdr *) buf;	hdr->code = EAP_CODE_REQUEST;	hdr->identifier = 0;	hdr->length = host_to_be16(sizeof(*hdr) + 1);	buf[sizeof(*hdr)] = EAP_TYPE_IDENTITY;	return buf;}static int eap_ttls_encrypt_response(struct eap_sm *sm,				     struct eap_ttls_data *data,				     struct wpabuf *resp, u8 identifier,				     struct wpabuf **out_data){	if (resp == NULL)		return 0;	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data",			    resp);	if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,				 data->ttls_version, identifier,				 resp, out_data)) {		wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt a Phase 2 "			   "frame");		return -1;	}	wpabuf_free(resp);	return 0;}static int eap_ttls_process_phase2_eap(struct eap_sm *sm,				       struct eap_ttls_data *data,				       struct eap_method_ret *ret,				       struct ttls_parse_avp *parse,				       struct wpabuf **resp){	struct eap_hdr *hdr;	size_t len;	if (parse->eapdata == NULL) {		wpa_printf(MSG_WARNING, "EAP-TTLS: No EAP Message in the "			   "packet - dropped");		return -1;	}	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP",		    parse->eapdata, parse->eap_len);	hdr = (struct eap_hdr *) parse->eapdata;	if (parse->eap_len < sizeof(*hdr)) {		wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 EAP "			   "frame (len=%lu, expected %lu or more) - dropped",			   (unsigned long) parse->eap_len,			   (unsigned long) sizeof(*hdr));		return -1;	}	len = be_to_host16(hdr->length);	if (len > parse->eap_len) {		wpa_printf(MSG_INFO, "EAP-TTLS: Length mismatch in Phase 2 "			   "EAP frame (EAP hdr len=%lu, EAP data len in "			   "AVP=%lu)",			   (unsigned long) len,			   (unsigned long) parse->eap_len);		return -1;	}	wpa_printf(MSG_DEBUG, "EAP-TTLS: received Phase 2: code=%d "		   "identifier=%d length=%lu",		   hdr->code, hdr->identifier, (unsigned long) len);	switch (hdr->code) {	case EAP_CODE_REQUEST:		if (eap_ttls_phase2_request(sm, data, ret, hdr, resp)) {			wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "				   "processing failed");			return -1;		}		break;	default:		wpa_printf(MSG_INFO, "EAP-TTLS: Unexpected code=%d in "			   "Phase 2 EAP header", hdr->code);		return -1;	}	return 0;}static int eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,					    struct eap_ttls_data *data,					    struct eap_method_ret *ret,					    struct ttls_parse_avp *parse){	if (parse->mschapv2_error) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Received "			   "MS-CHAP-Error - failed");		ret->methodState = METHOD_DONE;		ret->decision = DECISION_FAIL;		/* Reply with empty data to ACK error */		return 1;	}	if (parse->mschapv2 == NULL) {#ifdef EAP_TNC		if (data->phase2_success && parse->eapdata) {			/*			 * Allow EAP-TNC to be started after successfully			 * completed MSCHAPV2.			 */			return 1;		}#endif /* EAP_TNC */		wpa_printf(MSG_WARNING, "EAP-TTLS: no MS-CHAP2-Success AVP "			   "received for Phase2 MSCHAPV2");		return -1;	}	if (parse->mschapv2[0] != data->ident) {		wpa_printf(MSG_WARNING, "EAP-TTLS: Ident mismatch for Phase 2 "			   "MSCHAPV2 (received Ident 0x%02x, expected 0x%02x)",			   parse->mschapv2[0], data->ident);		return -1;	}	if (!data->auth_response_valid ||	    mschapv2_verify_auth_response(data->auth_response,					  parse->mschapv2 + 1, 42)) {		wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid authenticator "			   "response in Phase 2 MSCHAPV2 success request");		return -1;	}	wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 "		   "authentication succeeded");	if (data->ttls_version > 0) {		/*		 * EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report		 * success, so do not allow connection to be terminated		 * yet.		 */		ret->methodState = METHOD_CONT;		ret->decision = DECISION_COND_SUCC;	} else {		ret->methodState = METHOD_DONE;		ret->decision = DECISION_UNCOND_SUCC;		data->phase2_success = 1;	}	/*	 * Reply with empty data; authentication server will reply	 * with EAP-Success after this.	 */	return 1;}#ifdef EAP_TNCstatic int eap_ttls_process_tnc_start(struct eap_sm *sm,				      struct eap_ttls_data *data,				      struct eap_method_ret *ret,				      struct ttls_parse_avp *parse,				      struct wpabuf **resp){	/* TNC uses inner EAP method after non-EAP TTLS phase 2. */	if (parse->eapdata == NULL) {		wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "			   "unexpected tunneled data (no EAP)");		return -1;	}	if (!data->ready_for_tnc) {		wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "			   "EAP after non-EAP, but not ready for TNC");		return -1;	}	wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed "		   "non-EAP method");	data->tnc_started = 1;	if (eap_ttls_process_phase2_eap(sm, data, ret, parse, resp) < 0)		return -1;	return 0;}#endif /* EAP_TNC */static int eap_ttls_process_decrypted(struct eap_sm *sm,				      struct eap_ttls_data *data,				      struct eap_method_ret *ret,				      u8 identifier,				      struct ttls_parse_avp *parse,				      struct wpabuf *in_decrypted,				      struct wpabuf **out_data){	struct wpabuf *resp = NULL;	struct eap_peer_config *config = eap_get_config(sm);	int res;	enum phase2_types phase2_type = data->phase2_type;#ifdef EAP_TNC	if (data->tnc_started)		phase2_type = EAP_TTLS_PHASE2_EAP;#endif /* EAP_TNC */	switch (phase2_type) {	case EAP_TTLS_PHASE2_EAP:		if (eap_ttls_process_phase2_eap(sm, data, ret, parse, &resp) <		    0)			return -1;		break;	case EAP_TTLS_PHASE2_MSCHAPV2:		res = eap_ttls_process_phase2_mschapv2(sm, data, ret, parse);#ifdef EAP_TNC		if (res == 1 && parse->eapdata && data->phase2_success) {			/*			 * TNC may be required as the next			 * authentication method within the tunnel.			 */			ret->methodState = METHOD_MAY_CONT;			data->ready_for_tnc = 1;			if (eap_ttls_process_tnc_start(sm, data, ret, parse,						       &resp) == 0)				break;		}#endif /* EAP_TNC */		return res;	case EAP_TTLS_PHASE2_MSCHAP:	case EAP_TTLS_PHASE2_PAP:	case EAP_TTLS_PHASE2_CHAP:#ifdef EAP_TNC		if (eap_ttls_process_tnc_start(sm, data, ret, parse, &resp) <		    0)			return -1;		break;#else /* EAP_TNC */		/* EAP-TTLS/{MSCHAP,PAP,CHAP} should not send any TLS tunneled		 * requests to the supplicant */		wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received unexpected "			   "tunneled data");		return -1;#endif /* EAP_TNC */	}	if (resp) {		if (eap_ttls_encrypt_response(sm, data, resp, identifier,					      out_data) < 0)			return -1;	} else if (config->pending_req_identity ||		   config->pending_req_password ||		   config->pending_req_otp ||		   config->pending_req_new_password) {		wpabuf_free(data->pending_phase2_req);		data->pending_phase2_req = wpabuf_dup(in_decrypted);	}

⌨️ 快捷键说明

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