Cumulative patch from commit 3e7f1c7980c6e9fc7173f78aa72b2761fcd8924d (DO NOT MERGE)

3e7f1c7 GnuTLS: Add TLS event callbacks for chain success/failure and peer cert
0eb2ed0 GnuTLS: Add support for OCSP stapling as a client
cf08e9b Add MESH to modes capabilities
db5adfe Add SAE to auth_alg capabilities
0e1bb94 GnuTLS: Verify that server certificate EKU is valid for a server
d4d1f5c GnuTLS: Fix tls_disable_time_checks=1 processing
594d1fc GnuTLS: Add support for private_key and client_cert as blobs
79b1dd9 GnuTLS: Fix DER encoding certificate parsing
a165145 Add "GET tls_library" to provide information on TLS library and version
c3bb84b GnuTLS: Add event callbacks
8ddcd6b GnuTLS: Add support for domain_suffix_match
4bc13bf GnuTLS: Check for any unknown verification failure
e0d431a GnuTLS: Add more debug prints for version and session status
65ec7f4 GnuTLS: Move peer certificate validation into callback function
7c82457 GnuTLS: Remove support for versions older than 2.12.x
e1d63f6 GnuTLS: Remove old version number checks for 1.3.2
ae0a23a GnuTLS: Remove GNUTLS_INTERNAL_STRUCTURE_HACK
db4cf40 GnuTLS: Add support for ca_cert as a blob
224104d TLS: Reject openssl_ciphers parameter in non-OpenSSL cases
b09baf3 Work around Windows build issues
6dbbef9 Define host_to_le32() for Windows builds
7d28e46 Fix os_win32 build
0b40247 Remove Network Security Service (NSS) support
d166947 schannel: Reject subject_match, altsubject_match, suffix_match
59051f8 TLS: Reject subject_match, altsubject_match, suffix_match
f8717ac GnuTLS: Reject subject_match, altsubject_match, suffix_match
e24aef1 Fix a typo in domain_suffix_match documentation
394b547 Improve subject_match and domain_suffix_match documentation
8a42a07 trace: Fix out-of-memory testing logic
79cd993 Add address masks to BSSID lists
b83e455 Add network specific BSSID black and white lists
b3d6a0a Add generic parser for MAC address lists
21c74e8 nl80211: Use a helper function to put mesh_id
85e1fad nl80211: Use a helper function for putting beacon interval
6dfc557 Remove mesh_ht_mode network block parameter
54fe48b mesh: Use the shared function with IBSS to determine channel parameters
f7e889f mesh: Convert channel configuration to use common routines
6334330 mesh: Use a separate variable to track whether HT is enabled
1fc4ab2 nl80211: Move debug prints into nl80211_put_freq_params()
cae87ab nl80211: Add a helper function for putting basic rates
6b8b077 ibss/mesh: Enable HT40 if supported
a828f62 Make check_40mhz_2g4 common
fdd989d Make check_20mhz_bss common
0e550fe Make check_40mhz_5g common
6d5d098 Make get_pri_sec_chan() common
5144274 Introduce common allowed_ht40_channel_pair()
5f10b7f Use common hw_get_freq/hw_get_chan helpers in hostapd
269dfe2 Introduce common hw features
1830817 IBSS: Add WPA_DRIVER_FLAGS_HT_IBSS
f3b8ad4 SAE: Implement retransmission timer
a206e2a SAE: Centralize function for sending initial COMMIT
28c91ee bsd: Fix parsing of ieee80211req_scan_result on FreeBSD and DragonFly
96d1d97 Android: Remove hardcoded ICU include paths from hs20-osu-client
a354bcc D-Bus: Use NoMemory error message from CreateInterface
635874b Handle interface disabled/enabled more consistently
8f2cf37 P2P: Indicate reason=UNAVAILABLE for group netdev going down
86a7fbb Verify that eloop_register_read_sock() succeeds for ctrl_iface setup
27d9701 Fix a memory leak on WPA authenticator error path
c1c07dc Fix hostapd interface addition error path
a156ffd Add support for testing memory allocation failures
52b3943 D-Bus: Fix interface unregistration on error path
96dc9a6 D-Bus (old): Fix interface unregistration on error path
ef03557 Fix memory leak on wpa_supplicant_init_wpa() error path
52a8058 TDLS: Fix an interface addition error path
f2d5728 D-Bus: Fix string array dict entry parser in out-of-memory case
c61bc23 D-Bus: Fix byte array dict entry parser in out-of-memory case
dacf605 D-Bus: Fix Introspect() in case of os_strdup() failure
68a8669 D-Bus (old): Fix wpsReg error message
f0614bc D-Bus (old): Fix message handler error paths
a2af1c7 D-Bus (old): Fix memory leak on error path
3d2e2d5 trace: Fix compiler warning on 32-bit builds with bfd support
b9f6560 eloop: Fix WPA_TRACE tracking in case of realloc failure
e10422c Fix memory leak on hostapd BSS addition error path
2801659 Fix hostapd initialization error path on allocation failure
d58ade2 nl80211: Fix compilation with libnl 1.1 and 2.0
51f3427 crypto: Clear temporary stack buffers after use
77a2c39 crypto: Clear temporary heap allocations before freeing
a15a7fc DH: Clear memory explicitly on private key deinit
77c45e2 Add wpabuf_clear_free() to allow clearing of freed memory
a90c7d9 OpenSSL: Fix pbkdf2_sha1() wrapper
f6ebbcf AES-SIV: Make aes_s2v() static
dcf8fbc nl80211: Simplify event processing error paths
38751d8 nl80211: Remove cfg80211 state mismatch workaround for authentication
64ae244 nl80211: Check support for rekey offload on first use

