]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-SIM server: Store permanent username in session data
authorJouni Malinen <j@w1.fi>
Sat, 1 Sep 2012 16:10:33 +0000 (19:10 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 1 Sep 2012 16:15:01 +0000 (19:15 +0300)
This allows identity use to be cleaned up in various operations.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/eap_server/eap_server_sim.c
src/eap_server/eap_sim_db.c
src/eap_server/eap_sim_db.h

index ec20c780db867b5d148b660360ac1818687f9ccc..2f8871131f0914d5225f536b371db7f0408ad3a9 100644 (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,46 +433,71 @@ static void eap_sim_process_start(struct eap_sm *sm,
 
        wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity",
                          sm->identity, sm->identity_len);
+       username = sim_get_username(sm->identity, sm->identity_len);
+       if (username == NULL) {
+               eap_sim_state(data, FAILURE);
+               return;
+       }
 
-       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 (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 (identity == NULL) {
-               wpa_printf(MSG_DEBUG, "EAP-SIM: Could not get proper permanent"
-                          " user name");
+       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;
        }
 
-       if (data->reauth) {
-               eap_sim_state(data, REAUTH);
-               return;
-       }
+       /* Full authentication */
 
        if (attr->nonce_mt == NULL || attr->selected_version < 0) {
                wpa_printf(MSG_DEBUG, "EAP-SIM: Start/Response missing "
@@ -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 {
index fbaae651a6301667b8c2aa25f9ec507bfa40308f..b8516d5f14e02a60fa9d0fe32e2dfdf60bb845e7 100644 (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;
+}
index 4fda9041641d34a108be48491b6d155c3b9ffb13..6f829865e758110517f7298aae84c3aa40432df7 100644 (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 */