Exemplo n.º 1
0
SM_STATE(EAP, IDENTITY)
{
	u8 *eapReqData;
	size_t eapReqDataLen;

	SM_ENTRY(EAP, IDENTITY);
	eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
	eap_sm_processIdentity(sm, eapReqData, eapReqDataLen);
	free(sm->eapRespData);
	sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId,
					       &sm->eapRespDataLen, 0);
}
Exemplo n.º 2
0
static int eap_peap_phase2_request(struct eap_sm *sm,
				   struct eap_peap_data *data,
				   struct eap_method_ret *ret,
				   struct wpabuf *req,
				   struct wpabuf **resp)
{
	struct eap_hdr *hdr = wpabuf_mhead(req);
	size_t len = be_to_host16(hdr->length);
	u8 *pos;
	struct eap_method_ret iret;
	struct eap_peer_config *config = eap_get_config(sm);

	if (len <= sizeof(struct eap_hdr)) {
		wpa_printf(MSG_INFO, "EAP-PEAP: too short "
			   "Phase 2 request (len=%lu)", (unsigned long) len);
		return -1;
	}
	pos = (u8 *) (hdr + 1);
	wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Request: type=%d", *pos);
	switch (*pos) {
	case EAP_TYPE_IDENTITY:
		*resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
		break;
	case EAP_TYPE_TLV:
		os_memset(&iret, 0, sizeof(iret));
		if (eap_tlv_process(sm, data, &iret, req, resp,
				    data->phase2_eap_started &&
				    !data->phase2_eap_success)) {
			ret->methodState = METHOD_DONE;
			ret->decision = DECISION_FAIL;
			return -1;
		}
		if (iret.methodState == METHOD_DONE ||
		    iret.methodState == METHOD_MAY_CONT) {
			ret->methodState = iret.methodState;
			ret->decision = iret.decision;
			data->phase2_success = 1;
		}
		break;
	case EAP_TYPE_EXPANDED:
#ifdef EAP_TNC
		if (data->soh) {
			const u8 *epos;
			size_t eleft;

			epos = eap_hdr_validate(EAP_VENDOR_MICROSOFT, 0x21,
						req, &eleft);
			if (epos) {
				struct wpabuf *buf;
				wpa_printf(MSG_DEBUG,
					   "EAP-PEAP: SoH EAP Extensions");
				buf = tncc_process_soh_request(data->soh,
							       epos, eleft);
				if (buf) {
					*resp = eap_msg_alloc(
						EAP_VENDOR_MICROSOFT, 0x21,
						wpabuf_len(buf),
						EAP_CODE_RESPONSE,
						hdr->identifier);
					if (*resp == NULL) {
						ret->methodState = METHOD_DONE;
						ret->decision = DECISION_FAIL;
						return -1;
					}
					wpabuf_put_buf(*resp, buf);
					wpabuf_free(buf);
					break;
				}
			}
		}
#endif /* EAP_TNC */
		/* fall through */
	default:
		if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
		    data->phase2_type.method == EAP_TYPE_NONE) {
			size_t i;
			for (i = 0; i < data->num_phase2_types; i++) {
				if (data->phase2_types[i].vendor !=
				    EAP_VENDOR_IETF ||
				    data->phase2_types[i].method != *pos)
					continue;

				data->phase2_type.vendor =
					data->phase2_types[i].vendor;
				data->phase2_type.method =
					data->phase2_types[i].method;
				wpa_printf(MSG_DEBUG, "EAP-PEAP: Selected "
					   "Phase 2 EAP vendor %d method %d",
					   data->phase2_type.vendor,
					   data->phase2_type.method);
				break;
			}
		}
		if (*pos != data->phase2_type.method ||
		    *pos == EAP_TYPE_NONE) {
			if (eap_peer_tls_phase2_nak(data->phase2_types,
						    data->num_phase2_types,
						    hdr, resp))
				return -1;
			return 0;
		}

