diff options
author | Jimmy Chen <jimmycmchen@google.com> | 2022-08-09 23:21:26 +0800 |
---|---|---|
committer | Jimmy Chen <jimmycmchen@google.com> | 2022-08-13 09:09:03 +0800 |
commit | 1e9d915548b69ee3b077b5b10815e9d6534d6b11 (patch) | |
tree | e1ddb8250d2af85a7b6ad2eeca8a6880f91ee1a0 | |
parent | 67e53f80249339660b94057755f6e3488625b39c (diff) | |
download | wpa_supplicant_8-1e9d915548b69ee3b077b5b10815e9d6534d6b11.tar.gz |
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
-rw-r--r-- | src/eap_peer/eap.c | 55 | ||||
-rw-r--r-- | src/eap_peer/eap_aka.c | 25 | ||||
-rw-r--r-- | src/eap_peer/eap_i.h | 1 | ||||
-rw-r--r-- | src/eap_peer/eap_sim.c | 25 |
4 files changed, 64 insertions, 42 deletions
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index 276dca31..721c9d6b 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -2816,6 +2816,61 @@ const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len) 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 b7f86c37..e721efe4 100644 --- a/src/eap_peer/eap_aka.c +++ b/src/eap_peer/eap_aka.c @@ -409,33 +409,16 @@ static int eap_aka_learn_ids(struct eap_sm *sm, struct eap_aka_data *data, 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 f43891e3..652b67ed 100644 --- a/src/eap_peer/eap_i.h +++ b/src/eap_peer/eap_i.h @@ -392,6 +392,7 @@ const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len); 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 9f66db21..954c585f 100644 --- a/src/eap_peer/eap_sim.c +++ b/src/eap_peer/eap_sim.c @@ -432,33 +432,16 @@ static int eap_sim_learn_ids(struct eap_sm *sm, struct eap_sim_data *data, 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) { |