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

📄 eap_ttls.c

📁 hostapd源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return (u8 *) req;}static u8 * eap_ttls_build_phase2_eap_req(struct eap_sm *sm,					  struct eap_ttls_data *data,					  int id, size_t *reqDataLen){	u8 *req, *encr_req;	size_t req_len;	req = data->phase2_method->buildReq(sm, data->phase2_priv, id,					    &req_len);	if (req == NULL)		return NULL;	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encapsulate Phase 2 data",			req, req_len);	if (eap_ttls_avp_encapsulate(&req, &req_len, RADIUS_ATTR_EAP_MESSAGE,				     1) < 0) {		wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "			   "packet");		return NULL;	}	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated Phase "			"2 data", req, req_len);	encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);	free(req);	return encr_req;}static u8 * eap_ttls_build_phase2_mschapv2(struct eap_sm *sm,					   struct eap_ttls_data *data,					   int id, size_t *reqDataLen){	u8 *req, *encr_req, *pos, *end;	size_t req_len;	pos = req = malloc(100);	if (req == NULL)		return NULL;	end = req + 200;	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;		pos += snprintf((char *) pos, end - pos, "S=");		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);		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_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);	free(req);	return encr_req;}static u8 * eap_ttls_build_phase_finished(struct eap_sm *sm,					  struct eap_ttls_data *data,					  int id, int final,					  size_t *reqDataLen){	int len;	struct eap_hdr *req;	u8 *pos;	const int max_len = 300;	len = sizeof(struct eap_hdr) + 2 + max_len;	req = malloc(len);	if (req == NULL)		return NULL;	req->code = EAP_CODE_REQUEST;	req->identifier = id;	pos = (u8 *) (req + 1);	*pos++ = EAP_TYPE_TTLS;	*pos++ = data->ttls_version;	len = tls_connection_ia_send_phase_finished(sm->ssl_ctx,						    data->ssl.conn,						    final, pos, max_len);	if (len < 0) {		free(req);		return NULL;	}	*reqDataLen = sizeof(struct eap_hdr) + 2 + len;	req->length = host_to_be16(*reqDataLen);	return (u8 *) req;}static u8 * eap_ttls_buildReq(struct eap_sm *sm, void *priv, int id,			      size_t *reqDataLen){	struct eap_ttls_data *data = priv;	switch (data->state) {	case START:		return eap_ttls_build_start(sm, data, id, reqDataLen);	case PHASE1:		return eap_ttls_build_req(sm, data, id, reqDataLen);	case PHASE2_METHOD:		return eap_ttls_build_phase2_eap_req(sm, data, id, reqDataLen);	case PHASE2_MSCHAPV2_RESP:		return eap_ttls_build_phase2_mschapv2(sm, data, id,						      reqDataLen);	case PHASE_FINISHED:		return eap_ttls_build_phase_finished(sm, data, id, 1,						     reqDataLen);	default:		wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",			   __func__, data->state);		return NULL;	}}static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,			      u8 *respData, size_t respDataLen){	struct eap_hdr *resp;	u8 *pos;	size_t len;	resp = (struct eap_hdr *) respData;	pos = (u8 *) (resp + 1);	if (respDataLen < sizeof(*resp) + 2 || *pos != EAP_TYPE_TTLS ||	    (len = ntohs(resp->length)) > respDataLen) {		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 = malloc(buf_len);		if (buf == NULL)			return -1;		WPA_PUT_BE16(buf, key_len);		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);	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){	/* TODO: add support for verifying that the user entry accepts	 * EAP-TTLS/PAP. */	if (!sm->user || !sm->user->password || sm->user->password_hash) {		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 ||	    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[MD5_MAC_LEN];	const u8 *addr[3];	size_t len[3];	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;	}	/* TODO: add support for verifying that the user entry accepts	 * EAP-TTLS/CHAP. */	if (!sm->user || !sm->user->password || sm->user->password_hash) {		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 (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");		free(chal);		eap_ttls_state(data, FAILURE);		return;	}	free(chal);	/* MD5(Ident + Password + Challenge) */	addr[0] = password;	len[0] = 1;	addr[1] = sm->user->password;	len[1] = sm->user->password_len;	addr[2] = challenge;	len[2] = challenge_len;	md5_vector(3, addr, len, hash);	if (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;	}	/* TODO: add support for verifying that the user entry accepts	 * EAP-TTLS/MSCHAP. */	if (!sm->user || !sm->user->password) {		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 (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");		free(chal);		eap_ttls_state(data, FAILURE);		return;	}	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 (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], *pos, *rx_resp, *peer_challenge,		*auth_challenge;	size_t username_len;	int 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;	}	/* TODO: add support for verifying that the user entry accepts	 * EAP-TTLS/MSCHAPV2. */	if (!sm->user || !sm->user->password) {		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;	pos = username;	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 (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");		free(chal);		eap_ttls_state(data, FAILURE);		return;	}	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 (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)

⌨️ 快捷键说明

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