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

📄 eap_ttls.c

📁 一个Linux下无线网卡的设置工具
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* MS-CHAP2-Response */	pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_RESPONSE,			       RADIUS_VENDOR_ID_MICROSOFT, 1,			       EAP_TTLS_MSCHAPV2_RESPONSE_LEN);	data->ident = challenge[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN];	*pos++ = data->ident;	*pos++ = 0; /* Flags */	memcpy(pos, peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);	pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;	memset(pos, 0, 8); /* Reserved, must be zero */	pos += 8;	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAPV2: implicit auth_challenge",		    challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAPV2: peer_challenge",		    peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);	wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 username",			  username, username_len);	wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 password",			      config->password, config->password_len);	generate_nt_response(challenge, peer_challenge,			     username, username_len,			     config->password, config->password_len,			     pos);	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 response", pos, 24);	generate_authenticator_response(config->password, config->password_len,					peer_challenge, challenge,					username, username_len,					pos, data->auth_response);	data->auth_response_valid = 1;	pos += 24;	free(challenge);	AVP_PAD(buf, pos);	*resp = buf;	*resp_len = pos - buf;	if (sm->workaround) {		/* At least FreeRADIUS seems to be terminating		 * EAP-TTLS/MSHCAPV2 without the expected MS-CHAP-v2 Success		 * packet. */		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: EAP workaround - "			   "allow success without tunneled response");		ret->methodState = METHOD_MAY_CONT;		ret->decision = DECISION_COND_SUCC;	}	return 0;}static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,					  struct eap_ttls_data *data,					  struct eap_method_ret *ret,					  const struct eap_hdr *req,					  struct eap_hdr *hdr,					  u8 **resp, size_t *resp_len){	struct wpa_ssid *config = eap_get_config(sm);	u8 *buf, *pos, *challenge;	wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAP Request");	pos = buf = malloc(config->identity_len + 1000);	if (buf == NULL) {		wpa_printf(MSG_ERROR,			   "EAP-TTLS/MSCHAP: Failed to allocate memory");		return -1;	}	/* User-Name */	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,			       config->identity, config->identity_len);	/* MS-CHAP-Challenge */	challenge = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",				       EAP_TLS_KEY_LEN);	if (challenge == NULL) {		free(buf);		wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "			   "implicit challenge");		return -1;	}	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,			       RADIUS_VENDOR_ID_MICROSOFT, 1,			       challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);	/* MS-CHAP-Response */	pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_RESPONSE,			       RADIUS_VENDOR_ID_MICROSOFT, 1,			       EAP_TTLS_MSCHAP_RESPONSE_LEN);	data->ident = challenge[EAP_TTLS_MSCHAP_CHALLENGE_LEN];	*pos++ = data->ident;	*pos++ = 1; /* Flags: Use NT style passwords */	memset(pos, 0, 24); /* LM-Response */	pos += 24;	nt_challenge_response(challenge,			      config->password, config->password_len,			      pos); /* NT-Response */	wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password",			      config->password, config->password_len);	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP implicit challenge",		    challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP response", pos, 24);	pos += 24;	free(challenge);	AVP_PAD(buf, pos);	*resp = buf;	*resp_len = pos - buf;	/* EAP-TTLS/MSCHAP does not provide tunneled success notification, so	 * assume that Phase2 succeeds. */	ret->methodState = METHOD_DONE;	ret->decision = DECISION_COND_SUCC;	return 0;}static int eap_ttls_phase2_request_pap(struct eap_sm *sm,				       struct eap_ttls_data *data,				       struct eap_method_ret *ret,				       const struct eap_hdr *req,				       struct eap_hdr *hdr,				       u8 **resp, size_t *resp_len){	struct wpa_ssid *config = eap_get_config(sm);	u8 *buf, *pos;	size_t pad;	wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 PAP Request");	pos = buf = malloc(config->identity_len + config->password_len + 100);	if (buf == NULL) {		wpa_printf(MSG_ERROR,			   "EAP-TTLS/PAP: Failed to allocate memory");		return -1;	}	/* User-Name */	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,			       config->identity, config->identity_len);	/* User-Password; in RADIUS, this is encrypted, but EAP-TTLS encrypts	 * the data, so no separate encryption is used in the AVP itself.	 * However, the password is padded to obfuscate its length. */	pad = (16 - (config->password_len & 15)) & 15;	pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_USER_PASSWORD, 0, 1,			       config->password_len + pad);	memcpy(pos, config->password, config->password_len);	pos += config->password_len;	memset(pos, 0, pad);	pos += pad;	AVP_PAD(buf, pos);	*resp = buf;	*resp_len = pos - buf;	/* EAP-TTLS/PAP does not provide tunneled success notification, so	 * assume that Phase2 succeeds. */	ret->methodState = METHOD_DONE;	ret->decision = DECISION_COND_SUCC;	return 0;}static int eap_ttls_phase2_request_chap(struct eap_sm *sm,					struct eap_ttls_data *data,					struct eap_method_ret *ret,					const struct eap_hdr *req,					struct eap_hdr *hdr,					u8 **resp, size_t *resp_len){	struct wpa_ssid *config = eap_get_config(sm);	u8 *buf, *pos, *challenge;	const u8 *addr[3];	size_t len[3];	wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 CHAP Request");	pos = buf = malloc(config->identity_len + 1000);	if (buf == NULL) {		wpa_printf(MSG_ERROR,			   "EAP-TTLS/CHAP: Failed to allocate memory");		return -1;	}	/* User-Name */	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,			       config->identity, config->identity_len);	/* CHAP-Challenge */	challenge = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",				       EAP_TLS_KEY_LEN);	if (challenge == NULL) {		free(buf);		wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "			   "implicit challenge");		return -1;	}	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_CHAP_CHALLENGE, 0, 1,			       challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);	/* CHAP-Password */	pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_CHAP_PASSWORD, 0, 1,			       1 + EAP_TTLS_CHAP_PASSWORD_LEN);	data->ident = challenge[EAP_TTLS_CHAP_CHALLENGE_LEN];	*pos++ = data->ident;	/* MD5(Ident + Password + Challenge) */	addr[0] = &data->ident;	len[0] = 1;	addr[1] = config->password;	len[1] = config->password_len;	addr[2] = challenge;	len[2] = EAP_TTLS_CHAP_CHALLENGE_LEN;	md5_vector(3, addr, len, pos);	wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: CHAP username",			  config->identity, config->identity_len);	wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: CHAP password",			      config->password, config->password_len);	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP implicit challenge",		    challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP password",		    pos, EAP_TTLS_CHAP_PASSWORD_LEN);	pos += EAP_TTLS_CHAP_PASSWORD_LEN;	free(challenge);	AVP_PAD(buf, pos);	*resp = buf;	*resp_len = pos - buf;	/* EAP-TTLS/CHAP does not provide tunneled success notification, so	 * assume that Phase2 succeeds. */	ret->methodState = METHOD_DONE;	ret->decision = DECISION_COND_SUCC;	return 0;}static int eap_ttls_phase2_request(struct eap_sm *sm,				   struct eap_ttls_data *data,				   struct eap_method_ret *ret,				   const struct eap_hdr *req,				   struct eap_hdr *hdr,				   u8 **resp, size_t *resp_len){	struct wpa_ssid *config = eap_get_config(sm);	int res = 0;	if (data->phase2_type == EAP_TTLS_PHASE2_MSCHAPV2 ||	    data->phase2_type == EAP_TTLS_PHASE2_MSCHAP ||	    data->phase2_type == EAP_TTLS_PHASE2_PAP ||	    data->phase2_type == EAP_TTLS_PHASE2_CHAP) {		if (config->identity == NULL) {			wpa_printf(MSG_INFO,				   "EAP-TTLS: Identity not configured");			eap_sm_request_identity(sm, config);			if (config->password == NULL)				eap_sm_request_password(sm, config);			return 0;		}		if (config->password == NULL) {			wpa_printf(MSG_INFO,				   "EAP-TTLS: Password not configured");			eap_sm_request_password(sm, config);			return 0;		}	}	switch (data->phase2_type) {	case EAP_TTLS_PHASE2_EAP:		res = eap_ttls_phase2_request_eap(sm, data, ret, req, hdr,						  resp, resp_len);		break;	case EAP_TTLS_PHASE2_MSCHAPV2:		res = eap_ttls_phase2_request_mschapv2(sm, data, ret, req, hdr,						       resp, resp_len);		break;	case EAP_TTLS_PHASE2_MSCHAP:		res = eap_ttls_phase2_request_mschap(sm, data, ret, req, hdr,						     resp, resp_len);		break;	case EAP_TTLS_PHASE2_PAP:		res = eap_ttls_phase2_request_pap(sm, data, ret, req, hdr,						  resp, resp_len);		break;	case EAP_TTLS_PHASE2_CHAP:		res = eap_ttls_phase2_request_chap(sm, data, ret, req, hdr,						   resp, resp_len);		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;}static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,			    struct eap_method_ret *ret,			    const struct eap_hdr *req,			    const u8 *in_data, size_t in_len,			    u8 **out_data, size_t *out_len){	u8 *in_decrypted = NULL, *pos;	int buf_len, len_decrypted = 0, len, left, retval = 0;	struct eap_hdr *hdr = NULL;	u8 *resp = NULL, *mschapv2 = NULL, *eapdata = NULL;	size_t resp_len, eap_len = 0;	struct ttls_avp *avp;	u8 recv_response[20];	int mschapv2_error = 0;	struct wpa_ssid *config = eap_get_config(sm);	const u8 *msg;	size_t msg_len;	int need_more_input;	wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"		   " Phase 2", (unsigned long) in_len);	if (data->pending_phase2_req) {		wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 request - "			   "skip decryption and use old data");		/* Clear TLS reassembly state. */		free(data->ssl.tls_in);		data->ssl.tls_in = NULL;		data->ssl.tls_in_len = 0;		data->ssl.tls_in_left = 0;		data->ssl.tls_in_total = 0;		in_decrypted = data->pending_phase2_req;		data->pending_phase2_req = NULL;		len_decrypted = data->pending_phase2_req_len;		if (data->pending_phase2_req_len == 0) {			free(in_decrypted);			in_decrypted = NULL;			goto fake_req_identity;		}		goto continue_req;	}	if (in_len == 0 && data->phase2_start) {		data->phase2_start = 0;		/* EAP-TTLS does not use Phase2 on fast re-auth; this must be		 * done only if TLS part was indeed resuming a previous		 * session. Most Authentication Servers terminate EAP-TTLS		 * before reaching this point, but some do not. Make		 * wpa_supplicant stop phase 2 here, if needed. */		if (data->reauth &&		    tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {			wpa_printf(MSG_DEBUG, "EAP-TTLS: Session resumption - "				   "skip phase 2");			*out_data = eap_tls_build_ack(&data->ssl, out_len,						      req->identifier,						      EAP_TYPE_TTLS, 0);			ret->methodState = METHOD_DONE;			ret->decision = DECISION_UNCOND_SUCC;			data->phase2_success = 1;			return 0;		}	fake_req_identity:		wpa_printf(MSG_DEBUG, "EAP-TTLS: empty data in beginning of "			   "Phase 2 - use fake EAP-Request Identity");		buf_len = sizeof(*hdr) + 1;		in_decrypted = malloc(buf_len);		if (in_decrypted == NULL) {			wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate "				   "memory for fake EAP-Identity Request");			retval = -1;			goto done;		}		hdr = (struct eap_hdr *) in_decrypted;		hdr->code = EAP_CODE_REQUEST;		hdr->identifier = 0;		hdr->length = host_to_be16(sizeof(*hdr) + 1);		in_decrypted[sizeof(*hdr)] = EAP_TYPE_IDENTITY;		goto process_eap;	}	msg = eap_tls_data_reassemble(sm, &data->ssl, in_data, in_len,				      &msg_len, &need_more_input);	if (msg == NULL)		return need_more_input ? 1 : -1;	buf_len = in_len;	if (data->ssl.tls_in_total > buf_len)		buf_len = data->ssl.tls_in_total;	in_decrypted = malloc(buf_len);	if (in_decrypted == NULL) {		free(data->ssl.tls_in);		data->ssl.tls_in = NULL;		data->ssl.tls_in_len = 0;		wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate memory "			   "for decryption");		retval = -1;		goto done;	}	len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,					       msg, msg_len,					       in_decrypted, buf_len);	free(data->ssl.tls_in);	data->ssl.tls_in = NULL;	data->ssl.tls_in_len = 0;	if (len_decrypted < 0) {		wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "			   "data");		retval = -1;		goto done;	}continue_req:	data->phase2_start = 0;	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs",		    in_decrypted, len_decrypted);	if (len_decrypted < sizeof(struct ttls_avp)) {		wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 AVP frame"			   " len=%d expected %lu or more - dropped",			   len_decrypted,			   (unsigned long) sizeof(struct ttls_avp));		retval = -1;		goto done;	}	/* Parse AVPs */	pos = in_decrypted;	left = len_decrypted;	mschapv2 = NULL;	while (left > 0) {		u32 avp_code, avp_length, vendor_id = 0;		u8 avp_flags, *dpos;		size_t pad, 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;

⌨️ 快捷键说明

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