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

📄 eap_ttls.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (data->mschapv2_resp_ok) {		pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,				       RADIUS_VENDOR_ID_MICROSOFT, 1, 43);		*pos++ = data->mschapv2_ident;		ret = os_snprintf((char *) pos, end - pos, "S=");		if (ret >= 0 && ret < end - pos)			pos += ret;		pos += wpa_snprintf_hex_uppercase(			(char *) pos, end - pos, data->mschapv2_auth_response,			sizeof(data->mschapv2_auth_response));	} else {		pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,				       RADIUS_VENDOR_ID_MICROSOFT, 1, 6);		os_memcpy(pos, "Failed", 6);		pos += 6;		AVP_PAD(req, pos);	}	req_len = pos - req;	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "			"data", req, req_len);	encr_req = eap_server_tls_encrypt(sm, &data->ssl, req, req_len);	os_free(req);	return encr_req;}static struct wpabuf * eap_ttls_build_phase_finished(	struct eap_sm *sm, struct eap_ttls_data *data, int final){	int len;	struct wpabuf *req;	const int max_len = 300;	req = wpabuf_alloc(max_len);	if (req == NULL)		return NULL;	len = tls_connection_ia_send_phase_finished(sm->ssl_ctx,						    data->ssl.conn, final,						    wpabuf_mhead(req),						    max_len);	if (len < 0) {		wpabuf_free(req);		return NULL;	}	wpabuf_put(req, len);	return req;}static struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id){	struct eap_ttls_data *data = priv;	if (data->ssl.state == FRAG_ACK) {		return eap_server_tls_build_ack(id, EAP_TYPE_TTLS,						data->ttls_version);	}	if (data->ssl.state == WAIT_FRAG_ACK) {		return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,						data->ttls_version, id);	}	switch (data->state) {	case START:		return eap_ttls_build_start(sm, data, id);	case PHASE1:		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {			wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, "				   "starting Phase2");			eap_ttls_state(data, PHASE2_START);		}		break;	case PHASE2_METHOD:		wpabuf_free(data->ssl.out_buf);		data->ssl.out_used = 0;		data->ssl.out_buf = eap_ttls_build_phase2_eap_req(sm, data,								  id);		break;	case PHASE2_MSCHAPV2_RESP:		wpabuf_free(data->ssl.out_buf);		data->ssl.out_used = 0;		data->ssl.out_buf = eap_ttls_build_phase2_mschapv2(sm, data);		break;	case PHASE_FINISHED:		wpabuf_free(data->ssl.out_buf);		data->ssl.out_used = 0;		data->ssl.out_buf = eap_ttls_build_phase_finished(sm, data, 1);		break;	default:		wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",			   __func__, data->state);		return NULL;	}	return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,					data->ttls_version, id);}static Boolean eap_ttls_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_TTLS, respData, &len);	if (pos == NULL || len < 1) {		wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");		return TRUE;	}	return FALSE;}static int eap_ttls_ia_permute_inner_secret(struct eap_sm *sm,					    struct eap_ttls_data *data,					    const u8 *key, size_t key_len){	u8 *buf;	size_t buf_len;	int ret;	if (key) {		buf_len = 2 + key_len;		buf = os_malloc(buf_len);		if (buf == NULL)			return -1;		WPA_PUT_BE16(buf, key_len);		os_memcpy(buf + 2, key, key_len);	} else {		buf = NULL;		buf_len = 0;	}	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Session keys for TLS/IA inner "			"secret permutation", buf, buf_len);	ret = tls_connection_ia_permute_inner_secret(sm->ssl_ctx,						     data->ssl.conn,						     buf, buf_len);	os_free(buf);	return ret;}static void eap_ttls_process_phase2_pap(struct eap_sm *sm,					struct eap_ttls_data *data,					const u8 *user_password,					size_t user_password_len){	if (!sm->user || !sm->user->password || sm->user->password_hash ||	    !(sm->user->ttls_auth & EAP_TTLS_AUTH_PAP)) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user "			   "password configured");		eap_ttls_state(data, FAILURE);		return;	}	if (sm->user->password_len != user_password_len ||	    os_memcmp(sm->user->password, user_password, user_password_len) !=	    0) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");		eap_ttls_state(data, FAILURE);		return;	}	wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");	eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :		       SUCCESS);}static void eap_ttls_process_phase2_chap(struct eap_sm *sm,					 struct eap_ttls_data *data,					 const u8 *challenge,					 size_t challenge_len,					 const u8 *password,					 size_t password_len){	u8 *chal, hash[CHAP_MD5_LEN];	if (challenge == NULL || password == NULL ||	    challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||	    password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes "			   "(challenge len %lu password len %lu)",			   (unsigned long) challenge_len,			   (unsigned long) password_len);		eap_ttls_state(data, FAILURE);		return;	}	if (!sm->user || !sm->user->password || sm->user->password_hash ||	    !(sm->user->ttls_auth & EAP_TTLS_AUTH_CHAP)) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user "			   "password configured");		eap_ttls_state(data, FAILURE);		return;	}	chal = eap_ttls_implicit_challenge(sm, data,					   EAP_TTLS_CHAP_CHALLENGE_LEN + 1);	if (chal == NULL) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "			   "challenge from TLS data");		eap_ttls_state(data, FAILURE);		return;	}	if (os_memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 ||	    password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");		os_free(chal);		eap_ttls_state(data, FAILURE);		return;	}	os_free(chal);	/* MD5(Ident + Password + Challenge) */	chap_md5(password[0], sm->user->password, sm->user->password_len,		 challenge, challenge_len, hash);	if (os_memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");		eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :			       SUCCESS);	} else {		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password");		eap_ttls_state(data, FAILURE);	}}static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,					   struct eap_ttls_data *data,					   u8 *challenge, size_t challenge_len,					   u8 *response, size_t response_len){	u8 *chal, nt_response[24];	if (challenge == NULL || response == NULL ||	    challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN ||	    response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP "			   "attributes (challenge len %lu response len %lu)",			   (unsigned long) challenge_len,			   (unsigned long) response_len);		eap_ttls_state(data, FAILURE);		return;	}	if (!sm->user || !sm->user->password ||	    !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAP)) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "			   "configured");		eap_ttls_state(data, FAILURE);		return;	}	chal = eap_ttls_implicit_challenge(sm, data,					   EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);	if (chal == NULL) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "			   "challenge from TLS data");		eap_ttls_state(data, FAILURE);		return;	}	if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 ||	    response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");		os_free(chal);		eap_ttls_state(data, FAILURE);		return;	}	os_free(chal);	if (sm->user->password_hash)		challenge_response(challenge, sm->user->password, nt_response);	else		nt_challenge_response(challenge, sm->user->password,				      sm->user->password_len, nt_response);	if (os_memcmp(nt_response, response + 2 + 24, 24) == 0) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");		eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :			       SUCCESS);	} else {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response");		wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received",			    response + 2 + 24, 24);		wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected",			    nt_response, 24);		eap_ttls_state(data, FAILURE);	}}static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,					     struct eap_ttls_data *data,					     u8 *challenge,					     size_t challenge_len,					     u8 *response, size_t response_len){	u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge,		*auth_challenge;	size_t username_len, i;	if (challenge == NULL || response == NULL ||	    challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN ||	    response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 "			   "attributes (challenge len %lu response len %lu)",			   (unsigned long) challenge_len,			   (unsigned long) response_len);		eap_ttls_state(data, FAILURE);		return;	}	if (!sm->user || !sm->user->password ||	    !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAPV2)) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "			   "configured");		eap_ttls_state(data, FAILURE);		return;	}	/* MSCHAPv2 does not include optional domain name in the	 * challenge-response calculation, so remove domain prefix	 * (if present). */	username = sm->identity;	username_len = sm->identity_len;	for (i = 0; i < username_len; i++) {		if (username[i] == '\\') {			username_len -= i + 1;			username += i + 1;			break;		}	}	chal = eap_ttls_implicit_challenge(		sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);	if (chal == NULL) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "			   "challenge from TLS data");		eap_ttls_state(data, FAILURE);		return;	}	if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 ||	    response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");		os_free(chal);		eap_ttls_state(data, FAILURE);		return;	}	os_free(chal);	auth_challenge = challenge;	peer_challenge = response + 2;	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",			  username, username_len);	wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",		    auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);	wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",		    peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);	if (sm->user->password_hash) {		generate_nt_response_pwhash(auth_challenge, peer_challenge,					    username, username_len,					    sm->user->password,					    nt_response);	} else {		generate_nt_response(auth_challenge, peer_challenge,				     username, username_len,				     sm->user->password,				     sm->user->password_len,				     nt_response);	}	rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;	if (os_memcmp(nt_response, rx_resp, 24) == 0) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "			   "NT-Response");		data->mschapv2_resp_ok = 1;		if (data->ttls_version > 0) {			const u8 *pw_hash;			u8 pw_hash_buf[16], pw_hash_hash[16], master_key[16];			u8 session_key[2 * MSCHAPV2_KEY_LEN];			if (sm->user->password_hash)				pw_hash = sm->user->password;			else {				nt_password_hash(sm->user->password,						 sm->user->password_len,						 pw_hash_buf);				pw_hash = pw_hash_buf;			}			hash_nt_password_hash(pw_hash, pw_hash_hash);			get_master_key(pw_hash_hash, nt_response, master_key);			get_asymetric_start_key(master_key, session_key,						MSCHAPV2_KEY_LEN, 0, 0);			get_asymetric_start_key(master_key,						session_key + MSCHAPV2_KEY_LEN,						MSCHAPV2_KEY_LEN, 1, 0);			eap_ttls_ia_permute_inner_secret(sm, data,							 session_key,							 sizeof(session_key));		}		if (sm->user->password_hash) {			generate_authenticator_response_pwhash(				sm->user->password,				peer_challenge, auth_challenge,				username, username_len, nt_response,				data->mschapv2_auth_response);		} else {			generate_authenticator_response(				sm->user->password, sm->user->password_len,				peer_challenge, auth_challenge,				username, username_len, nt_response,				data->mschapv2_auth_response);		}	} else {		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "			   "NT-Response");		wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",			    rx_resp, 24);		wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",			    nt_response, 24);		data->mschapv2_resp_ok = 0;	}	eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);	data->mschapv2_ident = response[0];}static int eap_ttls_phase2_eap_init(struct eap_sm *sm,				    struct eap_ttls_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 data->phase2_priv == NULL ? -1 : 0;}static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,						 struct eap_ttls_data *data,						 u8 *in_data, size_t in_len){	u8 next_type = EAP_TYPE_NONE;	struct eap_hdr *hdr;	u8 *pos;	size_t left;	struct wpabuf buf;	const struct eap_method *m = data->phase2_method;	void *priv = data->phase2_priv;	if (priv == NULL) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "			   "initialized?!", __func__);		return;	}	hdr = (struct eap_hdr *) in_data;	pos = (u8 *) (hdr + 1);	if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {		left = in_len - sizeof(*hdr);		wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "			    "allowed types", pos + 1, left - 1);		eap_sm_process_nak(sm, pos + 1, left - 1);

⌨️ 快捷键说明

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