Accumulative patch from commit dc013f1e37df3462085cf01a13f0c432f146ad7a

Author: Jouni Malinen <jouni@qca.qualcomm.com>
Date:   Tue Jan 15 12:03:29 2013 +0200
    eapol_test: Remove unnecessary header file inclusion

 - P2P: Send P2P-FIND-STOPPED event in the new continue-search states
 - P2P: Add some more details on Service Query TLV format
 - P2P: Use the same Dialog Token value for every GO Negotiation retry
 - P2P: Publish more connected clients info in Probe Response frames
 - P2P: Fix some memory leaks in p2p_add_device()
 - P2P: Use the same Dialog Token value for every PD retry
 - P2P: Document operating channel selection functions
 - P2P: Always re-select operating channel if not hard coded
 - P2P: Do not allow re-selection of GO channel if forced_freq in use
 - P2P: Set FORCE_FREQ flag as part of p2p_prepare_channel()
 - P2P: Share a single function for GO channel selection
 - P2P: Prefer operating channels where HT40 is possible
 - P2P: Be more careful with wpa_config_update_psk() call
 - P2P: Allow PSK to be used instead of passphrase for persistent GO
 - P2P: Consider age for the P2P scan results
 - Move some P2P offchannel operations to offchannel.c
 - P2P: Add more complete description of p2p_cancel
 - P2P: Allow p2p_cancel to be used to stop p2p_connect-join operation
 - Interworking changes
 - WNM changes
 - WPS changes
 - SAE changes

Change-Id: I38b847d3460066cc58aecbcf67266bfcff1d344e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index e157845..2c52c68 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -629,49 +629,12 @@
 
 static int wpa_config_parse_cipher(int line, const char *value)
 {
-	int val = 0, last;
-	char *start, *end, *buf;
-
-	buf = os_strdup(value);
-	if (buf == NULL)
+	int val = wpa_parse_cipher(value);
+	if (val < 0) {
+		wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
+			   line, value);
 		return -1;
-	start = buf;
-
-	while (*start != '\0') {
-		while (*start == ' ' || *start == '\t')
-			start++;
-		if (*start == '\0')
-			break;
-		end = start;
-		while (*end != ' ' && *end != '\t' && *end != '\0')
-			end++;
-		last = *end == '\0';
-		*end = '\0';
-		if (os_strcmp(start, "CCMP") == 0)
-			val |= WPA_CIPHER_CCMP;
-		else if (os_strcmp(start, "GCMP") == 0)
-			val |= WPA_CIPHER_GCMP;
-		else if (os_strcmp(start, "TKIP") == 0)
-			val |= WPA_CIPHER_TKIP;
-		else if (os_strcmp(start, "WEP104") == 0)
-			val |= WPA_CIPHER_WEP104;
-		else if (os_strcmp(start, "WEP40") == 0)
-			val |= WPA_CIPHER_WEP40;
-		else if (os_strcmp(start, "NONE") == 0)
-			val |= WPA_CIPHER_NONE;
-		else {
-			wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
-				   line, start);
-			os_free(buf);
-			return -1;
-		}
-
-		if (last)
-			break;
-		start = end + 1;
 	}
-	os_free(buf);
-
 	if (val == 0) {
 		wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
 			   line);
