Cumulative patch from commit b2b688d18d40cd667d0faa149b4a7172166b3bd4

b2b688d P2P: Fix crash when failed to create GO interface
6197169 WPS NFC: Fix build without CONFIG_AP=y
e1ae5d7 SAE: Fix build without CONFIG_AP=y
813e7b3 P2P: Remove group from timeout on PSK failure
5bf9a6c P2P: Add event messages for possible PSK failures on P2P groups
eac8dab P2P: Document per-client keys and p2p_remove_client
43c693c P2P: Do not store duplicate PSK entries for the same device
f2c5660 P2P: Add a command for removing a client from all groups
01a57fe P2P: Maintain list of per-client PSKs for persistent groups
759fd76 P2P: Select PSK based on Device Address instead of Interface Address
94ddef3 P2P: Make peer's P2P Device Address available to authenticator
52177fb P2P: Store P2P Device Address in per-device PSK records
05766ed P2P: Allow per-device PSK to be assigned
698e921 wpa_cli: Add tab completion for p2p_set field values
0b5fb86 P2P: Stop listen state when listen-only duration is over
02a3e5c wpa_cli: Allow first DISCONNECTED event to be reported
cdf8bfa Disallow WEP configuration in WPA network
731ef43 D-Bus: Fix per-iface object unregistration on not existing objects
447969e D-Bus: Do not send network notification for all P2P groups
eb32460 Fix switching from EAP-SIM to EAP-AKA/AKA'
f2b3f4d P2P: Allow P2P functionality to be disabled per interface
50f4f2a hostapd: Add Automatic Channel Selection (ACS) support
43ee470 P2P: Immediate group removal in GC in case of deauthentication
fcf2052 Fix MNC length for Swisscom SIM cards

Bug: 10606228, 10513949

Change-Id: I63ba0e2ab4fa76e6afa7a34be42e8e847e1511b0
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index a35be51..d666c91 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1372,6 +1372,60 @@
 }
 #endif /* NO_CONFIG_WRITE */
 
+
+static int wpa_config_parse_psk_list(const struct parse_data *data,
+				     struct wpa_ssid *ssid, int line,
+				     const char *value)
+{
+	struct psk_list_entry *p;
+	const char *pos;
+
+	p = os_zalloc(sizeof(*p));
+	if (p == NULL)
+		return -1;
+
+	pos = value;
+	if (os_strncmp(pos, "P2P-", 4) == 0) {
+		p->p2p = 1;
+		pos += 4;
+	}
+
+	if (hwaddr_aton(pos, p->addr)) {
+		wpa_printf(MSG_ERROR, "Line %d: Invalid psk_list address '%s'",
+			   line, pos);
+		os_free(p);
+		return -1;
+	}
+	pos += 17;
+	if (*pos != '-') {
+		wpa_printf(MSG_ERROR, "Line %d: Invalid psk_list '%s'",
+			   line, pos);
+		os_free(p);
+		return -1;
+	}
+	pos++;
+
+	if (hexstr2bin(pos, p->psk, PMK_LEN) || pos[PMK_LEN * 2] != '\0') {
+		wpa_printf(MSG_ERROR, "Line %d: Invalid psk_list PSK '%s'",
+			   line, pos);
+		os_free(p);
+		return -1;
+	}
+
+	dl_list_add(&ssid->psk_list, &p->list);
+
+	return 0;
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_psk_list(const struct parse_data *data,
+					struct wpa_ssid *ssid)
+{
+	return NULL;
+}
+#endif /* NO_CONFIG_WRITE */
+
 #endif /* CONFIG_P2P */
 
 /* Helper macros for network block parser */
@@ -1539,6 +1593,7 @@
 	{ INT_RANGE(ignore_broadcast_ssid, 0, 2) },
 #ifdef CONFIG_P2P
 	{ FUNC(p2p_client_list) },
+	{ FUNC(psk_list) },
 #endif /* CONFIG_P2P */
 #ifdef CONFIG_HT_OVERRIDES
 	{ INT_RANGE(disable_ht, 0, 1) },
@@ -1731,6 +1786,8 @@
  */
 void wpa_config_free_ssid(struct wpa_ssid *ssid)
 {
+	struct psk_list_entry *psk;
+
 	os_free(ssid->ssid);
 	os_free(ssid->passphrase);
 	os_free(ssid->ext_psk);
@@ -1745,6 +1802,11 @@
 #ifdef CONFIG_HT_OVERRIDES
 	os_free(ssid->ht_mcs);
 #endif /* CONFIG_HT_OVERRIDES */
+	while ((psk = dl_list_first(&ssid->psk_list, struct psk_list_entry,
+				    list))) {
+		dl_list_del(&psk->list);
+		os_free(psk);
+	}
 	os_free(ssid);
 }
 
@@ -1908,6 +1970,7 @@
 	if (ssid == NULL)
 		return NULL;
 	ssid->id = id;
+	dl_list_init(&ssid->psk_list);
 	if (last)
 		last->next = ssid;
 	else