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

📄 eap_aka.c

📁 hostapd源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* 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 (data->reauth) {		eap_aka_state(data, REAUTH);		return;	}	data->counter = 0; /* reset re-auth counter since this is full auth */	data->reauth = NULL;	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;	}	if (res != 0) {		wpa_printf(MSG_INFO, "EAP-AKA: Failed to get AKA "			   "authentication data for the peer");		eap_aka_state(data, FAILURE);		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;	}	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity for MK derivation",			  sm->identity, sm->identity_len);	eap_aka_derive_mk(sm->identity, sm->identity_len, data->ik, data->ck,			  data->mk);	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk);	eap_aka_state(data, CHALLENGE);}static void eap_aka_process_identity(struct eap_sm *sm,				     struct eap_aka_data *data,				     u8 *respData, size_t respDataLen,				     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");		eap_aka_state(data, FAILURE);		return;	}	if (attr->identity) {		free(sm->identity);		sm->identity = malloc(attr->identity_len);		if (sm->identity) {			memcpy(sm->identity, attr->identity,			       attr->identity_len);			sm->identity_len = attr->identity_len;		}	}	eap_aka_determine_identity(sm, data, 0);}static void eap_aka_process_challenge(struct eap_sm *sm,				      struct eap_aka_data *data,				      u8 *respData, size_t respDataLen,				      struct eap_sim_attrs *attr){	const u8 *identity;	size_t identity_len;	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Challenge");	if (attr->mac == NULL ||	    eap_sim_verify_mac(data->k_aut, respData, respDataLen, attr->mac,			       NULL, 0)) {		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "			   "did not include valid AT_MAC");		eap_aka_state(data, FAILURE);		return;	}	if (attr->res == NULL || attr->res_len != data->res_len ||	    memcmp(attr->res, data->res, data->res_len) != 0) {		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not "			   "include valid AT_RES");		eap_aka_state(data, FAILURE);		return;	}	wpa_printf(MSG_DEBUG, "EAP-AKA: Challenge response includes the "		   "correct AT_MAC");	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,					 u8 *respData, size_t respDataLen,					 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");		eap_aka_state(data, FAILURE);		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");		eap_aka_state(data, FAILURE);		return;	}	data->auts_reported = 1;	/* Try again after resynchronization */	eap_aka_determine_identity(sm, data, 0);}static void eap_aka_process_reauth(struct eap_sm *sm,				   struct eap_aka_data *data,				   u8 *respData, size_t respDataLen,				   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, respDataLen, 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;	}	free(decrypted);	decrypted = NULL;	wpa_printf(MSG_DEBUG, "EAP-AKA: Re-authentication response includes "		   "the correct AT_MAC");	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:	eap_aka_state(data, FAILURE);	eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);	data->reauth = NULL;	free(decrypted);}static void eap_aka_process_client_error(struct eap_sm *sm,					 struct eap_aka_data *data,					 u8 *respData, size_t respDataLen,					 struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Client reported error %d",		   attr->client_error_code);	eap_aka_state(data, FAILURE);}static void eap_aka_process(struct eap_sm *sm, void *priv,			    u8 *respData, size_t respDataLen){	struct eap_aka_data *data = priv;	struct eap_hdr *resp;	u8 *pos, subtype;	size_t len;	struct eap_sim_attrs attr;	resp = (struct eap_hdr *) respData;	pos = (u8 *) (resp + 1);	subtype = pos[1];	len = ntohs(resp->length);	pos += 4;	if (eap_sim_parse_attr(pos, respData + len, &attr, 1, 0)) {		wpa_printf(MSG_DEBUG, "EAP-AKA: Failed to parse attributes");		eap_aka_state(data, FAILURE);		return;	}	if (subtype == EAP_AKA_SUBTYPE_CLIENT_ERROR) {		eap_aka_process_client_error(sm, data, respData, len, &attr);		return;	}	switch (data->state) {	case IDENTITY:		eap_aka_process_identity(sm, data, respData, len, &attr);		break;	case CHALLENGE:		if (subtype == EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE) {			eap_aka_process_sync_failure(sm, data, respData, len,						     &attr);		} else {			eap_aka_process_challenge(sm, data, respData, len,						  &attr);		}		break;	case REAUTH:		eap_aka_process_reauth(sm, data, respData, len, &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 = malloc(EAP_SIM_KEYING_DATA_LEN);	if (key == NULL)		return NULL;	memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);	*len = EAP_SIM_KEYING_DATA_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;	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 + -