@@ -684,72 +647,13 @@
 #ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_cipher(int cipher)
 {
-	char *buf, *pos, *end;
-	int ret;
-
-	pos = buf = os_zalloc(50);
+	char *buf = os_zalloc(50);
 	if (buf == NULL)
 		return NULL;
-	end = buf + 50;
 
-	if (cipher & WPA_CIPHER_CCMP) {
-		ret = os_snprintf(pos, end - pos, "%sCCMP",
-				  pos == buf ? "" : " ");
-		if (ret < 0 || ret >= end - pos) {
-			end[-1] = '\0';
-			return buf;
-		}
-		pos += ret;
-	}
-
-	if (cipher & WPA_CIPHER_GCMP) {
-		ret = os_snprintf(pos, end - pos, "%sGCMP",
-				  pos == buf ? "" : " ");
-		if (ret < 0 || ret >= end - pos) {
-			end[-1] = '\0';
-			return buf;
-		}
-		pos += ret;
-	}
-
-	if (cipher & WPA_CIPHER_TKIP) {
-		ret = os_snprintf(pos, end - pos, "%sTKIP",
-				  pos == buf ? "" : " ");
-		if (ret < 0 || ret >= end - pos) {
-			end[-1] = '\0';
-			return buf;
-		}
-		pos += ret;
-	}
-
-	if (cipher & WPA_CIPHER_WEP104) {
-		ret = os_snprintf(pos, end - pos, "%sWEP104",
-				  pos == buf ? "" : " ");
-		if (ret < 0 || ret >= end - pos) {
-			end[-1] = '\0';
-			return buf;
-		}
-		pos += ret;
-	}
-
-	if (cipher & WPA_CIPHER_WEP40) {
-		ret = os_snprintf(pos, end - pos, "%sWEP40",
-				  pos == buf ? "" : " ");
-		if (ret < 0 || ret >= end - pos) {
-			end[-1] = '\0';
-			return buf;
-		}
-		pos += ret;
-	}
-
-	if (cipher & WPA_CIPHER_NONE) {
-		ret = os_snprintf(pos, end - pos, "%sNONE",
-				  pos == buf ? "" : " ");
-		if (ret < 0 || ret >= end - pos) {
-			end[-1] = '\0';
-			return buf;
-		}
-		pos += ret;
+	if (wpa_write_ciphers(buf, buf + 50, cipher, " ") < 0) {
+		os_free(buf);
+		return NULL;
 	}
 
 	return buf;
@@ -765,8 +669,7 @@
 	val = wpa_config_parse_cipher(line, value);
 	if (val == -1)
 		return -1;
-	if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP |
-		    WPA_CIPHER_NONE)) {
+	if (val & ~WPA_ALLOWED_PAIRWISE_CIPHERS) {
 		wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
 			   "(0x%x).", line, val);
 		return -1;
@@ -795,8 +698,7 @@
 	val = wpa_config_parse_cipher(line, value);
 	if (val == -1)
 		return -1;
-	if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP |
-		    WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40)) {
+	if (val & ~WPA_ALLOWED_GROUP_CIPHERS) {
 		wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
 			   "(0x%x).", line, val);
 		return -1;
@@ -916,9 +818,7 @@
 #endif /* NO_CONFIG_WRITE */
 
 
-static int * wpa_config_parse_freqs(const struct parse_data *data,
-				    struct wpa_ssid *ssid, int line,
-				    const char *value)
+static int * wpa_config_parse_int_array(const char *value)
 {
 	int *freqs;
 	size_t used, len;
@@ -965,7 +865,7 @@
 {
 	int *freqs;
 
-	freqs = wpa_config_parse_freqs(data, ssid, line, value);
+	freqs = wpa_config_parse_int_array(value);
 	if (freqs == NULL)
 		return -1;
 	os_free(ssid->scan_freq);
@@ -981,7 +881,7 @@
 {
 	int *freqs;
 
-	freqs = wpa_config_parse_freqs(data, ssid, line, value);
+	freqs = wpa_config_parse_int_array(value);
 	if (freqs == NULL)
 		return -1;
 	os_free(ssid->freq_list);
@@ -1627,7 +1527,7 @@
 #endif /* CONFIG_IEEE80211W */
 	{ INT_RANGE(peerkey, 0, 1) },
 	{ INT_RANGE(mixed_cell, 0, 1) },
-	{ INT_RANGE(frequency, 0, 10000) },
+	{ INT_RANGE(frequency, 0, 65000) },
 	{ INT(wpa_ptk_rekey) },
 	{ STR(bgscan) },
 	{ INT_RANGE(ignore_broadcast_ssid, 0, 2) },
@@ -1637,6 +1537,7 @@
 #ifdef CONFIG_HT_OVERRIDES
 	{ INT_RANGE(disable_ht, 0, 1) },
 	{ INT_RANGE(disable_ht40, -1, 1) },
+	{ INT_RANGE(disable_sgi, 0, 1) },
 	{ INT_RANGE(disable_max_amsdu, -1, 1) },
 	{ INT_RANGE(ampdu_factor, -1, 3) },
 	{ INT_RANGE(ampdu_density, -1, 7) },
@@ -1835,6 +1736,7 @@
 	os_free(cred->eap_method);
 	os_free(cred->phase1);
 	os_free(cred->phase2);
+	os_free(cred->excluded_ssid);
 	os_free(cred);
 }
 
@@ -1901,6 +1803,7 @@
 	wpabuf_free(config->wps_nfc_dh_privkey);
 	wpabuf_free(config->wps_nfc_dev_pw);
 	os_free(config->ext_password_backend);
+	os_free(config->sae_groups);
 	os_free(config);
 }
 
@@ -2037,6 +1940,7 @@
 #ifdef CONFIG_HT_OVERRIDES
 	ssid->disable_ht = DEFAULT_DISABLE_HT;
 	ssid->disable_ht40 = DEFAULT_DISABLE_HT40;
+	ssid->disable_sgi = DEFAULT_DISABLE_SGI;
 	ssid->disable_max_amsdu = DEFAULT_DISABLE_MAX_AMSDU;
 	ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR;
 	ssid->ampdu_density = DEFAULT_AMPDU_DENSITY;
@@ -2411,6 +2315,34 @@
 		return 0;
 	}
 
+	if (os_strcmp(var, "excluded_ssid") == 0) {
+		struct excluded_ssid *e;
+
+		if (len > MAX_SSID_LEN) {
+			wpa_printf(MSG_ERROR, "Line %d: invalid "
+				   "excluded_ssid length %d", line, (int) len);
+			os_free(val);
+			return -1;
+		}
+
+		e = os_realloc_array(cred->excluded_ssid,
+				     cred->num_excluded_ssid + 1,
+				     sizeof(struct excluded_ssid));
+		if (e == NULL) {
+			os_free(val);
+			return -1;
+		}
+		cred->excluded_ssid = e;
+
+		e = &cred->excluded_ssid[cred->num_excluded_ssid++];
+		os_memcpy(e->ssid, val, len);
+		e->ssid_len = len;
+
+		os_free(val);
+
+		return 0;
+	}
+
 	if (line) {
 		wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
 			   line, var);
@@ -2947,6 +2879,24 @@
 }
 
 
+static int wpa_config_process_sae_groups(
+	const struct global_parse_data *data,
+	struct wpa_config *config, int line, const char *pos)
+{
+	int *groups = wpa_config_parse_int_array(pos);
+	if (groups == NULL) {
+		wpa_printf(MSG_ERROR, "Line %d: Invalid sae_groups '%s'",
+			   line, pos);
+		return -1;
+	}
+
+	os_free(config->sae_groups);
+	config->sae_groups = groups;
+
+	return 0;
+}
+
+
 #ifdef OFFSET
 #undef OFFSET
 #endif /* OFFSET */
@@ -3039,6 +2989,7 @@
 	{ INT_RANGE(auto_interworking, 0, 1), 0 },
 	{ INT(okc), 0 },
 	{ INT(pmf), 0 },
+	{ FUNC(sae_groups), 0 },
 };
 
 #undef FUNC