Merge "wifi: Correct check condition for SAP 11AX mode." into sc-dev
diff --git a/src/eap_common/eap_sim_common.c b/src/eap_common/eap_sim_common.c
index 58861cd..ea38e6a 100644
--- a/src/eap_common/eap_sim_common.c
+++ b/src/eap_common/eap_sim_common.c
@@ -1209,10 +1209,23 @@
 	}
 }
 
+static const u8 * get_last_char(const u8 *val, size_t len, char c)
+{
+	while (len > 0) {
+		const u8 *pos = &val[len - 1];
+
+		if (*pos == (u8) c)
+			return pos;
+		len--;
+	}
+
+	return NULL;
+}
+
 int eap_sim_anonymous_username(const u8 *id, size_t id_len)
 {
 	static const char *anonymous_id_prefix = "anonymous@";
-	const char *decorated;
+	const u8 *decorated;
 	size_t anonymous_id_len = os_strlen(anonymous_id_prefix);
 
 	if (id_len > anonymous_id_len &&
@@ -1226,12 +1239,14 @@
 	if (id_len > 1 && id[0] == '@')
 		return 1; /* '@realm' */
 
-	/* RFC 7542 decorated username, for example;
-	   homerealm.example.org!anonymous@otherrealm.example.net */
-	decorated = os_strrchr((const char *)id, '!');
-	if (decorated && os_strlen(decorated + 1) > 1) {
-		return eap_sim_anonymous_username((const u8 *)(decorated + 1),
-				os_strlen(decorated + 1));
+	/* RFC 7542 decorated username, for example:
+	 * homerealm.example.org!anonymous@otherrealm.example.net */
+	decorated = get_last_char(id, id_len, '!');
+	if (decorated) {
+		decorated++;
+		return eap_sim_anonymous_username(decorated,
+						  id + id_len - decorated);
 	}
 	return 0;
 }
+
diff --git a/src/utils/common.c b/src/utils/common.c
index 2c12751..20f1c6c 100644
--- a/src/utils/common.c
+++ b/src/utils/common.c
@@ -720,6 +720,20 @@
 }
 
 
+int has_non_nvt_ascii_char(const u8 *data, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++) {
+		if (data[i] < 7
+			|| (13 < data[i] && data[i] < 32)
+				|| data[i] == 127)
+			return 1;
+	}
+	return 0;
+}
+
+
 int has_newline(const char *str)
 {
 	while (*str) {
diff --git a/src/utils/common.h b/src/utils/common.h
index 45f72bb..660951e 100644
--- a/src/utils/common.h
+++ b/src/utils/common.h
@@ -509,6 +509,7 @@
 char * wpa_config_parse_string(const char *value, size_t *len);
 int is_hex(const u8 *data, size_t len);
 int has_ctrl_char(const u8 *data, size_t len);
+int has_non_nvt_ascii_char(const u8 *data, size_t len);
 int has_newline(const char *str);
 size_t merge_byte_arrays(u8 *res, size_t res_len,
 			 const u8 *src1, size_t src1_len,
diff --git a/wpa_supplicant/hidl/1.4/sta_network.cpp b/wpa_supplicant/hidl/1.4/sta_network.cpp
index ee132ac..ac3e974 100644
--- a/wpa_supplicant/hidl/1.4/sta_network.cpp
+++ b/wpa_supplicant/hidl/1.4/sta_network.cpp
@@ -2412,7 +2412,7 @@
 					  PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
 		return 1;
 	}
-	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
+	if (has_non_nvt_ascii_char((u8 *)psk.c_str(), psk.size())) {
 		return 1;
 	}
 	return 0;
diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c
index 8aeb3b0..eaf0803 100644
--- a/wpa_supplicant/hs20_supplicant.c
+++ b/wpa_supplicant/hs20_supplicant.c
@@ -73,7 +73,12 @@
 	const u8 *ext_capa;
 	u32 filter = 0;
 
-	if (!bss || !is_hs20_network(wpa_s, wpa_s->current_ssid, bss)) {
+	if (!bss || !is_hs20_network(wpa_s, wpa_s->current_ssid, bss)
+#ifndef ANDROID
+			// HS 2.0 Configuration is not used in AOSP
+			|| !is_hs20_config(wpa_s)
+#endif
+			) {
 		wpa_printf(MSG_DEBUG,
 			   "Not configuring frame filtering - BSS " MACSTR
 			   " is not a Hotspot 2.0 network", MAC2STR(bssid));
@@ -158,11 +163,15 @@
 	return ((ie[6] >> 4) & 0x0f) + 1;
 }
 
+int is_hs20_config(struct wpa_supplicant *wpa_s)
+{
+	return wpa_s->conf->hs20;
+}
 
 int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
 		    struct wpa_bss *bss)
 {
-	if (!wpa_s->conf->hs20 || !ssid)
+	if (!ssid)
 		return 0;
 
 	if (ssid->parent_cred)
diff --git a/wpa_supplicant/hs20_supplicant.h b/wpa_supplicant/hs20_supplicant.h
index e43414b..2d478f4 100644
--- a/wpa_supplicant/hs20_supplicant.h
+++ b/wpa_supplicant/hs20_supplicant.h
@@ -22,6 +22,7 @@
 				  struct wpa_bss *bss, const u8 *sa,
 				  const u8 *data, size_t slen, u8 dialog_token);
 int get_hs20_version(struct wpa_bss *bss);
+int is_hs20_config(struct wpa_supplicant *wpa_s);
 int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
 		    struct wpa_bss *bss);
 int hs20_get_pps_mo_id(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index c6cef5b..36f4d3c 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -663,7 +663,7 @@
 	}
 
 #ifdef CONFIG_HS20
-	if (is_hs20_network(wpa_s, ssid, bss)) {
+	if (is_hs20_config(wpa_s) && is_hs20_network(wpa_s, ssid, bss)) {
 		struct wpabuf *hs20;
 
 		hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 1fd6506..224fb10 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1016,6 +1016,9 @@
 		if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_OWE))
 			wpas_update_owe_connect_params(wpa_s);
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_HS20
+		hs20_configure_frame_filters(wpa_s);
+#endif
 	} else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
 		   state == WPA_ASSOCIATED) {
 		wpa_s->new_connection = 1;
@@ -3033,7 +3036,7 @@
 	}
 
 #ifdef CONFIG_HS20
-	if (is_hs20_network(wpa_s, ssid, bss)) {
+	if (is_hs20_config(wpa_s) && is_hs20_network(wpa_s, ssid, bss)) {
 		struct wpabuf *hs20;
 
 		hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
@@ -3051,10 +3054,9 @@
 				wpa_ie_len += wpabuf_len(hs20);
 			}
 			wpabuf_free(hs20);
-
-			hs20_configure_frame_filters(wpa_s);
 		}
 	}
+	hs20_configure_frame_filters(wpa_s);
 #endif /* CONFIG_HS20 */
 
 	if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {