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

📄 eap_ttls.c

📁 一个Linux下无线网卡的设置工具
💻 C
📖 第 1 页 / 共 3 页
字号:
		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=%d) - dropped",				   (int) avp_length, left);			retval = -1;			goto done;		}		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");				retval = -1;				goto done;			}			vendor_id = be_to_host32(* (u32 *) 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) {			wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");			if (eapdata == NULL) {				eapdata = malloc(dlen);				if (eapdata == NULL) {					retval = -1;					wpa_printf(MSG_WARNING, "EAP-TTLS: "						   "failed to allocate memory "						   "for Phase 2 EAP data");					goto done;				}				memcpy(eapdata, dpos, dlen);				eap_len = dlen;			} else {				u8 *neweap = realloc(eapdata, eap_len + dlen);				if (neweap == NULL) {					retval = -1;					wpa_printf(MSG_WARNING, "EAP-TTLS: "						   "failed to allocate memory "						   "for Phase 2 EAP data");					goto done;				}				memcpy(neweap + eap_len, dpos, dlen);				eapdata = neweap;				eap_len += dlen;			}		} 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);				retval = -1;				break;			}			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);			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);			retval = -1;			goto done;		} else {			wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "				   "AVP code %d vendor_id %d",				   (int) avp_code, (int) vendor_id);		}		pad = (4 - (avp_length & 3)) & 3;		pos += avp_length + pad;		left -= avp_length + pad;	}	switch (data->phase2_type) {	case EAP_TTLS_PHASE2_EAP:		if (eapdata == NULL) {			wpa_printf(MSG_WARNING, "EAP-TTLS: No EAP Message in "				   "the packet - dropped");			retval = -1;			goto done;		}		wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP",			    eapdata, eap_len);		hdr = (struct eap_hdr *) eapdata;		if (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) eap_len,				   (unsigned long) sizeof(*hdr));			retval = -1;			goto done;		}		len = be_to_host16(hdr->length);		if (len > eap_len) {			wpa_printf(MSG_INFO, "EAP-TTLS: Length mismatch in "				   "Phase 2 EAP frame (EAP hdr len=%d, EAP "				   "data len in AVP=%lu)", len,				   (unsigned long) eap_len);			retval = -1;			goto done;		}		wpa_printf(MSG_DEBUG, "EAP-TTLS: received Phase 2: code=%d "			   "identifier=%d length=%d",			   hdr->code, hdr->identifier, len);	process_eap:		switch (hdr->code) {		case EAP_CODE_REQUEST:			if (eap_ttls_phase2_request(sm, data, ret, req, hdr,						    &resp, &resp_len)) {				wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 "					   "Request processing failed");				retval = -1;				goto done;			}			break;		default:			wpa_printf(MSG_INFO, "EAP-TTLS: Unexpected code=%d in "				   "Phase 2 EAP header", hdr->code);			retval = -1;			break;		}		break;	case EAP_TTLS_PHASE2_MSCHAPV2:		if (mschapv2_error) {			wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Received "				   "MS-CHAP-Error - failed");			ret->methodState = METHOD_DONE;			ret->decision = DECISION_FAIL;			*out_data = eap_tls_build_ack(&data->ssl, out_len,						      req->identifier,						      EAP_TYPE_TTLS, 0);			break;		}		if (mschapv2 == NULL) {			wpa_printf(MSG_WARNING, "EAP-TTLS: no MS-CHAP2-Success"				   " AVP received for Phase2 MSCHAPV2");			retval = -1;			break;		}		if (mschapv2[0] != data->ident) {			wpa_printf(MSG_WARNING, "EAP-TTLS: Ident mismatch "				   "for Phase 2 MSCHAPV2 (received Ident "				   "0x%02x, expected 0x%02x)",				   mschapv2[0], data->ident);			retval = -1;			break;		}		if (!data->auth_response_valid ||		    mschapv2[1] != 'S' || mschapv2[2] != '=' ||		    hexstr2bin((char *) (mschapv2 + 3), recv_response, 20) ||		    memcmp(data->auth_response, recv_response, 20) != 0) {			wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid "				   "authenticator response in Phase 2 "				   "MSCHAPV2 success request");			retval = -1;			break;		}		wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 "			   "authentication succeeded");		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. */		retval = 1;		goto done;	case EAP_TTLS_PHASE2_MSCHAP:	case EAP_TTLS_PHASE2_PAP:	case EAP_TTLS_PHASE2_CHAP:		/* 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");		retval = -1;		break;	}	if (resp) {		wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data",				resp, resp_len);		if (eap_ttls_encrypt(sm, data, req->identifier,				     resp, resp_len, out_data, out_len)) {			wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt "				   "a Phase 2 frame");		}		free(resp);	} else if (config->pending_req_identity ||		   config->pending_req_password ||		   config->pending_req_otp ||		   config->pending_req_new_password) {		free(data->pending_phase2_req);		data->pending_phase2_req = malloc(len_decrypted);		if (data->pending_phase2_req) {			memcpy(data->pending_phase2_req, in_decrypted,			       len_decrypted);			data->pending_phase2_req_len = len_decrypted;		}	}done:	free(in_decrypted);	free(eapdata);	if (retval < 0) {		ret->methodState = METHOD_DONE;		ret->decision = DECISION_FAIL;	}	return retval;}static u8 * eap_ttls_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_ttls_data *data = priv;	pos = eap_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, 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) {		wpa_printf(MSG_DEBUG, "EAP-TTLS: Start");		/* draft-ietf-pppext-eap-ttls-03.txt, Ch. 8.1:		 * EAP-TTLS Start packet may, in a future specification, be		 * allowed to contain data. Client based on this draft version		 * must ignore such data but must not reject the Start packet.		 */		left = 0;	}	resp = NULL;	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&	    !data->resuming) {		res = eap_ttls_decrypt(sm, data, ret, req, pos, left,				       &resp, respDataLen);	} else {		res = eap_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS, 0,					     id, pos, left,					     &resp, respDataLen);		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {			wpa_printf(MSG_DEBUG,				   "EAP-TTLS: TLS done, proceed to Phase 2");			if (data->resuming) {				wpa_printf(MSG_DEBUG, "EAP-TTLS: fast reauth -"					   " may skip Phase 2");				ret->decision = DECISION_COND_SUCC;				ret->methodState = METHOD_MAY_CONT;			}			data->phase2_start = 1;			free(data->key_data);			data->key_data =				eap_tls_derive_key(sm, &data->ssl,						   "ttls keying material",						   EAP_TLS_KEY_LEN);			if (data->key_data) {				wpa_hexdump_key(MSG_DEBUG,						"EAP-TTLS: Derived key",						data->key_data,						EAP_TLS_KEY_LEN);			} else {				wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to "					   "derive key");			}			if (*respDataLen == 0) {				if (eap_ttls_decrypt(sm, data, ret, req, NULL,						     0, &resp, respDataLen)) {					wpa_printf(MSG_WARNING, "EAP-TTLS: "						   "failed to process early "						   "start for Phase 2");				}				res = 0;			}			data->resuming = 0;		}	}	if (ret->methodState == METHOD_DONE) {		ret->allowNotifications = FALSE;		if (ret->decision == DECISION_UNCOND_SUCC ||		    ret->decision == DECISION_COND_SUCC) {			wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "				   "completed successfully");			data->phase2_success = 1;		}	} else if (sm->workaround && ret->methodState == METHOD_MAY_CONT &&		   (ret->decision == DECISION_UNCOND_SUCC ||		    ret->decision == DECISION_COND_SUCC)) {			wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "				   "completed successfully (EAP workaround)");			data->phase2_success = 1;	}	if (res == 1) {		return eap_tls_build_ack(&data->ssl, respDataLen, id,					 EAP_TYPE_TTLS, 0);	}	return resp;}static Boolean eap_ttls_has_reauth_data(struct eap_sm *sm, void *priv){	struct eap_ttls_data *data = priv;	return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&		data->phase2_success;}static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv){	struct eap_ttls_data *data = priv;	free(data->pending_phase2_req);	data->pending_phase2_req = NULL;}static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv){	struct eap_ttls_data *data = priv;	free(data->key_data);	data->key_data = NULL;	if (eap_tls_reauth_init(sm, &data->ssl)) {		free(data);		return NULL;	}	data->phase2_start = 0;	data->phase2_success = 0;	data->resuming = 1;	data->reauth = 1;	return priv;}static int eap_ttls_get_status(struct eap_sm *sm, void *priv, char *buf,			       size_t buflen, int verbose){	struct eap_ttls_data *data = priv;	int len;	len = eap_tls_status(sm, &data->ssl, buf, buflen, verbose);	switch (data->phase2_type) {	case EAP_TTLS_PHASE2_EAP:		len += snprintf(buf + len, buflen - len,				"EAP-TTLS Phase2 method=EAP-%s\n",				data->phase2_method ? data->phase2_method->name				: "?");		break;	case EAP_TTLS_PHASE2_MSCHAPV2:		len += snprintf(buf + len, buflen - len,				"EAP-TTLS Phase2 method=MSCHAPV2\n");		break;	case EAP_TTLS_PHASE2_MSCHAP:		len += snprintf(buf + len, buflen - len,				"EAP-TTLS Phase2 method=MSCHAP\n");		break;	case EAP_TTLS_PHASE2_PAP:		len += snprintf(buf + len, buflen - len,				"EAP-TTLS Phase2 method=PAP\n");		break;	case EAP_TTLS_PHASE2_CHAP:		len += snprintf(buf + len, buflen - len,				"EAP-TTLS Phase2 method=CHAP\n");		break;	}	return len;}static Boolean eap_ttls_isKeyAvailable(struct eap_sm *sm, void *priv){	struct eap_ttls_data *data = priv;	return data->key_data != NULL && data->phase2_success;}static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len){	struct eap_ttls_data *data = priv;	u8 *key;	if (data->key_data == NULL || !data->phase2_success)		return NULL;	key = malloc(EAP_TLS_KEY_LEN);	if (key == NULL)		return NULL;	*len = EAP_TLS_KEY_LEN;	memcpy(key, data->key_data, EAP_TLS_KEY_LEN);	return key;}const struct eap_method eap_method_ttls ={	.method = EAP_TYPE_TTLS,	.name = "TTLS",	.init = eap_ttls_init,	.deinit = eap_ttls_deinit,	.process = eap_ttls_process,	.isKeyAvailable = eap_ttls_isKeyAvailable,	.getKey = eap_ttls_getKey,	.get_status = eap_ttls_get_status,	.has_reauth_data = eap_ttls_has_reauth_data,	.deinit_for_reauth = eap_ttls_deinit_for_reauth,	.init_for_reauth = eap_ttls_init_for_reauth,};

⌨️ 快捷键说明

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