		if (data->phase2_priv == NULL) {
			data->phase2_method = eap_peer_get_eap_method(
				data->phase2_type.vendor,
				data->phase2_type.method);
			if (data->phase2_method) {
				sm->init_phase2 = 1;
				data->phase2_priv =
					data->phase2_method->init(sm);
				sm->init_phase2 = 0;
			}
		}
		if (data->phase2_priv == NULL || data->phase2_method == NULL) {
			wpa_printf(MSG_INFO, "EAP-PEAP: failed to initialize "
				   "Phase 2 EAP method %d", *pos);
			ret->methodState = METHOD_DONE;
			ret->decision = DECISION_FAIL;
			return -1;
		}
		data->phase2_eap_started = 1;
		os_memset(&iret, 0, sizeof(iret));
		*resp = data->phase2_method->process(sm, data->phase2_priv,
						     &iret, req);
		if ((iret.methodState == METHOD_DONE ||
		     iret.methodState == METHOD_MAY_CONT) &&
		    (iret.decision == DECISION_UNCOND_SUCC ||
		     iret.decision == DECISION_COND_SUCC)) {
			data->phase2_eap_success = 1;
			data->phase2_success = 1;
		}
		break;
	}

	if (*resp == NULL &&
	    (config->pending_req_identity || config->pending_req_password ||
	     config->pending_req_otp || config->pending_req_new_password)) {
		wpabuf_free(data->pending_phase2_req);
		data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
	}

	return 0;
}
Exemplo n.º 3
0
static int eap_fast_phase2_request(struct eap_sm *sm,
				   struct eap_fast_data *data,
				   struct eap_method_ret *ret,
				   struct eap_hdr *hdr,
				   struct wpabuf **resp)
{
	size_t len = be_to_host16(hdr->length);
	u8 *pos;
	struct eap_method_ret iret;
	struct eap_peer_config *config = eap_get_config(sm);
	struct wpabuf msg;

	if (len <= sizeof(struct eap_hdr)) {
		wpa_printf(MSG_INFO, "EAP-FAST: too short "
			   "Phase 2 request (len=%lu)", (unsigned long) len);
		return -1;
	}
	pos = (u8 *) (hdr + 1);
	wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 Request: type=%d", *pos);
	if (*pos == EAP_TYPE_IDENTITY) {
		*resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
		return 0;
	}

