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

📄 eap_aka.c

📁 IEEE 802.11a/b/g 服务器端AP
💻 C
📖 第 1 页 / 共 2 页
字号:
		   sm->identity[0] == EAP_AKA_PERMANENT_PREFIX) {		identity = sm->identity;		identity_len = sm->identity_len;	} else {		identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv,						    sm->identity,						    sm->identity_len,						    &identity_len);		if (identity == NULL) {			data->reauth = eap_sim_db_get_reauth_entry(				sm->eap_sim_db_priv, sm->identity,				sm->identity_len);			if (data->reauth) {				wpa_printf(MSG_DEBUG, "EAP-AKA: Using fast "					   "re-authentication");				identity = data->reauth->identity;				identity_len = data->reauth->identity_len;				data->counter = data->reauth->counter;				os_memcpy(data->mk, data->reauth->mk,					  EAP_SIM_MK_LEN);			}		}	}	if (identity == NULL ||	    eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity,				      sm->identity_len) < 0) {		if (before_identity) {			wpa_printf(MSG_DEBUG, "EAP-AKA: Permanent user name "				   "not known - send AKA-Identity request");			eap_aka_state(data, IDENTITY);			return;		} else {			wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown whether the "				   "permanent user name is known; try to use "				   "it");			/* eap_sim_db_get_aka_auth() will report failure, if			 * this identity is not known. */		}	}	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity",			  identity, identity_len);	if (!after_reauth && data->reauth) {		eap_aka_state(data, REAUTH);		return;	}	res = eap_sim_db_get_aka_auth(sm->eap_sim_db_priv, identity,				      identity_len, data->rand, data->autn,				      data->ik, data->ck, data->res,				      &data->res_len, sm);	if (res == EAP_SIM_DB_PENDING) {		wpa_printf(MSG_DEBUG, "EAP-AKA: AKA authentication data "			   "not yet available - pending request");		sm->method_pending = METHOD_PENDING_WAIT;		return;	}	data->reauth = NULL;	data->counter = 0; /* reset re-auth counter since this is full auth */	if (res != 0) {		wpa_printf(MSG_INFO, "EAP-AKA: Failed to get AKA "			   "authentication data for the peer");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	if (sm->method_pending == METHOD_PENDING_WAIT) {		wpa_printf(MSG_DEBUG, "EAP-AKA: AKA authentication data "			   "available - abort pending wait");		sm->method_pending = METHOD_PENDING_NONE;	}	identity_len = sm->identity_len;	while (identity_len > 0 && sm->identity[identity_len - 1] == '\0') {		wpa_printf(MSG_DEBUG, "EAP-AKA: Workaround - drop last null "			   "character from identity");		identity_len--;	}	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity for MK derivation",			  sm->identity, identity_len);	eap_aka_derive_mk(sm->identity, identity_len, data->ik, data->ck,			  data->mk);	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,			    data->emsk);	eap_aka_state(data, CHALLENGE);}static void eap_aka_process_identity(struct eap_sm *sm,				     struct eap_aka_data *data,				     struct wpabuf *respData,				     struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Identity");	if (attr->mac || attr->iv || attr->encr_data) {		wpa_printf(MSG_WARNING, "EAP-AKA: Unexpected attribute "			   "received in EAP-Response/AKA-Identity");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	if (attr->identity) {		os_free(sm->identity);		sm->identity = os_malloc(attr->identity_len);		if (sm->identity) {			os_memcpy(sm->identity, attr->identity,				  attr->identity_len);			sm->identity_len = attr->identity_len;		}	}	eap_aka_determine_identity(sm, data, 0, 0);	if (eap_get_id(respData) == data->pending_id) {		data->pending_id = -1;		eap_aka_add_id_msg(data, respData);	}}static void eap_aka_process_challenge(struct eap_sm *sm,				      struct eap_aka_data *data,				      struct wpabuf *respData,				      struct eap_sim_attrs *attr){	const u8 *identity;	size_t identity_len;	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Challenge");	if (attr->checkcode &&	    eap_aka_verify_checkcode(data, attr->checkcode,				     attr->checkcode_len)) {		wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "			   "message");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	if (attr->mac == NULL ||	    eap_sim_verify_mac(data->k_aut, respData, attr->mac, NULL, 0)) {		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "			   "did not include valid AT_MAC");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	if (attr->res == NULL || attr->res_len != data->res_len ||	    os_memcmp(attr->res, data->res, data->res_len) != 0) {		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not "			   "include valid AT_RES");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	wpa_printf(MSG_DEBUG, "EAP-AKA: Challenge response includes the "		   "correct AT_MAC");	if (sm->eap_sim_aka_result_ind && attr->result_ind) {		data->use_result_ind = 1;		data->notification = EAP_SIM_SUCCESS;		eap_aka_state(data, NOTIFICATION);	} else		eap_aka_state(data, SUCCESS);	identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv, sm->identity,					    sm->identity_len, &identity_len);	if (identity == NULL) {		identity = sm->identity;		identity_len = sm->identity_len;	}	if (data->next_pseudonym) {		eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,					 identity_len,					 data->next_pseudonym);		data->next_pseudonym = NULL;	}	if (data->next_reauth_id) {		eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,				      identity_len,				      data->next_reauth_id, data->counter + 1,				      data->mk);		data->next_reauth_id = NULL;	}}static void eap_aka_process_sync_failure(struct eap_sm *sm,					 struct eap_aka_data *data,					 struct wpabuf *respData,					 struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Synchronization-Failure");	if (attr->auts == NULL) {		wpa_printf(MSG_WARNING, "EAP-AKA: Synchronization-Failure "			   "message did not include valid AT_AUTS");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	/* Avoid re-reporting AUTS when processing pending EAP packet by	 * maintaining a local flag stating whether this AUTS has already been	 * reported. */	if (!data->auts_reported &&	    eap_sim_db_resynchronize(sm->eap_sim_db_priv, sm->identity,				     sm->identity_len, attr->auts,				     data->rand)) {		wpa_printf(MSG_WARNING, "EAP-AKA: Resynchronization failed");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	data->auts_reported = 1;	/* Try again after resynchronization */	eap_aka_determine_identity(sm, data, 0, 0);}static void eap_aka_process_reauth(struct eap_sm *sm,				   struct eap_aka_data *data,				   struct wpabuf *respData,				   struct eap_sim_attrs *attr){	struct eap_sim_attrs eattr;	u8 *decrypted = NULL;	const u8 *identity, *id2;	size_t identity_len, id2_len;	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Reauthentication");	if (attr->mac == NULL ||	    eap_sim_verify_mac(data->k_aut, respData, attr->mac, data->nonce_s,			       EAP_SIM_NONCE_S_LEN)) {		wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message "			   "did not include valid AT_MAC");		goto fail;	}	if (attr->encr_data == NULL || attr->iv == NULL) {		wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "			   "message did not include encrypted data");		goto fail;	}	decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,				       attr->encr_data_len, attr->iv, &eattr,				       0);	if (decrypted == NULL) {		wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "			   "data from reauthentication message");		goto fail;	}	if (eattr.counter != data->counter) {		wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message "			   "used incorrect counter %u, expected %u",			   eattr.counter, data->counter);		goto fail;	}	os_free(decrypted);	decrypted = NULL;	wpa_printf(MSG_DEBUG, "EAP-AKA: Re-authentication response includes "		   "the correct AT_MAC");	if (eattr.counter_too_small) {		wpa_printf(MSG_DEBUG, "EAP-AKA: Re-authentication response "			   "included AT_COUNTER_TOO_SMALL - starting full "			   "authentication");		eap_aka_determine_identity(sm, data, 0, 1);		return;	}	if (sm->eap_sim_aka_result_ind && attr->result_ind) {		data->use_result_ind = 1;		data->notification = EAP_SIM_SUCCESS;		eap_aka_state(data, NOTIFICATION);	} else		eap_aka_state(data, SUCCESS);	if (data->reauth) {		identity = data->reauth->identity;		identity_len = data->reauth->identity_len;	} else {		identity = sm->identity;		identity_len = sm->identity_len;	}	id2 = eap_sim_db_get_permanent(sm->eap_sim_db_priv, identity,				       identity_len, &id2_len);	if (id2) {		identity = id2;		identity_len = id2_len;	}	if (data->next_pseudonym) {		eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,					 identity_len, data->next_pseudonym);		data->next_pseudonym = NULL;	}	if (data->next_reauth_id) {		eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,				      identity_len, data->next_reauth_id,				      data->counter + 1, data->mk);		data->next_reauth_id = NULL;	} else {		eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);		data->reauth = NULL;	}	return;fail:	data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;	eap_aka_state(data, NOTIFICATION);	eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);	data->reauth = NULL;	os_free(decrypted);}static void eap_aka_process_client_error(struct eap_sm *sm,					 struct eap_aka_data *data,					 struct wpabuf *respData,					 struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Client reported error %d",		   attr->client_error_code);	if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)		eap_aka_state(data, SUCCESS);	else		eap_aka_state(data, FAILURE);}static void eap_aka_process_authentication_reject(	struct eap_sm *sm, struct eap_aka_data *data,	struct wpabuf *respData, struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Client rejected authentication");	eap_aka_state(data, FAILURE);}static void eap_aka_process_notification(struct eap_sm *sm,					 struct eap_aka_data *data,					 struct wpabuf *respData,					 struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Client replied to notification");	if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)		eap_aka_state(data, SUCCESS);	else		eap_aka_state(data, FAILURE);}static void eap_aka_process(struct eap_sm *sm, void *priv,			    struct wpabuf *respData){	struct eap_aka_data *data = priv;	const u8 *pos, *end;	u8 subtype;	size_t len;	struct eap_sim_attrs attr;	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA, respData, &len);	if (pos == NULL || len < 3)		return;	end = pos + len;	subtype = *pos;	pos += 3;	if (eap_aka_subtype_ok(data, subtype)) {		wpa_printf(MSG_DEBUG, "EAP-AKA: Unrecognized or unexpected "			   "EAP-AKA Subtype in EAP Response");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	if (eap_sim_parse_attr(pos, end, &attr, 1, 0)) {		wpa_printf(MSG_DEBUG, "EAP-AKA: Failed to parse attributes");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	if (subtype == EAP_AKA_SUBTYPE_CLIENT_ERROR) {		eap_aka_process_client_error(sm, data, respData, &attr);		return;	}	if (subtype == EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT) {		eap_aka_process_authentication_reject(sm, data, respData,						      &attr);		return;	}	switch (data->state) {	case IDENTITY:		eap_aka_process_identity(sm, data, respData, &attr);		break;	case CHALLENGE:		if (subtype == EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE) {			eap_aka_process_sync_failure(sm, data, respData,						     &attr);		} else {			eap_aka_process_challenge(sm, data, respData, &attr);		}		break;	case REAUTH:		eap_aka_process_reauth(sm, data, respData, &attr);		break;	case NOTIFICATION:		eap_aka_process_notification(sm, data, respData, &attr);		break;	default:		wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown state %d in "			   "process", data->state);		break;	}}static Boolean eap_aka_isDone(struct eap_sm *sm, void *priv){	struct eap_aka_data *data = priv;	return data->state == SUCCESS || data->state == FAILURE;}static u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len){	struct eap_aka_data *data = priv;	u8 *key;	if (data->state != SUCCESS)		return NULL;	key = os_malloc(EAP_SIM_KEYING_DATA_LEN);	if (key == NULL)		return NULL;	os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);	*len = EAP_SIM_KEYING_DATA_LEN;	return key;}static u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len){	struct eap_aka_data *data = priv;	u8 *key;	if (data->state != SUCCESS)		return NULL;	key = os_malloc(EAP_EMSK_LEN);	if (key == NULL)		return NULL;	os_memcpy(key, data->emsk, EAP_EMSK_LEN);	*len = EAP_EMSK_LEN;	return key;}static Boolean eap_aka_isSuccess(struct eap_sm *sm, void *priv){	struct eap_aka_data *data = priv;	return data->state == SUCCESS;}int eap_server_aka_register(void){	struct eap_method *eap;	int ret;	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,				      EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA");	if (eap == NULL)		return -1;	eap->init = eap_aka_init;	eap->reset = eap_aka_reset;	eap->buildReq = eap_aka_buildReq;	eap->check = eap_aka_check;	eap->process = eap_aka_process;	eap->isDone = eap_aka_isDone;	eap->getKey = eap_aka_getKey;	eap->isSuccess = eap_aka_isSuccess;	eap->get_emsk = eap_aka_get_emsk;	ret = eap_server_method_register(eap);	if (ret)		eap_server_method_free(eap);	return ret;}

⌨️ 快捷键说明

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