Snap for 5626917 from 6fd30c84f6e493af490bacf73201f43388c47827 to qt-aml-release

Change-Id: Ia82fc78a9f1bafef12e2d0072b2d8439c6f114ae
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index a444141..a96a39f 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -57,6 +57,7 @@
 	u16 last_kdf_attrs[EAP_AKA_PRIME_KDF_MAX];
 	size_t last_kdf_count;
 	int error_code;
+	int anonymous_flag;
 };
 
 
@@ -93,6 +94,7 @@
 	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)
@@ -107,6 +109,7 @@
 	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) {
@@ -115,6 +118,13 @@
 			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");
+			}
 		}
 	}
 
@@ -417,6 +427,7 @@
 		if (data->use_pseudonym)
 			eap_set_anon_id(sm, data->pseudonym,
 					data->pseudonym_len);
+		data->anonymous_flag = 0;
 	}
 
 	if (attr->next_reauth_id) {
@@ -622,7 +633,7 @@
 		identity_len = data->reauth_id_len;
 		data->reauth = 1;
 	} else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
-		   data->pseudonym) {
+		   data->pseudonym && !data->anonymous_flag) {
 		identity = data->pseudonym;
 		identity_len = data->pseudonym_len;
 		eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID);
@@ -1026,7 +1037,7 @@
 	if (data->last_eap_identity) {
 		identity = data->last_eap_identity;
 		identity_len = data->last_eap_identity_len;
-	} else if (data->pseudonym) {
+	} else if (data->pseudonym && !data->anonymous_flag) {
 		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 ba5eea9..6989aa8 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -48,6 +48,7 @@
 	int result_ind, use_result_ind;
 	int use_pseudonym;
 	int error_code;
+	int anonymous_flag;
 };
 
 
@@ -83,6 +84,7 @@
 {
 	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)
@@ -97,7 +99,7 @@
 
 	/* 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=");
@@ -127,6 +129,14 @@
 			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");
+			}
+
 		}
 	}
 
@@ -437,6 +447,7 @@
 		if (data->use_pseudonym)
 			eap_set_anon_id(sm, data->pseudonym,
 					data->pseudonym_len);
+		data->anonymous_flag = 0;
 	}
 
 	if (attr->next_reauth_id) {
@@ -492,7 +503,7 @@
 		identity_len = data->reauth_id_len;
 		data->reauth = 1;
 	} else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
-		   data->pseudonym) {
+		   data->pseudonym && !data->anonymous_flag) {
 		identity = data->pseudonym;
 		identity_len = data->pseudonym_len;
 		eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID);
@@ -768,7 +779,7 @@
 	if (data->last_eap_identity) {
 		identity = data->last_eap_identity;
 		identity_len = data->last_eap_identity_len;
-	} else if (data->pseudonym) {
+	} else if (data->pseudonym && !data->anonymous_flag) {
 		identity = data->pseudonym;
 		identity_len = data->pseudonym_len;
 	} else {
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 17a984d..e2cc439 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -965,9 +965,9 @@
 
 	os_memset(&params, 0, sizeof(params));
 	params.status = status;
-	params.ssid = wpa_s->sme.ext_auth.ssid;
-	params.ssid_len = wpa_s->sme.ext_auth.ssid_len;
-	params.bssid = wpa_s->sme.ext_auth.bssid;
+	params.ssid = wpa_s->sme.ext_auth_ssid;
+	params.ssid_len = wpa_s->sme.ext_auth_ssid_len;
+	params.bssid = wpa_s->sme.ext_auth_bssid;
 	wpa_drv_send_external_auth_status(wpa_s, &params);
 }
 
@@ -1032,8 +1032,13 @@
 		return;
 
 	if (data->external_auth.action == EXT_AUTH_START) {
-		os_memcpy(&wpa_s->sme.ext_auth, data,
-			  sizeof(struct external_auth));
+		if (!data->external_auth.bssid || !data->external_auth.ssid)
+			return;
+		os_memcpy(wpa_s->sme.ext_auth_bssid, data->external_auth.bssid,
+			  ETH_ALEN);
+		os_memcpy(wpa_s->sme.ext_auth_ssid, data->external_auth.ssid,
+			  data->external_auth.ssid_len);
+		wpa_s->sme.ext_auth_ssid_len = data->external_auth.ssid_len;
 		wpa_s->sme.seq_num = 0;
 		wpa_s->sme.sae.state = SAE_NOTHING;
 		wpa_s->sme.sae.send_confirm = 0;
@@ -1091,7 +1096,7 @@
 						wpa_s->current_ssid, 2);
 		else
 			sme_external_auth_send_sae_commit(
-				wpa_s, wpa_s->sme.ext_auth.bssid,
+				wpa_s, wpa_s->sme.ext_auth_bssid,
 				wpa_s->current_ssid);
 		return 0;
 	}
@@ -1110,7 +1115,7 @@
 						wpa_s->current_ssid, 1);
 		else
 			sme_external_auth_send_sae_commit(
-				wpa_s, wpa_s->sme.ext_auth.bssid,
+				wpa_s, wpa_s->sme.ext_auth_bssid,
 				wpa_s->current_ssid);
 		return 0;
 	}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index a97353f..7eef32c 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -802,7 +802,9 @@
 		int sae_group_index;
 		unsigned int sae_pmksa_caching:1;
 		u16 seq_num;
-		struct external_auth ext_auth;
+		u8 ext_auth_bssid[ETH_ALEN];
+		u8 ext_auth_ssid[SSID_MAX_LEN];
+		size_t ext_auth_ssid_len;
 #endif /* CONFIG_SAE */
 	} sme;
 #endif /* CONFIG_SME */