	if (data->phase2_priv && data->phase2_method &&
	    *pos != data->phase2_type.method) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 EAP sequence - "
			   "deinitialize previous method");
		data->phase2_method->deinit(sm, data->phase2_priv);
		data->phase2_method = NULL;
		data->phase2_priv = NULL;
		data->phase2_type.vendor = EAP_VENDOR_IETF;
		data->phase2_type.method = EAP_TYPE_NONE;
	}

	if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
	    data->phase2_type.method == EAP_TYPE_NONE &&
	    eap_fast_select_phase2_method(data, *pos) < 0) {
		if (eap_peer_tls_phase2_nak(data->phase2_types,
					    data->num_phase2_types,
					    hdr, resp))
			return -1;
		return 0;
	}

	if (data->phase2_priv == NULL &&
	    eap_fast_init_phase2_method(sm, data) < 0) {
		wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize "
			   "Phase 2 EAP method %d", *pos);
		ret->methodState = METHOD_DONE;
		ret->decision = DECISION_FAIL;
		return -1;
	}

	os_memset(&iret, 0, sizeof(iret));
	wpabuf_set(&msg, hdr, len);
	*resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
					     &msg);
	if (*resp == NULL ||
	    (iret.methodState == METHOD_DONE &&
	     iret.decision == DECISION_FAIL)) {
		ret->methodState = METHOD_DONE;
		ret->decision = DECISION_FAIL;
	} else if ((iret.methodState == METHOD_DONE ||
		    iret.methodState == METHOD_MAY_CONT) &&
		   (iret.decision == DECISION_UNCOND_SUCC ||
		    iret.decision == DECISION_COND_SUCC)) {
		data->phase2_success = 1;
	}

	if (*resp == NULL && config &&
	    (config->pending_req_identity || config->pending_req_password ||
	     config->pending_req_otp || config->pending_req_new_password)) {
		wpabuf_free(data->pending_phase2_req);
		data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
	} else if (*resp == NULL)
		return -1;

	return 0;
}
Exemplo n.º 4
0
int eap_peer_step(void)
{
	unsigned char data[0x4000];
	int res;
	res = eap_peer_sm_step(eap_ctx.eap);
	
	/* This part was not tested properly */
	if(	!eap_ctx.eapSuccess &&
		!eap_ctx.eapRestart &&
		!eap_ctx.eapFail &&
		!eap_ctx.eapResp &&
		!eap_ctx.eapNoResp &&
		!eap_ctx.eapReq
	) {
		struct wpabuf *resp;
		resp = eap_sm_buildIdentity( eap_ctx.eap, 0, 0 );
		if (resp) {
			// Send EAP response to the server 
			memcpy(data,wpabuf_head(resp),wpabuf_len(resp)); // memcpy Maybe useless!!!!
			eap_server_rx(data,  wpabuf_len(resp));		

			wpabuf_free(resp);
		}	
	}
		
	if (eap_ctx.eapResp) {
		struct wpabuf *resp;
		eap_ctx.eapResp = FALSE;
		resp = eap_get_eapRespData(eap_ctx.eap);
		if (resp) {
			/* Send EAP response to the server */
			memcpy(data,wpabuf_head(resp),wpabuf_len(resp)); // memcpy Maybe useless!!!!
			eap_server_rx(data,  wpabuf_len(resp));		
			
			//eap_server_rx(wpabuf_head(resp),
			//		      wpabuf_len(resp));
			wpabuf_free(resp);
		}
	}

	if (eap_ctx.eapSuccess) {
		res = 0;
		if (eap_key_available(eap_ctx.eap)) {
			const u8 *key;
			size_t key_len;
			key = eap_get_eapKeyData(eap_ctx.eap, &key_len);

			memcpy(data,key,key_len);
			eap_key(data, key_len);
			
			wpa_hexdump(MSG_DEBUG, "EAP keying material",
				    key, key_len);
		}
	}
	
	if (eap_ctx.eapFail) {
		res = -1;
	}	
		
	return res;
}
static int eap_ttls_phase2_request_eap(struct eap_sm *sm,
				       struct eap_ttls_data *data,
				       struct eap_method_ret *ret,
				       struct eap_hdr *hdr,
				       u8 **resp, size_t *resp_len)
{
	size_t len = be_to_host16(hdr->length);
	u8 *pos;
	struct eap_method_ret iret;
	struct wpa_ssid *config = eap_get_config(sm);

	if (len <= sizeof(struct eap_hdr)) {
		wpa_printf(MSG_INFO, "EAP-TTLS: too short "
			   "Phase 2 request (len=%lu)", (unsigned long) len);
		return -1;
	}
	pos = (u8 *) (hdr + 1);
	wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP Request: type=%d", *pos);
	switch (*pos) {
	case EAP_TYPE_IDENTITY:
		*resp = eap_sm_buildIdentity(sm, hdr->identifier, resp_len, 1);
		break;
	default:
		if (data->phase2_eap_type.vendor == EAP_VENDOR_IETF &&
		    data->phase2_eap_type.method == EAP_TYPE_NONE) {
			size_t i;
			for (i = 0; i < data->num_phase2_eap_types; i++) {
				if (data->phase2_eap_types[i].vendor !=
				    EAP_VENDOR_IETF ||
				    data->phase2_eap_types[i].method != *pos)
					continue;

				data->phase2_eap_type.vendor =
					data->phase2_eap_types[i].vendor;
				data->phase2_eap_type.method =
					data->phase2_eap_types[i].method;
				wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
					   "Phase 2 EAP vendor %d method %d",
					   data->phase2_eap_type.vendor,
					   data->phase2_eap_type.method);
				break;
			}
		}
		if (*pos != data->phase2_eap_type.method ||
		    *pos == EAP_TYPE_NONE) {
			if (eap_ttls_phase2_nak(data, hdr, resp, resp_len))
				return -1;
			break;
		}

		if (data->phase2_priv == NULL) {
			data->phase2_method = eap_sm_get_eap_methods(
				EAP_VENDOR_IETF, *pos);
			if (data->phase2_method) {
				sm->init_phase2 = 1;
				sm->mschapv2_full_key = 1;
				data->phase2_priv =
					data->phase2_method->init(sm);
				sm->init_phase2 = 0;
				sm->mschapv2_full_key = 0;
			}
		}
		if (data->phase2_priv == NULL || data->phase2_method == NULL) {
			wpa_printf(MSG_INFO, "EAP-TTLS: failed to initialize "
				   "Phase 2 EAP method %d", *pos);
			return -1;
		}
		os_memset(&iret, 0, sizeof(iret));
		*resp = data->phase2_method->process(sm, data->phase2_priv,
						     &iret, (u8 *) hdr, len,
						     resp_len);
		if ((iret.methodState == METHOD_DONE ||
		     iret.methodState == METHOD_MAY_CONT) &&
		    (iret.decision == DECISION_UNCOND_SUCC ||
		     iret.decision == DECISION_COND_SUCC ||
		     iret.decision == DECISION_FAIL)) {
			ret->methodState = iret.methodState;
			ret->decision = iret.decision;
		}
		if (data->ttls_version > 0) {
			const struct eap_method *m = data->phase2_method;
			void *priv = data->phase2_priv;

			/* TTLSv1 requires TLS/IA FinalPhaseFinished */
			if (ret->decision == DECISION_UNCOND_SUCC)
				ret->decision = DECISION_COND_SUCC;
			ret->methodState = METHOD_CONT;

			if (ret->decision == DECISION_COND_SUCC &&
			    m->isKeyAvailable && m->getKey &&
			    m->isKeyAvailable(sm, priv)) {
				u8 *key;
				size_t key_len;
				key = m->getKey(sm, priv, &key_len);
				if (key) {
					eap_ttls_ia_permute_inner_secret(
						sm, data, key, key_len);
					os_free(key);
				}
			}
		}
		break;
	}

	if (*resp == NULL &&
	    (config->pending_req_identity || config->pending_req_password ||
	     config->pending_req_otp)) {
		return 0;
	}

	if (*resp == NULL)
		return -1;

	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP encapsulate EAP Response",
		    *resp, *resp_len);
	return eap_ttls_avp_encapsulate(resp, resp_len,
					RADIUS_ATTR_EAP_MESSAGE, 1);
}