mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-02-21 19:43:03 -05:00
EAP-SIM server: Store permanent username in session data
This allows identity use to be cleaned up in various operations. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
15cfe2b40f
commit
9bf403b920
@ -37,6 +37,7 @@ struct eap_sim_data {
|
|||||||
u16 notification;
|
u16 notification;
|
||||||
int use_result_ind;
|
int use_result_ind;
|
||||||
int start_round;
|
int start_round;
|
||||||
|
char permanent[20]; /* Permanent username */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -402,10 +403,10 @@ static void eap_sim_process_start(struct eap_sm *sm,
|
|||||||
struct wpabuf *respData,
|
struct wpabuf *respData,
|
||||||
struct eap_sim_attrs *attr)
|
struct eap_sim_attrs *attr)
|
||||||
{
|
{
|
||||||
const u8 *identity;
|
|
||||||
size_t identity_len;
|
size_t identity_len;
|
||||||
u8 ver_list[2];
|
u8 ver_list[2];
|
||||||
u8 *new_identity;
|
u8 *new_identity;
|
||||||
|
char *username;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM: Receive start response");
|
wpa_printf(MSG_DEBUG, "EAP-SIM: Receive start response");
|
||||||
|
|
||||||
@ -432,47 +433,72 @@ static void eap_sim_process_start(struct eap_sm *sm,
|
|||||||
|
|
||||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity",
|
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity",
|
||||||
sm->identity, sm->identity_len);
|
sm->identity, sm->identity_len);
|
||||||
|
username = sim_get_username(sm->identity, sm->identity_len);
|
||||||
identity = NULL;
|
if (username == NULL) {
|
||||||
identity_len = 0;
|
|
||||||
|
|
||||||
if (sm->identity && sm->identity_len > 0 &&
|
|
||||||
sm->identity[0] == EAP_SIM_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-SIM: 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) {
|
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM: Could not get proper permanent"
|
|
||||||
" user name");
|
|
||||||
eap_sim_state(data, FAILURE);
|
eap_sim_state(data, FAILURE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->reauth) {
|
if (username[0] == EAP_SIM_REAUTH_ID_PREFIX) {
|
||||||
|
size_t len;
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM: Reauth username '%s'",
|
||||||
|
username);
|
||||||
|
data->reauth = eap_sim_db_get_reauth_entry(
|
||||||
|
sm->eap_sim_db_priv, (u8 *) username,
|
||||||
|
os_strlen(username));
|
||||||
|
os_free(username);
|
||||||
|
if (data->reauth == NULL) {
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown reauth "
|
||||||
|
"identity - request full auth identity");
|
||||||
|
/* Remain in START state for another round */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM: Using fast re-authentication");
|
||||||
|
len = data->reauth->identity_len;
|
||||||
|
if (len >= sizeof(data->permanent))
|
||||||
|
len = sizeof(data->permanent) - 1;
|
||||||
|
os_memcpy(data->permanent, data->reauth->identity, len);
|
||||||
|
data->permanent[len] = '\0';
|
||||||
|
data->counter = data->reauth->counter;
|
||||||
|
os_memcpy(data->mk, data->reauth->mk, EAP_SIM_MK_LEN);
|
||||||
eap_sim_state(data, REAUTH);
|
eap_sim_state(data, REAUTH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (username[0] == EAP_SIM_PSEUDONYM_PREFIX) {
|
||||||
|
const u8 *permanent;
|
||||||
|
size_t len;
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM: Pseudonym username '%s'",
|
||||||
|
username);
|
||||||
|
permanent = eap_sim_db_get_permanent(
|
||||||
|
sm->eap_sim_db_priv, (u8 *) username,
|
||||||
|
os_strlen(username), &len);
|
||||||
|
os_free(username);
|
||||||
|
if (permanent == NULL) {
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown pseudonym "
|
||||||
|
"identity - request permanent identity");
|
||||||
|
/* Remain in START state for another round */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (len >= sizeof(data->permanent))
|
||||||
|
len = sizeof(data->permanent) - 1;
|
||||||
|
os_memcpy(data->permanent, permanent, len);
|
||||||
|
data->permanent[len] = '\0';
|
||||||
|
} else if (username[0] == EAP_SIM_PERMANENT_PREFIX) {
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM: Permanent username '%s'",
|
||||||
|
username);
|
||||||
|
os_strlcpy(data->permanent, username, sizeof(data->permanent));
|
||||||
|
os_free(username);
|
||||||
|
} else {
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-SIM: Unrecognized username '%s'",
|
||||||
|
username);
|
||||||
|
os_free(username);
|
||||||
|
eap_sim_state(data, FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Full authentication */
|
||||||
|
|
||||||
if (attr->nonce_mt == NULL || attr->selected_version < 0) {
|
if (attr->nonce_mt == NULL || attr->selected_version < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM: Start/Response missing "
|
wpa_printf(MSG_DEBUG, "EAP-SIM: Start/Response missing "
|
||||||
"required attributes");
|
"required attributes");
|
||||||
@ -491,8 +517,8 @@ static void eap_sim_process_start(struct eap_sm *sm,
|
|||||||
data->reauth = NULL;
|
data->reauth = NULL;
|
||||||
|
|
||||||
data->num_chal = eap_sim_db_get_gsm_triplets(
|
data->num_chal = eap_sim_db_get_gsm_triplets(
|
||||||
sm->eap_sim_db_priv, identity, identity_len,
|
sm->eap_sim_db_priv, (u8 *) data->permanent,
|
||||||
EAP_SIM_MAX_CHAL,
|
os_strlen(data->permanent), EAP_SIM_MAX_CHAL,
|
||||||
(u8 *) data->rand, (u8 *) data->kc, (u8 *) data->sres, sm);
|
(u8 *) data->rand, (u8 *) data->kc, (u8 *) data->sres, sm);
|
||||||
if (data->num_chal == EAP_SIM_DB_PENDING) {
|
if (data->num_chal == EAP_SIM_DB_PENDING) {
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication triplets "
|
wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication triplets "
|
||||||
@ -533,9 +559,6 @@ static void eap_sim_process_challenge(struct eap_sm *sm,
|
|||||||
struct wpabuf *respData,
|
struct wpabuf *respData,
|
||||||
struct eap_sim_attrs *attr)
|
struct eap_sim_attrs *attr)
|
||||||
{
|
{
|
||||||
const u8 *identity;
|
|
||||||
size_t identity_len;
|
|
||||||
|
|
||||||
if (attr->mac == NULL ||
|
if (attr->mac == NULL ||
|
||||||
eap_sim_verify_mac(data->k_aut, respData, attr->mac,
|
eap_sim_verify_mac(data->k_aut, respData, attr->mac,
|
||||||
(u8 *) data->sres,
|
(u8 *) data->sres,
|
||||||
@ -555,22 +578,17 @@ static void eap_sim_process_challenge(struct eap_sm *sm,
|
|||||||
} else
|
} else
|
||||||
eap_sim_state(data, SUCCESS);
|
eap_sim_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) {
|
if (data->next_pseudonym) {
|
||||||
eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,
|
eap_sim_db_add_pseudonym(sm->eap_sim_db_priv,
|
||||||
identity_len,
|
(u8 *) data->permanent,
|
||||||
|
os_strlen(data->permanent),
|
||||||
data->next_pseudonym);
|
data->next_pseudonym);
|
||||||
data->next_pseudonym = NULL;
|
data->next_pseudonym = NULL;
|
||||||
}
|
}
|
||||||
if (data->next_reauth_id) {
|
if (data->next_reauth_id) {
|
||||||
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
|
eap_sim_db_add_reauth(sm->eap_sim_db_priv,
|
||||||
identity_len,
|
(u8 *) data->permanent,
|
||||||
|
os_strlen(data->permanent),
|
||||||
data->next_reauth_id, data->counter + 1,
|
data->next_reauth_id, data->counter + 1,
|
||||||
data->mk);
|
data->mk);
|
||||||
data->next_reauth_id = NULL;
|
data->next_reauth_id = NULL;
|
||||||
@ -585,8 +603,6 @@ static void eap_sim_process_reauth(struct eap_sm *sm,
|
|||||||
{
|
{
|
||||||
struct eap_sim_attrs eattr;
|
struct eap_sim_attrs eattr;
|
||||||
u8 *decrypted = NULL;
|
u8 *decrypted = NULL;
|
||||||
const u8 *identity, *id2;
|
|
||||||
size_t identity_len, id2_len;
|
|
||||||
|
|
||||||
if (attr->mac == NULL ||
|
if (attr->mac == NULL ||
|
||||||
eap_sim_verify_mac(data->k_aut, respData, attr->mac, data->nonce_s,
|
eap_sim_verify_mac(data->k_aut, respData, attr->mac, data->nonce_s,
|
||||||
@ -629,24 +645,11 @@ static void eap_sim_process_reauth(struct eap_sm *sm,
|
|||||||
} else
|
} else
|
||||||
eap_sim_state(data, SUCCESS);
|
eap_sim_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_reauth_id) {
|
if (data->next_reauth_id) {
|
||||||
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
|
eap_sim_db_add_reauth(sm->eap_sim_db_priv,
|
||||||
identity_len, data->next_reauth_id,
|
(u8 *) data->permanent,
|
||||||
|
os_strlen(data->permanent),
|
||||||
|
data->next_reauth_id,
|
||||||
data->counter + 1, data->mk);
|
data->counter + 1, data->mk);
|
||||||
data->next_reauth_id = NULL;
|
data->next_reauth_id = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1838,3 +1838,31 @@ int eap_sim_db_resynchronize(void *priv, const u8 *identity,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sim_get_username - Extract username from SIM identity
|
||||||
|
* @identity: Identity
|
||||||
|
* @identity_len: Identity length
|
||||||
|
* Returns: Allocated buffer with the username part of the identity
|
||||||
|
*
|
||||||
|
* Caller is responsible for freeing the returned buffer with os_free().
|
||||||
|
*/
|
||||||
|
char * sim_get_username(const u8 *identity, size_t identity_len)
|
||||||
|
{
|
||||||
|
char *username;
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
|
for (pos = 0; pos < identity_len; pos++) {
|
||||||
|
if (identity[pos] == '@' || identity[pos] == '\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
username = os_malloc(pos + 1);
|
||||||
|
if (username == NULL)
|
||||||
|
return NULL;
|
||||||
|
os_memcpy(username, identity, pos);
|
||||||
|
username[pos] = '\0';
|
||||||
|
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
@ -92,4 +92,6 @@ int eap_sim_db_resynchronize(void *priv, const u8 *identity,
|
|||||||
size_t identity_len, const u8 *auts,
|
size_t identity_len, const u8 *auts,
|
||||||
const u8 *_rand);
|
const u8 *_rand);
|
||||||
|
|
||||||
|
char * sim_get_username(const u8 *identity, size_t identity_len);
|
||||||
|
|
||||||
#endif /* EAP_SIM_DB_H */
|
#endif /* EAP_SIM_DB_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user