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

📄 eap_ttls.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 4 页
字号:
			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;		if (left < avp_length + pad)			left = 0;		else			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=%lu, EAP "				   "data len in AVP=%lu)",				   (unsigned long) len,				   (unsigned long) eap_len);			retval = -1;			goto done;		}		wpa_printf(MSG_DEBUG, "EAP-TTLS: received Phase 2: code=%d "			   "identifier=%d length=%lu",			   hdr->code, hdr->identifier, (unsigned long) 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) ||		    os_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");		if (data->ttls_version > 0) {			/* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report			 * success, so do not allow connection to be terminated			 * yet. */			ret->methodState = METHOD_CONT;			ret->decision = DECISION_COND_SUCC;		} else {			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");		}		os_free(resp);	} else if (config->pending_req_identity ||		   config->pending_req_password ||		   config->pending_req_otp ||		   config->pending_req_new_password) {		os_free(data->pending_phase2_req);		data->pending_phase2_req = os_malloc(len_decrypted);		if (data->pending_phase2_req) {			os_memcpy(data->pending_phase2_req, in_decrypted,				  len_decrypted);			data->pending_phase2_req_len = len_decrypted;		}	}done:	os_free(in_decrypted);	os_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;	struct wpa_ssid *config = eap_get_config(sm);	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 (server ver=%d, own "			   "ver=%d)", flags & EAP_PEAP_VERSION_MASK,			   data->ttls_version);		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 NULL;		}		wpa_printf(MSG_DEBUG, "EAP-TTLS: Using TTLS version %d",			   data->ttls_version);		if (data->ttls_version > 0)			data->ssl.tls_ia = 1;		if (!data->ssl_initialized &&		    eap_tls_ssl_init(sm, &data->ssl, config)) {			wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize "				   "SSL.");			return NULL;		}		data->ssl_initialized = 1;		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;	} 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) {		res = eap_ttls_decrypt(sm, data, ret, req, pos, left,				       &resp, respDataLen);	} else {		res = eap_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS,					     data->ttls_version, 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;			if (data->ttls_version == 0)				eap_ttls_v0_derive_key(sm, data);			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 (res == 2) {			/*			 * Application data included in the handshake message.			 */			os_free(data->pending_phase2_req);			data->pending_phase2_req = resp;			data->pending_phase2_req_len = *respDataLen;			resp = NULL;			*respDataLen = 0;			res = eap_ttls_decrypt(sm, data, ret, req, pos, left,					       &resp, respDataLen);		}	}	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;		}	} else if (data->ttls_version == 0 && 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, 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;	os_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;	os_free(data->key_data);	data->key_data = NULL;	if (eap_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_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 + -