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

📄 eap_ttls.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	return 0;}#if EAP_TTLS_VERSION > 0static void eap_ttls_final_phase_finished(struct eap_sm *sm,					  struct eap_ttls_data *data,					  struct eap_method_ret *ret,					  u8 identifier,					  struct wpabuf **out_data){	wpa_printf(MSG_DEBUG, "EAP-TTLS: FinalPhaseFinished received");	wpa_printf(MSG_INFO, "EAP-TTLS: TLS/IA authentication succeeded");	ret->methodState = METHOD_DONE;	ret->decision = DECISION_UNCOND_SUCC;	data->phase2_success = 1;	*out_data = eap_ttls_build_phase_finished(sm, data, identifier, 1);	eap_ttls_v1_derive_key(sm, data);}#endif /* EAP_TTLS_VERSION */static int eap_ttls_implicit_identity_request(struct eap_sm *sm,					      struct eap_ttls_data *data,					      struct eap_method_ret *ret,					      u8 identifier,					      struct wpabuf **out_data){	int retval = 0;	struct eap_hdr *hdr;	struct wpabuf *resp;	hdr = (struct eap_hdr *) eap_ttls_fake_identity_request();	if (hdr == NULL) {		ret->methodState = METHOD_DONE;		ret->decision = DECISION_FAIL;		return -1;	}	resp = NULL;	if (eap_ttls_phase2_request(sm, data, ret, hdr, &resp)) {		wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "			   "processing failed");		retval = -1;	} else {		retval = eap_ttls_encrypt_response(sm, data, resp, identifier,						   out_data);	}	os_free(hdr);	if (retval < 0) {		ret->methodState = METHOD_DONE;		ret->decision = DECISION_FAIL;	}	return retval;}static int eap_ttls_phase2_start(struct eap_sm *sm, struct eap_ttls_data *data,				 struct eap_method_ret *ret, u8 identifier,				 struct wpabuf **out_data){	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_peer_tls_build_ack(identifier, EAP_TYPE_TTLS,						   data->ttls_version);		ret->methodState = METHOD_DONE;		ret->decision = DECISION_UNCOND_SUCC;		data->phase2_success = 1;		return 0;	}	return eap_ttls_implicit_identity_request(sm, data, ret, identifier,						  out_data);}static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,			    struct eap_method_ret *ret, u8 identifier,			    const struct wpabuf *in_data,			    struct wpabuf **out_data){	struct wpabuf *in_decrypted = NULL;	int retval = 0;	struct ttls_parse_avp parse;	os_memset(&parse, 0, sizeof(parse));	wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"		   " Phase 2",		   in_data ? (unsigned long) wpabuf_len(in_data) : 0);	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. */		eap_peer_tls_reset_input(&data->ssl);		in_decrypted = data->pending_phase2_req;		data->pending_phase2_req = NULL;		if (wpabuf_len(in_decrypted) == 0) {			wpabuf_free(in_decrypted);			return eap_ttls_implicit_identity_request(				sm, data, ret, identifier, out_data);		}		goto continue_req;	}	if ((in_data == NULL || wpabuf_len(in_data) == 0) &&	    data->phase2_start) {		return eap_ttls_phase2_start(sm, data, ret, identifier,					     out_data);	}	if (in_data == NULL || wpabuf_len(in_data) == 0) {		/* Received TLS ACK - requesting more fragments */		return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,					    data->ttls_version,					    identifier, NULL, out_data);	}	retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);	if (retval)		goto done;#if EAP_TTLS_VERSION > 0	if (data->ttls_version > 0 &&	    (in_decrypted == NULL || wpabuf_len(in_decrypted) == 0) &&	    tls_connection_ia_final_phase_finished(sm->ssl_ctx,						   data->ssl.conn)) {		eap_ttls_final_phase_finished(sm, data, ret, identifier,					      out_data);		goto done;	}#endif /* EAP_TTLS_VERSION */continue_req:	data->phase2_start = 0;	if (eap_ttls_parse_avps(in_decrypted, &parse) < 0) {		retval = -1;		goto done;	}	retval = eap_ttls_process_decrypted(sm, data, ret, identifier,					    &parse, in_decrypted, out_data);done:	wpabuf_free(in_decrypted);	os_free(parse.eapdata);	if (retval < 0) {		ret->methodState = METHOD_DONE;		ret->decision = DECISION_FAIL;	}	return retval;}static int eap_ttls_process_start(struct eap_sm *sm,				  struct eap_ttls_data *data, u8 flags,				  struct eap_method_ret *ret){	struct eap_peer_config *config = eap_get_config(sm);	wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own ver=%d)",		   flags & EAP_PEAP_VERSION_MASK, data->ttls_version);#if EAP_TTLS_VERSION > 0	if ((flags & EAP_PEAP_VERSION_MASK) < data->ttls_version)		data->ttls_version = flags & EAP_PEAP_VERSION_MASK;	if (data->force_ttls_version >= 0 &&	    data->force_ttls_version != data->ttls_version) {		wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to select "			   "forced TTLS version %d",			   data->force_ttls_version);		ret->methodState = METHOD_DONE;		ret->decision = DECISION_FAIL;		ret->allowNotifications = FALSE;		return -1;	}	wpa_printf(MSG_DEBUG, "EAP-TTLS: Using TTLS version %d",		   data->ttls_version);	if (data->ttls_version > 0)		data->ssl.tls_ia = 1;#endif /* EAP_TTLS_VERSION */	if (!data->ssl_initialized &&	    eap_peer_tls_ssl_init(sm, &data->ssl, config)) {		wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");		return -1;	}	data->ssl_initialized = 1;	wpa_printf(MSG_DEBUG, "EAP-TTLS: Start");	return 0;}static int eap_ttls_process_handshake(struct eap_sm *sm,				      struct eap_ttls_data *data,				      struct eap_method_ret *ret,				      u8 identifier,				      const u8 *in_data, size_t in_len,				      struct wpabuf **out_data){	int res;	res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS,					  data->ttls_version, identifier,					  in_data, in_len, out_data);	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;		if (data->ttls_version == 0)			eap_ttls_v0_derive_key(sm, data);		if (*out_data == NULL || wpabuf_len(*out_data) == 0) {			if (eap_ttls_decrypt(sm, data, ret, identifier,					     NULL, out_data)) {				wpa_printf(MSG_WARNING, "EAP-TTLS: "					   "failed to process early "					   "start for Phase 2");			}			res = 0;		}		data->resuming = 0;	}	if (res == 2) {		struct wpabuf msg;		/*		 * Application data included in the handshake message.		 */		wpabuf_free(data->pending_phase2_req);		data->pending_phase2_req = *out_data;		*out_data = NULL;		wpabuf_set(&msg, in_data, in_len);		res = eap_ttls_decrypt(sm, data, ret, identifier, &msg,				       out_data);	}	return res;}static void eap_ttls_check_auth_status(struct eap_sm *sm, 				       struct eap_ttls_data *data,				       struct eap_method_ret *ret){	if (data->ttls_version == 0 && 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;#ifdef EAP_TNC			if (!data->ready_for_tnc && !data->tnc_started) {				/*				 * TNC may be required as the next				 * authentication method within the tunnel.				 */				ret->methodState = METHOD_MAY_CONT;				data->ready_for_tnc = 1;			}#endif /* EAP_TNC */		}	} else if (data->ttls_version == 0 &&		   ret->methodState == METHOD_MAY_CONT &&		   (ret->decision == DECISION_UNCOND_SUCC ||		    ret->decision == DECISION_COND_SUCC)) {			wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "				   "completed successfully (MAY_CONT)");			data->phase2_success = 1;	}}static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,					struct eap_method_ret *ret,					const struct wpabuf *reqData){	size_t left;	int res;	u8 flags, id;	struct wpabuf *resp;	const u8 *pos;	struct eap_ttls_data *data = priv;	pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret,					reqData, &left, &flags);	if (pos == NULL)		return NULL;	id = eap_get_id(reqData);	if (flags & EAP_TLS_FLAGS_START) {		if (eap_ttls_process_start(sm, data, flags, ret) < 0)			return NULL;		/* RFC 5281, Ch. 9.2:		 * "This packet MAY contain additional information in the form		 * of AVPs, which may provide useful hints to the client"		 * For now, ignore any potential extra data.		 */		left = 0;	} else if (!data->ssl_initialized) {		wpa_printf(MSG_DEBUG, "EAP-TTLS: First message did not "			   "include Start flag");		ret->methodState = METHOD_DONE;		ret->decision = DECISION_FAIL;		ret->allowNotifications = FALSE;		return NULL;	}	resp = NULL;	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&	    !data->resuming) {		struct wpabuf msg;		wpabuf_set(&msg, pos, left);		res = eap_ttls_decrypt(sm, data, ret, id, &msg, &resp);	} else {		res = eap_ttls_process_handshake(sm, data, ret, id,						 pos, left, &resp);	}	eap_ttls_check_auth_status(sm, data, ret);	/* FIX: what about res == -1? Could just move all error processing into	 * the other functions and get rid of this res==1 case here. */	if (res == 1) {		wpabuf_free(resp);		return eap_peer_tls_build_ack(id, EAP_TYPE_TTLS,					      data->ttls_version);	}	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;	wpabuf_free(data->pending_phase2_req);	data->pending_phase2_req = NULL;#ifdef EAP_TNC	data->ready_for_tnc = 0;	data->tnc_started = 0;#endif /* EAP_TNC */}static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv){	struct eap_ttls_data *data = priv;	os_free(data->key_data);	data->key_data = NULL;	if (eap_peer_tls_reauth_init(sm, &data->ssl)) {		os_free(data);		return NULL;	}	if (data->phase2_priv && data->phase2_method &&	    data->phase2_method->init_for_reauth)		data->phase2_method->init_for_reauth(sm, data->phase2_priv);	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, ret;	len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);	ret = os_snprintf(buf + len, buflen - len,			  "EAP-TTLSv%d Phase2 method=",			  data->ttls_version);	if (ret < 0 || (size_t) ret >= buflen - len)		return len;	len += ret;	switch (data->phase2_type) {	case EAP_TTLS_PHASE2_EAP:		ret = os_snprintf(buf + len, buflen - len, "EAP-%s\n",				  data->phase2_method ?				  data->phase2_method->name : "?");		break;	case EAP_TTLS_PHASE2_MSCHAPV2:		ret = os_snprintf(buf + len, buflen - len, "MSCHAPV2\n");		break;	case EAP_TTLS_PHASE2_MSCHAP:		ret = os_snprintf(buf + len, buflen - len, "MSCHAP\n");		break;	case EAP_TTLS_PHASE2_PAP:		ret = os_snprintf(buf + len, buflen - len, "PAP\n");		break;	case EAP_TTLS_PHASE2_CHAP:		ret = os_snprintf(buf + len, buflen - len, "CHAP\n");		break;	default:		ret = 0;		break;	}	if (ret < 0 || (size_t) ret >= buflen - len)		return len;	len += ret;	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 = os_malloc(EAP_TLS_KEY_LEN);	if (key == NULL)		return NULL;	*len = EAP_TLS_KEY_LEN;	os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN);	return key;}int eap_peer_ttls_register(void){	struct eap_method *eap;	int ret;	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,				    EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");	if (eap == NULL)		return -1;	eap->init = eap_ttls_init;	eap->deinit = eap_ttls_deinit;	eap->process = eap_ttls_process;	eap->isKeyAvailable = eap_ttls_isKeyAvailable;	eap->getKey = eap_ttls_getKey;	eap->get_status = eap_ttls_get_status;	eap->has_reauth_data = eap_ttls_has_reauth_data;	eap->deinit_for_reauth = eap_ttls_deinit_for_reauth;	eap->init_for_reauth = eap_ttls_init_for_reauth;	ret = eap_peer_method_register(eap);	if (ret)		eap_peer_method_free(eap);	return ret;}

⌨️ 快捷键说明

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