aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHai Shalom <haishalom@google.com>2019-08-02 15:56:26 -0700
committerHai Shalom <haishalom@google.com>2019-08-13 16:49:04 +0000
commitef6ae566f2444bff52e4b3f009f8d0be4976019d (patch)
treea5f8a0c451fbcdb75c0e15007e5f18f18d08a2ed
parent43b5a299f9d6cfb161342030cdca2ae37cf5e65f (diff)
downloadwpa_supplicant_8-ef6ae566f2444bff52e4b3f009f8d0be4976019d.tar.gz
Do not clear anonymous id when anonymous@<realm> is used
If the EAP-SIM/AKA server does not provide a new pseudonym and the locally configured "pseudonym" in anonymous_identity is actually an anonymous identity instead of a real EAP-SIM/AKA pseudonym, do not clear the anonymous_identity network profile parameter. This is needed to avoid forgetting the anonymous identity when going through EAP-SIM/AKA authentication and then reverting back to using IMSI-based (e.g., encrypted) identity. Bug: 138610772 Test: Associate to <carrier> AP, get out of range, reassociate Test: Associate to <carrier> AP, pop SIM, reinsert, reassociate Change-Id: I41819a22005848d37d5247ebf6543bb66ea78fce (cherry picked from commit afd394b5a79e48be55dd82fcaf6782e7ed6cc77a)
-rw-r--r--src/eap_common/eap_sim_common.c16
-rw-r--r--src/eap_common/eap_sim_common.h1
-rw-r--r--src/eap_peer/eap_aka.c28
-rw-r--r--src/eap_peer/eap_sim.c30
4 files changed, 44 insertions, 31 deletions
diff --git a/src/eap_common/eap_sim_common.c b/src/eap_common/eap_sim_common.c
index 6290c35f..cfdd1bf4 100644
--- a/src/eap_common/eap_sim_common.c
+++ b/src/eap_common/eap_sim_common.c
@@ -1203,3 +1203,19 @@ void eap_sim_report_notification(void *msg_ctx, int notification, int aka)
}
}
}
+
+
+int eap_sim_anonymous_username(const u8 *id, size_t id_len)
+{
+ static const char *anonymous_id_prefix = "anonymous@";
+ size_t anonymous_id_len = os_strlen(anonymous_id_prefix);
+
+ if (id_len > anonymous_id_len &&
+ os_memcmp(id, anonymous_id_prefix, anonymous_id_len) == 0)
+ return 1; /* 'anonymous@realm' */
+
+ if (id_len > 1 && id[0] == '@')
+ return 1; /* '@realm' */
+
+ return 0;
+}
diff --git a/src/eap_common/eap_sim_common.h b/src/eap_common/eap_sim_common.h
index daeb0e2d..7142b94c 100644
--- a/src/eap_common/eap_sim_common.h
+++ b/src/eap_common/eap_sim_common.h
@@ -226,5 +226,6 @@ int eap_sim_msg_add_encr_end(struct eap_sim_msg *msg, u8 *k_encr,
int attr_pad);
void eap_sim_report_notification(void *msg_ctx, int notification, int aka);
+int eap_sim_anonymous_username(const u8 *id, size_t id_len);
#endif /* EAP_SIM_COMMON_H */
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index a96a39f4..ff88cf8a 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -57,7 +57,6 @@ struct eap_aka_data {
u16 last_kdf_attrs[EAP_AKA_PRIME_KDF_MAX];
size_t last_kdf_count;
int error_code;
- int anonymous_flag;
};
@@ -94,7 +93,6 @@ static void * eap_aka_init(struct eap_sm *sm)
struct eap_aka_data *data;
const char *phase1 = eap_get_config_phase1(sm);
struct eap_peer_config *config = eap_get_config(sm);
- static const char *anonymous_id_prefix = "anonymous@";
data = os_zalloc(sizeof(*data));
if (data == NULL)
@@ -109,7 +107,6 @@ static void * eap_aka_init(struct eap_sm *sm)
data->prev_id = -1;
data->result_ind = phase1 && os_strstr(phase1, "result_ind=1") != NULL;
- data->anonymous_flag = 0;
data->use_pseudonym = !sm->init_phase2;
if (config && config->anonymous_identity && data->use_pseudonym) {
@@ -118,13 +115,6 @@ static void * eap_aka_init(struct eap_sm *sm)
os_memcpy(data->pseudonym, config->anonymous_identity,
config->anonymous_identity_len);
data->pseudonym_len = config->anonymous_identity_len;
- if (data->pseudonym_len > os_strlen(anonymous_id_prefix) &&
- !os_memcmp(data->pseudonym, anonymous_id_prefix,
- os_strlen(anonymous_id_prefix))) {
- data->anonymous_flag = 1;
- wpa_printf(MSG_DEBUG,
- "EAP-AKA: Setting anonymous@realm flag");
- }
}
}
@@ -427,7 +417,6 @@ static int eap_aka_learn_ids(struct eap_sm *sm, struct eap_aka_data *data,
if (data->use_pseudonym)
eap_set_anon_id(sm, data->pseudonym,
data->pseudonym_len);
- data->anonymous_flag = 0;
}
if (attr->next_reauth_id) {
@@ -633,15 +622,22 @@ static struct wpabuf * eap_aka_response_identity(struct eap_sm *sm,
identity_len = data->reauth_id_len;
data->reauth = 1;
} else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
- data->pseudonym && !data->anonymous_flag) {
+ data->pseudonym &&
+ !eap_sim_anonymous_username(data->pseudonym,
+ data->pseudonym_len)) {
identity = data->pseudonym;
identity_len = data->pseudonym_len;
eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID);
} else if (id_req != NO_ID_REQ) {
identity = eap_get_config_identity(sm, &identity_len);
if (identity) {
- eap_aka_clear_identities(sm, data, CLEAR_PSEUDONYM |
- CLEAR_REAUTH_ID);
+ int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID;
+
+ if (data->pseudonym &&
+ eap_sim_anonymous_username(data->pseudonym,
+ data->pseudonym_len))
+ ids &= ~CLEAR_PSEUDONYM;
+ eap_aka_clear_identities(sm, data, ids);
}
}
if (id_req != NO_ID_REQ)
@@ -1037,7 +1033,9 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
if (data->last_eap_identity) {
identity = data->last_eap_identity;
identity_len = data->last_eap_identity_len;
- } else if (data->pseudonym && !data->anonymous_flag) {
+ } else if (data->pseudonym &&
+ !eap_sim_anonymous_username(data->pseudonym,
+ data->pseudonym_len)) {
identity = data->pseudonym;
identity_len = data->pseudonym_len;
} else {
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 6989aa88..b5811a8a 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -48,7 +48,6 @@ struct eap_sim_data {
int result_ind, use_result_ind;
int use_pseudonym;
int error_code;
- int anonymous_flag;
};
@@ -84,7 +83,6 @@ static void * eap_sim_init(struct eap_sm *sm)
{
struct eap_sim_data *data;
struct eap_peer_config *config = eap_get_config(sm);
- static const char *anonymous_id_prefix = "anonymous@";
data = os_zalloc(sizeof(*data));
if (data == NULL)
@@ -99,7 +97,7 @@ static void * eap_sim_init(struct eap_sm *sm)
/* Zero is a valid error code, so we need to initialize */
data->error_code = NO_EAP_METHOD_ERROR;
- data->anonymous_flag = 0;
+
data->min_num_chal = 2;
if (config && config->phase1) {
char *pos = os_strstr(config->phase1, "sim_min_num_chal=");
@@ -129,14 +127,6 @@ static void * eap_sim_init(struct eap_sm *sm)
os_memcpy(data->pseudonym, config->anonymous_identity,
config->anonymous_identity_len);
data->pseudonym_len = config->anonymous_identity_len;
- if (data->pseudonym_len > os_strlen(anonymous_id_prefix) &&
- !os_memcmp(data->pseudonym, anonymous_id_prefix,
- os_strlen(anonymous_id_prefix))) {
- data->anonymous_flag = 1;
- wpa_printf(MSG_DEBUG,
- "EAP-SIM: Setting anonymous@realm flag");
- }
-
}
}
@@ -447,7 +437,6 @@ static int eap_sim_learn_ids(struct eap_sm *sm, struct eap_sim_data *data,
if (data->use_pseudonym)
eap_set_anon_id(sm, data->pseudonym,
data->pseudonym_len);
- data->anonymous_flag = 0;
}
if (attr->next_reauth_id) {
@@ -503,15 +492,22 @@ static struct wpabuf * eap_sim_response_start(struct eap_sm *sm,
identity_len = data->reauth_id_len;
data->reauth = 1;
} else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
- data->pseudonym && !data->anonymous_flag) {
+ data->pseudonym &&
+ !eap_sim_anonymous_username(data->pseudonym,
+ data->pseudonym_len)) {
identity = data->pseudonym;
identity_len = data->pseudonym_len;
eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID);
} else if (id_req != NO_ID_REQ) {
identity = eap_get_config_identity(sm, &identity_len);
if (identity) {
- eap_sim_clear_identities(sm, data, CLEAR_PSEUDONYM |
- CLEAR_REAUTH_ID);
+ int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID;
+
+ if (data->pseudonym &&
+ eap_sim_anonymous_username(data->pseudonym,
+ data->pseudonym_len))
+ ids &= ~CLEAR_PSEUDONYM;
+ eap_sim_clear_identities(sm, data, ids);
}
}
if (id_req != NO_ID_REQ)
@@ -779,7 +775,9 @@ static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm,
if (data->last_eap_identity) {
identity = data->last_eap_identity;
identity_len = data->last_eap_identity_len;
- } else if (data->pseudonym && !data->anonymous_flag) {
+ } else if (data->pseudonym &&
+ !eap_sim_anonymous_username(data->pseudonym,
+ data->pseudonym_len)) {
identity = data->pseudonym;
identity_len = data->pseudonym_len;
} else {