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
3 changed files with 102 additions and 69 deletions
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue