wifi: look for realm from the real identity

The realm could be retrieved from identity, anonymous
identity, or real identity.

Bug: 241719330
Test: verify roaming flow: AP1 -> AP2 -> AP1 -> AP2
Change-Id: Iae4617607edb11b99ae7d7e4e15cad522c557da7
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 276dca3..721c9d6 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -2816,6 +2816,61 @@
 	return config->identity;
 }
 
+static const u8 * strnchr(const u8 *str, size_t len, u8 needle) {
+	const u8 *cur = str;
+
+	if (NULL == str) return NULL;
+	if (0 >= len) return NULL;
+
+	while (cur < str + len) {
+		if (*cur == needle)
+			return cur;
+		cur++;
+	}
+	return NULL;
+}
+
+const u8 * eap_get_config_realm(struct eap_sm *sm, size_t *len) {
+	struct eap_peer_config *config = eap_get_config(sm);
+	const u8 *realm = NULL;
+	size_t realm_len = 0;
+	const u8 *identity = NULL;
+	size_t identity_len = 0;
+
+	if (!config)
+		return NULL;
+
+	/* Look for the realm of the permanent identity */
+	identity = eap_get_config_identity(sm, &identity_len);
+	realm = strnchr(identity, identity_len, '@');
+	if (NULL != realm) {
+		wpa_printf(MSG_DEBUG, "Get the realm from identity.");
+		*len = identity_len - (realm - identity);
+		return realm;
+	}
+
+	/* Look for the realm of the anonymous identity. */
+	realm = strnchr(config->anonymous_identity,
+	    config->anonymous_identity_len, '@');
+	if (NULL != realm) {
+		wpa_printf(MSG_DEBUG, "Get the realm from anonymous identity.");
+		*len = identity_len - (realm - identity);
+		return realm;
+	}
+
+	/* Look for the realm of the real identity. */
+	realm = strnchr(config->imsi_identity,
+	    config->imsi_identity_len, '@');
+	if (NULL != realm) {
+		wpa_printf(MSG_DEBUG, "Get the realm from IMSI identity.");
+		*len = identity_len - (realm - identity);
+		return realm;
+	}
+	wpa_printf(MSG_DEBUG, "No realm information in identities.");
+	*len = 0;
+	return NULL;
+}
+
 
 static int eap_get_ext_password(struct eap_sm *sm,
 				struct eap_peer_config *config)
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index b7f86c3..e721efe 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -409,33 +409,16 @@
 		size_t identity_len = 0;
 		const u8 *realm = NULL;
 		size_t realm_len = 0;
-		struct eap_peer_config *config = eap_get_config(sm);
 
 		wpa_hexdump_ascii(MSG_DEBUG,
 				  "EAP-AKA: (encr) AT_NEXT_PSEUDONYM",
 				  attr->next_pseudonym,
 				  attr->next_pseudonym_len);
 		os_free(data->pseudonym);
-		/* Look for the realm of the permanent identity */
-		identity = eap_get_config_identity(sm, &identity_len);
-		if (identity) {
-			for (realm = identity, realm_len = identity_len;
-			     realm_len > 0; realm_len--, realm++) {
-				if (*realm == '@')
-					break;
-			}
-		}
-		// If no realm from the permanent identity, look for the
-		// realm of the anonymous identity.
-		if (realm_len == 0 && config && config->anonymous_identity
-		    && config->anonymous_identity_len > 0) {
-			for (realm = config->anonymous_identity,
-			    realm_len = config->anonymous_identity_len;
-			    realm_len > 0; realm_len--, realm++) {
-				if (*realm == '@')
-					break;
-			}
-		}
+
+		/* Get realm from identities to decorate pseudonym. */
+		realm = eap_get_config_realm(sm, &realm_len);
+
 		data->pseudonym = os_malloc(attr->next_pseudonym_len +
 					    realm_len);
 		if (data->pseudonym == NULL) {
diff --git a/src/eap_peer/eap_i.h b/src/eap_peer/eap_i.h
index f43891e..652b67e 100644
--- a/src/eap_peer/eap_i.h
+++ b/src/eap_peer/eap_i.h
@@ -392,6 +392,7 @@
 const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash);
 const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len);
 const u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len);
+const u8 * eap_get_config_realm(struct eap_sm *sm, size_t *len);
 void eap_clear_config_otp(struct eap_sm *sm);
 const char * eap_get_config_phase1(struct eap_sm *sm);
 const char * eap_get_config_phase2(struct eap_sm *sm);
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 9f66db2..954c585 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -432,33 +432,16 @@
 		size_t identity_len = 0;
 		const u8 *realm = NULL;
 		size_t realm_len = 0;
-		struct eap_peer_config *config = eap_get_config(sm);
 
 		wpa_hexdump_ascii(MSG_DEBUG,
 				  "EAP-SIM: (encr) AT_NEXT_PSEUDONYM",
 				  attr->next_pseudonym,
 				  attr->next_pseudonym_len);
 		os_free(data->pseudonym);
-		/* Look for the realm of the permanent identity */
-		identity = eap_get_config_identity(sm, &identity_len);
-		if (identity) {
-			for (realm = identity, realm_len = identity_len;
-			     realm_len > 0; realm_len--, realm++) {
-				if (*realm == '@')
-					break;
-			}
-		}
-		// If no realm from the permanent identity, look for the
-		// realm of the anonymous identity.
-		if (realm_len == 0 && config && config->anonymous_identity
-		    && config->anonymous_identity_len > 0) {
-			for (realm = config->anonymous_identity,
-			    realm_len = config->anonymous_identity_len;
-			    realm_len > 0; realm_len--, realm++) {
-				if (*realm == '@')
-					break;
-			}
-		}
+
+		/* Get realm from identities to decorate pseudonym. */
+		realm = eap_get_config_realm(sm, &realm_len);
+
 		data->pseudonym = os_malloc(attr->next_pseudonym_len +
 					    realm_len);
 		if (data->pseudonym == NULL) {