Parcourir la source

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>
Jouni Malinen il y a 12 ans
Parent
commit
9bf403b920
3 fichiers modifiés avec 101 ajouts et 68 suppressions
  1. 71 68
      src/eap_server/eap_server_sim.c
  2. 28 0
      src/eap_server/eap_sim_db.c
  3. 2 0
      src/eap_server/eap_sim_db.h

+ 71 - 68
src/eap_server/eap_server_sim.c

@@ -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 {

+ 28 - 0
src/eap_server/eap_sim_db.c

@@ -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;
+}

+ 2 - 0
src/eap_server/eap_sim_db.h

@@ -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 */