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:
Jouni Malinen 2012-09-01 19:10:33 +03:00
parent 15cfe2b40f
commit 9bf403b920
3 changed files with 102 additions and 69 deletions

View file

@ -37,6 +37,7 @@ struct eap_sim_data {
u16 notification;
int use_result_ind;
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 eap_sim_attrs *attr)
{
const u8 *identity;
size_t identity_len;
u8 ver_list[2];
u8 *new_identity;
char *username;
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",
sm->identity, sm->identity_len);
identity = 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");
username = sim_get_username(sm->identity, sm->identity_len);
if (username == NULL) {
eap_sim_state(data, FAILURE);
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);
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) {
wpa_printf(MSG_DEBUG, "EAP-SIM: Start/Response missing "
"required attributes");
@ -491,8 +517,8 @@ static void eap_sim_process_start(struct eap_sm *sm,
data->reauth = NULL;
data->num_chal = eap_sim_db_get_gsm_triplets(
sm->eap_sim_db_priv, identity, identity_len,
EAP_SIM_MAX_CHAL,
sm->eap_sim_db_priv, (u8 *) data->permanent,
os_strlen(data->permanent), EAP_SIM_MAX_CHAL,
(u8 *) data->rand, (u8 *) data->kc, (u8 *) data->sres, sm);
if (data->num_chal == EAP_SIM_DB_PENDING) {
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 eap_sim_attrs *attr)
{
const u8 *identity;
size_t identity_len;
if (attr->mac == NULL ||
eap_sim_verify_mac(data->k_aut, respData, attr->mac,
(u8 *) data->sres,
@ -555,22 +578,17 @@ static void eap_sim_process_challenge(struct eap_sm *sm,
} else
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) {
eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,
identity_len,
eap_sim_db_add_pseudonym(sm->eap_sim_db_priv,
(u8 *) data->permanent,
os_strlen(data->permanent),
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,
eap_sim_db_add_reauth(sm->eap_sim_db_priv,
(u8 *) data->permanent,
os_strlen(data->permanent),
data->next_reauth_id, data->counter + 1,
data->mk);
data->next_reauth_id = NULL;
@ -585,8 +603,6 @@ static void eap_sim_process_reauth(struct eap_sm *sm,
{
struct eap_sim_attrs eattr;
u8 *decrypted = NULL;
const u8 *identity, *id2;
size_t identity_len, id2_len;
if (attr->mac == NULL ||
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
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) {
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
identity_len, data->next_reauth_id,
eap_sim_db_add_reauth(sm->eap_sim_db_priv,
(u8 *) data->permanent,
os_strlen(data->permanent),
data->next_reauth_id,
data->counter + 1, data->mk);
data->next_reauth_id = NULL;
} else {

View file

@ -1838,3 +1838,31 @@ int eap_sim_db_resynchronize(void *priv, const u8 *identity,
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;
}

View file

@ -92,4 +92,6 @@ int eap_sim_db_resynchronize(void *priv, const u8 *identity,
size_t identity_len, const u8 *auts,
const u8 *_rand);
char * sim_get_username(const u8 *identity, size_t identity_len);
#endif /* EAP_SIM_DB_H */