Change-Id: Ice94c3cf8e39a6d2cac993aacd0f6d45b31c7c15
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 4ebf684..a810632 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -235,6 +235,99 @@
 #endif /* NO_CONFIG_WRITE */
 
 
+static int wpa_config_parse_addr_list(const struct parse_data *data,
+				      int line, const char *value,
+				      u8 **list, size_t *num, char *name,
+				      u8 abort_on_error, u8 masked)
+{
+	const char *pos;
+	u8 *buf, *n, addr[2 * ETH_ALEN];
+	size_t count;
+
+	buf = NULL;
+	count = 0;
+
+	pos = value;
+	while (pos && *pos) {
+		while (*pos == ' ')
+			pos++;
+
+		if (hwaddr_masked_aton(pos, addr, &addr[ETH_ALEN], masked)) {
+			if (abort_on_error || count == 0) {
+				wpa_printf(MSG_ERROR,
+					   "Line %d: Invalid %s address '%s'",
+					   line, name, value);
+				os_free(buf);
+				return -1;
+			}
+			/* continue anyway since this could have been from a
+			 * truncated configuration file line */
+			wpa_printf(MSG_INFO,
+				   "Line %d: Ignore likely truncated %s address '%s'",
+				   line, name, pos);
+		} else {
+			n = os_realloc_array(buf, count + 1, 2 * ETH_ALEN);
+			if (n == NULL) {
+				os_free(buf);
+				return -1;
+			}
+			buf = n;
+			os_memmove(buf + 2 * ETH_ALEN, buf,
+				   count * 2 * ETH_ALEN);
+			os_memcpy(buf, addr, 2 * ETH_ALEN);
+			count++;
+			wpa_printf(MSG_MSGDUMP,
+				   "%s: addr=" MACSTR " mask=" MACSTR,
+				   name, MAC2STR(addr),
+				   MAC2STR(&addr[ETH_ALEN]));
+		}
+
+		pos = os_strchr(pos, ' ');
+	}
+
+	os_free(*list);
+	*list = buf;
+	*num = count;
+
+	return 0;
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_addr_list(const struct parse_data *data,
+					 const u8 *list, size_t num, char *name)
+{
+	char *value, *end, *pos;
+	int res;
+	size_t i;
+
+	if (list == NULL || num == 0)
+		return NULL;
+
+	value = os_malloc(2 * 20 * num);
+	if (value == NULL)
+		return NULL;
+	pos = value;
+	end = value + 2 * 20 * num;
+
+	for (i = num; i > 0; i--) {
+		const u8 *a = list + (i - 1) * 2 * ETH_ALEN;
+		const u8 *m = a + ETH_ALEN;
+
+		if (i < num)
+			*pos++ = ' ';
+		res = hwaddr_mask_txt(pos, end - pos, a, m);
+		if (res < 0) {
+			os_free(value);
+			return NULL;
+		}
+		pos += res;
+	}
+
+	return value;
+}
+#endif /* NO_CONFIG_WRITE */
+
 static int wpa_config_parse_bssid(const struct parse_data *data,
 				  struct wpa_ssid *ssid, int line,
 				  const char *value)
@@ -280,6 +373,50 @@
 #endif /* NO_CONFIG_WRITE */
 
 
+static int wpa_config_parse_bssid_blacklist(const struct parse_data *data,
+					    struct wpa_ssid *ssid, int line,
+					    const char *value)
+{
+	return wpa_config_parse_addr_list(data, line, value,
+					  &ssid->bssid_blacklist,
+					  &ssid->num_bssid_blacklist,
+					  "bssid_blacklist", 1, 1);
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_bssid_blacklist(const struct parse_data *data,
+					       struct wpa_ssid *ssid)
+{
+	return wpa_config_write_addr_list(data, ssid->bssid_blacklist,
+					  ssid->num_bssid_blacklist,
+					  "bssid_blacklist");
+}
+#endif /* NO_CONFIG_WRITE */
+
+
+static int wpa_config_parse_bssid_whitelist(const struct parse_data *data,
+					    struct wpa_ssid *ssid, int line,
+					    const char *value)
+{
+	return wpa_config_parse_addr_list(data, line, value,
+					  &ssid->bssid_whitelist,
+					  &ssid->num_bssid_whitelist,
+					  "bssid_whitelist", 1, 1);
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_bssid_whitelist(const struct parse_data *data,
+					       struct wpa_ssid *ssid)
+{
+	return wpa_config_write_addr_list(data, ssid->bssid_whitelist,
+					  ssid->num_bssid_whitelist,
+					  "bssid_whitelist");
+}
+#endif /* NO_CONFIG_WRITE */
+
+
 static int wpa_config_parse_psk(const struct parse_data *data,
 				struct wpa_ssid *ssid, int line,
 				const char *value)
@@ -1453,53 +1590,10 @@
 					    struct wpa_ssid *ssid, int line,
 					    const char *value)
 {
-	const char *pos;
-	u8 *buf, *n, addr[ETH_ALEN];
-	size_t count;
-
-	buf = NULL;
-	count = 0;
-
-	pos = value;
-	while (pos && *pos) {
-		while (*pos == ' ')
-			pos++;
-
-		if (hwaddr_aton(pos, addr)) {
-			if (count == 0) {
-				wpa_printf(MSG_ERROR, "Line %d: Invalid "
-					   "p2p_client_list address '%s'.",
-					   line, value);
-				os_free(buf);
-				return -1;
-			}
-			/* continue anyway since this could have been from a
-			 * truncated configuration file line */
-			wpa_printf(MSG_INFO, "Line %d: Ignore likely "
-				   "truncated p2p_client_list address '%s'",
-				   line, pos);
-		} else {
-			n = os_realloc_array(buf, count + 1, ETH_ALEN);
-			if (n == NULL) {
-				os_free(buf);
-				return -1;
-			}
-			buf = n;
-			os_memmove(buf + ETH_ALEN, buf, count * ETH_ALEN);
-			os_memcpy(buf, addr, ETH_ALEN);
-			count++;
-			wpa_hexdump(MSG_MSGDUMP, "p2p_client_list",
-				    addr, ETH_ALEN);
-		}
-
-		pos = os_strchr(pos, ' ');
-	}
-
-	os_free(ssid->p2p_client_list);
-	ssid->p2p_client_list = buf;
-	ssid->num_p2p_clients = count;
-
-	return 0;
+	return wpa_config_parse_addr_list(data, line, value,
+					  &ssid->p2p_client_list,
+					  &ssid->num_p2p_clients,
+					  "p2p_client_list", 0, 0);
 }
 
 
@@ -1507,34 +1601,9 @@
 static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
 					       struct wpa_ssid *ssid)
 {
-	char *value, *end, *pos;
-	int res;
-	size_t i;
-
-	if (ssid->p2p_client_list == NULL || ssid->num_p2p_clients == 0)
-		return NULL;
-
-	value = os_malloc(20 * ssid->num_p2p_clients);
-	if (value == NULL)
-		return NULL;
-	pos = value;
-	end = value + 20 * ssid->num_p2p_clients;
-
-	for (i = ssid->num_p2p_clients; i > 0; i--) {
-		res = os_snprintf(pos, end - pos, MACSTR " ",
-				  MAC2STR(ssid->p2p_client_list +
-					  (i - 1) * ETH_ALEN));
-		if (os_snprintf_error(end - pos, res)) {
-			os_free(value);
-			return NULL;
-		}
-		pos += res;
-	}
-
-	if (pos > value)
-		pos[-1] = '\0';
-
-	return value;
+	return wpa_config_write_addr_list(data, ssid->p2p_client_list,
+					  ssid->num_p2p_clients,
+					  "p2p_client_list");
 }
 #endif /* NO_CONFIG_WRITE */
 
@@ -1597,32 +1666,6 @@
 
 #ifdef CONFIG_MESH
 
-static int wpa_config_parse_mesh_ht_mode(const struct parse_data *data,
-					 struct wpa_ssid *ssid, int line,
-					 const char *value)
-{
-	int htval = 0;
-
-	if (os_strcmp(value, "NOHT") == 0)
-		htval = CHAN_NO_HT;
-	else if (os_strcmp(value, "HT20") == 0)
-		htval = CHAN_HT20;
-	else if (os_strcmp(value, "HT40-") == 0)
-		htval = CHAN_HT40MINUS;
-	else if (os_strcmp(value, "HT40+") == 0)
-		htval = CHAN_HT40PLUS;
-	else {
-		wpa_printf(MSG_ERROR,
-			   "Line %d: no ht_mode configured.", line);
-		return -1;
-	}
-
-	wpa_printf(MSG_MSGDUMP, "mesh_ht_mode: 0x%x", htval);
-	ssid->mesh_ht_mode = htval;
-	return 0;
-}
-
-
 static int wpa_config_parse_mesh_basic_rates(const struct parse_data *data,
 					     struct wpa_ssid *ssid, int line,
 					     const char *value)
@@ -1648,32 +1691,6 @@
 
 #ifndef NO_CONFIG_WRITE
 
-static char * wpa_config_write_mesh_ht_mode(const struct parse_data *data,
-					    struct wpa_ssid *ssid)
-{
-	char *val;
-
-	switch (ssid->mesh_ht_mode) {
-	default:
-		val = NULL;
-		break;
-	case CHAN_NO_HT:
-		val = "NOHT";
-		break;
-	case CHAN_HT20:
-		val = "HT20";
-		break;
-	case CHAN_HT40MINUS:
-		val = "HT40-";
-		break;
-	case CHAN_HT40PLUS:
-		val = "HT40+";
-		break;
-	}
-	return val ? os_strdup(val) : NULL;
-}
-
-
 static char * wpa_config_write_mesh_basic_rates(const struct parse_data *data,
 						struct wpa_ssid *ssid)
 {
@@ -1776,6 +1793,8 @@
 	{ STR_RANGE(ssid, 0, MAX_SSID_LEN) },
 	{ INT_RANGE(scan_ssid, 0, 1) },
 	{ FUNC(bssid) },
+	{ FUNC(bssid_blacklist) },
+	{ FUNC(bssid_whitelist) },
 	{ FUNC_KEY(psk) },
 	{ FUNC(proto) },
 	{ FUNC(key_mgmt) },
@@ -1856,7 +1875,6 @@
 	{ INT_RANGE(mixed_cell, 0, 1) },
 	{ INT_RANGE(frequency, 0, 65000) },
 #ifdef CONFIG_MESH
-	{ FUNC(mesh_ht_mode) },
 	{ FUNC(mesh_basic_rates) },
 	{ INT(dot11MeshMaxRetries) },
 	{ INT(dot11MeshRetryTimeout) },
@@ -2088,6 +2106,8 @@
 	os_free(ssid->freq_list);
 	os_free(ssid->bgscan);
 	os_free(ssid->p2p_client_list);
+	os_free(ssid->bssid_blacklist);
+	os_free(ssid->bssid_whitelist);
 #ifdef CONFIG_HT_OVERRIDES
 	os_free(ssid->ht_mcs);
 #endif /* CONFIG_HT_OVERRIDES */
@@ -2347,7 +2367,6 @@
 	ssid->eap.sim_num = DEFAULT_USER_SELECTED_SIM;
 #endif /* IEEE8021X_EAPOL */
 #ifdef CONFIG_MESH
-	ssid->mesh_ht_mode = DEFAULT_MESH_HT_MODE;
 	ssid->dot11MeshMaxRetries = DEFAULT_MESH_MAX_RETRIES;
 	ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT;
 	ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT;