xref: /aosp_15_r20/external/wpa_supplicant_8/wpa_supplicant/config.c (revision 03f9172ca588f91df233974f4258bab95191f931)
1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker  * WPA Supplicant / Configuration parser and common functions
3*03f9172cSAndroid Build Coastguard Worker  * Copyright (c) 2003-2019, Jouni Malinen <[email protected]>
4*03f9172cSAndroid Build Coastguard Worker  *
5*03f9172cSAndroid Build Coastguard Worker  * This software may be distributed under the terms of the BSD license.
6*03f9172cSAndroid Build Coastguard Worker  * See README for more details.
7*03f9172cSAndroid Build Coastguard Worker  */
8*03f9172cSAndroid Build Coastguard Worker 
9*03f9172cSAndroid Build Coastguard Worker #include "includes.h"
10*03f9172cSAndroid Build Coastguard Worker 
11*03f9172cSAndroid Build Coastguard Worker #include "common.h"
12*03f9172cSAndroid Build Coastguard Worker #include "utils/uuid.h"
13*03f9172cSAndroid Build Coastguard Worker #include "utils/ip_addr.h"
14*03f9172cSAndroid Build Coastguard Worker #include "common/ieee802_1x_defs.h"
15*03f9172cSAndroid Build Coastguard Worker #include "common/sae.h"
16*03f9172cSAndroid Build Coastguard Worker #include "crypto/sha1.h"
17*03f9172cSAndroid Build Coastguard Worker #include "rsn_supp/wpa.h"
18*03f9172cSAndroid Build Coastguard Worker #include "eap_peer/eap.h"
19*03f9172cSAndroid Build Coastguard Worker #include "p2p/p2p.h"
20*03f9172cSAndroid Build Coastguard Worker #include "fst/fst.h"
21*03f9172cSAndroid Build Coastguard Worker #include "config.h"
22*03f9172cSAndroid Build Coastguard Worker 
23*03f9172cSAndroid Build Coastguard Worker 
24*03f9172cSAndroid Build Coastguard Worker #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE)
25*03f9172cSAndroid Build Coastguard Worker #define NO_CONFIG_WRITE
26*03f9172cSAndroid Build Coastguard Worker #endif
27*03f9172cSAndroid Build Coastguard Worker 
28*03f9172cSAndroid Build Coastguard Worker /*
29*03f9172cSAndroid Build Coastguard Worker  * Structure for network configuration parsing. This data is used to implement
30*03f9172cSAndroid Build Coastguard Worker  * a generic parser for each network block variable. The table of configuration
31*03f9172cSAndroid Build Coastguard Worker  * variables is defined below in this file (ssid_fields[]).
32*03f9172cSAndroid Build Coastguard Worker  */
33*03f9172cSAndroid Build Coastguard Worker struct parse_data {
34*03f9172cSAndroid Build Coastguard Worker 	/* Configuration variable name */
35*03f9172cSAndroid Build Coastguard Worker 	char *name;
36*03f9172cSAndroid Build Coastguard Worker 
37*03f9172cSAndroid Build Coastguard Worker 	/* Parser function for this variable. The parser functions return 0 or 1
38*03f9172cSAndroid Build Coastguard Worker 	 * to indicate success. Value 0 indicates that the parameter value may
39*03f9172cSAndroid Build Coastguard Worker 	 * have changed while value 1 means that the value did not change.
40*03f9172cSAndroid Build Coastguard Worker 	 * Error cases (failure to parse the string) are indicated by returning
41*03f9172cSAndroid Build Coastguard Worker 	 * -1. */
42*03f9172cSAndroid Build Coastguard Worker 	int (*parser)(const struct parse_data *data, struct wpa_ssid *ssid,
43*03f9172cSAndroid Build Coastguard Worker 		      int line, const char *value);
44*03f9172cSAndroid Build Coastguard Worker 
45*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
46*03f9172cSAndroid Build Coastguard Worker 	/* Writer function (i.e., to get the variable in text format from
47*03f9172cSAndroid Build Coastguard Worker 	 * internal presentation). */
48*03f9172cSAndroid Build Coastguard Worker 	char * (*writer)(const struct parse_data *data, struct wpa_ssid *ssid);
49*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
50*03f9172cSAndroid Build Coastguard Worker 
51*03f9172cSAndroid Build Coastguard Worker 	/* Variable specific parameters for the parser. */
52*03f9172cSAndroid Build Coastguard Worker 	void *param1, *param2, *param3, *param4;
53*03f9172cSAndroid Build Coastguard Worker 
54*03f9172cSAndroid Build Coastguard Worker 	/* 0 = this variable can be included in debug output and ctrl_iface
55*03f9172cSAndroid Build Coastguard Worker 	 * 1 = this variable contains key/private data and it must not be
56*03f9172cSAndroid Build Coastguard Worker 	 *     included in debug output unless explicitly requested. In
57*03f9172cSAndroid Build Coastguard Worker 	 *     addition, this variable will not be readable through the
58*03f9172cSAndroid Build Coastguard Worker 	 *     ctrl_iface.
59*03f9172cSAndroid Build Coastguard Worker 	 */
60*03f9172cSAndroid Build Coastguard Worker 	int key_data;
61*03f9172cSAndroid Build Coastguard Worker };
62*03f9172cSAndroid Build Coastguard Worker 
63*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_str(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)64*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_str(const struct parse_data *data,
65*03f9172cSAndroid Build Coastguard Worker 				struct wpa_ssid *ssid,
66*03f9172cSAndroid Build Coastguard Worker 				int line, const char *value)
67*03f9172cSAndroid Build Coastguard Worker {
68*03f9172cSAndroid Build Coastguard Worker 	size_t res_len, *dst_len, prev_len;
69*03f9172cSAndroid Build Coastguard Worker 	char **dst, *tmp;
70*03f9172cSAndroid Build Coastguard Worker 
71*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(value, "NULL") == 0) {
72*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_DEBUG, "Unset configuration string '%s'",
73*03f9172cSAndroid Build Coastguard Worker 			   data->name);
74*03f9172cSAndroid Build Coastguard Worker 		tmp = NULL;
75*03f9172cSAndroid Build Coastguard Worker 		res_len = 0;
76*03f9172cSAndroid Build Coastguard Worker 		goto set;
77*03f9172cSAndroid Build Coastguard Worker 	}
78*03f9172cSAndroid Build Coastguard Worker 
79*03f9172cSAndroid Build Coastguard Worker 	tmp = wpa_config_parse_string(value, &res_len);
80*03f9172cSAndroid Build Coastguard Worker 	if (tmp == NULL) {
81*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: failed to parse %s '%s'.",
82*03f9172cSAndroid Build Coastguard Worker 			   line, data->name,
83*03f9172cSAndroid Build Coastguard Worker 			   data->key_data ? "[KEY DATA REMOVED]" : value);
84*03f9172cSAndroid Build Coastguard Worker 		return -1;
85*03f9172cSAndroid Build Coastguard Worker 	}
86*03f9172cSAndroid Build Coastguard Worker 
87*03f9172cSAndroid Build Coastguard Worker 	if (data->key_data) {
88*03f9172cSAndroid Build Coastguard Worker 		wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
89*03f9172cSAndroid Build Coastguard Worker 				      (u8 *) tmp, res_len);
90*03f9172cSAndroid Build Coastguard Worker 	} else {
91*03f9172cSAndroid Build Coastguard Worker 		wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
92*03f9172cSAndroid Build Coastguard Worker 				  (u8 *) tmp, res_len);
93*03f9172cSAndroid Build Coastguard Worker 	}
94*03f9172cSAndroid Build Coastguard Worker 
95*03f9172cSAndroid Build Coastguard Worker 	if (data->param3 && res_len < (size_t) data->param3) {
96*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
97*03f9172cSAndroid Build Coastguard Worker 			   "min_len=%ld)", line, data->name,
98*03f9172cSAndroid Build Coastguard Worker 			   (unsigned long) res_len, (long) data->param3);
99*03f9172cSAndroid Build Coastguard Worker 		os_free(tmp);
100*03f9172cSAndroid Build Coastguard Worker 		return -1;
101*03f9172cSAndroid Build Coastguard Worker 	}
102*03f9172cSAndroid Build Coastguard Worker 
103*03f9172cSAndroid Build Coastguard Worker 	if (data->param4 && res_len > (size_t) data->param4) {
104*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
105*03f9172cSAndroid Build Coastguard Worker 			   "max_len=%ld)", line, data->name,
106*03f9172cSAndroid Build Coastguard Worker 			   (unsigned long) res_len, (long) data->param4);
107*03f9172cSAndroid Build Coastguard Worker 		os_free(tmp);
108*03f9172cSAndroid Build Coastguard Worker 		return -1;
109*03f9172cSAndroid Build Coastguard Worker 	}
110*03f9172cSAndroid Build Coastguard Worker 
111*03f9172cSAndroid Build Coastguard Worker set:
112*03f9172cSAndroid Build Coastguard Worker 	dst = (char **) (((u8 *) ssid) + (long) data->param1);
113*03f9172cSAndroid Build Coastguard Worker 	dst_len = (size_t *) (((u8 *) ssid) + (long) data->param2);
114*03f9172cSAndroid Build Coastguard Worker 
115*03f9172cSAndroid Build Coastguard Worker 	if (data->param2)
116*03f9172cSAndroid Build Coastguard Worker 		prev_len = *dst_len;
117*03f9172cSAndroid Build Coastguard Worker 	else if (*dst)
118*03f9172cSAndroid Build Coastguard Worker 		prev_len = os_strlen(*dst);
119*03f9172cSAndroid Build Coastguard Worker 	else
120*03f9172cSAndroid Build Coastguard Worker 		prev_len = 0;
121*03f9172cSAndroid Build Coastguard Worker 	if ((*dst == NULL && tmp == NULL) ||
122*03f9172cSAndroid Build Coastguard Worker 	    (*dst && tmp && prev_len == res_len &&
123*03f9172cSAndroid Build Coastguard Worker 	     os_memcmp(*dst, tmp, res_len) == 0)) {
124*03f9172cSAndroid Build Coastguard Worker 		/* No change to the previously configured value */
125*03f9172cSAndroid Build Coastguard Worker 		os_free(tmp);
126*03f9172cSAndroid Build Coastguard Worker 		return 1;
127*03f9172cSAndroid Build Coastguard Worker 	}
128*03f9172cSAndroid Build Coastguard Worker 
129*03f9172cSAndroid Build Coastguard Worker 	os_free(*dst);
130*03f9172cSAndroid Build Coastguard Worker 	*dst = tmp;
131*03f9172cSAndroid Build Coastguard Worker 	if (data->param2)
132*03f9172cSAndroid Build Coastguard Worker 		*dst_len = res_len;
133*03f9172cSAndroid Build Coastguard Worker 
134*03f9172cSAndroid Build Coastguard Worker 	return 0;
135*03f9172cSAndroid Build Coastguard Worker }
136*03f9172cSAndroid Build Coastguard Worker 
137*03f9172cSAndroid Build Coastguard Worker 
138*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_string_ascii(const u8 * value,size_t len)139*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_string_ascii(const u8 *value, size_t len)
140*03f9172cSAndroid Build Coastguard Worker {
141*03f9172cSAndroid Build Coastguard Worker 	char *buf;
142*03f9172cSAndroid Build Coastguard Worker 
143*03f9172cSAndroid Build Coastguard Worker 	buf = os_malloc(len + 3);
144*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
145*03f9172cSAndroid Build Coastguard Worker 		return NULL;
146*03f9172cSAndroid Build Coastguard Worker 	buf[0] = '"';
147*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf + 1, value, len);
148*03f9172cSAndroid Build Coastguard Worker 	buf[len + 1] = '"';
149*03f9172cSAndroid Build Coastguard Worker 	buf[len + 2] = '\0';
150*03f9172cSAndroid Build Coastguard Worker 
151*03f9172cSAndroid Build Coastguard Worker 	return buf;
152*03f9172cSAndroid Build Coastguard Worker }
153*03f9172cSAndroid Build Coastguard Worker 
154*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_string_hex(const u8 * value,size_t len)155*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_string_hex(const u8 *value, size_t len)
156*03f9172cSAndroid Build Coastguard Worker {
157*03f9172cSAndroid Build Coastguard Worker 	char *buf;
158*03f9172cSAndroid Build Coastguard Worker 
159*03f9172cSAndroid Build Coastguard Worker 	buf = os_zalloc(2 * len + 1);
160*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
161*03f9172cSAndroid Build Coastguard Worker 		return NULL;
162*03f9172cSAndroid Build Coastguard Worker 	wpa_snprintf_hex(buf, 2 * len + 1, value, len);
163*03f9172cSAndroid Build Coastguard Worker 
164*03f9172cSAndroid Build Coastguard Worker 	return buf;
165*03f9172cSAndroid Build Coastguard Worker }
166*03f9172cSAndroid Build Coastguard Worker 
167*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_string(const u8 * value,size_t len)168*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_string(const u8 *value, size_t len)
169*03f9172cSAndroid Build Coastguard Worker {
170*03f9172cSAndroid Build Coastguard Worker 	if (value == NULL)
171*03f9172cSAndroid Build Coastguard Worker 		return NULL;
172*03f9172cSAndroid Build Coastguard Worker 
173*03f9172cSAndroid Build Coastguard Worker 	if (is_hex(value, len))
174*03f9172cSAndroid Build Coastguard Worker 		return wpa_config_write_string_hex(value, len);
175*03f9172cSAndroid Build Coastguard Worker 	else
176*03f9172cSAndroid Build Coastguard Worker 		return wpa_config_write_string_ascii(value, len);
177*03f9172cSAndroid Build Coastguard Worker }
178*03f9172cSAndroid Build Coastguard Worker 
179*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_str(const struct parse_data * data,struct wpa_ssid * ssid)180*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_str(const struct parse_data *data,
181*03f9172cSAndroid Build Coastguard Worker 				   struct wpa_ssid *ssid)
182*03f9172cSAndroid Build Coastguard Worker {
183*03f9172cSAndroid Build Coastguard Worker 	size_t len;
184*03f9172cSAndroid Build Coastguard Worker 	char **src;
185*03f9172cSAndroid Build Coastguard Worker 
186*03f9172cSAndroid Build Coastguard Worker 	src = (char **) (((u8 *) ssid) + (long) data->param1);
187*03f9172cSAndroid Build Coastguard Worker 	if (*src == NULL)
188*03f9172cSAndroid Build Coastguard Worker 		return NULL;
189*03f9172cSAndroid Build Coastguard Worker 
190*03f9172cSAndroid Build Coastguard Worker 	if (data->param2)
191*03f9172cSAndroid Build Coastguard Worker 		len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
192*03f9172cSAndroid Build Coastguard Worker 	else
193*03f9172cSAndroid Build Coastguard Worker 		len = os_strlen(*src);
194*03f9172cSAndroid Build Coastguard Worker 
195*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_string((const u8 *) *src, len);
196*03f9172cSAndroid Build Coastguard Worker }
197*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
198*03f9172cSAndroid Build Coastguard Worker 
199*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_int_impl(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value,bool check_range)200*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_int_impl(const struct parse_data *data,
201*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid,
202*03f9172cSAndroid Build Coastguard Worker 				     int line, const char *value,
203*03f9172cSAndroid Build Coastguard Worker 				     bool check_range)
204*03f9172cSAndroid Build Coastguard Worker {
205*03f9172cSAndroid Build Coastguard Worker 	int val, *dst;
206*03f9172cSAndroid Build Coastguard Worker 	char *end;
207*03f9172cSAndroid Build Coastguard Worker 
208*03f9172cSAndroid Build Coastguard Worker 	dst = (int *) (((u8 *) ssid) + (long) data->param1);
209*03f9172cSAndroid Build Coastguard Worker 	val = strtol(value, &end, 0);
210*03f9172cSAndroid Build Coastguard Worker 	if (*end) {
211*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: invalid number \"%s\"",
212*03f9172cSAndroid Build Coastguard Worker 			   line, value);
213*03f9172cSAndroid Build Coastguard Worker 		return -1;
214*03f9172cSAndroid Build Coastguard Worker 	}
215*03f9172cSAndroid Build Coastguard Worker 
216*03f9172cSAndroid Build Coastguard Worker 	if (check_range && val < (long) data->param3) {
217*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
218*03f9172cSAndroid Build Coastguard Worker 			   "min_value=%ld)", line, data->name, val,
219*03f9172cSAndroid Build Coastguard Worker 			   (long) data->param3);
220*03f9172cSAndroid Build Coastguard Worker 		return -1;
221*03f9172cSAndroid Build Coastguard Worker 	}
222*03f9172cSAndroid Build Coastguard Worker 
223*03f9172cSAndroid Build Coastguard Worker 	if (check_range && val > (long) data->param4) {
224*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
225*03f9172cSAndroid Build Coastguard Worker 			   "max_value=%ld)", line, data->name, val,
226*03f9172cSAndroid Build Coastguard Worker 			   (long) data->param4);
227*03f9172cSAndroid Build Coastguard Worker 		return -1;
228*03f9172cSAndroid Build Coastguard Worker 	}
229*03f9172cSAndroid Build Coastguard Worker 
230*03f9172cSAndroid Build Coastguard Worker 	if (*dst == val)
231*03f9172cSAndroid Build Coastguard Worker 		return 1;
232*03f9172cSAndroid Build Coastguard Worker 
233*03f9172cSAndroid Build Coastguard Worker 	*dst = val;
234*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst);
235*03f9172cSAndroid Build Coastguard Worker 
236*03f9172cSAndroid Build Coastguard Worker 	return 0;
237*03f9172cSAndroid Build Coastguard Worker }
238*03f9172cSAndroid Build Coastguard Worker 
239*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_int(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)240*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_int(const struct parse_data *data,
241*03f9172cSAndroid Build Coastguard Worker 				struct wpa_ssid *ssid,
242*03f9172cSAndroid Build Coastguard Worker 				int line, const char *value)
243*03f9172cSAndroid Build Coastguard Worker {
244*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_int_impl(data, ssid, line, value, false);
245*03f9172cSAndroid Build Coastguard Worker }
246*03f9172cSAndroid Build Coastguard Worker 
247*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_int_range(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)248*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_int_range(const struct parse_data *data,
249*03f9172cSAndroid Build Coastguard Worker 				      struct wpa_ssid *ssid,
250*03f9172cSAndroid Build Coastguard Worker 				      int line, const char *value)
251*03f9172cSAndroid Build Coastguard Worker {
252*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_int_impl(data, ssid, line, value, true);
253*03f9172cSAndroid Build Coastguard Worker }
254*03f9172cSAndroid Build Coastguard Worker 
255*03f9172cSAndroid Build Coastguard Worker 
256*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_int(const struct parse_data * data,struct wpa_ssid * ssid)257*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_int(const struct parse_data *data,
258*03f9172cSAndroid Build Coastguard Worker 				   struct wpa_ssid *ssid)
259*03f9172cSAndroid Build Coastguard Worker {
260*03f9172cSAndroid Build Coastguard Worker 	int *src, res;
261*03f9172cSAndroid Build Coastguard Worker 	char *value;
262*03f9172cSAndroid Build Coastguard Worker 
263*03f9172cSAndroid Build Coastguard Worker 	src = (int *) (((u8 *) ssid) + (long) data->param1);
264*03f9172cSAndroid Build Coastguard Worker 
265*03f9172cSAndroid Build Coastguard Worker 	value = os_malloc(20);
266*03f9172cSAndroid Build Coastguard Worker 	if (value == NULL)
267*03f9172cSAndroid Build Coastguard Worker 		return NULL;
268*03f9172cSAndroid Build Coastguard Worker 	res = os_snprintf(value, 20, "%d", *src);
269*03f9172cSAndroid Build Coastguard Worker 	if (os_snprintf_error(20, res)) {
270*03f9172cSAndroid Build Coastguard Worker 		os_free(value);
271*03f9172cSAndroid Build Coastguard Worker 		return NULL;
272*03f9172cSAndroid Build Coastguard Worker 	}
273*03f9172cSAndroid Build Coastguard Worker 	value[20 - 1] = '\0';
274*03f9172cSAndroid Build Coastguard Worker 	return value;
275*03f9172cSAndroid Build Coastguard Worker }
276*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
277*03f9172cSAndroid Build Coastguard Worker 
278*03f9172cSAndroid Build Coastguard Worker 
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)279*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_addr_list(const struct parse_data *data,
280*03f9172cSAndroid Build Coastguard Worker 				      int line, const char *value,
281*03f9172cSAndroid Build Coastguard Worker 				      u8 **list, size_t *num, char *name,
282*03f9172cSAndroid Build Coastguard Worker 				      u8 abort_on_error, u8 masked)
283*03f9172cSAndroid Build Coastguard Worker {
284*03f9172cSAndroid Build Coastguard Worker 	const char *pos;
285*03f9172cSAndroid Build Coastguard Worker 	u8 *buf, *n, addr[2 * ETH_ALEN];
286*03f9172cSAndroid Build Coastguard Worker 	size_t count;
287*03f9172cSAndroid Build Coastguard Worker 
288*03f9172cSAndroid Build Coastguard Worker 	buf = NULL;
289*03f9172cSAndroid Build Coastguard Worker 	count = 0;
290*03f9172cSAndroid Build Coastguard Worker 
291*03f9172cSAndroid Build Coastguard Worker 	pos = value;
292*03f9172cSAndroid Build Coastguard Worker 	while (pos && *pos) {
293*03f9172cSAndroid Build Coastguard Worker 		while (*pos == ' ')
294*03f9172cSAndroid Build Coastguard Worker 			pos++;
295*03f9172cSAndroid Build Coastguard Worker 
296*03f9172cSAndroid Build Coastguard Worker 		if (hwaddr_masked_aton(pos, addr, &addr[ETH_ALEN], masked)) {
297*03f9172cSAndroid Build Coastguard Worker 			if (abort_on_error || count == 0) {
298*03f9172cSAndroid Build Coastguard Worker 				wpa_printf(MSG_ERROR,
299*03f9172cSAndroid Build Coastguard Worker 					   "Line %d: Invalid %s address '%s'",
300*03f9172cSAndroid Build Coastguard Worker 					   line, name, value);
301*03f9172cSAndroid Build Coastguard Worker 				os_free(buf);
302*03f9172cSAndroid Build Coastguard Worker 				return -1;
303*03f9172cSAndroid Build Coastguard Worker 			}
304*03f9172cSAndroid Build Coastguard Worker 			/* continue anyway since this could have been from a
305*03f9172cSAndroid Build Coastguard Worker 			 * truncated configuration file line */
306*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_INFO,
307*03f9172cSAndroid Build Coastguard Worker 				   "Line %d: Ignore likely truncated %s address '%s'",
308*03f9172cSAndroid Build Coastguard Worker 				   line, name, pos);
309*03f9172cSAndroid Build Coastguard Worker 		} else {
310*03f9172cSAndroid Build Coastguard Worker 			n = os_realloc_array(buf, count + 1, 2 * ETH_ALEN);
311*03f9172cSAndroid Build Coastguard Worker 			if (n == NULL) {
312*03f9172cSAndroid Build Coastguard Worker 				os_free(buf);
313*03f9172cSAndroid Build Coastguard Worker 				return -1;
314*03f9172cSAndroid Build Coastguard Worker 			}
315*03f9172cSAndroid Build Coastguard Worker 			buf = n;
316*03f9172cSAndroid Build Coastguard Worker 			os_memmove(buf + 2 * ETH_ALEN, buf,
317*03f9172cSAndroid Build Coastguard Worker 				   count * 2 * ETH_ALEN);
318*03f9172cSAndroid Build Coastguard Worker 			os_memcpy(buf, addr, 2 * ETH_ALEN);
319*03f9172cSAndroid Build Coastguard Worker 			count++;
320*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_MSGDUMP,
321*03f9172cSAndroid Build Coastguard Worker 				   "%s: addr=" MACSTR " mask=" MACSTR,
322*03f9172cSAndroid Build Coastguard Worker 				   name, MAC2STR(addr),
323*03f9172cSAndroid Build Coastguard Worker 				   MAC2STR(&addr[ETH_ALEN]));
324*03f9172cSAndroid Build Coastguard Worker 		}
325*03f9172cSAndroid Build Coastguard Worker 
326*03f9172cSAndroid Build Coastguard Worker 		pos = os_strchr(pos, ' ');
327*03f9172cSAndroid Build Coastguard Worker 	}
328*03f9172cSAndroid Build Coastguard Worker 
329*03f9172cSAndroid Build Coastguard Worker 	os_free(*list);
330*03f9172cSAndroid Build Coastguard Worker 	*list = buf;
331*03f9172cSAndroid Build Coastguard Worker 	*num = count;
332*03f9172cSAndroid Build Coastguard Worker 
333*03f9172cSAndroid Build Coastguard Worker 	return 0;
334*03f9172cSAndroid Build Coastguard Worker }
335*03f9172cSAndroid Build Coastguard Worker 
336*03f9172cSAndroid Build Coastguard Worker 
337*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_addr_list(const struct parse_data * data,const u8 * list,size_t num,char * name)338*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_addr_list(const struct parse_data *data,
339*03f9172cSAndroid Build Coastguard Worker 					 const u8 *list, size_t num, char *name)
340*03f9172cSAndroid Build Coastguard Worker {
341*03f9172cSAndroid Build Coastguard Worker 	char *value, *end, *pos;
342*03f9172cSAndroid Build Coastguard Worker 	int res;
343*03f9172cSAndroid Build Coastguard Worker 	size_t i;
344*03f9172cSAndroid Build Coastguard Worker 
345*03f9172cSAndroid Build Coastguard Worker 	if (list == NULL || num == 0)
346*03f9172cSAndroid Build Coastguard Worker 		return NULL;
347*03f9172cSAndroid Build Coastguard Worker 
348*03f9172cSAndroid Build Coastguard Worker 	value = os_malloc(2 * 20 * num);
349*03f9172cSAndroid Build Coastguard Worker 	if (value == NULL)
350*03f9172cSAndroid Build Coastguard Worker 		return NULL;
351*03f9172cSAndroid Build Coastguard Worker 	pos = value;
352*03f9172cSAndroid Build Coastguard Worker 	end = value + 2 * 20 * num;
353*03f9172cSAndroid Build Coastguard Worker 
354*03f9172cSAndroid Build Coastguard Worker 	for (i = num; i > 0; i--) {
355*03f9172cSAndroid Build Coastguard Worker 		const u8 *a = list + (i - 1) * 2 * ETH_ALEN;
356*03f9172cSAndroid Build Coastguard Worker 		const u8 *m = a + ETH_ALEN;
357*03f9172cSAndroid Build Coastguard Worker 
358*03f9172cSAndroid Build Coastguard Worker 		if (i < num)
359*03f9172cSAndroid Build Coastguard Worker 			*pos++ = ' ';
360*03f9172cSAndroid Build Coastguard Worker 		res = hwaddr_mask_txt(pos, end - pos, a, m);
361*03f9172cSAndroid Build Coastguard Worker 		if (res < 0) {
362*03f9172cSAndroid Build Coastguard Worker 			os_free(value);
363*03f9172cSAndroid Build Coastguard Worker 			return NULL;
364*03f9172cSAndroid Build Coastguard Worker 		}
365*03f9172cSAndroid Build Coastguard Worker 		pos += res;
366*03f9172cSAndroid Build Coastguard Worker 	}
367*03f9172cSAndroid Build Coastguard Worker 
368*03f9172cSAndroid Build Coastguard Worker 	return value;
369*03f9172cSAndroid Build Coastguard Worker }
370*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
371*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_bssid(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)372*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_bssid(const struct parse_data *data,
373*03f9172cSAndroid Build Coastguard Worker 				  struct wpa_ssid *ssid, int line,
374*03f9172cSAndroid Build Coastguard Worker 				  const char *value)
375*03f9172cSAndroid Build Coastguard Worker {
376*03f9172cSAndroid Build Coastguard Worker 	if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 ||
377*03f9172cSAndroid Build Coastguard Worker 	    os_strcmp(value, "any") == 0) {
378*03f9172cSAndroid Build Coastguard Worker 		ssid->bssid_set = 0;
379*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_MSGDUMP, "BSSID any");
380*03f9172cSAndroid Build Coastguard Worker 		return 0;
381*03f9172cSAndroid Build Coastguard Worker 	}
382*03f9172cSAndroid Build Coastguard Worker 	if (hwaddr_aton(value, ssid->bssid)) {
383*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.",
384*03f9172cSAndroid Build Coastguard Worker 			   line, value);
385*03f9172cSAndroid Build Coastguard Worker 		return -1;
386*03f9172cSAndroid Build Coastguard Worker 	}
387*03f9172cSAndroid Build Coastguard Worker 	ssid->bssid_set = 1;
388*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump(MSG_MSGDUMP, "BSSID", ssid->bssid, ETH_ALEN);
389*03f9172cSAndroid Build Coastguard Worker 	return 0;
390*03f9172cSAndroid Build Coastguard Worker }
391*03f9172cSAndroid Build Coastguard Worker 
392*03f9172cSAndroid Build Coastguard Worker 
393*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_bssid(const struct parse_data * data,struct wpa_ssid * ssid)394*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_bssid(const struct parse_data *data,
395*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid)
396*03f9172cSAndroid Build Coastguard Worker {
397*03f9172cSAndroid Build Coastguard Worker 	char *value;
398*03f9172cSAndroid Build Coastguard Worker 	int res;
399*03f9172cSAndroid Build Coastguard Worker 
400*03f9172cSAndroid Build Coastguard Worker 	if (!ssid->bssid_set)
401*03f9172cSAndroid Build Coastguard Worker 		return NULL;
402*03f9172cSAndroid Build Coastguard Worker 
403*03f9172cSAndroid Build Coastguard Worker 	value = os_malloc(20);
404*03f9172cSAndroid Build Coastguard Worker 	if (value == NULL)
405*03f9172cSAndroid Build Coastguard Worker 		return NULL;
406*03f9172cSAndroid Build Coastguard Worker 	res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid));
407*03f9172cSAndroid Build Coastguard Worker 	if (os_snprintf_error(20, res)) {
408*03f9172cSAndroid Build Coastguard Worker 		os_free(value);
409*03f9172cSAndroid Build Coastguard Worker 		return NULL;
410*03f9172cSAndroid Build Coastguard Worker 	}
411*03f9172cSAndroid Build Coastguard Worker 	value[20 - 1] = '\0';
412*03f9172cSAndroid Build Coastguard Worker 	return value;
413*03f9172cSAndroid Build Coastguard Worker }
414*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
415*03f9172cSAndroid Build Coastguard Worker 
416*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_bssid_hint(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)417*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_bssid_hint(const struct parse_data *data,
418*03f9172cSAndroid Build Coastguard Worker 				       struct wpa_ssid *ssid, int line,
419*03f9172cSAndroid Build Coastguard Worker 				       const char *value)
420*03f9172cSAndroid Build Coastguard Worker {
421*03f9172cSAndroid Build Coastguard Worker 	if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 ||
422*03f9172cSAndroid Build Coastguard Worker 	    os_strcmp(value, "any") == 0) {
423*03f9172cSAndroid Build Coastguard Worker 		ssid->bssid_hint_set = 0;
424*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_MSGDUMP, "BSSID hint any");
425*03f9172cSAndroid Build Coastguard Worker 		return 0;
426*03f9172cSAndroid Build Coastguard Worker 	}
427*03f9172cSAndroid Build Coastguard Worker 	if (hwaddr_aton(value, ssid->bssid_hint)) {
428*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID hint '%s'.",
429*03f9172cSAndroid Build Coastguard Worker 			   line, value);
430*03f9172cSAndroid Build Coastguard Worker 		return -1;
431*03f9172cSAndroid Build Coastguard Worker 	}
432*03f9172cSAndroid Build Coastguard Worker 	ssid->bssid_hint_set = 1;
433*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump(MSG_MSGDUMP, "BSSID hint", ssid->bssid_hint, ETH_ALEN);
434*03f9172cSAndroid Build Coastguard Worker 	return 0;
435*03f9172cSAndroid Build Coastguard Worker }
436*03f9172cSAndroid Build Coastguard Worker 
437*03f9172cSAndroid Build Coastguard Worker 
438*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_bssid_hint(const struct parse_data * data,struct wpa_ssid * ssid)439*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_bssid_hint(const struct parse_data *data,
440*03f9172cSAndroid Build Coastguard Worker 					  struct wpa_ssid *ssid)
441*03f9172cSAndroid Build Coastguard Worker {
442*03f9172cSAndroid Build Coastguard Worker 	char *value;
443*03f9172cSAndroid Build Coastguard Worker 	int res;
444*03f9172cSAndroid Build Coastguard Worker 
445*03f9172cSAndroid Build Coastguard Worker 	if (!ssid->bssid_hint_set)
446*03f9172cSAndroid Build Coastguard Worker 		return NULL;
447*03f9172cSAndroid Build Coastguard Worker 
448*03f9172cSAndroid Build Coastguard Worker 	value = os_malloc(20);
449*03f9172cSAndroid Build Coastguard Worker 	if (!value)
450*03f9172cSAndroid Build Coastguard Worker 		return NULL;
451*03f9172cSAndroid Build Coastguard Worker 	res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid_hint));
452*03f9172cSAndroid Build Coastguard Worker 	if (os_snprintf_error(20, res)) {
453*03f9172cSAndroid Build Coastguard Worker 		os_free(value);
454*03f9172cSAndroid Build Coastguard Worker 		return NULL;
455*03f9172cSAndroid Build Coastguard Worker 	}
456*03f9172cSAndroid Build Coastguard Worker 	return value;
457*03f9172cSAndroid Build Coastguard Worker }
458*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
459*03f9172cSAndroid Build Coastguard Worker 
460*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_bssid_ignore(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)461*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_bssid_ignore(const struct parse_data *data,
462*03f9172cSAndroid Build Coastguard Worker 					 struct wpa_ssid *ssid, int line,
463*03f9172cSAndroid Build Coastguard Worker 					 const char *value)
464*03f9172cSAndroid Build Coastguard Worker {
465*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_addr_list(data, line, value,
466*03f9172cSAndroid Build Coastguard Worker 					  &ssid->bssid_ignore,
467*03f9172cSAndroid Build Coastguard Worker 					  &ssid->num_bssid_ignore,
468*03f9172cSAndroid Build Coastguard Worker 					  "bssid_ignore", 1, 1);
469*03f9172cSAndroid Build Coastguard Worker }
470*03f9172cSAndroid Build Coastguard Worker 
471*03f9172cSAndroid Build Coastguard Worker 
472*03f9172cSAndroid Build Coastguard Worker /* deprecated alias for bssid_ignore for backwards compatibility */
wpa_config_parse_bssid_blacklist(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)473*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_bssid_blacklist(const struct parse_data *data,
474*03f9172cSAndroid Build Coastguard Worker 					    struct wpa_ssid *ssid, int line,
475*03f9172cSAndroid Build Coastguard Worker 					    const char *value)
476*03f9172cSAndroid Build Coastguard Worker {
477*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_addr_list(data, line, value,
478*03f9172cSAndroid Build Coastguard Worker 					  &ssid->bssid_ignore,
479*03f9172cSAndroid Build Coastguard Worker 					  &ssid->num_bssid_ignore,
480*03f9172cSAndroid Build Coastguard Worker 					  "bssid_ignore", 1, 1);
481*03f9172cSAndroid Build Coastguard Worker }
482*03f9172cSAndroid Build Coastguard Worker 
483*03f9172cSAndroid Build Coastguard Worker 
484*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
485*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_bssid_ignore(const struct parse_data * data,struct wpa_ssid * ssid)486*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_bssid_ignore(const struct parse_data *data,
487*03f9172cSAndroid Build Coastguard Worker 					    struct wpa_ssid *ssid)
488*03f9172cSAndroid Build Coastguard Worker {
489*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_addr_list(data, ssid->bssid_ignore,
490*03f9172cSAndroid Build Coastguard Worker 					  ssid->num_bssid_ignore,
491*03f9172cSAndroid Build Coastguard Worker 					  "bssid_ignore");
492*03f9172cSAndroid Build Coastguard Worker }
493*03f9172cSAndroid Build Coastguard Worker 
494*03f9172cSAndroid Build Coastguard Worker 
495*03f9172cSAndroid Build Coastguard Worker /* deprecated alias for bssid_ignore for backwards compatibility */
wpa_config_write_bssid_blacklist(const struct parse_data * data,struct wpa_ssid * ssid)496*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_bssid_blacklist(const struct parse_data *data,
497*03f9172cSAndroid Build Coastguard Worker 					       struct wpa_ssid *ssid)
498*03f9172cSAndroid Build Coastguard Worker {
499*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_addr_list(data, ssid->bssid_ignore,
500*03f9172cSAndroid Build Coastguard Worker 					  ssid->num_bssid_ignore,
501*03f9172cSAndroid Build Coastguard Worker 					  "bssid_ignore");
502*03f9172cSAndroid Build Coastguard Worker }
503*03f9172cSAndroid Build Coastguard Worker 
504*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
505*03f9172cSAndroid Build Coastguard Worker 
506*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_bssid_accept(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)507*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_bssid_accept(const struct parse_data *data,
508*03f9172cSAndroid Build Coastguard Worker 					 struct wpa_ssid *ssid, int line,
509*03f9172cSAndroid Build Coastguard Worker 					 const char *value)
510*03f9172cSAndroid Build Coastguard Worker {
511*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_addr_list(data, line, value,
512*03f9172cSAndroid Build Coastguard Worker 					  &ssid->bssid_accept,
513*03f9172cSAndroid Build Coastguard Worker 					  &ssid->num_bssid_accept,
514*03f9172cSAndroid Build Coastguard Worker 					  "bssid_accept", 1, 1);
515*03f9172cSAndroid Build Coastguard Worker }
516*03f9172cSAndroid Build Coastguard Worker 
517*03f9172cSAndroid Build Coastguard Worker 
518*03f9172cSAndroid Build Coastguard Worker /* deprecated alias for bssid_accept for backwards compatibility */
wpa_config_parse_bssid_whitelist(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)519*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_bssid_whitelist(const struct parse_data *data,
520*03f9172cSAndroid Build Coastguard Worker 					    struct wpa_ssid *ssid, int line,
521*03f9172cSAndroid Build Coastguard Worker 					    const char *value)
522*03f9172cSAndroid Build Coastguard Worker {
523*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_addr_list(data, line, value,
524*03f9172cSAndroid Build Coastguard Worker 					  &ssid->bssid_accept,
525*03f9172cSAndroid Build Coastguard Worker 					  &ssid->num_bssid_accept,
526*03f9172cSAndroid Build Coastguard Worker 					  "bssid_accept", 1, 1);
527*03f9172cSAndroid Build Coastguard Worker }
528*03f9172cSAndroid Build Coastguard Worker 
529*03f9172cSAndroid Build Coastguard Worker 
530*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
531*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_bssid_accept(const struct parse_data * data,struct wpa_ssid * ssid)532*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_bssid_accept(const struct parse_data *data,
533*03f9172cSAndroid Build Coastguard Worker 					    struct wpa_ssid *ssid)
534*03f9172cSAndroid Build Coastguard Worker {
535*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_addr_list(data, ssid->bssid_accept,
536*03f9172cSAndroid Build Coastguard Worker 					  ssid->num_bssid_accept,
537*03f9172cSAndroid Build Coastguard Worker 					  "bssid_accept");
538*03f9172cSAndroid Build Coastguard Worker }
539*03f9172cSAndroid Build Coastguard Worker 
540*03f9172cSAndroid Build Coastguard Worker 
541*03f9172cSAndroid Build Coastguard Worker /* deprecated alias for bssid_accept for backwards compatibility */
wpa_config_write_bssid_whitelist(const struct parse_data * data,struct wpa_ssid * ssid)542*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_bssid_whitelist(const struct parse_data *data,
543*03f9172cSAndroid Build Coastguard Worker 					       struct wpa_ssid *ssid)
544*03f9172cSAndroid Build Coastguard Worker {
545*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_addr_list(data, ssid->bssid_accept,
546*03f9172cSAndroid Build Coastguard Worker 					  ssid->num_bssid_accept,
547*03f9172cSAndroid Build Coastguard Worker 					  "bssid_accept");
548*03f9172cSAndroid Build Coastguard Worker }
549*03f9172cSAndroid Build Coastguard Worker 
550*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
551*03f9172cSAndroid Build Coastguard Worker 
552*03f9172cSAndroid Build Coastguard Worker 
553*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
554*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
555*03f9172cSAndroid Build Coastguard Worker 
556*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_psk(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)557*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_psk(const struct parse_data *data,
558*03f9172cSAndroid Build Coastguard Worker 				struct wpa_ssid *ssid, int line,
559*03f9172cSAndroid Build Coastguard Worker 				const char *value)
560*03f9172cSAndroid Build Coastguard Worker {
561*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_EXT_PASSWORD
562*03f9172cSAndroid Build Coastguard Worker 	if (os_strncmp(value, "ext:", 4) == 0) {
563*03f9172cSAndroid Build Coastguard Worker 		str_clear_free(ssid->passphrase);
564*03f9172cSAndroid Build Coastguard Worker 		ssid->passphrase = NULL;
565*03f9172cSAndroid Build Coastguard Worker 		ssid->psk_set = 0;
566*03f9172cSAndroid Build Coastguard Worker 		os_free(ssid->ext_psk);
567*03f9172cSAndroid Build Coastguard Worker 		ssid->ext_psk = os_strdup(value + 4);
568*03f9172cSAndroid Build Coastguard Worker 		if (ssid->ext_psk == NULL)
569*03f9172cSAndroid Build Coastguard Worker 			return -1;
570*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_DEBUG, "PSK: External password '%s'",
571*03f9172cSAndroid Build Coastguard Worker 			   ssid->ext_psk);
572*03f9172cSAndroid Build Coastguard Worker 		return 0;
573*03f9172cSAndroid Build Coastguard Worker 	}
574*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_EXT_PASSWORD */
575*03f9172cSAndroid Build Coastguard Worker 
576*03f9172cSAndroid Build Coastguard Worker 	if (*value == '"') {
577*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_NO_PBKDF2
578*03f9172cSAndroid Build Coastguard Worker 		const char *pos;
579*03f9172cSAndroid Build Coastguard Worker 		size_t len;
580*03f9172cSAndroid Build Coastguard Worker 
581*03f9172cSAndroid Build Coastguard Worker 		value++;
582*03f9172cSAndroid Build Coastguard Worker 		pos = os_strrchr(value, '"');
583*03f9172cSAndroid Build Coastguard Worker 		if (pos)
584*03f9172cSAndroid Build Coastguard Worker 			len = pos - value;
585*03f9172cSAndroid Build Coastguard Worker 		else
586*03f9172cSAndroid Build Coastguard Worker 			len = os_strlen(value);
587*03f9172cSAndroid Build Coastguard Worker 		if (len < 8 || len > 63) {
588*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: Invalid passphrase "
589*03f9172cSAndroid Build Coastguard Worker 				   "length %lu (expected: 8..63) '%s'.",
590*03f9172cSAndroid Build Coastguard Worker 				   line, (unsigned long) len, value);
591*03f9172cSAndroid Build Coastguard Worker 			return -1;
592*03f9172cSAndroid Build Coastguard Worker 		}
593*03f9172cSAndroid Build Coastguard Worker 		wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)",
594*03f9172cSAndroid Build Coastguard Worker 				      (u8 *) value, len);
595*03f9172cSAndroid Build Coastguard Worker 		if (has_ctrl_char((u8 *) value, len)) {
596*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR,
597*03f9172cSAndroid Build Coastguard Worker 				   "Line %d: Invalid passphrase character",
598*03f9172cSAndroid Build Coastguard Worker 				   line);
599*03f9172cSAndroid Build Coastguard Worker 			return -1;
600*03f9172cSAndroid Build Coastguard Worker 		}
601*03f9172cSAndroid Build Coastguard Worker 		if (ssid->passphrase && os_strlen(ssid->passphrase) == len &&
602*03f9172cSAndroid Build Coastguard Worker 		    os_memcmp(ssid->passphrase, value, len) == 0) {
603*03f9172cSAndroid Build Coastguard Worker 			/* No change to the previously configured value */
604*03f9172cSAndroid Build Coastguard Worker 			return 1;
605*03f9172cSAndroid Build Coastguard Worker 		}
606*03f9172cSAndroid Build Coastguard Worker 		ssid->psk_set = 0;
607*03f9172cSAndroid Build Coastguard Worker 		str_clear_free(ssid->passphrase);
608*03f9172cSAndroid Build Coastguard Worker 		ssid->passphrase = dup_binstr(value, len);
609*03f9172cSAndroid Build Coastguard Worker 		if (ssid->passphrase == NULL)
610*03f9172cSAndroid Build Coastguard Worker 			return -1;
611*03f9172cSAndroid Build Coastguard Worker 		return 0;
612*03f9172cSAndroid Build Coastguard Worker #else /* CONFIG_NO_PBKDF2 */
613*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: ASCII passphrase not "
614*03f9172cSAndroid Build Coastguard Worker 			   "supported.", line);
615*03f9172cSAndroid Build Coastguard Worker 		return -1;
616*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_PBKDF2 */
617*03f9172cSAndroid Build Coastguard Worker 	}
618*03f9172cSAndroid Build Coastguard Worker 
619*03f9172cSAndroid Build Coastguard Worker 	if (hexstr2bin(value, ssid->psk, PMK_LEN) ||
620*03f9172cSAndroid Build Coastguard Worker 	    value[PMK_LEN * 2] != '\0') {
621*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
622*03f9172cSAndroid Build Coastguard Worker 			   line, value);
623*03f9172cSAndroid Build Coastguard Worker 		return -1;
624*03f9172cSAndroid Build Coastguard Worker 	}
625*03f9172cSAndroid Build Coastguard Worker 
626*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(ssid->passphrase);
627*03f9172cSAndroid Build Coastguard Worker 	ssid->passphrase = NULL;
628*03f9172cSAndroid Build Coastguard Worker 
629*03f9172cSAndroid Build Coastguard Worker 	ssid->psk_set = 1;
630*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump_key(MSG_MSGDUMP, "PSK", ssid->psk, PMK_LEN);
631*03f9172cSAndroid Build Coastguard Worker 	return 0;
632*03f9172cSAndroid Build Coastguard Worker }
633*03f9172cSAndroid Build Coastguard Worker 
634*03f9172cSAndroid Build Coastguard Worker 
635*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_psk(const struct parse_data * data,struct wpa_ssid * ssid)636*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_psk(const struct parse_data *data,
637*03f9172cSAndroid Build Coastguard Worker 				   struct wpa_ssid *ssid)
638*03f9172cSAndroid Build Coastguard Worker {
639*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_EXT_PASSWORD
640*03f9172cSAndroid Build Coastguard Worker 	if (ssid->ext_psk) {
641*03f9172cSAndroid Build Coastguard Worker 		size_t len = 4 + os_strlen(ssid->ext_psk) + 1;
642*03f9172cSAndroid Build Coastguard Worker 		char *buf = os_malloc(len);
643*03f9172cSAndroid Build Coastguard Worker 		int res;
644*03f9172cSAndroid Build Coastguard Worker 
645*03f9172cSAndroid Build Coastguard Worker 		if (buf == NULL)
646*03f9172cSAndroid Build Coastguard Worker 			return NULL;
647*03f9172cSAndroid Build Coastguard Worker 		res = os_snprintf(buf, len, "ext:%s", ssid->ext_psk);
648*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(len, res)) {
649*03f9172cSAndroid Build Coastguard Worker 			os_free(buf);
650*03f9172cSAndroid Build Coastguard Worker 			buf = NULL;
651*03f9172cSAndroid Build Coastguard Worker 		}
652*03f9172cSAndroid Build Coastguard Worker 		return buf;
653*03f9172cSAndroid Build Coastguard Worker 	}
654*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_EXT_PASSWORD */
655*03f9172cSAndroid Build Coastguard Worker 
656*03f9172cSAndroid Build Coastguard Worker 	if (ssid->passphrase)
657*03f9172cSAndroid Build Coastguard Worker 		return wpa_config_write_string_ascii(
658*03f9172cSAndroid Build Coastguard Worker 			(const u8 *) ssid->passphrase,
659*03f9172cSAndroid Build Coastguard Worker 			os_strlen(ssid->passphrase));
660*03f9172cSAndroid Build Coastguard Worker 
661*03f9172cSAndroid Build Coastguard Worker 	if (ssid->psk_set)
662*03f9172cSAndroid Build Coastguard Worker 		return wpa_config_write_string_hex(ssid->psk, PMK_LEN);
663*03f9172cSAndroid Build Coastguard Worker 
664*03f9172cSAndroid Build Coastguard Worker 	return NULL;
665*03f9172cSAndroid Build Coastguard Worker }
666*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
667*03f9172cSAndroid Build Coastguard Worker 
668*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_proto(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)669*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_proto(const struct parse_data *data,
670*03f9172cSAndroid Build Coastguard Worker 				  struct wpa_ssid *ssid, int line,
671*03f9172cSAndroid Build Coastguard Worker 				  const char *value)
672*03f9172cSAndroid Build Coastguard Worker {
673*03f9172cSAndroid Build Coastguard Worker 	int val = 0, last, errors = 0;
674*03f9172cSAndroid Build Coastguard Worker 	char *start, *end, *buf;
675*03f9172cSAndroid Build Coastguard Worker 
676*03f9172cSAndroid Build Coastguard Worker 	buf = os_strdup(value);
677*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
678*03f9172cSAndroid Build Coastguard Worker 		return -1;
679*03f9172cSAndroid Build Coastguard Worker 	start = buf;
680*03f9172cSAndroid Build Coastguard Worker 
681*03f9172cSAndroid Build Coastguard Worker 	while (*start != '\0') {
682*03f9172cSAndroid Build Coastguard Worker 		while (*start == ' ' || *start == '\t')
683*03f9172cSAndroid Build Coastguard Worker 			start++;
684*03f9172cSAndroid Build Coastguard Worker 		if (*start == '\0')
685*03f9172cSAndroid Build Coastguard Worker 			break;
686*03f9172cSAndroid Build Coastguard Worker 		end = start;
687*03f9172cSAndroid Build Coastguard Worker 		while (*end != ' ' && *end != '\t' && *end != '\0')
688*03f9172cSAndroid Build Coastguard Worker 			end++;
689*03f9172cSAndroid Build Coastguard Worker 		last = *end == '\0';
690*03f9172cSAndroid Build Coastguard Worker 		*end = '\0';
691*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(start, "WPA") == 0)
692*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_PROTO_WPA;
693*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "RSN") == 0 ||
694*03f9172cSAndroid Build Coastguard Worker 			 os_strcmp(start, "WPA2") == 0)
695*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_PROTO_RSN;
696*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "OSEN") == 0)
697*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_PROTO_OSEN;
698*03f9172cSAndroid Build Coastguard Worker 		else {
699*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'",
700*03f9172cSAndroid Build Coastguard Worker 				   line, start);
701*03f9172cSAndroid Build Coastguard Worker 			errors++;
702*03f9172cSAndroid Build Coastguard Worker 		}
703*03f9172cSAndroid Build Coastguard Worker 
704*03f9172cSAndroid Build Coastguard Worker 		if (last)
705*03f9172cSAndroid Build Coastguard Worker 			break;
706*03f9172cSAndroid Build Coastguard Worker 		start = end + 1;
707*03f9172cSAndroid Build Coastguard Worker 	}
708*03f9172cSAndroid Build Coastguard Worker 	os_free(buf);
709*03f9172cSAndroid Build Coastguard Worker 
710*03f9172cSAndroid Build Coastguard Worker 	if (val == 0) {
711*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR,
712*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: no proto values configured.", line);
713*03f9172cSAndroid Build Coastguard Worker 		errors++;
714*03f9172cSAndroid Build Coastguard Worker 	}
715*03f9172cSAndroid Build Coastguard Worker 
716*03f9172cSAndroid Build Coastguard Worker 	if (!errors && ssid->proto == val)
717*03f9172cSAndroid Build Coastguard Worker 		return 1;
718*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_MSGDUMP, "proto: 0x%x", val);
719*03f9172cSAndroid Build Coastguard Worker 	ssid->proto = val;
720*03f9172cSAndroid Build Coastguard Worker 	return errors ? -1 : 0;
721*03f9172cSAndroid Build Coastguard Worker }
722*03f9172cSAndroid Build Coastguard Worker 
723*03f9172cSAndroid Build Coastguard Worker 
724*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_proto(const struct parse_data * data,struct wpa_ssid * ssid)725*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_proto(const struct parse_data *data,
726*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid)
727*03f9172cSAndroid Build Coastguard Worker {
728*03f9172cSAndroid Build Coastguard Worker 	int ret;
729*03f9172cSAndroid Build Coastguard Worker 	char *buf, *pos, *end;
730*03f9172cSAndroid Build Coastguard Worker 
731*03f9172cSAndroid Build Coastguard Worker 	pos = buf = os_zalloc(20);
732*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
733*03f9172cSAndroid Build Coastguard Worker 		return NULL;
734*03f9172cSAndroid Build Coastguard Worker 	end = buf + 20;
735*03f9172cSAndroid Build Coastguard Worker 
736*03f9172cSAndroid Build Coastguard Worker 	if (ssid->proto & WPA_PROTO_WPA) {
737*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPA",
738*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
739*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret))
740*03f9172cSAndroid Build Coastguard Worker 			return buf;
741*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
742*03f9172cSAndroid Build Coastguard Worker 	}
743*03f9172cSAndroid Build Coastguard Worker 
744*03f9172cSAndroid Build Coastguard Worker 	if (ssid->proto & WPA_PROTO_RSN) {
745*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sRSN",
746*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
747*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret))
748*03f9172cSAndroid Build Coastguard Worker 			return buf;
749*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
750*03f9172cSAndroid Build Coastguard Worker 	}
751*03f9172cSAndroid Build Coastguard Worker 
752*03f9172cSAndroid Build Coastguard Worker 	if (ssid->proto & WPA_PROTO_OSEN) {
753*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sOSEN",
754*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
755*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret))
756*03f9172cSAndroid Build Coastguard Worker 			return buf;
757*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
758*03f9172cSAndroid Build Coastguard Worker 	}
759*03f9172cSAndroid Build Coastguard Worker 
760*03f9172cSAndroid Build Coastguard Worker 	if (pos == buf) {
761*03f9172cSAndroid Build Coastguard Worker 		os_free(buf);
762*03f9172cSAndroid Build Coastguard Worker 		buf = NULL;
763*03f9172cSAndroid Build Coastguard Worker 	}
764*03f9172cSAndroid Build Coastguard Worker 
765*03f9172cSAndroid Build Coastguard Worker 	return buf;
766*03f9172cSAndroid Build Coastguard Worker }
767*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
768*03f9172cSAndroid Build Coastguard Worker 
769*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_key_mgmt(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)770*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_key_mgmt(const struct parse_data *data,
771*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid, int line,
772*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
773*03f9172cSAndroid Build Coastguard Worker {
774*03f9172cSAndroid Build Coastguard Worker 	int val = 0, last, errors = 0;
775*03f9172cSAndroid Build Coastguard Worker 	char *start, *end, *buf;
776*03f9172cSAndroid Build Coastguard Worker 
777*03f9172cSAndroid Build Coastguard Worker 	buf = os_strdup(value);
778*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
779*03f9172cSAndroid Build Coastguard Worker 		return -1;
780*03f9172cSAndroid Build Coastguard Worker 	start = buf;
781*03f9172cSAndroid Build Coastguard Worker 
782*03f9172cSAndroid Build Coastguard Worker 	while (*start != '\0') {
783*03f9172cSAndroid Build Coastguard Worker 		while (*start == ' ' || *start == '\t')
784*03f9172cSAndroid Build Coastguard Worker 			start++;
785*03f9172cSAndroid Build Coastguard Worker 		if (*start == '\0')
786*03f9172cSAndroid Build Coastguard Worker 			break;
787*03f9172cSAndroid Build Coastguard Worker 		end = start;
788*03f9172cSAndroid Build Coastguard Worker 		while (*end != ' ' && *end != '\t' && *end != '\0')
789*03f9172cSAndroid Build Coastguard Worker 			end++;
790*03f9172cSAndroid Build Coastguard Worker 		last = *end == '\0';
791*03f9172cSAndroid Build Coastguard Worker 		*end = '\0';
792*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(start, "WPA-PSK") == 0)
793*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_PSK;
794*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "WPA-EAP") == 0)
795*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_IEEE8021X;
796*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "IEEE8021X") == 0)
797*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_IEEE8021X_NO_WPA;
798*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "NONE") == 0)
799*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_NONE;
800*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "WPA-NONE") == 0)
801*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_WPA_NONE;
802*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211R
803*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "FT-PSK") == 0)
804*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_FT_PSK;
805*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "FT-EAP") == 0)
806*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_FT_IEEE8021X;
807*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SHA384
808*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "FT-EAP-SHA384") == 0)
809*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
810*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SHA384 */
811*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211R */
812*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SHA384
813*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "WPA-EAP-SHA384") == 0)
814*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_IEEE8021X_SHA384;
815*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SHA384 */
816*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
817*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_PSK_SHA256;
818*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
819*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
820*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_WPS
821*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "WPS") == 0)
822*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_WPS;
823*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_WPS */
824*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SAE
825*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "SAE") == 0)
826*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_SAE;
827*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "SAE-EXT-KEY") == 0)
828*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_SAE_EXT_KEY;
829*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "FT-SAE") == 0)
830*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_FT_SAE;
831*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "FT-SAE-EXT-KEY") == 0)
832*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_FT_SAE_EXT_KEY;
833*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SAE */
834*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_HS20
835*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "OSEN") == 0)
836*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_OSEN;
837*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_HS20 */
838*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SUITEB
839*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
840*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B;
841*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SUITEB */
842*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SUITEB192
843*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "WPA-EAP-SUITE-B-192") == 0)
844*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
845*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SUITEB192 */
846*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_FILS
847*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "FILS-SHA256") == 0)
848*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_FILS_SHA256;
849*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "FILS-SHA384") == 0)
850*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_FILS_SHA384;
851*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211R
852*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "FT-FILS-SHA256") == 0)
853*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_FT_FILS_SHA256;
854*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "FT-FILS-SHA384") == 0)
855*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_FT_FILS_SHA384;
856*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211R */
857*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_FILS */
858*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_OWE
859*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "OWE") == 0)
860*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_OWE;
861*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_OWE */
862*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_DPP
863*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "DPP") == 0)
864*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_KEY_MGMT_DPP;
865*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_DPP */
866*03f9172cSAndroid Build Coastguard Worker 		else {
867*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
868*03f9172cSAndroid Build Coastguard Worker 				   line, start);
869*03f9172cSAndroid Build Coastguard Worker 			errors++;
870*03f9172cSAndroid Build Coastguard Worker 		}
871*03f9172cSAndroid Build Coastguard Worker 
872*03f9172cSAndroid Build Coastguard Worker 		if (last)
873*03f9172cSAndroid Build Coastguard Worker 			break;
874*03f9172cSAndroid Build Coastguard Worker 		start = end + 1;
875*03f9172cSAndroid Build Coastguard Worker 	}
876*03f9172cSAndroid Build Coastguard Worker 	os_free(buf);
877*03f9172cSAndroid Build Coastguard Worker 
878*03f9172cSAndroid Build Coastguard Worker 	if (val == 0) {
879*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR,
880*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: no key_mgmt values configured.", line);
881*03f9172cSAndroid Build Coastguard Worker 		errors++;
882*03f9172cSAndroid Build Coastguard Worker 	}
883*03f9172cSAndroid Build Coastguard Worker 
884*03f9172cSAndroid Build Coastguard Worker 	if (!errors && ssid->key_mgmt == val)
885*03f9172cSAndroid Build Coastguard Worker 		return 1;
886*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val);
887*03f9172cSAndroid Build Coastguard Worker 	ssid->key_mgmt = val;
888*03f9172cSAndroid Build Coastguard Worker 	return errors ? -1 : 0;
889*03f9172cSAndroid Build Coastguard Worker }
890*03f9172cSAndroid Build Coastguard Worker 
891*03f9172cSAndroid Build Coastguard Worker 
892*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_key_mgmt(const struct parse_data * data,struct wpa_ssid * ssid)893*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_key_mgmt(const struct parse_data *data,
894*03f9172cSAndroid Build Coastguard Worker 					struct wpa_ssid *ssid)
895*03f9172cSAndroid Build Coastguard Worker {
896*03f9172cSAndroid Build Coastguard Worker 	char *buf, *pos, *end;
897*03f9172cSAndroid Build Coastguard Worker 	int ret;
898*03f9172cSAndroid Build Coastguard Worker 
899*03f9172cSAndroid Build Coastguard Worker 	pos = buf = os_zalloc(100);
900*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
901*03f9172cSAndroid Build Coastguard Worker 		return NULL;
902*03f9172cSAndroid Build Coastguard Worker 	end = buf + 100;
903*03f9172cSAndroid Build Coastguard Worker 
904*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
905*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPA-PSK",
906*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
907*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
908*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
909*03f9172cSAndroid Build Coastguard Worker 			return buf;
910*03f9172cSAndroid Build Coastguard Worker 		}
911*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
912*03f9172cSAndroid Build Coastguard Worker 	}
913*03f9172cSAndroid Build Coastguard Worker 
914*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
915*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPA-EAP",
916*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
917*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
918*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
919*03f9172cSAndroid Build Coastguard Worker 			return buf;
920*03f9172cSAndroid Build Coastguard Worker 		}
921*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
922*03f9172cSAndroid Build Coastguard Worker 	}
923*03f9172cSAndroid Build Coastguard Worker 
924*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
925*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sIEEE8021X",
926*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
927*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
928*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
929*03f9172cSAndroid Build Coastguard Worker 			return buf;
930*03f9172cSAndroid Build Coastguard Worker 		}
931*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
932*03f9172cSAndroid Build Coastguard Worker 	}
933*03f9172cSAndroid Build Coastguard Worker 
934*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_NONE) {
935*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sNONE",
936*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
937*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
938*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
939*03f9172cSAndroid Build Coastguard Worker 			return buf;
940*03f9172cSAndroid Build Coastguard Worker 		}
941*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
942*03f9172cSAndroid Build Coastguard Worker 	}
943*03f9172cSAndroid Build Coastguard Worker 
944*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
945*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPA-NONE",
946*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
947*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
948*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
949*03f9172cSAndroid Build Coastguard Worker 			return buf;
950*03f9172cSAndroid Build Coastguard Worker 		}
951*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
952*03f9172cSAndroid Build Coastguard Worker 	}
953*03f9172cSAndroid Build Coastguard Worker 
954*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211R
955*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK) {
956*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sFT-PSK",
957*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
958*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
959*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
960*03f9172cSAndroid Build Coastguard Worker 			return buf;
961*03f9172cSAndroid Build Coastguard Worker 		}
962*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
963*03f9172cSAndroid Build Coastguard Worker 	}
964*03f9172cSAndroid Build Coastguard Worker 
965*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
966*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sFT-EAP",
967*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
968*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
969*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
970*03f9172cSAndroid Build Coastguard Worker 			return buf;
971*03f9172cSAndroid Build Coastguard Worker 		}
972*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
973*03f9172cSAndroid Build Coastguard Worker 	}
974*03f9172cSAndroid Build Coastguard Worker 
975*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SHA384
976*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) {
977*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sFT-EAP-SHA384",
978*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
979*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
980*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
981*03f9172cSAndroid Build Coastguard Worker 			return buf;
982*03f9172cSAndroid Build Coastguard Worker 		}
983*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
984*03f9172cSAndroid Build Coastguard Worker 	}
985*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SHA384 */
986*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211R */
987*03f9172cSAndroid Build Coastguard Worker 
988*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SHA384
989*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA384) {
990*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SHA384",
991*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
992*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
993*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
994*03f9172cSAndroid Build Coastguard Worker 			return buf;
995*03f9172cSAndroid Build Coastguard Worker 		}
996*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
997*03f9172cSAndroid Build Coastguard Worker 	}
998*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SHA384 */
999*03f9172cSAndroid Build Coastguard Worker 
1000*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
1001*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPA-PSK-SHA256",
1002*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1003*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1004*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1005*03f9172cSAndroid Build Coastguard Worker 			return buf;
1006*03f9172cSAndroid Build Coastguard Worker 		}
1007*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1008*03f9172cSAndroid Build Coastguard Worker 	}
1009*03f9172cSAndroid Build Coastguard Worker 
1010*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1011*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SHA256",
1012*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1013*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1014*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1015*03f9172cSAndroid Build Coastguard Worker 			return buf;
1016*03f9172cSAndroid Build Coastguard Worker 		}
1017*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1018*03f9172cSAndroid Build Coastguard Worker 	}
1019*03f9172cSAndroid Build Coastguard Worker 
1020*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_WPS
1021*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
1022*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPS",
1023*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1024*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1025*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1026*03f9172cSAndroid Build Coastguard Worker 			return buf;
1027*03f9172cSAndroid Build Coastguard Worker 		}
1028*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1029*03f9172cSAndroid Build Coastguard Worker 	}
1030*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_WPS */
1031*03f9172cSAndroid Build Coastguard Worker 
1032*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SAE
1033*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
1034*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sSAE",
1035*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1036*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1037*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1038*03f9172cSAndroid Build Coastguard Worker 			return buf;
1039*03f9172cSAndroid Build Coastguard Worker 		}
1040*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1041*03f9172cSAndroid Build Coastguard Worker 	}
1042*03f9172cSAndroid Build Coastguard Worker 
1043*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) {
1044*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sSAE-EXT-KEY",
1045*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1046*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1047*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1048*03f9172cSAndroid Build Coastguard Worker 			return buf;
1049*03f9172cSAndroid Build Coastguard Worker 		}
1050*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1051*03f9172cSAndroid Build Coastguard Worker 	}
1052*03f9172cSAndroid Build Coastguard Worker 
1053*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_SAE) {
1054*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sFT-SAE",
1055*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1056*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1057*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1058*03f9172cSAndroid Build Coastguard Worker 			return buf;
1059*03f9172cSAndroid Build Coastguard Worker 		}
1060*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1061*03f9172cSAndroid Build Coastguard Worker 	}
1062*03f9172cSAndroid Build Coastguard Worker 
1063*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
1064*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sFT-SAE-EXT-KEY",
1065*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1066*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1067*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1068*03f9172cSAndroid Build Coastguard Worker 			return buf;
1069*03f9172cSAndroid Build Coastguard Worker 		}
1070*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1071*03f9172cSAndroid Build Coastguard Worker 	}
1072*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SAE */
1073*03f9172cSAndroid Build Coastguard Worker 
1074*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_HS20
1075*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_OSEN) {
1076*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sOSEN",
1077*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1078*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1079*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1080*03f9172cSAndroid Build Coastguard Worker 			return buf;
1081*03f9172cSAndroid Build Coastguard Worker 		}
1082*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1083*03f9172cSAndroid Build Coastguard Worker 	}
1084*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_HS20 */
1085*03f9172cSAndroid Build Coastguard Worker 
1086*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SUITEB
1087*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
1088*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SUITE-B",
1089*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1090*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1091*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1092*03f9172cSAndroid Build Coastguard Worker 			return buf;
1093*03f9172cSAndroid Build Coastguard Worker 		}
1094*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1095*03f9172cSAndroid Build Coastguard Worker 	}
1096*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SUITEB */
1097*03f9172cSAndroid Build Coastguard Worker 
1098*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SUITEB192
1099*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
1100*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SUITE-B-192",
1101*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1102*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1103*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1104*03f9172cSAndroid Build Coastguard Worker 			return buf;
1105*03f9172cSAndroid Build Coastguard Worker 		}
1106*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1107*03f9172cSAndroid Build Coastguard Worker 	}
1108*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SUITEB192 */
1109*03f9172cSAndroid Build Coastguard Worker 
1110*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_FILS
1111*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_FILS_SHA256) {
1112*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sFILS-SHA256",
1113*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1114*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1115*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1116*03f9172cSAndroid Build Coastguard Worker 			return buf;
1117*03f9172cSAndroid Build Coastguard Worker 		}
1118*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1119*03f9172cSAndroid Build Coastguard Worker 	}
1120*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_FILS_SHA384) {
1121*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sFILS-SHA384",
1122*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1123*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1124*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1125*03f9172cSAndroid Build Coastguard Worker 			return buf;
1126*03f9172cSAndroid Build Coastguard Worker 		}
1127*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1128*03f9172cSAndroid Build Coastguard Worker 	}
1129*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211R
1130*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {
1131*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sFT-FILS-SHA256",
1132*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1133*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1134*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1135*03f9172cSAndroid Build Coastguard Worker 			return buf;
1136*03f9172cSAndroid Build Coastguard Worker 		}
1137*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1138*03f9172cSAndroid Build Coastguard Worker 	}
1139*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) {
1140*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sFT-FILS-SHA384",
1141*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1142*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1143*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1144*03f9172cSAndroid Build Coastguard Worker 			return buf;
1145*03f9172cSAndroid Build Coastguard Worker 		}
1146*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1147*03f9172cSAndroid Build Coastguard Worker 	}
1148*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211R */
1149*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_FILS */
1150*03f9172cSAndroid Build Coastguard Worker 
1151*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_DPP
1152*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_DPP) {
1153*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sDPP",
1154*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1155*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1156*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1157*03f9172cSAndroid Build Coastguard Worker 			return buf;
1158*03f9172cSAndroid Build Coastguard Worker 		}
1159*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1160*03f9172cSAndroid Build Coastguard Worker 	}
1161*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_DPP */
1162*03f9172cSAndroid Build Coastguard Worker 
1163*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_OWE
1164*03f9172cSAndroid Build Coastguard Worker 	if (ssid->key_mgmt & WPA_KEY_MGMT_OWE) {
1165*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sOWE",
1166*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1167*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1168*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1169*03f9172cSAndroid Build Coastguard Worker 			return buf;
1170*03f9172cSAndroid Build Coastguard Worker 		}
1171*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1172*03f9172cSAndroid Build Coastguard Worker 	}
1173*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_OWE */
1174*03f9172cSAndroid Build Coastguard Worker 
1175*03f9172cSAndroid Build Coastguard Worker 	if (pos == buf) {
1176*03f9172cSAndroid Build Coastguard Worker 		os_free(buf);
1177*03f9172cSAndroid Build Coastguard Worker 		buf = NULL;
1178*03f9172cSAndroid Build Coastguard Worker 	}
1179*03f9172cSAndroid Build Coastguard Worker 
1180*03f9172cSAndroid Build Coastguard Worker 	return buf;
1181*03f9172cSAndroid Build Coastguard Worker }
1182*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
1183*03f9172cSAndroid Build Coastguard Worker 
1184*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_cipher(int line,const char * value)1185*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_cipher(int line, const char *value)
1186*03f9172cSAndroid Build Coastguard Worker {
1187*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_NO_WPA
1188*03f9172cSAndroid Build Coastguard Worker 	return -1;
1189*03f9172cSAndroid Build Coastguard Worker #else /* CONFIG_NO_WPA */
1190*03f9172cSAndroid Build Coastguard Worker 	int val = wpa_parse_cipher(value);
1191*03f9172cSAndroid Build Coastguard Worker 	if (val < 0) {
1192*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
1193*03f9172cSAndroid Build Coastguard Worker 			   line, value);
1194*03f9172cSAndroid Build Coastguard Worker 		return -1;
1195*03f9172cSAndroid Build Coastguard Worker 	}
1196*03f9172cSAndroid Build Coastguard Worker 	if (val == 0) {
1197*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
1198*03f9172cSAndroid Build Coastguard Worker 			   line);
1199*03f9172cSAndroid Build Coastguard Worker 		return -1;
1200*03f9172cSAndroid Build Coastguard Worker 	}
1201*03f9172cSAndroid Build Coastguard Worker 	return val;
1202*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_WPA */
1203*03f9172cSAndroid Build Coastguard Worker }
1204*03f9172cSAndroid Build Coastguard Worker 
1205*03f9172cSAndroid Build Coastguard Worker 
1206*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_cipher(int cipher)1207*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_cipher(int cipher)
1208*03f9172cSAndroid Build Coastguard Worker {
1209*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_NO_WPA
1210*03f9172cSAndroid Build Coastguard Worker 	return NULL;
1211*03f9172cSAndroid Build Coastguard Worker #else /* CONFIG_NO_WPA */
1212*03f9172cSAndroid Build Coastguard Worker 	char *buf = os_zalloc(50);
1213*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
1214*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1215*03f9172cSAndroid Build Coastguard Worker 
1216*03f9172cSAndroid Build Coastguard Worker 	if (wpa_write_ciphers(buf, buf + 50, cipher, " ") < 0) {
1217*03f9172cSAndroid Build Coastguard Worker 		os_free(buf);
1218*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1219*03f9172cSAndroid Build Coastguard Worker 	}
1220*03f9172cSAndroid Build Coastguard Worker 
1221*03f9172cSAndroid Build Coastguard Worker 	return buf;
1222*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_WPA */
1223*03f9172cSAndroid Build Coastguard Worker }
1224*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
1225*03f9172cSAndroid Build Coastguard Worker 
1226*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_pairwise(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1227*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_pairwise(const struct parse_data *data,
1228*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid, int line,
1229*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
1230*03f9172cSAndroid Build Coastguard Worker {
1231*03f9172cSAndroid Build Coastguard Worker 	int val;
1232*03f9172cSAndroid Build Coastguard Worker 	val = wpa_config_parse_cipher(line, value);
1233*03f9172cSAndroid Build Coastguard Worker 	if (val == -1)
1234*03f9172cSAndroid Build Coastguard Worker 		return -1;
1235*03f9172cSAndroid Build Coastguard Worker 	if (val & ~WPA_ALLOWED_PAIRWISE_CIPHERS) {
1236*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
1237*03f9172cSAndroid Build Coastguard Worker 			   "(0x%x).", line, val);
1238*03f9172cSAndroid Build Coastguard Worker 		return -1;
1239*03f9172cSAndroid Build Coastguard Worker 	}
1240*03f9172cSAndroid Build Coastguard Worker 
1241*03f9172cSAndroid Build Coastguard Worker 	if (ssid->pairwise_cipher == val)
1242*03f9172cSAndroid Build Coastguard Worker 		return 1;
1243*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_MSGDUMP, "pairwise: 0x%x", val);
1244*03f9172cSAndroid Build Coastguard Worker 	ssid->pairwise_cipher = val;
1245*03f9172cSAndroid Build Coastguard Worker 	return 0;
1246*03f9172cSAndroid Build Coastguard Worker }
1247*03f9172cSAndroid Build Coastguard Worker 
1248*03f9172cSAndroid Build Coastguard Worker 
1249*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_pairwise(const struct parse_data * data,struct wpa_ssid * ssid)1250*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_pairwise(const struct parse_data *data,
1251*03f9172cSAndroid Build Coastguard Worker 					struct wpa_ssid *ssid)
1252*03f9172cSAndroid Build Coastguard Worker {
1253*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_cipher(ssid->pairwise_cipher);
1254*03f9172cSAndroid Build Coastguard Worker }
1255*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
1256*03f9172cSAndroid Build Coastguard Worker 
1257*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_group(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1258*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_group(const struct parse_data *data,
1259*03f9172cSAndroid Build Coastguard Worker 				  struct wpa_ssid *ssid, int line,
1260*03f9172cSAndroid Build Coastguard Worker 				  const char *value)
1261*03f9172cSAndroid Build Coastguard Worker {
1262*03f9172cSAndroid Build Coastguard Worker 	int val;
1263*03f9172cSAndroid Build Coastguard Worker 	val = wpa_config_parse_cipher(line, value);
1264*03f9172cSAndroid Build Coastguard Worker 	if (val == -1)
1265*03f9172cSAndroid Build Coastguard Worker 		return -1;
1266*03f9172cSAndroid Build Coastguard Worker 
1267*03f9172cSAndroid Build Coastguard Worker 	/*
1268*03f9172cSAndroid Build Coastguard Worker 	 * Backwards compatibility - filter out WEP ciphers that were previously
1269*03f9172cSAndroid Build Coastguard Worker 	 * allowed.
1270*03f9172cSAndroid Build Coastguard Worker 	 */
1271*03f9172cSAndroid Build Coastguard Worker 	val &= ~(WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40);
1272*03f9172cSAndroid Build Coastguard Worker 
1273*03f9172cSAndroid Build Coastguard Worker 	if (val & ~WPA_ALLOWED_GROUP_CIPHERS) {
1274*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
1275*03f9172cSAndroid Build Coastguard Worker 			   "(0x%x).", line, val);
1276*03f9172cSAndroid Build Coastguard Worker 		return -1;
1277*03f9172cSAndroid Build Coastguard Worker 	}
1278*03f9172cSAndroid Build Coastguard Worker 
1279*03f9172cSAndroid Build Coastguard Worker 	if (ssid->group_cipher == val)
1280*03f9172cSAndroid Build Coastguard Worker 		return 1;
1281*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_MSGDUMP, "group: 0x%x", val);
1282*03f9172cSAndroid Build Coastguard Worker 	ssid->group_cipher = val;
1283*03f9172cSAndroid Build Coastguard Worker 	return 0;
1284*03f9172cSAndroid Build Coastguard Worker }
1285*03f9172cSAndroid Build Coastguard Worker 
1286*03f9172cSAndroid Build Coastguard Worker 
1287*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_group(const struct parse_data * data,struct wpa_ssid * ssid)1288*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_group(const struct parse_data *data,
1289*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid)
1290*03f9172cSAndroid Build Coastguard Worker {
1291*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_cipher(ssid->group_cipher);
1292*03f9172cSAndroid Build Coastguard Worker }
1293*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
1294*03f9172cSAndroid Build Coastguard Worker 
1295*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_group_mgmt(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1296*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_group_mgmt(const struct parse_data *data,
1297*03f9172cSAndroid Build Coastguard Worker 				       struct wpa_ssid *ssid, int line,
1298*03f9172cSAndroid Build Coastguard Worker 				       const char *value)
1299*03f9172cSAndroid Build Coastguard Worker {
1300*03f9172cSAndroid Build Coastguard Worker 	int val;
1301*03f9172cSAndroid Build Coastguard Worker 
1302*03f9172cSAndroid Build Coastguard Worker 	val = wpa_config_parse_cipher(line, value);
1303*03f9172cSAndroid Build Coastguard Worker 	if (val == -1)
1304*03f9172cSAndroid Build Coastguard Worker 		return -1;
1305*03f9172cSAndroid Build Coastguard Worker 
1306*03f9172cSAndroid Build Coastguard Worker 	if (val & ~WPA_ALLOWED_GROUP_MGMT_CIPHERS) {
1307*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR,
1308*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: not allowed group management cipher (0x%x).",
1309*03f9172cSAndroid Build Coastguard Worker 			   line, val);
1310*03f9172cSAndroid Build Coastguard Worker 		return -1;
1311*03f9172cSAndroid Build Coastguard Worker 	}
1312*03f9172cSAndroid Build Coastguard Worker 
1313*03f9172cSAndroid Build Coastguard Worker 	if (ssid->group_mgmt_cipher == val)
1314*03f9172cSAndroid Build Coastguard Worker 		return 1;
1315*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_MSGDUMP, "group_mgmt: 0x%x", val);
1316*03f9172cSAndroid Build Coastguard Worker 	ssid->group_mgmt_cipher = val;
1317*03f9172cSAndroid Build Coastguard Worker 	return 0;
1318*03f9172cSAndroid Build Coastguard Worker }
1319*03f9172cSAndroid Build Coastguard Worker 
1320*03f9172cSAndroid Build Coastguard Worker 
1321*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_group_mgmt(const struct parse_data * data,struct wpa_ssid * ssid)1322*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_group_mgmt(const struct parse_data *data,
1323*03f9172cSAndroid Build Coastguard Worker 					  struct wpa_ssid *ssid)
1324*03f9172cSAndroid Build Coastguard Worker {
1325*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_cipher(ssid->group_mgmt_cipher);
1326*03f9172cSAndroid Build Coastguard Worker }
1327*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
1328*03f9172cSAndroid Build Coastguard Worker 
1329*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_auth_alg(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1330*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_auth_alg(const struct parse_data *data,
1331*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid, int line,
1332*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
1333*03f9172cSAndroid Build Coastguard Worker {
1334*03f9172cSAndroid Build Coastguard Worker 	int val = 0, last, errors = 0;
1335*03f9172cSAndroid Build Coastguard Worker 	char *start, *end, *buf;
1336*03f9172cSAndroid Build Coastguard Worker 
1337*03f9172cSAndroid Build Coastguard Worker 	buf = os_strdup(value);
1338*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
1339*03f9172cSAndroid Build Coastguard Worker 		return -1;
1340*03f9172cSAndroid Build Coastguard Worker 	start = buf;
1341*03f9172cSAndroid Build Coastguard Worker 
1342*03f9172cSAndroid Build Coastguard Worker 	while (*start != '\0') {
1343*03f9172cSAndroid Build Coastguard Worker 		while (*start == ' ' || *start == '\t')
1344*03f9172cSAndroid Build Coastguard Worker 			start++;
1345*03f9172cSAndroid Build Coastguard Worker 		if (*start == '\0')
1346*03f9172cSAndroid Build Coastguard Worker 			break;
1347*03f9172cSAndroid Build Coastguard Worker 		end = start;
1348*03f9172cSAndroid Build Coastguard Worker 		while (*end != ' ' && *end != '\t' && *end != '\0')
1349*03f9172cSAndroid Build Coastguard Worker 			end++;
1350*03f9172cSAndroid Build Coastguard Worker 		last = *end == '\0';
1351*03f9172cSAndroid Build Coastguard Worker 		*end = '\0';
1352*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(start, "OPEN") == 0)
1353*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_AUTH_ALG_OPEN;
1354*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "SHARED") == 0)
1355*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_AUTH_ALG_SHARED;
1356*03f9172cSAndroid Build Coastguard Worker 		else if (os_strcmp(start, "LEAP") == 0)
1357*03f9172cSAndroid Build Coastguard Worker 			val |= WPA_AUTH_ALG_LEAP;
1358*03f9172cSAndroid Build Coastguard Worker 		else {
1359*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: invalid auth_alg '%s'",
1360*03f9172cSAndroid Build Coastguard Worker 				   line, start);
1361*03f9172cSAndroid Build Coastguard Worker 			errors++;
1362*03f9172cSAndroid Build Coastguard Worker 		}
1363*03f9172cSAndroid Build Coastguard Worker 
1364*03f9172cSAndroid Build Coastguard Worker 		if (last)
1365*03f9172cSAndroid Build Coastguard Worker 			break;
1366*03f9172cSAndroid Build Coastguard Worker 		start = end + 1;
1367*03f9172cSAndroid Build Coastguard Worker 	}
1368*03f9172cSAndroid Build Coastguard Worker 	os_free(buf);
1369*03f9172cSAndroid Build Coastguard Worker 
1370*03f9172cSAndroid Build Coastguard Worker 	if (val == 0) {
1371*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR,
1372*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: no auth_alg values configured.", line);
1373*03f9172cSAndroid Build Coastguard Worker 		errors++;
1374*03f9172cSAndroid Build Coastguard Worker 	}
1375*03f9172cSAndroid Build Coastguard Worker 
1376*03f9172cSAndroid Build Coastguard Worker 	if (!errors && ssid->auth_alg == val)
1377*03f9172cSAndroid Build Coastguard Worker 		return 1;
1378*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", val);
1379*03f9172cSAndroid Build Coastguard Worker 	ssid->auth_alg = val;
1380*03f9172cSAndroid Build Coastguard Worker 	return errors ? -1 : 0;
1381*03f9172cSAndroid Build Coastguard Worker }
1382*03f9172cSAndroid Build Coastguard Worker 
1383*03f9172cSAndroid Build Coastguard Worker 
1384*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_auth_alg(const struct parse_data * data,struct wpa_ssid * ssid)1385*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_auth_alg(const struct parse_data *data,
1386*03f9172cSAndroid Build Coastguard Worker 					struct wpa_ssid *ssid)
1387*03f9172cSAndroid Build Coastguard Worker {
1388*03f9172cSAndroid Build Coastguard Worker 	char *buf, *pos, *end;
1389*03f9172cSAndroid Build Coastguard Worker 	int ret;
1390*03f9172cSAndroid Build Coastguard Worker 
1391*03f9172cSAndroid Build Coastguard Worker 	pos = buf = os_zalloc(30);
1392*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
1393*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1394*03f9172cSAndroid Build Coastguard Worker 	end = buf + 30;
1395*03f9172cSAndroid Build Coastguard Worker 
1396*03f9172cSAndroid Build Coastguard Worker 	if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) {
1397*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sOPEN",
1398*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1399*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1400*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1401*03f9172cSAndroid Build Coastguard Worker 			return buf;
1402*03f9172cSAndroid Build Coastguard Worker 		}
1403*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1404*03f9172cSAndroid Build Coastguard Worker 	}
1405*03f9172cSAndroid Build Coastguard Worker 
1406*03f9172cSAndroid Build Coastguard Worker 	if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) {
1407*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sSHARED",
1408*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1409*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1410*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1411*03f9172cSAndroid Build Coastguard Worker 			return buf;
1412*03f9172cSAndroid Build Coastguard Worker 		}
1413*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1414*03f9172cSAndroid Build Coastguard Worker 	}
1415*03f9172cSAndroid Build Coastguard Worker 
1416*03f9172cSAndroid Build Coastguard Worker 	if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) {
1417*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%sLEAP",
1418*03f9172cSAndroid Build Coastguard Worker 				  pos == buf ? "" : " ");
1419*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1420*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1421*03f9172cSAndroid Build Coastguard Worker 			return buf;
1422*03f9172cSAndroid Build Coastguard Worker 		}
1423*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1424*03f9172cSAndroid Build Coastguard Worker 	}
1425*03f9172cSAndroid Build Coastguard Worker 
1426*03f9172cSAndroid Build Coastguard Worker 	if (pos == buf) {
1427*03f9172cSAndroid Build Coastguard Worker 		os_free(buf);
1428*03f9172cSAndroid Build Coastguard Worker 		buf = NULL;
1429*03f9172cSAndroid Build Coastguard Worker 	}
1430*03f9172cSAndroid Build Coastguard Worker 
1431*03f9172cSAndroid Build Coastguard Worker 	return buf;
1432*03f9172cSAndroid Build Coastguard Worker }
1433*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
1434*03f9172cSAndroid Build Coastguard Worker 
1435*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_int_array(const char * value)1436*03f9172cSAndroid Build Coastguard Worker static int * wpa_config_parse_int_array(const char *value)
1437*03f9172cSAndroid Build Coastguard Worker {
1438*03f9172cSAndroid Build Coastguard Worker 	int *freqs;
1439*03f9172cSAndroid Build Coastguard Worker 	size_t used, len;
1440*03f9172cSAndroid Build Coastguard Worker 	const char *pos;
1441*03f9172cSAndroid Build Coastguard Worker 
1442*03f9172cSAndroid Build Coastguard Worker 	used = 0;
1443*03f9172cSAndroid Build Coastguard Worker 	len = 10;
1444*03f9172cSAndroid Build Coastguard Worker 	freqs = os_calloc(len + 1, sizeof(int));
1445*03f9172cSAndroid Build Coastguard Worker 	if (freqs == NULL)
1446*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1447*03f9172cSAndroid Build Coastguard Worker 
1448*03f9172cSAndroid Build Coastguard Worker 	pos = value;
1449*03f9172cSAndroid Build Coastguard Worker 	while (pos) {
1450*03f9172cSAndroid Build Coastguard Worker 		while (*pos == ' ')
1451*03f9172cSAndroid Build Coastguard Worker 			pos++;
1452*03f9172cSAndroid Build Coastguard Worker 		if (used == len) {
1453*03f9172cSAndroid Build Coastguard Worker 			int *n;
1454*03f9172cSAndroid Build Coastguard Worker 			size_t i;
1455*03f9172cSAndroid Build Coastguard Worker 			n = os_realloc_array(freqs, len * 2 + 1, sizeof(int));
1456*03f9172cSAndroid Build Coastguard Worker 			if (n == NULL) {
1457*03f9172cSAndroid Build Coastguard Worker 				os_free(freqs);
1458*03f9172cSAndroid Build Coastguard Worker 				return NULL;
1459*03f9172cSAndroid Build Coastguard Worker 			}
1460*03f9172cSAndroid Build Coastguard Worker 			for (i = len; i <= len * 2; i++)
1461*03f9172cSAndroid Build Coastguard Worker 				n[i] = 0;
1462*03f9172cSAndroid Build Coastguard Worker 			freqs = n;
1463*03f9172cSAndroid Build Coastguard Worker 			len *= 2;
1464*03f9172cSAndroid Build Coastguard Worker 		}
1465*03f9172cSAndroid Build Coastguard Worker 
1466*03f9172cSAndroid Build Coastguard Worker 		freqs[used] = atoi(pos);
1467*03f9172cSAndroid Build Coastguard Worker 		if (freqs[used] == 0)
1468*03f9172cSAndroid Build Coastguard Worker 			break;
1469*03f9172cSAndroid Build Coastguard Worker 		used++;
1470*03f9172cSAndroid Build Coastguard Worker 		pos = os_strchr(pos + 1, ' ');
1471*03f9172cSAndroid Build Coastguard Worker 	}
1472*03f9172cSAndroid Build Coastguard Worker 
1473*03f9172cSAndroid Build Coastguard Worker 	return freqs;
1474*03f9172cSAndroid Build Coastguard Worker }
1475*03f9172cSAndroid Build Coastguard Worker 
1476*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_scan_freq(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1477*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_scan_freq(const struct parse_data *data,
1478*03f9172cSAndroid Build Coastguard Worker 				      struct wpa_ssid *ssid, int line,
1479*03f9172cSAndroid Build Coastguard Worker 				      const char *value)
1480*03f9172cSAndroid Build Coastguard Worker {
1481*03f9172cSAndroid Build Coastguard Worker 	int *freqs;
1482*03f9172cSAndroid Build Coastguard Worker 
1483*03f9172cSAndroid Build Coastguard Worker 	freqs = wpa_config_parse_int_array(value);
1484*03f9172cSAndroid Build Coastguard Worker 	if (freqs == NULL)
1485*03f9172cSAndroid Build Coastguard Worker 		return -1;
1486*03f9172cSAndroid Build Coastguard Worker 	if (freqs[0] == 0) {
1487*03f9172cSAndroid Build Coastguard Worker 		os_free(freqs);
1488*03f9172cSAndroid Build Coastguard Worker 		freqs = NULL;
1489*03f9172cSAndroid Build Coastguard Worker 	}
1490*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->scan_freq);
1491*03f9172cSAndroid Build Coastguard Worker 	ssid->scan_freq = freqs;
1492*03f9172cSAndroid Build Coastguard Worker 
1493*03f9172cSAndroid Build Coastguard Worker 	return 0;
1494*03f9172cSAndroid Build Coastguard Worker }
1495*03f9172cSAndroid Build Coastguard Worker 
1496*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_freq_list(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1497*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_freq_list(const struct parse_data *data,
1498*03f9172cSAndroid Build Coastguard Worker 				      struct wpa_ssid *ssid, int line,
1499*03f9172cSAndroid Build Coastguard Worker 				      const char *value)
1500*03f9172cSAndroid Build Coastguard Worker {
1501*03f9172cSAndroid Build Coastguard Worker 	int *freqs;
1502*03f9172cSAndroid Build Coastguard Worker 
1503*03f9172cSAndroid Build Coastguard Worker 	freqs = wpa_config_parse_int_array(value);
1504*03f9172cSAndroid Build Coastguard Worker 	if (freqs == NULL)
1505*03f9172cSAndroid Build Coastguard Worker 		return -1;
1506*03f9172cSAndroid Build Coastguard Worker 	if (freqs[0] == 0) {
1507*03f9172cSAndroid Build Coastguard Worker 		os_free(freqs);
1508*03f9172cSAndroid Build Coastguard Worker 		freqs = NULL;
1509*03f9172cSAndroid Build Coastguard Worker 	}
1510*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->freq_list);
1511*03f9172cSAndroid Build Coastguard Worker 	ssid->freq_list = freqs;
1512*03f9172cSAndroid Build Coastguard Worker 
1513*03f9172cSAndroid Build Coastguard Worker 	return 0;
1514*03f9172cSAndroid Build Coastguard Worker }
1515*03f9172cSAndroid Build Coastguard Worker 
1516*03f9172cSAndroid Build Coastguard Worker 
1517*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_freqs(const struct parse_data * data,const int * freqs)1518*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_freqs(const struct parse_data *data,
1519*03f9172cSAndroid Build Coastguard Worker 				     const int *freqs)
1520*03f9172cSAndroid Build Coastguard Worker {
1521*03f9172cSAndroid Build Coastguard Worker 	char *buf, *pos, *end;
1522*03f9172cSAndroid Build Coastguard Worker 	int i, ret;
1523*03f9172cSAndroid Build Coastguard Worker 	size_t count;
1524*03f9172cSAndroid Build Coastguard Worker 
1525*03f9172cSAndroid Build Coastguard Worker 	if (freqs == NULL)
1526*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1527*03f9172cSAndroid Build Coastguard Worker 
1528*03f9172cSAndroid Build Coastguard Worker 	count = 0;
1529*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; freqs[i]; i++)
1530*03f9172cSAndroid Build Coastguard Worker 		count++;
1531*03f9172cSAndroid Build Coastguard Worker 
1532*03f9172cSAndroid Build Coastguard Worker 	pos = buf = os_zalloc(10 * count + 1);
1533*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
1534*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1535*03f9172cSAndroid Build Coastguard Worker 	end = buf + 10 * count + 1;
1536*03f9172cSAndroid Build Coastguard Worker 
1537*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; freqs[i]; i++) {
1538*03f9172cSAndroid Build Coastguard Worker 		ret = os_snprintf(pos, end - pos, "%s%u",
1539*03f9172cSAndroid Build Coastguard Worker 				  i == 0 ? "" : " ", freqs[i]);
1540*03f9172cSAndroid Build Coastguard Worker 		if (os_snprintf_error(end - pos, ret)) {
1541*03f9172cSAndroid Build Coastguard Worker 			end[-1] = '\0';
1542*03f9172cSAndroid Build Coastguard Worker 			return buf;
1543*03f9172cSAndroid Build Coastguard Worker 		}
1544*03f9172cSAndroid Build Coastguard Worker 		pos += ret;
1545*03f9172cSAndroid Build Coastguard Worker 	}
1546*03f9172cSAndroid Build Coastguard Worker 
1547*03f9172cSAndroid Build Coastguard Worker 	return buf;
1548*03f9172cSAndroid Build Coastguard Worker }
1549*03f9172cSAndroid Build Coastguard Worker 
1550*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_scan_freq(const struct parse_data * data,struct wpa_ssid * ssid)1551*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_scan_freq(const struct parse_data *data,
1552*03f9172cSAndroid Build Coastguard Worker 					 struct wpa_ssid *ssid)
1553*03f9172cSAndroid Build Coastguard Worker {
1554*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_freqs(data, ssid->scan_freq);
1555*03f9172cSAndroid Build Coastguard Worker }
1556*03f9172cSAndroid Build Coastguard Worker 
1557*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_freq_list(const struct parse_data * data,struct wpa_ssid * ssid)1558*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_freq_list(const struct parse_data *data,
1559*03f9172cSAndroid Build Coastguard Worker 					 struct wpa_ssid *ssid)
1560*03f9172cSAndroid Build Coastguard Worker {
1561*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_freqs(data, ssid->freq_list);
1562*03f9172cSAndroid Build Coastguard Worker }
1563*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
1564*03f9172cSAndroid Build Coastguard Worker 
1565*03f9172cSAndroid Build Coastguard Worker 
1566*03f9172cSAndroid Build Coastguard Worker #ifdef IEEE8021X_EAPOL
wpa_config_parse_eap(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1567*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_eap(const struct parse_data *data,
1568*03f9172cSAndroid Build Coastguard Worker 				struct wpa_ssid *ssid, int line,
1569*03f9172cSAndroid Build Coastguard Worker 				const char *value)
1570*03f9172cSAndroid Build Coastguard Worker {
1571*03f9172cSAndroid Build Coastguard Worker 	int last, errors = 0;
1572*03f9172cSAndroid Build Coastguard Worker 	char *start, *end, *buf;
1573*03f9172cSAndroid Build Coastguard Worker 	struct eap_method_type *methods = NULL, *tmp;
1574*03f9172cSAndroid Build Coastguard Worker 	size_t num_methods = 0;
1575*03f9172cSAndroid Build Coastguard Worker 
1576*03f9172cSAndroid Build Coastguard Worker 	buf = os_strdup(value);
1577*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
1578*03f9172cSAndroid Build Coastguard Worker 		return -1;
1579*03f9172cSAndroid Build Coastguard Worker 	start = buf;
1580*03f9172cSAndroid Build Coastguard Worker 
1581*03f9172cSAndroid Build Coastguard Worker 	while (*start != '\0') {
1582*03f9172cSAndroid Build Coastguard Worker 		while (*start == ' ' || *start == '\t')
1583*03f9172cSAndroid Build Coastguard Worker 			start++;
1584*03f9172cSAndroid Build Coastguard Worker 		if (*start == '\0')
1585*03f9172cSAndroid Build Coastguard Worker 			break;
1586*03f9172cSAndroid Build Coastguard Worker 		end = start;
1587*03f9172cSAndroid Build Coastguard Worker 		while (*end != ' ' && *end != '\t' && *end != '\0')
1588*03f9172cSAndroid Build Coastguard Worker 			end++;
1589*03f9172cSAndroid Build Coastguard Worker 		last = *end == '\0';
1590*03f9172cSAndroid Build Coastguard Worker 		*end = '\0';
1591*03f9172cSAndroid Build Coastguard Worker 		tmp = methods;
1592*03f9172cSAndroid Build Coastguard Worker 		methods = os_realloc_array(methods, num_methods + 1,
1593*03f9172cSAndroid Build Coastguard Worker 					   sizeof(*methods));
1594*03f9172cSAndroid Build Coastguard Worker 		if (methods == NULL) {
1595*03f9172cSAndroid Build Coastguard Worker 			os_free(tmp);
1596*03f9172cSAndroid Build Coastguard Worker 			os_free(buf);
1597*03f9172cSAndroid Build Coastguard Worker 			return -1;
1598*03f9172cSAndroid Build Coastguard Worker 		}
1599*03f9172cSAndroid Build Coastguard Worker 		methods[num_methods].method = eap_peer_get_type(
1600*03f9172cSAndroid Build Coastguard Worker 			start, &methods[num_methods].vendor);
1601*03f9172cSAndroid Build Coastguard Worker 		if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
1602*03f9172cSAndroid Build Coastguard Worker 		    methods[num_methods].method == EAP_TYPE_NONE) {
1603*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: unknown EAP method "
1604*03f9172cSAndroid Build Coastguard Worker 				   "'%s'", line, start);
1605*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "You may need to add support for"
1606*03f9172cSAndroid Build Coastguard Worker 				   " this EAP method during wpa_supplicant\n"
1607*03f9172cSAndroid Build Coastguard Worker 				   "build time configuration.\n"
1608*03f9172cSAndroid Build Coastguard Worker 				   "See README for more information.");
1609*03f9172cSAndroid Build Coastguard Worker 			errors++;
1610*03f9172cSAndroid Build Coastguard Worker 		} else if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
1611*03f9172cSAndroid Build Coastguard Worker 			   methods[num_methods].method == EAP_TYPE_LEAP)
1612*03f9172cSAndroid Build Coastguard Worker 			ssid->leap++;
1613*03f9172cSAndroid Build Coastguard Worker 		else
1614*03f9172cSAndroid Build Coastguard Worker 			ssid->non_leap++;
1615*03f9172cSAndroid Build Coastguard Worker 		num_methods++;
1616*03f9172cSAndroid Build Coastguard Worker 		if (last)
1617*03f9172cSAndroid Build Coastguard Worker 			break;
1618*03f9172cSAndroid Build Coastguard Worker 		start = end + 1;
1619*03f9172cSAndroid Build Coastguard Worker 	}
1620*03f9172cSAndroid Build Coastguard Worker 	os_free(buf);
1621*03f9172cSAndroid Build Coastguard Worker 
1622*03f9172cSAndroid Build Coastguard Worker 	tmp = methods;
1623*03f9172cSAndroid Build Coastguard Worker 	methods = os_realloc_array(methods, num_methods + 1, sizeof(*methods));
1624*03f9172cSAndroid Build Coastguard Worker 	if (methods == NULL) {
1625*03f9172cSAndroid Build Coastguard Worker 		os_free(tmp);
1626*03f9172cSAndroid Build Coastguard Worker 		return -1;
1627*03f9172cSAndroid Build Coastguard Worker 	}
1628*03f9172cSAndroid Build Coastguard Worker 	methods[num_methods].vendor = EAP_VENDOR_IETF;
1629*03f9172cSAndroid Build Coastguard Worker 	methods[num_methods].method = EAP_TYPE_NONE;
1630*03f9172cSAndroid Build Coastguard Worker 	num_methods++;
1631*03f9172cSAndroid Build Coastguard Worker 
1632*03f9172cSAndroid Build Coastguard Worker 	if (!errors && ssid->eap.eap_methods) {
1633*03f9172cSAndroid Build Coastguard Worker 		struct eap_method_type *prev_m;
1634*03f9172cSAndroid Build Coastguard Worker 		size_t i, j, prev_methods, match = 0;
1635*03f9172cSAndroid Build Coastguard Worker 
1636*03f9172cSAndroid Build Coastguard Worker 		prev_m = ssid->eap.eap_methods;
1637*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; prev_m[i].vendor != EAP_VENDOR_IETF ||
1638*03f9172cSAndroid Build Coastguard Worker 			     prev_m[i].method != EAP_TYPE_NONE; i++) {
1639*03f9172cSAndroid Build Coastguard Worker 			/* Count the methods */
1640*03f9172cSAndroid Build Coastguard Worker 		}
1641*03f9172cSAndroid Build Coastguard Worker 		prev_methods = i + 1;
1642*03f9172cSAndroid Build Coastguard Worker 
1643*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; prev_methods == num_methods && i < prev_methods;
1644*03f9172cSAndroid Build Coastguard Worker 		     i++) {
1645*03f9172cSAndroid Build Coastguard Worker 			for (j = 0; j < num_methods; j++) {
1646*03f9172cSAndroid Build Coastguard Worker 				if (prev_m[i].vendor == methods[j].vendor &&
1647*03f9172cSAndroid Build Coastguard Worker 				    prev_m[i].method == methods[j].method) {
1648*03f9172cSAndroid Build Coastguard Worker 					match++;
1649*03f9172cSAndroid Build Coastguard Worker 					break;
1650*03f9172cSAndroid Build Coastguard Worker 				}
1651*03f9172cSAndroid Build Coastguard Worker 			}
1652*03f9172cSAndroid Build Coastguard Worker 		}
1653*03f9172cSAndroid Build Coastguard Worker 		if (match == num_methods) {
1654*03f9172cSAndroid Build Coastguard Worker 			os_free(methods);
1655*03f9172cSAndroid Build Coastguard Worker 			return 1;
1656*03f9172cSAndroid Build Coastguard Worker 		}
1657*03f9172cSAndroid Build Coastguard Worker 	}
1658*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump(MSG_MSGDUMP, "eap methods",
1659*03f9172cSAndroid Build Coastguard Worker 		    (u8 *) methods, num_methods * sizeof(*methods));
1660*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->eap.eap_methods);
1661*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.eap_methods = methods;
1662*03f9172cSAndroid Build Coastguard Worker 	return errors ? -1 : 0;
1663*03f9172cSAndroid Build Coastguard Worker }
1664*03f9172cSAndroid Build Coastguard Worker 
1665*03f9172cSAndroid Build Coastguard Worker 
1666*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_eap(const struct parse_data * data,struct wpa_ssid * ssid)1667*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_eap(const struct parse_data *data,
1668*03f9172cSAndroid Build Coastguard Worker 				   struct wpa_ssid *ssid)
1669*03f9172cSAndroid Build Coastguard Worker {
1670*03f9172cSAndroid Build Coastguard Worker 	int i, ret;
1671*03f9172cSAndroid Build Coastguard Worker 	char *buf, *pos, *end;
1672*03f9172cSAndroid Build Coastguard Worker 	const struct eap_method_type *eap_methods = ssid->eap.eap_methods;
1673*03f9172cSAndroid Build Coastguard Worker 	const char *name;
1674*03f9172cSAndroid Build Coastguard Worker 
1675*03f9172cSAndroid Build Coastguard Worker 	if (eap_methods == NULL)
1676*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1677*03f9172cSAndroid Build Coastguard Worker 
1678*03f9172cSAndroid Build Coastguard Worker 	pos = buf = os_zalloc(100);
1679*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
1680*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1681*03f9172cSAndroid Build Coastguard Worker 	end = buf + 100;
1682*03f9172cSAndroid Build Coastguard Worker 
1683*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; eap_methods[i].vendor != EAP_VENDOR_IETF ||
1684*03f9172cSAndroid Build Coastguard Worker 		     eap_methods[i].method != EAP_TYPE_NONE; i++) {
1685*03f9172cSAndroid Build Coastguard Worker 		name = eap_get_name(eap_methods[i].vendor,
1686*03f9172cSAndroid Build Coastguard Worker 				    eap_methods[i].method);
1687*03f9172cSAndroid Build Coastguard Worker 		if (name) {
1688*03f9172cSAndroid Build Coastguard Worker 			ret = os_snprintf(pos, end - pos, "%s%s",
1689*03f9172cSAndroid Build Coastguard Worker 					  pos == buf ? "" : " ", name);
1690*03f9172cSAndroid Build Coastguard Worker 			if (os_snprintf_error(end - pos, ret))
1691*03f9172cSAndroid Build Coastguard Worker 				break;
1692*03f9172cSAndroid Build Coastguard Worker 			pos += ret;
1693*03f9172cSAndroid Build Coastguard Worker 		}
1694*03f9172cSAndroid Build Coastguard Worker 	}
1695*03f9172cSAndroid Build Coastguard Worker 
1696*03f9172cSAndroid Build Coastguard Worker 	end[-1] = '\0';
1697*03f9172cSAndroid Build Coastguard Worker 
1698*03f9172cSAndroid Build Coastguard Worker 	return buf;
1699*03f9172cSAndroid Build Coastguard Worker }
1700*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
1701*03f9172cSAndroid Build Coastguard Worker 
1702*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_password(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1703*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_password(const struct parse_data *data,
1704*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid, int line,
1705*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
1706*03f9172cSAndroid Build Coastguard Worker {
1707*03f9172cSAndroid Build Coastguard Worker 	u8 *hash;
1708*03f9172cSAndroid Build Coastguard Worker 
1709*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(value, "NULL") == 0) {
1710*03f9172cSAndroid Build Coastguard Worker 		if (!ssid->eap.password)
1711*03f9172cSAndroid Build Coastguard Worker 			return 1; /* Already unset */
1712*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_DEBUG, "Unset configuration string 'password'");
1713*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(ssid->eap.password, ssid->eap.password_len);
1714*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.password = NULL;
1715*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.password_len = 0;
1716*03f9172cSAndroid Build Coastguard Worker 		return 0;
1717*03f9172cSAndroid Build Coastguard Worker 	}
1718*03f9172cSAndroid Build Coastguard Worker 
1719*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_EXT_PASSWORD
1720*03f9172cSAndroid Build Coastguard Worker 	if (os_strncmp(value, "ext:", 4) == 0) {
1721*03f9172cSAndroid Build Coastguard Worker 		char *name = os_strdup(value + 4);
1722*03f9172cSAndroid Build Coastguard Worker 		if (!name)
1723*03f9172cSAndroid Build Coastguard Worker 			return -1;
1724*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(ssid->eap.password, ssid->eap.password_len);
1725*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.password = (u8 *) name;
1726*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.password_len = os_strlen(name);
1727*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
1728*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.flags |= EAP_CONFIG_FLAGS_EXT_PASSWORD;
1729*03f9172cSAndroid Build Coastguard Worker 		return 0;
1730*03f9172cSAndroid Build Coastguard Worker 	}
1731*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_EXT_PASSWORD */
1732*03f9172cSAndroid Build Coastguard Worker 
1733*03f9172cSAndroid Build Coastguard Worker 	if (os_strncmp(value, "hash:", 5) != 0) {
1734*03f9172cSAndroid Build Coastguard Worker 		char *tmp;
1735*03f9172cSAndroid Build Coastguard Worker 		size_t res_len;
1736*03f9172cSAndroid Build Coastguard Worker 
1737*03f9172cSAndroid Build Coastguard Worker 		tmp = wpa_config_parse_string(value, &res_len);
1738*03f9172cSAndroid Build Coastguard Worker 		if (!tmp) {
1739*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR,
1740*03f9172cSAndroid Build Coastguard Worker 				   "Line %d: failed to parse password.", line);
1741*03f9172cSAndroid Build Coastguard Worker 			return -1;
1742*03f9172cSAndroid Build Coastguard Worker 		}
1743*03f9172cSAndroid Build Coastguard Worker 		wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
1744*03f9172cSAndroid Build Coastguard Worker 				      (u8 *) tmp, res_len);
1745*03f9172cSAndroid Build Coastguard Worker 
1746*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(ssid->eap.password, ssid->eap.password_len);
1747*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.password = (u8 *) tmp;
1748*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.password_len = res_len;
1749*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
1750*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
1751*03f9172cSAndroid Build Coastguard Worker 
1752*03f9172cSAndroid Build Coastguard Worker 		return 0;
1753*03f9172cSAndroid Build Coastguard Worker 	}
1754*03f9172cSAndroid Build Coastguard Worker 
1755*03f9172cSAndroid Build Coastguard Worker 
1756*03f9172cSAndroid Build Coastguard Worker 	/* NtPasswordHash: hash:<32 hex digits> */
1757*03f9172cSAndroid Build Coastguard Worker 	if (os_strlen(value + 5) != 2 * 16) {
1758*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR,
1759*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: Invalid password hash length (expected 32 hex digits)",
1760*03f9172cSAndroid Build Coastguard Worker 			   line);
1761*03f9172cSAndroid Build Coastguard Worker 		return -1;
1762*03f9172cSAndroid Build Coastguard Worker 	}
1763*03f9172cSAndroid Build Coastguard Worker 
1764*03f9172cSAndroid Build Coastguard Worker 	hash = os_malloc(16);
1765*03f9172cSAndroid Build Coastguard Worker 	if (!hash)
1766*03f9172cSAndroid Build Coastguard Worker 		return -1;
1767*03f9172cSAndroid Build Coastguard Worker 
1768*03f9172cSAndroid Build Coastguard Worker 	if (hexstr2bin(value + 5, hash, 16)) {
1769*03f9172cSAndroid Build Coastguard Worker 		os_free(hash);
1770*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid password hash", line);
1771*03f9172cSAndroid Build Coastguard Worker 		return -1;
1772*03f9172cSAndroid Build Coastguard Worker 	}
1773*03f9172cSAndroid Build Coastguard Worker 
1774*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
1775*03f9172cSAndroid Build Coastguard Worker 
1776*03f9172cSAndroid Build Coastguard Worker 	if (ssid->eap.password && ssid->eap.password_len == 16 &&
1777*03f9172cSAndroid Build Coastguard Worker 	    os_memcmp(ssid->eap.password, hash, 16) == 0 &&
1778*03f9172cSAndroid Build Coastguard Worker 	    (ssid->eap.flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH)) {
1779*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(hash, 16);
1780*03f9172cSAndroid Build Coastguard Worker 		return 1;
1781*03f9172cSAndroid Build Coastguard Worker 	}
1782*03f9172cSAndroid Build Coastguard Worker 	bin_clear_free(ssid->eap.password, ssid->eap.password_len);
1783*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.password = hash;
1784*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.password_len = 16;
1785*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.flags |= EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
1786*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
1787*03f9172cSAndroid Build Coastguard Worker 
1788*03f9172cSAndroid Build Coastguard Worker 	return 0;
1789*03f9172cSAndroid Build Coastguard Worker }
1790*03f9172cSAndroid Build Coastguard Worker 
1791*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_machine_password(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1792*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_machine_password(const struct parse_data *data,
1793*03f9172cSAndroid Build Coastguard Worker 					     struct wpa_ssid *ssid, int line,
1794*03f9172cSAndroid Build Coastguard Worker 					     const char *value)
1795*03f9172cSAndroid Build Coastguard Worker {
1796*03f9172cSAndroid Build Coastguard Worker 	u8 *hash;
1797*03f9172cSAndroid Build Coastguard Worker 
1798*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(value, "NULL") == 0) {
1799*03f9172cSAndroid Build Coastguard Worker 		if (!ssid->eap.machine_password)
1800*03f9172cSAndroid Build Coastguard Worker 			return 1; /* Already unset */
1801*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_DEBUG,
1802*03f9172cSAndroid Build Coastguard Worker 			   "Unset configuration string 'machine_password'");
1803*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(ssid->eap.machine_password,
1804*03f9172cSAndroid Build Coastguard Worker 			       ssid->eap.machine_password_len);
1805*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.machine_password = NULL;
1806*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.machine_password_len = 0;
1807*03f9172cSAndroid Build Coastguard Worker 		return 0;
1808*03f9172cSAndroid Build Coastguard Worker 	}
1809*03f9172cSAndroid Build Coastguard Worker 
1810*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_EXT_PASSWORD
1811*03f9172cSAndroid Build Coastguard Worker 	if (os_strncmp(value, "ext:", 4) == 0) {
1812*03f9172cSAndroid Build Coastguard Worker 		char *name = os_strdup(value + 4);
1813*03f9172cSAndroid Build Coastguard Worker 
1814*03f9172cSAndroid Build Coastguard Worker 		if (!name)
1815*03f9172cSAndroid Build Coastguard Worker 			return -1;
1816*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(ssid->eap.machine_password,
1817*03f9172cSAndroid Build Coastguard Worker 			       ssid->eap.machine_password_len);
1818*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.machine_password = (u8 *) name;
1819*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.machine_password_len = os_strlen(name);
1820*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH;
1821*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.flags |= EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD;
1822*03f9172cSAndroid Build Coastguard Worker 		return 0;
1823*03f9172cSAndroid Build Coastguard Worker 	}
1824*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_EXT_PASSWORD */
1825*03f9172cSAndroid Build Coastguard Worker 
1826*03f9172cSAndroid Build Coastguard Worker 	if (os_strncmp(value, "hash:", 5) != 0) {
1827*03f9172cSAndroid Build Coastguard Worker 		char *tmp;
1828*03f9172cSAndroid Build Coastguard Worker 		size_t res_len;
1829*03f9172cSAndroid Build Coastguard Worker 
1830*03f9172cSAndroid Build Coastguard Worker 		tmp = wpa_config_parse_string(value, &res_len);
1831*03f9172cSAndroid Build Coastguard Worker 		if (!tmp) {
1832*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR,
1833*03f9172cSAndroid Build Coastguard Worker 				   "Line %d: failed to parse machine_password.",
1834*03f9172cSAndroid Build Coastguard Worker 				   line);
1835*03f9172cSAndroid Build Coastguard Worker 			return -1;
1836*03f9172cSAndroid Build Coastguard Worker 		}
1837*03f9172cSAndroid Build Coastguard Worker 		wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
1838*03f9172cSAndroid Build Coastguard Worker 				      (u8 *) tmp, res_len);
1839*03f9172cSAndroid Build Coastguard Worker 
1840*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(ssid->eap.machine_password,
1841*03f9172cSAndroid Build Coastguard Worker 			       ssid->eap.machine_password_len);
1842*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.machine_password = (u8 *) tmp;
1843*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.machine_password_len = res_len;
1844*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH;
1845*03f9172cSAndroid Build Coastguard Worker 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD;
1846*03f9172cSAndroid Build Coastguard Worker 
1847*03f9172cSAndroid Build Coastguard Worker 		return 0;
1848*03f9172cSAndroid Build Coastguard Worker 	}
1849*03f9172cSAndroid Build Coastguard Worker 
1850*03f9172cSAndroid Build Coastguard Worker 
1851*03f9172cSAndroid Build Coastguard Worker 	/* NtPasswordHash: hash:<32 hex digits> */
1852*03f9172cSAndroid Build Coastguard Worker 	if (os_strlen(value + 5) != 2 * 16) {
1853*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR,
1854*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: Invalid machine_password hash length (expected 32 hex digits)",
1855*03f9172cSAndroid Build Coastguard Worker 			   line);
1856*03f9172cSAndroid Build Coastguard Worker 		return -1;
1857*03f9172cSAndroid Build Coastguard Worker 	}
1858*03f9172cSAndroid Build Coastguard Worker 
1859*03f9172cSAndroid Build Coastguard Worker 	hash = os_malloc(16);
1860*03f9172cSAndroid Build Coastguard Worker 	if (!hash)
1861*03f9172cSAndroid Build Coastguard Worker 		return -1;
1862*03f9172cSAndroid Build Coastguard Worker 
1863*03f9172cSAndroid Build Coastguard Worker 	if (hexstr2bin(value + 5, hash, 16)) {
1864*03f9172cSAndroid Build Coastguard Worker 		os_free(hash);
1865*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid machine_password hash",
1866*03f9172cSAndroid Build Coastguard Worker 			   line);
1867*03f9172cSAndroid Build Coastguard Worker 		return -1;
1868*03f9172cSAndroid Build Coastguard Worker 	}
1869*03f9172cSAndroid Build Coastguard Worker 
1870*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
1871*03f9172cSAndroid Build Coastguard Worker 
1872*03f9172cSAndroid Build Coastguard Worker 	if (ssid->eap.machine_password &&
1873*03f9172cSAndroid Build Coastguard Worker 	    ssid->eap.machine_password_len == 16 &&
1874*03f9172cSAndroid Build Coastguard Worker 	    os_memcmp(ssid->eap.machine_password, hash, 16) == 0 &&
1875*03f9172cSAndroid Build Coastguard Worker 	    (ssid->eap.flags & EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH)) {
1876*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(hash, 16);
1877*03f9172cSAndroid Build Coastguard Worker 		return 1;
1878*03f9172cSAndroid Build Coastguard Worker 	}
1879*03f9172cSAndroid Build Coastguard Worker 	bin_clear_free(ssid->eap.machine_password,
1880*03f9172cSAndroid Build Coastguard Worker 		       ssid->eap.machine_password_len);
1881*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.machine_password = hash;
1882*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.machine_password_len = 16;
1883*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.flags |= EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH;
1884*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD;
1885*03f9172cSAndroid Build Coastguard Worker 
1886*03f9172cSAndroid Build Coastguard Worker 	return 0;
1887*03f9172cSAndroid Build Coastguard Worker }
1888*03f9172cSAndroid Build Coastguard Worker 
1889*03f9172cSAndroid Build Coastguard Worker 
1890*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
1891*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_password(const struct parse_data * data,struct wpa_ssid * ssid)1892*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_password(const struct parse_data *data,
1893*03f9172cSAndroid Build Coastguard Worker 					struct wpa_ssid *ssid)
1894*03f9172cSAndroid Build Coastguard Worker {
1895*03f9172cSAndroid Build Coastguard Worker 	char *buf;
1896*03f9172cSAndroid Build Coastguard Worker 
1897*03f9172cSAndroid Build Coastguard Worker 	if (!ssid->eap.password)
1898*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1899*03f9172cSAndroid Build Coastguard Worker 
1900*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_EXT_PASSWORD
1901*03f9172cSAndroid Build Coastguard Worker 	if (ssid->eap.flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
1902*03f9172cSAndroid Build Coastguard Worker 		buf = os_zalloc(4 + ssid->eap.password_len + 1);
1903*03f9172cSAndroid Build Coastguard Worker 		if (!buf)
1904*03f9172cSAndroid Build Coastguard Worker 			return NULL;
1905*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(buf, "ext:", 4);
1906*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(buf + 4, ssid->eap.password, ssid->eap.password_len);
1907*03f9172cSAndroid Build Coastguard Worker 		return buf;
1908*03f9172cSAndroid Build Coastguard Worker 	}
1909*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_EXT_PASSWORD */
1910*03f9172cSAndroid Build Coastguard Worker 
1911*03f9172cSAndroid Build Coastguard Worker 	if (!(ssid->eap.flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH)) {
1912*03f9172cSAndroid Build Coastguard Worker 		return wpa_config_write_string(
1913*03f9172cSAndroid Build Coastguard Worker 			ssid->eap.password, ssid->eap.password_len);
1914*03f9172cSAndroid Build Coastguard Worker 	}
1915*03f9172cSAndroid Build Coastguard Worker 
1916*03f9172cSAndroid Build Coastguard Worker 	buf = os_malloc(5 + 32 + 1);
1917*03f9172cSAndroid Build Coastguard Worker 	if (!buf)
1918*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1919*03f9172cSAndroid Build Coastguard Worker 
1920*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf, "hash:", 5);
1921*03f9172cSAndroid Build Coastguard Worker 	wpa_snprintf_hex(buf + 5, 32 + 1, ssid->eap.password, 16);
1922*03f9172cSAndroid Build Coastguard Worker 
1923*03f9172cSAndroid Build Coastguard Worker 	return buf;
1924*03f9172cSAndroid Build Coastguard Worker }
1925*03f9172cSAndroid Build Coastguard Worker 
1926*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_machine_password(const struct parse_data * data,struct wpa_ssid * ssid)1927*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_machine_password(const struct parse_data *data,
1928*03f9172cSAndroid Build Coastguard Worker 						struct wpa_ssid *ssid)
1929*03f9172cSAndroid Build Coastguard Worker {
1930*03f9172cSAndroid Build Coastguard Worker 	char *buf;
1931*03f9172cSAndroid Build Coastguard Worker 
1932*03f9172cSAndroid Build Coastguard Worker 	if (!ssid->eap.machine_password)
1933*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1934*03f9172cSAndroid Build Coastguard Worker 
1935*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_EXT_PASSWORD
1936*03f9172cSAndroid Build Coastguard Worker 	if (ssid->eap.flags & EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD) {
1937*03f9172cSAndroid Build Coastguard Worker 		buf = os_zalloc(4 + ssid->eap.machine_password_len + 1);
1938*03f9172cSAndroid Build Coastguard Worker 		if (!buf)
1939*03f9172cSAndroid Build Coastguard Worker 			return NULL;
1940*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(buf, "ext:", 4);
1941*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(buf + 4, ssid->eap.machine_password,
1942*03f9172cSAndroid Build Coastguard Worker 			  ssid->eap.machine_password_len);
1943*03f9172cSAndroid Build Coastguard Worker 		return buf;
1944*03f9172cSAndroid Build Coastguard Worker 	}
1945*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_EXT_PASSWORD */
1946*03f9172cSAndroid Build Coastguard Worker 
1947*03f9172cSAndroid Build Coastguard Worker 	if (!(ssid->eap.flags & EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH)) {
1948*03f9172cSAndroid Build Coastguard Worker 		return wpa_config_write_string(
1949*03f9172cSAndroid Build Coastguard Worker 			ssid->eap.machine_password,
1950*03f9172cSAndroid Build Coastguard Worker 			ssid->eap.machine_password_len);
1951*03f9172cSAndroid Build Coastguard Worker 	}
1952*03f9172cSAndroid Build Coastguard Worker 
1953*03f9172cSAndroid Build Coastguard Worker 	buf = os_malloc(5 + 32 + 1);
1954*03f9172cSAndroid Build Coastguard Worker 	if (!buf)
1955*03f9172cSAndroid Build Coastguard Worker 		return NULL;
1956*03f9172cSAndroid Build Coastguard Worker 
1957*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf, "hash:", 5);
1958*03f9172cSAndroid Build Coastguard Worker 	wpa_snprintf_hex(buf + 5, 32 + 1, ssid->eap.machine_password, 16);
1959*03f9172cSAndroid Build Coastguard Worker 
1960*03f9172cSAndroid Build Coastguard Worker 	return buf;
1961*03f9172cSAndroid Build Coastguard Worker }
1962*03f9172cSAndroid Build Coastguard Worker 
1963*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
1964*03f9172cSAndroid Build Coastguard Worker #endif /* IEEE8021X_EAPOL */
1965*03f9172cSAndroid Build Coastguard Worker 
1966*03f9172cSAndroid Build Coastguard Worker 
1967*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_WEP
1968*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_wep_key(u8 * key,size_t * len,int line,const char * value,int idx)1969*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line,
1970*03f9172cSAndroid Build Coastguard Worker 				    const char *value, int idx)
1971*03f9172cSAndroid Build Coastguard Worker {
1972*03f9172cSAndroid Build Coastguard Worker 	char *buf, title[20];
1973*03f9172cSAndroid Build Coastguard Worker 	int res;
1974*03f9172cSAndroid Build Coastguard Worker 
1975*03f9172cSAndroid Build Coastguard Worker 	buf = wpa_config_parse_string(value, len);
1976*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL) {
1977*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key %d '%s'.",
1978*03f9172cSAndroid Build Coastguard Worker 			   line, idx, value);
1979*03f9172cSAndroid Build Coastguard Worker 		return -1;
1980*03f9172cSAndroid Build Coastguard Worker 	}
1981*03f9172cSAndroid Build Coastguard Worker 	if (*len > MAX_WEP_KEY_LEN) {
1982*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Too long WEP key %d '%s'.",
1983*03f9172cSAndroid Build Coastguard Worker 			   line, idx, value);
1984*03f9172cSAndroid Build Coastguard Worker 		os_free(buf);
1985*03f9172cSAndroid Build Coastguard Worker 		return -1;
1986*03f9172cSAndroid Build Coastguard Worker 	}
1987*03f9172cSAndroid Build Coastguard Worker 	if (*len && *len != 5 && *len != 13 && *len != 16) {
1988*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key length %u - "
1989*03f9172cSAndroid Build Coastguard Worker 			   "this network block will be ignored",
1990*03f9172cSAndroid Build Coastguard Worker 			   line, (unsigned int) *len);
1991*03f9172cSAndroid Build Coastguard Worker 	}
1992*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(key, buf, *len);
1993*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(buf);
1994*03f9172cSAndroid Build Coastguard Worker 	res = os_snprintf(title, sizeof(title), "wep_key%d", idx);
1995*03f9172cSAndroid Build Coastguard Worker 	if (!os_snprintf_error(sizeof(title), res))
1996*03f9172cSAndroid Build Coastguard Worker 		wpa_hexdump_key(MSG_MSGDUMP, title, key, *len);
1997*03f9172cSAndroid Build Coastguard Worker 	return 0;
1998*03f9172cSAndroid Build Coastguard Worker }
1999*03f9172cSAndroid Build Coastguard Worker 
2000*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_wep_key0(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2001*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_wep_key0(const struct parse_data *data,
2002*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid, int line,
2003*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
2004*03f9172cSAndroid Build Coastguard Worker {
2005*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_wep_key(ssid->wep_key[0],
2006*03f9172cSAndroid Build Coastguard Worker 					&ssid->wep_key_len[0], line,
2007*03f9172cSAndroid Build Coastguard Worker 					value, 0);
2008*03f9172cSAndroid Build Coastguard Worker }
2009*03f9172cSAndroid Build Coastguard Worker 
2010*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_wep_key1(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2011*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_wep_key1(const struct parse_data *data,
2012*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid, int line,
2013*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
2014*03f9172cSAndroid Build Coastguard Worker {
2015*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_wep_key(ssid->wep_key[1],
2016*03f9172cSAndroid Build Coastguard Worker 					&ssid->wep_key_len[1], line,
2017*03f9172cSAndroid Build Coastguard Worker 					value, 1);
2018*03f9172cSAndroid Build Coastguard Worker }
2019*03f9172cSAndroid Build Coastguard Worker 
2020*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_wep_key2(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2021*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_wep_key2(const struct parse_data *data,
2022*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid, int line,
2023*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
2024*03f9172cSAndroid Build Coastguard Worker {
2025*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_wep_key(ssid->wep_key[2],
2026*03f9172cSAndroid Build Coastguard Worker 					&ssid->wep_key_len[2], line,
2027*03f9172cSAndroid Build Coastguard Worker 					value, 2);
2028*03f9172cSAndroid Build Coastguard Worker }
2029*03f9172cSAndroid Build Coastguard Worker 
2030*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_wep_key3(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2031*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_wep_key3(const struct parse_data *data,
2032*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid, int line,
2033*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
2034*03f9172cSAndroid Build Coastguard Worker {
2035*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_wep_key(ssid->wep_key[3],
2036*03f9172cSAndroid Build Coastguard Worker 					&ssid->wep_key_len[3], line,
2037*03f9172cSAndroid Build Coastguard Worker 					value, 3);
2038*03f9172cSAndroid Build Coastguard Worker }
2039*03f9172cSAndroid Build Coastguard Worker 
2040*03f9172cSAndroid Build Coastguard Worker 
2041*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_wep_key(struct wpa_ssid * ssid,int idx)2042*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx)
2043*03f9172cSAndroid Build Coastguard Worker {
2044*03f9172cSAndroid Build Coastguard Worker 	if (ssid->wep_key_len[idx] == 0)
2045*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2046*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_string(ssid->wep_key[idx],
2047*03f9172cSAndroid Build Coastguard Worker 				       ssid->wep_key_len[idx]);
2048*03f9172cSAndroid Build Coastguard Worker }
2049*03f9172cSAndroid Build Coastguard Worker 
2050*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_wep_key0(const struct parse_data * data,struct wpa_ssid * ssid)2051*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_wep_key0(const struct parse_data *data,
2052*03f9172cSAndroid Build Coastguard Worker 					struct wpa_ssid *ssid)
2053*03f9172cSAndroid Build Coastguard Worker {
2054*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_wep_key(ssid, 0);
2055*03f9172cSAndroid Build Coastguard Worker }
2056*03f9172cSAndroid Build Coastguard Worker 
2057*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_wep_key1(const struct parse_data * data,struct wpa_ssid * ssid)2058*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_wep_key1(const struct parse_data *data,
2059*03f9172cSAndroid Build Coastguard Worker 					struct wpa_ssid *ssid)
2060*03f9172cSAndroid Build Coastguard Worker {
2061*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_wep_key(ssid, 1);
2062*03f9172cSAndroid Build Coastguard Worker }
2063*03f9172cSAndroid Build Coastguard Worker 
2064*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_wep_key2(const struct parse_data * data,struct wpa_ssid * ssid)2065*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_wep_key2(const struct parse_data *data,
2066*03f9172cSAndroid Build Coastguard Worker 					struct wpa_ssid *ssid)
2067*03f9172cSAndroid Build Coastguard Worker {
2068*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_wep_key(ssid, 2);
2069*03f9172cSAndroid Build Coastguard Worker }
2070*03f9172cSAndroid Build Coastguard Worker 
2071*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_wep_key3(const struct parse_data * data,struct wpa_ssid * ssid)2072*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_wep_key3(const struct parse_data *data,
2073*03f9172cSAndroid Build Coastguard Worker 					struct wpa_ssid *ssid)
2074*03f9172cSAndroid Build Coastguard Worker {
2075*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_wep_key(ssid, 3);
2076*03f9172cSAndroid Build Coastguard Worker }
2077*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2078*03f9172cSAndroid Build Coastguard Worker 
2079*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_WEP */
2080*03f9172cSAndroid Build Coastguard Worker 
2081*03f9172cSAndroid Build Coastguard Worker 
2082*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_P2P
2083*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_go_p2p_dev_addr(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2084*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_go_p2p_dev_addr(const struct parse_data *data,
2085*03f9172cSAndroid Build Coastguard Worker 					    struct wpa_ssid *ssid, int line,
2086*03f9172cSAndroid Build Coastguard Worker 					    const char *value)
2087*03f9172cSAndroid Build Coastguard Worker {
2088*03f9172cSAndroid Build Coastguard Worker 	if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 ||
2089*03f9172cSAndroid Build Coastguard Worker 	    os_strcmp(value, "any") == 0) {
2090*03f9172cSAndroid Build Coastguard Worker 		os_memset(ssid->go_p2p_dev_addr, 0, ETH_ALEN);
2091*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_MSGDUMP, "GO P2P Device Address any");
2092*03f9172cSAndroid Build Coastguard Worker 		return 0;
2093*03f9172cSAndroid Build Coastguard Worker 	}
2094*03f9172cSAndroid Build Coastguard Worker 	if (hwaddr_aton(value, ssid->go_p2p_dev_addr)) {
2095*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid GO P2P Device Address '%s'.",
2096*03f9172cSAndroid Build Coastguard Worker 			   line, value);
2097*03f9172cSAndroid Build Coastguard Worker 		return -1;
2098*03f9172cSAndroid Build Coastguard Worker 	}
2099*03f9172cSAndroid Build Coastguard Worker 	ssid->bssid_set = 1;
2100*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_MSGDUMP, "GO P2P Device Address " MACSTR,
2101*03f9172cSAndroid Build Coastguard Worker 		   MAC2STR(ssid->go_p2p_dev_addr));
2102*03f9172cSAndroid Build Coastguard Worker 	return 0;
2103*03f9172cSAndroid Build Coastguard Worker }
2104*03f9172cSAndroid Build Coastguard Worker 
2105*03f9172cSAndroid Build Coastguard Worker 
2106*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_go_p2p_dev_addr(const struct parse_data * data,struct wpa_ssid * ssid)2107*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_go_p2p_dev_addr(const struct parse_data *data,
2108*03f9172cSAndroid Build Coastguard Worker 					       struct wpa_ssid *ssid)
2109*03f9172cSAndroid Build Coastguard Worker {
2110*03f9172cSAndroid Build Coastguard Worker 	char *value;
2111*03f9172cSAndroid Build Coastguard Worker 	int res;
2112*03f9172cSAndroid Build Coastguard Worker 
2113*03f9172cSAndroid Build Coastguard Worker 	if (is_zero_ether_addr(ssid->go_p2p_dev_addr))
2114*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2115*03f9172cSAndroid Build Coastguard Worker 
2116*03f9172cSAndroid Build Coastguard Worker 	value = os_malloc(20);
2117*03f9172cSAndroid Build Coastguard Worker 	if (value == NULL)
2118*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2119*03f9172cSAndroid Build Coastguard Worker 	res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->go_p2p_dev_addr));
2120*03f9172cSAndroid Build Coastguard Worker 	if (os_snprintf_error(20, res)) {
2121*03f9172cSAndroid Build Coastguard Worker 		os_free(value);
2122*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2123*03f9172cSAndroid Build Coastguard Worker 	}
2124*03f9172cSAndroid Build Coastguard Worker 	value[20 - 1] = '\0';
2125*03f9172cSAndroid Build Coastguard Worker 	return value;
2126*03f9172cSAndroid Build Coastguard Worker }
2127*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2128*03f9172cSAndroid Build Coastguard Worker 
2129*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_p2p_client_list(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2130*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_p2p_client_list(const struct parse_data *data,
2131*03f9172cSAndroid Build Coastguard Worker 					    struct wpa_ssid *ssid, int line,
2132*03f9172cSAndroid Build Coastguard Worker 					    const char *value)
2133*03f9172cSAndroid Build Coastguard Worker {
2134*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_parse_addr_list(data, line, value,
2135*03f9172cSAndroid Build Coastguard Worker 					  &ssid->p2p_client_list,
2136*03f9172cSAndroid Build Coastguard Worker 					  &ssid->num_p2p_clients,
2137*03f9172cSAndroid Build Coastguard Worker 					  "p2p_client_list", 0, 0);
2138*03f9172cSAndroid Build Coastguard Worker }
2139*03f9172cSAndroid Build Coastguard Worker 
2140*03f9172cSAndroid Build Coastguard Worker 
2141*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_p2p_client_list(const struct parse_data * data,struct wpa_ssid * ssid)2142*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
2143*03f9172cSAndroid Build Coastguard Worker 					       struct wpa_ssid *ssid)
2144*03f9172cSAndroid Build Coastguard Worker {
2145*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_addr_list(data, ssid->p2p_client_list,
2146*03f9172cSAndroid Build Coastguard Worker 					  ssid->num_p2p_clients,
2147*03f9172cSAndroid Build Coastguard Worker 					  "p2p_client_list");
2148*03f9172cSAndroid Build Coastguard Worker }
2149*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2150*03f9172cSAndroid Build Coastguard Worker 
2151*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_psk_list(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2152*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_psk_list(const struct parse_data *data,
2153*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_ssid *ssid, int line,
2154*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
2155*03f9172cSAndroid Build Coastguard Worker {
2156*03f9172cSAndroid Build Coastguard Worker 	struct psk_list_entry *p;
2157*03f9172cSAndroid Build Coastguard Worker 	const char *pos;
2158*03f9172cSAndroid Build Coastguard Worker 
2159*03f9172cSAndroid Build Coastguard Worker 	p = os_zalloc(sizeof(*p));
2160*03f9172cSAndroid Build Coastguard Worker 	if (p == NULL)
2161*03f9172cSAndroid Build Coastguard Worker 		return -1;
2162*03f9172cSAndroid Build Coastguard Worker 
2163*03f9172cSAndroid Build Coastguard Worker 	pos = value;
2164*03f9172cSAndroid Build Coastguard Worker 	if (os_strncmp(pos, "P2P-", 4) == 0) {
2165*03f9172cSAndroid Build Coastguard Worker 		p->p2p = 1;
2166*03f9172cSAndroid Build Coastguard Worker 		pos += 4;
2167*03f9172cSAndroid Build Coastguard Worker 	}
2168*03f9172cSAndroid Build Coastguard Worker 
2169*03f9172cSAndroid Build Coastguard Worker 	if (hwaddr_aton(pos, p->addr)) {
2170*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid psk_list address '%s'",
2171*03f9172cSAndroid Build Coastguard Worker 			   line, pos);
2172*03f9172cSAndroid Build Coastguard Worker 		os_free(p);
2173*03f9172cSAndroid Build Coastguard Worker 		return -1;
2174*03f9172cSAndroid Build Coastguard Worker 	}
2175*03f9172cSAndroid Build Coastguard Worker 	pos += 17;
2176*03f9172cSAndroid Build Coastguard Worker 	if (*pos != '-') {
2177*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid psk_list '%s'",
2178*03f9172cSAndroid Build Coastguard Worker 			   line, pos);
2179*03f9172cSAndroid Build Coastguard Worker 		os_free(p);
2180*03f9172cSAndroid Build Coastguard Worker 		return -1;
2181*03f9172cSAndroid Build Coastguard Worker 	}
2182*03f9172cSAndroid Build Coastguard Worker 	pos++;
2183*03f9172cSAndroid Build Coastguard Worker 
2184*03f9172cSAndroid Build Coastguard Worker 	if (hexstr2bin(pos, p->psk, PMK_LEN) || pos[PMK_LEN * 2] != '\0') {
2185*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid psk_list PSK '%s'",
2186*03f9172cSAndroid Build Coastguard Worker 			   line, pos);
2187*03f9172cSAndroid Build Coastguard Worker 		os_free(p);
2188*03f9172cSAndroid Build Coastguard Worker 		return -1;
2189*03f9172cSAndroid Build Coastguard Worker 	}
2190*03f9172cSAndroid Build Coastguard Worker 
2191*03f9172cSAndroid Build Coastguard Worker 	dl_list_add(&ssid->psk_list, &p->list);
2192*03f9172cSAndroid Build Coastguard Worker 
2193*03f9172cSAndroid Build Coastguard Worker 	return 0;
2194*03f9172cSAndroid Build Coastguard Worker }
2195*03f9172cSAndroid Build Coastguard Worker 
2196*03f9172cSAndroid Build Coastguard Worker 
2197*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_psk_list(const struct parse_data * data,struct wpa_ssid * ssid)2198*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_psk_list(const struct parse_data *data,
2199*03f9172cSAndroid Build Coastguard Worker 					struct wpa_ssid *ssid)
2200*03f9172cSAndroid Build Coastguard Worker {
2201*03f9172cSAndroid Build Coastguard Worker 	return NULL;
2202*03f9172cSAndroid Build Coastguard Worker }
2203*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2204*03f9172cSAndroid Build Coastguard Worker 
2205*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_P2P */
2206*03f9172cSAndroid Build Coastguard Worker 
2207*03f9172cSAndroid Build Coastguard Worker 
2208*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MESH
2209*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_mesh_basic_rates(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2210*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_mesh_basic_rates(const struct parse_data *data,
2211*03f9172cSAndroid Build Coastguard Worker 					     struct wpa_ssid *ssid, int line,
2212*03f9172cSAndroid Build Coastguard Worker 					     const char *value)
2213*03f9172cSAndroid Build Coastguard Worker {
2214*03f9172cSAndroid Build Coastguard Worker 	int *rates = wpa_config_parse_int_array(value);
2215*03f9172cSAndroid Build Coastguard Worker 
2216*03f9172cSAndroid Build Coastguard Worker 	if (rates == NULL) {
2217*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid mesh_basic_rates '%s'",
2218*03f9172cSAndroid Build Coastguard Worker 			   line, value);
2219*03f9172cSAndroid Build Coastguard Worker 		return -1;
2220*03f9172cSAndroid Build Coastguard Worker 	}
2221*03f9172cSAndroid Build Coastguard Worker 	if (rates[0] == 0) {
2222*03f9172cSAndroid Build Coastguard Worker 		os_free(rates);
2223*03f9172cSAndroid Build Coastguard Worker 		rates = NULL;
2224*03f9172cSAndroid Build Coastguard Worker 	}
2225*03f9172cSAndroid Build Coastguard Worker 
2226*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->mesh_basic_rates);
2227*03f9172cSAndroid Build Coastguard Worker 	ssid->mesh_basic_rates = rates;
2228*03f9172cSAndroid Build Coastguard Worker 
2229*03f9172cSAndroid Build Coastguard Worker 	return 0;
2230*03f9172cSAndroid Build Coastguard Worker }
2231*03f9172cSAndroid Build Coastguard Worker 
2232*03f9172cSAndroid Build Coastguard Worker 
2233*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
2234*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_mesh_basic_rates(const struct parse_data * data,struct wpa_ssid * ssid)2235*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_mesh_basic_rates(const struct parse_data *data,
2236*03f9172cSAndroid Build Coastguard Worker 						struct wpa_ssid *ssid)
2237*03f9172cSAndroid Build Coastguard Worker {
2238*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_freqs(data, ssid->mesh_basic_rates);
2239*03f9172cSAndroid Build Coastguard Worker }
2240*03f9172cSAndroid Build Coastguard Worker 
2241*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2242*03f9172cSAndroid Build Coastguard Worker 
2243*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MESH */
2244*03f9172cSAndroid Build Coastguard Worker 
2245*03f9172cSAndroid Build Coastguard Worker 
2246*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MACSEC
2247*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_mka_cak(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2248*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_mka_cak(const struct parse_data *data,
2249*03f9172cSAndroid Build Coastguard Worker 				    struct wpa_ssid *ssid, int line,
2250*03f9172cSAndroid Build Coastguard Worker 				    const char *value)
2251*03f9172cSAndroid Build Coastguard Worker {
2252*03f9172cSAndroid Build Coastguard Worker 	size_t len;
2253*03f9172cSAndroid Build Coastguard Worker 
2254*03f9172cSAndroid Build Coastguard Worker 	len = os_strlen(value);
2255*03f9172cSAndroid Build Coastguard Worker 	if (len > 2 * MACSEC_CAK_MAX_LEN ||
2256*03f9172cSAndroid Build Coastguard Worker 	    (len != 2 * 16 && len != 2 * 32) ||
2257*03f9172cSAndroid Build Coastguard Worker 	    hexstr2bin(value, ssid->mka_cak, len / 2)) {
2258*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CAK '%s'.",
2259*03f9172cSAndroid Build Coastguard Worker 			   line, value);
2260*03f9172cSAndroid Build Coastguard Worker 		return -1;
2261*03f9172cSAndroid Build Coastguard Worker 	}
2262*03f9172cSAndroid Build Coastguard Worker 	ssid->mka_cak_len = len / 2;
2263*03f9172cSAndroid Build Coastguard Worker 	ssid->mka_psk_set |= MKA_PSK_SET_CAK;
2264*03f9172cSAndroid Build Coastguard Worker 
2265*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump_key(MSG_MSGDUMP, "MKA-CAK", ssid->mka_cak,
2266*03f9172cSAndroid Build Coastguard Worker 			ssid->mka_cak_len);
2267*03f9172cSAndroid Build Coastguard Worker 	return 0;
2268*03f9172cSAndroid Build Coastguard Worker }
2269*03f9172cSAndroid Build Coastguard Worker 
2270*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_mka_ckn(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2271*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_mka_ckn(const struct parse_data *data,
2272*03f9172cSAndroid Build Coastguard Worker 				    struct wpa_ssid *ssid, int line,
2273*03f9172cSAndroid Build Coastguard Worker 				    const char *value)
2274*03f9172cSAndroid Build Coastguard Worker {
2275*03f9172cSAndroid Build Coastguard Worker 	size_t len;
2276*03f9172cSAndroid Build Coastguard Worker 
2277*03f9172cSAndroid Build Coastguard Worker 	len = os_strlen(value);
2278*03f9172cSAndroid Build Coastguard Worker 	if (len > 2 * MACSEC_CKN_MAX_LEN || /* too long */
2279*03f9172cSAndroid Build Coastguard Worker 	    len < 2 || /* too short */
2280*03f9172cSAndroid Build Coastguard Worker 	    len % 2 != 0 /* not an integral number of bytes */) {
2281*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CKN '%s'.",
2282*03f9172cSAndroid Build Coastguard Worker 			   line, value);
2283*03f9172cSAndroid Build Coastguard Worker 		return -1;
2284*03f9172cSAndroid Build Coastguard Worker 	}
2285*03f9172cSAndroid Build Coastguard Worker 	ssid->mka_ckn_len = len / 2;
2286*03f9172cSAndroid Build Coastguard Worker 	if (hexstr2bin(value, ssid->mka_ckn, ssid->mka_ckn_len)) {
2287*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CKN '%s'.",
2288*03f9172cSAndroid Build Coastguard Worker 			   line, value);
2289*03f9172cSAndroid Build Coastguard Worker 		return -1;
2290*03f9172cSAndroid Build Coastguard Worker 	}
2291*03f9172cSAndroid Build Coastguard Worker 
2292*03f9172cSAndroid Build Coastguard Worker 	ssid->mka_psk_set |= MKA_PSK_SET_CKN;
2293*03f9172cSAndroid Build Coastguard Worker 
2294*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump_key(MSG_MSGDUMP, "MKA-CKN", ssid->mka_ckn,
2295*03f9172cSAndroid Build Coastguard Worker 			ssid->mka_ckn_len);
2296*03f9172cSAndroid Build Coastguard Worker 	return 0;
2297*03f9172cSAndroid Build Coastguard Worker }
2298*03f9172cSAndroid Build Coastguard Worker 
2299*03f9172cSAndroid Build Coastguard Worker 
2300*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
2301*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_mka_cak(const struct parse_data * data,struct wpa_ssid * ssid)2302*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_mka_cak(const struct parse_data *data,
2303*03f9172cSAndroid Build Coastguard Worker 				       struct wpa_ssid *ssid)
2304*03f9172cSAndroid Build Coastguard Worker {
2305*03f9172cSAndroid Build Coastguard Worker 	if (!(ssid->mka_psk_set & MKA_PSK_SET_CAK))
2306*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2307*03f9172cSAndroid Build Coastguard Worker 
2308*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_string_hex(ssid->mka_cak, ssid->mka_cak_len);
2309*03f9172cSAndroid Build Coastguard Worker }
2310*03f9172cSAndroid Build Coastguard Worker 
2311*03f9172cSAndroid Build Coastguard Worker 
wpa_config_write_mka_ckn(const struct parse_data * data,struct wpa_ssid * ssid)2312*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_mka_ckn(const struct parse_data *data,
2313*03f9172cSAndroid Build Coastguard Worker 				       struct wpa_ssid *ssid)
2314*03f9172cSAndroid Build Coastguard Worker {
2315*03f9172cSAndroid Build Coastguard Worker 	if (!(ssid->mka_psk_set & MKA_PSK_SET_CKN))
2316*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2317*03f9172cSAndroid Build Coastguard Worker 	return wpa_config_write_string_hex(ssid->mka_ckn, ssid->mka_ckn_len);
2318*03f9172cSAndroid Build Coastguard Worker }
2319*03f9172cSAndroid Build Coastguard Worker 
2320*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2321*03f9172cSAndroid Build Coastguard Worker 
2322*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MACSEC */
2323*03f9172cSAndroid Build Coastguard Worker 
2324*03f9172cSAndroid Build Coastguard Worker 
2325*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_OCV
2326*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_ocv(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2327*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_ocv(const struct parse_data *data,
2328*03f9172cSAndroid Build Coastguard Worker 				struct wpa_ssid *ssid, int line,
2329*03f9172cSAndroid Build Coastguard Worker 				const char *value)
2330*03f9172cSAndroid Build Coastguard Worker {
2331*03f9172cSAndroid Build Coastguard Worker 	char *end;
2332*03f9172cSAndroid Build Coastguard Worker 
2333*03f9172cSAndroid Build Coastguard Worker 	ssid->ocv = strtol(value, &end, 0);
2334*03f9172cSAndroid Build Coastguard Worker 	if (*end || ssid->ocv < 0 || ssid->ocv > 1) {
2335*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid ocv value '%s'.",
2336*03f9172cSAndroid Build Coastguard Worker 			   line, value);
2337*03f9172cSAndroid Build Coastguard Worker 		return -1;
2338*03f9172cSAndroid Build Coastguard Worker 	}
2339*03f9172cSAndroid Build Coastguard Worker 	if (ssid->ocv && ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION)
2340*03f9172cSAndroid Build Coastguard Worker 		ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
2341*03f9172cSAndroid Build Coastguard Worker 	return 0;
2342*03f9172cSAndroid Build Coastguard Worker }
2343*03f9172cSAndroid Build Coastguard Worker 
2344*03f9172cSAndroid Build Coastguard Worker 
2345*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_ocv(const struct parse_data * data,struct wpa_ssid * ssid)2346*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_ocv(const struct parse_data *data,
2347*03f9172cSAndroid Build Coastguard Worker 				   struct wpa_ssid *ssid)
2348*03f9172cSAndroid Build Coastguard Worker {
2349*03f9172cSAndroid Build Coastguard Worker 	char *value = os_malloc(20);
2350*03f9172cSAndroid Build Coastguard Worker 
2351*03f9172cSAndroid Build Coastguard Worker 	if (!value)
2352*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2353*03f9172cSAndroid Build Coastguard Worker 	os_snprintf(value, 20, "%d", ssid->ocv);
2354*03f9172cSAndroid Build Coastguard Worker 	value[20 - 1] = '\0';
2355*03f9172cSAndroid Build Coastguard Worker 	return value;
2356*03f9172cSAndroid Build Coastguard Worker }
2357*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2358*03f9172cSAndroid Build Coastguard Worker 
2359*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_OCV */
2360*03f9172cSAndroid Build Coastguard Worker 
2361*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_peerkey(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2362*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_peerkey(const struct parse_data *data,
2363*03f9172cSAndroid Build Coastguard Worker 				    struct wpa_ssid *ssid, int line,
2364*03f9172cSAndroid Build Coastguard Worker 				    const char *value)
2365*03f9172cSAndroid Build Coastguard Worker {
2366*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_INFO, "NOTE: Obsolete peerkey parameter ignored");
2367*03f9172cSAndroid Build Coastguard Worker 	return 0;
2368*03f9172cSAndroid Build Coastguard Worker }
2369*03f9172cSAndroid Build Coastguard Worker 
2370*03f9172cSAndroid Build Coastguard Worker 
2371*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_peerkey(const struct parse_data * data,struct wpa_ssid * ssid)2372*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_peerkey(const struct parse_data *data,
2373*03f9172cSAndroid Build Coastguard Worker 				       struct wpa_ssid *ssid)
2374*03f9172cSAndroid Build Coastguard Worker {
2375*03f9172cSAndroid Build Coastguard Worker 	return NULL;
2376*03f9172cSAndroid Build Coastguard Worker }
2377*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2378*03f9172cSAndroid Build Coastguard Worker 
2379*03f9172cSAndroid Build Coastguard Worker 
wpa_config_parse_mac_value(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)2380*03f9172cSAndroid Build Coastguard Worker static int wpa_config_parse_mac_value(const struct parse_data *data,
2381*03f9172cSAndroid Build Coastguard Worker 				      struct wpa_ssid *ssid, int line,
2382*03f9172cSAndroid Build Coastguard Worker 				      const char *value)
2383*03f9172cSAndroid Build Coastguard Worker {
2384*03f9172cSAndroid Build Coastguard Worker 	u8 mac_value[ETH_ALEN];
2385*03f9172cSAndroid Build Coastguard Worker 
2386*03f9172cSAndroid Build Coastguard Worker 	if (hwaddr_aton(value, mac_value) == 0) {
2387*03f9172cSAndroid Build Coastguard Worker 		if (ether_addr_equal(mac_value, ssid->mac_value))
2388*03f9172cSAndroid Build Coastguard Worker 			return 1;
2389*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(ssid->mac_value, mac_value, ETH_ALEN);
2390*03f9172cSAndroid Build Coastguard Worker 		return 0;
2391*03f9172cSAndroid Build Coastguard Worker 	}
2392*03f9172cSAndroid Build Coastguard Worker 
2393*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_ERROR, "Line %d: Invalid MAC address '%s'",
2394*03f9172cSAndroid Build Coastguard Worker 		   line, value);
2395*03f9172cSAndroid Build Coastguard Worker 	return -1;
2396*03f9172cSAndroid Build Coastguard Worker }
2397*03f9172cSAndroid Build Coastguard Worker 
2398*03f9172cSAndroid Build Coastguard Worker 
2399*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
wpa_config_write_mac_value(const struct parse_data * data,struct wpa_ssid * ssid)2400*03f9172cSAndroid Build Coastguard Worker static char * wpa_config_write_mac_value(const struct parse_data *data,
2401*03f9172cSAndroid Build Coastguard Worker 					 struct wpa_ssid *ssid)
2402*03f9172cSAndroid Build Coastguard Worker {
2403*03f9172cSAndroid Build Coastguard Worker 	const size_t size = 3 * ETH_ALEN;
2404*03f9172cSAndroid Build Coastguard Worker 	char *value;
2405*03f9172cSAndroid Build Coastguard Worker 	int res;
2406*03f9172cSAndroid Build Coastguard Worker 
2407*03f9172cSAndroid Build Coastguard Worker 	if (ssid->mac_addr != WPAS_MAC_ADDR_STYLE_DEDICATED_PER_ESS)
2408*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2409*03f9172cSAndroid Build Coastguard Worker 
2410*03f9172cSAndroid Build Coastguard Worker 	value = os_malloc(size);
2411*03f9172cSAndroid Build Coastguard Worker 	if (!value)
2412*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2413*03f9172cSAndroid Build Coastguard Worker 	res = os_snprintf(value, size, MACSTR, MAC2STR(ssid->mac_value));
2414*03f9172cSAndroid Build Coastguard Worker 	if (os_snprintf_error(size, res)) {
2415*03f9172cSAndroid Build Coastguard Worker 		os_free(value);
2416*03f9172cSAndroid Build Coastguard Worker 		return NULL;
2417*03f9172cSAndroid Build Coastguard Worker 	}
2418*03f9172cSAndroid Build Coastguard Worker 	value[size - 1] = '\0';
2419*03f9172cSAndroid Build Coastguard Worker 	return value;
2420*03f9172cSAndroid Build Coastguard Worker }
2421*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2422*03f9172cSAndroid Build Coastguard Worker 
2423*03f9172cSAndroid Build Coastguard Worker 
2424*03f9172cSAndroid Build Coastguard Worker /* Helper macros for network block parser */
2425*03f9172cSAndroid Build Coastguard Worker 
2426*03f9172cSAndroid Build Coastguard Worker #ifdef OFFSET
2427*03f9172cSAndroid Build Coastguard Worker #undef OFFSET
2428*03f9172cSAndroid Build Coastguard Worker #endif /* OFFSET */
2429*03f9172cSAndroid Build Coastguard Worker /* OFFSET: Get offset of a variable within the wpa_ssid structure */
2430*03f9172cSAndroid Build Coastguard Worker #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
2431*03f9172cSAndroid Build Coastguard Worker 
2432*03f9172cSAndroid Build Coastguard Worker /* STR: Define a string variable for an ASCII string; f = field name */
2433*03f9172cSAndroid Build Coastguard Worker #ifdef NO_CONFIG_WRITE
2434*03f9172cSAndroid Build Coastguard Worker #define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
2435*03f9172cSAndroid Build Coastguard Worker #define _STRe(f, m) #f, wpa_config_parse_str, OFFSET(eap.m)
2436*03f9172cSAndroid Build Coastguard Worker #else /* NO_CONFIG_WRITE */
2437*03f9172cSAndroid Build Coastguard Worker #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
2438*03f9172cSAndroid Build Coastguard Worker #define _STRe(f, m) #f, wpa_config_parse_str, wpa_config_write_str, \
2439*03f9172cSAndroid Build Coastguard Worker 		OFFSET(eap.m)
2440*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2441*03f9172cSAndroid Build Coastguard Worker #define STR(f) _STR(f), NULL, NULL, NULL, 0
2442*03f9172cSAndroid Build Coastguard Worker #define STRe(f, m) _STRe(f, m), NULL, NULL, NULL, 0
2443*03f9172cSAndroid Build Coastguard Worker #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
2444*03f9172cSAndroid Build Coastguard Worker #define STR_KEYe(f, m) _STRe(f, m), NULL, NULL, NULL, 1
2445*03f9172cSAndroid Build Coastguard Worker 
2446*03f9172cSAndroid Build Coastguard Worker /* STR_LEN: Define a string variable with a separate variable for storing the
2447*03f9172cSAndroid Build Coastguard Worker  * data length. Unlike STR(), this can be used to store arbitrary binary data
2448*03f9172cSAndroid Build Coastguard Worker  * (i.e., even nul termination character). */
2449*03f9172cSAndroid Build Coastguard Worker #define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
2450*03f9172cSAndroid Build Coastguard Worker #define _STR_LENe(f, m) _STRe(f, m), OFFSET(eap.m ## _len)
2451*03f9172cSAndroid Build Coastguard Worker #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
2452*03f9172cSAndroid Build Coastguard Worker #define STR_LENe(f, m) _STR_LENe(f, m), NULL, NULL, 0
2453*03f9172cSAndroid Build Coastguard Worker #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
2454*03f9172cSAndroid Build Coastguard Worker 
2455*03f9172cSAndroid Build Coastguard Worker /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
2456*03f9172cSAndroid Build Coastguard Worker  * explicitly specified. */
2457*03f9172cSAndroid Build Coastguard Worker #define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max)
2458*03f9172cSAndroid Build Coastguard Worker #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
2459*03f9172cSAndroid Build Coastguard Worker #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
2460*03f9172cSAndroid Build Coastguard Worker 
2461*03f9172cSAndroid Build Coastguard Worker #ifdef NO_CONFIG_WRITE
2462*03f9172cSAndroid Build Coastguard Worker #define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
2463*03f9172cSAndroid Build Coastguard Worker #define _INTe(f, m) #f, wpa_config_parse_int, OFFSET(eap.m), (void *) 0
2464*03f9172cSAndroid Build Coastguard Worker #else /* NO_CONFIG_WRITE */
2465*03f9172cSAndroid Build Coastguard Worker #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
2466*03f9172cSAndroid Build Coastguard Worker 	OFFSET(f), (void *) 0
2467*03f9172cSAndroid Build Coastguard Worker #define _INTe(f, m) #f, wpa_config_parse_int, wpa_config_write_int,	\
2468*03f9172cSAndroid Build Coastguard Worker 	OFFSET(eap.m), (void *) 0
2469*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2470*03f9172cSAndroid Build Coastguard Worker 
2471*03f9172cSAndroid Build Coastguard Worker /* INT: Define an integer variable */
2472*03f9172cSAndroid Build Coastguard Worker #define INT(f) _INT(f), NULL, NULL, 0
2473*03f9172cSAndroid Build Coastguard Worker #define INTe(f, m) _INTe(f, m), NULL, NULL, 0
2474*03f9172cSAndroid Build Coastguard Worker 
2475*03f9172cSAndroid Build Coastguard Worker /* INT_RANGE: Define an integer variable with allowed value range */
2476*03f9172cSAndroid Build Coastguard Worker #ifdef NO_CONFIG_WRITE
2477*03f9172cSAndroid Build Coastguard Worker #define INT_RANGE(f, min, max) #f, wpa_config_parse_int_range, OFFSET(f), \
2478*03f9172cSAndroid Build Coastguard Worker 	(void *) 0, (void *) (min), (void *) (max), 0
2479*03f9172cSAndroid Build Coastguard Worker #else /* NO_CONFIG_WRITE */
2480*03f9172cSAndroid Build Coastguard Worker #define INT_RANGE(f, min, max) #f, wpa_config_parse_int_range, \
2481*03f9172cSAndroid Build Coastguard Worker 	wpa_config_write_int, OFFSET(f),	       \
2482*03f9172cSAndroid Build Coastguard Worker 	(void *) 0, (void *) (min), (void *) (max), 0
2483*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2484*03f9172cSAndroid Build Coastguard Worker 
2485*03f9172cSAndroid Build Coastguard Worker /* FUNC: Define a configuration variable that uses a custom function for
2486*03f9172cSAndroid Build Coastguard Worker  * parsing and writing the value. */
2487*03f9172cSAndroid Build Coastguard Worker #ifdef NO_CONFIG_WRITE
2488*03f9172cSAndroid Build Coastguard Worker #define _FUNC(f) #f, wpa_config_parse_ ## f, NULL, NULL, NULL, NULL
2489*03f9172cSAndroid Build Coastguard Worker #else /* NO_CONFIG_WRITE */
2490*03f9172cSAndroid Build Coastguard Worker #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
2491*03f9172cSAndroid Build Coastguard Worker 	NULL, NULL, NULL, NULL
2492*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
2493*03f9172cSAndroid Build Coastguard Worker #define FUNC(f) _FUNC(f), 0
2494*03f9172cSAndroid Build Coastguard Worker #define FUNC_KEY(f) _FUNC(f), 1
2495*03f9172cSAndroid Build Coastguard Worker 
2496*03f9172cSAndroid Build Coastguard Worker /*
2497*03f9172cSAndroid Build Coastguard Worker  * Table of network configuration variables. This table is used to parse each
2498*03f9172cSAndroid Build Coastguard Worker  * network configuration variable, e.g., each line in wpa_supplicant.conf file
2499*03f9172cSAndroid Build Coastguard Worker  * that is inside a network block.
2500*03f9172cSAndroid Build Coastguard Worker  *
2501*03f9172cSAndroid Build Coastguard Worker  * This table is generated using the helper macros defined above and with
2502*03f9172cSAndroid Build Coastguard Worker  * generous help from the C pre-processor. The field name is stored as a string
2503*03f9172cSAndroid Build Coastguard Worker  * into .name and for STR and INT types, the offset of the target buffer within
2504*03f9172cSAndroid Build Coastguard Worker  * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
2505*03f9172cSAndroid Build Coastguard Worker  * offset to the field containing the length of the configuration variable.
2506*03f9172cSAndroid Build Coastguard Worker  * .param3 and .param4 can be used to mark the allowed range (length for STR
2507*03f9172cSAndroid Build Coastguard Worker  * and value for INT).
2508*03f9172cSAndroid Build Coastguard Worker  *
2509*03f9172cSAndroid Build Coastguard Worker  * For each configuration line in wpa_supplicant.conf, the parser goes through
2510*03f9172cSAndroid Build Coastguard Worker  * this table and select the entry that matches with the field name. The parser
2511*03f9172cSAndroid Build Coastguard Worker  * function (.parser) is then called to parse the actual value of the field.
2512*03f9172cSAndroid Build Coastguard Worker  *
2513*03f9172cSAndroid Build Coastguard Worker  * This kind of mechanism makes it easy to add new configuration parameters,
2514*03f9172cSAndroid Build Coastguard Worker  * since only one line needs to be added into this table and into the
2515*03f9172cSAndroid Build Coastguard Worker  * struct wpa_ssid definition if the new variable is either a string or
2516*03f9172cSAndroid Build Coastguard Worker  * integer. More complex types will need to use their own parser and writer
2517*03f9172cSAndroid Build Coastguard Worker  * functions.
2518*03f9172cSAndroid Build Coastguard Worker  */
2519*03f9172cSAndroid Build Coastguard Worker static const struct parse_data ssid_fields[] = {
2520*03f9172cSAndroid Build Coastguard Worker 	{ STR_RANGE(ssid, 0, SSID_MAX_LEN) },
2521*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(scan_ssid, 0, 1) },
2522*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(bssid) },
2523*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(bssid_hint) },
2524*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(bssid_ignore) },
2525*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(bssid_accept) },
2526*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(bssid_blacklist) }, /* deprecated alias for bssid_ignore */
2527*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(bssid_whitelist) }, /* deprecated alias for bssid_accept */
2528*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(psk) },
2529*03f9172cSAndroid Build Coastguard Worker 	{ INT(mem_only_psk) },
2530*03f9172cSAndroid Build Coastguard Worker 	{ STR_KEY(sae_password) },
2531*03f9172cSAndroid Build Coastguard Worker 	{ STR(sae_password_id) },
2532*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(proto) },
2533*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(key_mgmt) },
2534*03f9172cSAndroid Build Coastguard Worker 	{ INT(bg_scan_period) },
2535*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(pairwise) },
2536*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(group) },
2537*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(group_mgmt) },
2538*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(auth_alg) },
2539*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(scan_freq) },
2540*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(freq_list) },
2541*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ht, 0, 1) },
2542*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht, 0, 1) },
2543*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(he, 0, 1) },
2544*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ht40, -1, 1) },
2545*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(max_oper_chwidth, CONF_OPER_CHWIDTH_USE_HT,
2546*03f9172cSAndroid Build Coastguard Worker 		    CONF_OPER_CHWIDTH_80P80MHZ) },
2547*03f9172cSAndroid Build Coastguard Worker 	{ INT(vht_center_freq1) },
2548*03f9172cSAndroid Build Coastguard Worker 	{ INT(vht_center_freq2) },
2549*03f9172cSAndroid Build Coastguard Worker #ifdef IEEE8021X_EAPOL
2550*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(eap) },
2551*03f9172cSAndroid Build Coastguard Worker 	{ STR_LENe(identity, identity) },
2552*03f9172cSAndroid Build Coastguard Worker 	{ STR_LENe(anonymous_identity, anonymous_identity) },
2553*03f9172cSAndroid Build Coastguard Worker 	{ STR_LENe(imsi_identity, imsi_identity) },
2554*03f9172cSAndroid Build Coastguard Worker 	{ STR_LENe(machine_identity, machine_identity) },
2555*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(password) },
2556*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(machine_password) },
2557*03f9172cSAndroid Build Coastguard Worker 	{ STRe(ca_cert, cert.ca_cert) },
2558*03f9172cSAndroid Build Coastguard Worker 	{ STRe(ca_path, cert.ca_path) },
2559*03f9172cSAndroid Build Coastguard Worker 	{ STRe(client_cert, cert.client_cert) },
2560*03f9172cSAndroid Build Coastguard Worker 	{ STRe(private_key, cert.private_key) },
2561*03f9172cSAndroid Build Coastguard Worker 	{ STR_KEYe(private_key_passwd, cert.private_key_passwd) },
2562*03f9172cSAndroid Build Coastguard Worker 	{ STRe(subject_match, cert.subject_match) },
2563*03f9172cSAndroid Build Coastguard Worker 	{ STRe(check_cert_subject, cert.check_cert_subject) },
2564*03f9172cSAndroid Build Coastguard Worker 	{ STRe(altsubject_match, cert.altsubject_match) },
2565*03f9172cSAndroid Build Coastguard Worker 	{ STRe(domain_suffix_match, cert.domain_suffix_match) },
2566*03f9172cSAndroid Build Coastguard Worker 	{ STRe(domain_match, cert.domain_match) },
2567*03f9172cSAndroid Build Coastguard Worker 	{ STRe(ca_cert2, phase2_cert.ca_cert) },
2568*03f9172cSAndroid Build Coastguard Worker 	{ STRe(ca_path2, phase2_cert.ca_path) },
2569*03f9172cSAndroid Build Coastguard Worker 	{ STRe(client_cert2, phase2_cert.client_cert) },
2570*03f9172cSAndroid Build Coastguard Worker 	{ STRe(private_key2, phase2_cert.private_key) },
2571*03f9172cSAndroid Build Coastguard Worker 	{ STR_KEYe(private_key2_passwd, phase2_cert.private_key_passwd) },
2572*03f9172cSAndroid Build Coastguard Worker 	{ STRe(subject_match2, phase2_cert.subject_match) },
2573*03f9172cSAndroid Build Coastguard Worker 	{ STRe(check_cert_subject2, phase2_cert.check_cert_subject) },
2574*03f9172cSAndroid Build Coastguard Worker 	{ STRe(altsubject_match2, phase2_cert.altsubject_match) },
2575*03f9172cSAndroid Build Coastguard Worker 	{ STRe(domain_suffix_match2, phase2_cert.domain_suffix_match) },
2576*03f9172cSAndroid Build Coastguard Worker 	{ STRe(domain_match2, phase2_cert.domain_match) },
2577*03f9172cSAndroid Build Coastguard Worker 	{ STRe(phase1, phase1) },
2578*03f9172cSAndroid Build Coastguard Worker 	{ STRe(phase2, phase2) },
2579*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_phase2, machine_phase2) },
2580*03f9172cSAndroid Build Coastguard Worker 	{ STRe(pcsc, pcsc) },
2581*03f9172cSAndroid Build Coastguard Worker 	{ STR_KEYe(pin, cert.pin) },
2582*03f9172cSAndroid Build Coastguard Worker 	{ STRe(engine_id, cert.engine_id) },
2583*03f9172cSAndroid Build Coastguard Worker 	{ STRe(key_id, cert.key_id) },
2584*03f9172cSAndroid Build Coastguard Worker 	{ STRe(cert_id, cert.cert_id) },
2585*03f9172cSAndroid Build Coastguard Worker 	{ STRe(ca_cert_id, cert.ca_cert_id) },
2586*03f9172cSAndroid Build Coastguard Worker 	{ STR_KEYe(pin2, phase2_cert.pin) },
2587*03f9172cSAndroid Build Coastguard Worker 	{ STRe(engine_id2, phase2_cert.engine_id) },
2588*03f9172cSAndroid Build Coastguard Worker 	{ STRe(key_id2, phase2_cert.key_id) },
2589*03f9172cSAndroid Build Coastguard Worker 	{ STRe(cert_id2, phase2_cert.cert_id) },
2590*03f9172cSAndroid Build Coastguard Worker 	{ STRe(ca_cert_id2, phase2_cert.ca_cert_id) },
2591*03f9172cSAndroid Build Coastguard Worker 	{ INTe(engine, cert.engine) },
2592*03f9172cSAndroid Build Coastguard Worker 	{ INTe(engine2, phase2_cert.engine) },
2593*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_ca_cert, machine_cert.ca_cert) },
2594*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_ca_path, machine_cert.ca_path) },
2595*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_client_cert, machine_cert.client_cert) },
2596*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_private_key, machine_cert.private_key) },
2597*03f9172cSAndroid Build Coastguard Worker 	{ STR_KEYe(machine_private_key_passwd,
2598*03f9172cSAndroid Build Coastguard Worker 		   machine_cert.private_key_passwd) },
2599*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_subject_match, machine_cert.subject_match) },
2600*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_check_cert_subject, machine_cert.check_cert_subject) },
2601*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_altsubject_match, machine_cert.altsubject_match) },
2602*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_domain_suffix_match,
2603*03f9172cSAndroid Build Coastguard Worker 	       machine_cert.domain_suffix_match) },
2604*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_domain_match, machine_cert.domain_match) },
2605*03f9172cSAndroid Build Coastguard Worker 	{ STR_KEYe(machine_pin, machine_cert.pin) },
2606*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_engine_id, machine_cert.engine_id) },
2607*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_key_id, machine_cert.key_id) },
2608*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_cert_id, machine_cert.cert_id) },
2609*03f9172cSAndroid Build Coastguard Worker 	{ STRe(machine_ca_cert_id, machine_cert.ca_cert_id) },
2610*03f9172cSAndroid Build Coastguard Worker 	{ INTe(machine_engine, machine_cert.engine) },
2611*03f9172cSAndroid Build Coastguard Worker 	{ INTe(machine_ocsp, machine_cert.ocsp) },
2612*03f9172cSAndroid Build Coastguard Worker 	{ INT(eapol_flags) },
2613*03f9172cSAndroid Build Coastguard Worker 	{ INTe(sim_num, sim_num) },
2614*03f9172cSAndroid Build Coastguard Worker 	{ STRe(imsi_privacy_cert, imsi_privacy_cert) },
2615*03f9172cSAndroid Build Coastguard Worker 	{ STRe(imsi_privacy_attr, imsi_privacy_attr) },
2616*03f9172cSAndroid Build Coastguard Worker 	{ INTe(strict_conservative_peer_mode, strict_conservative_peer_mode) },
2617*03f9172cSAndroid Build Coastguard Worker 	{ STRe(openssl_ciphers, openssl_ciphers) },
2618*03f9172cSAndroid Build Coastguard Worker 	{ INTe(erp, erp) },
2619*03f9172cSAndroid Build Coastguard Worker #endif /* IEEE8021X_EAPOL */
2620*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_WEP
2621*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(wep_key0) },
2622*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(wep_key1) },
2623*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(wep_key2) },
2624*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(wep_key3) },
2625*03f9172cSAndroid Build Coastguard Worker 	{ INT(wep_tx_keyidx) },
2626*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_WEP */
2627*03f9172cSAndroid Build Coastguard Worker 	{ INT(priority) },
2628*03f9172cSAndroid Build Coastguard Worker #ifdef IEEE8021X_EAPOL
2629*03f9172cSAndroid Build Coastguard Worker 	{ INT(eap_workaround) },
2630*03f9172cSAndroid Build Coastguard Worker 	{ STRe(pac_file, pac_file) },
2631*03f9172cSAndroid Build Coastguard Worker 	{ INTe(fragment_size, fragment_size) },
2632*03f9172cSAndroid Build Coastguard Worker 	{ INTe(ocsp, cert.ocsp) },
2633*03f9172cSAndroid Build Coastguard Worker 	{ INTe(ocsp2, phase2_cert.ocsp) },
2634*03f9172cSAndroid Build Coastguard Worker #endif /* IEEE8021X_EAPOL */
2635*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MESH
2636*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mode, 0, 5) },
2637*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(no_auto_peer, 0, 1) },
2638*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mesh_fwding, 0, 1) },
2639*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mesh_rssi_threshold, -255, 1) },
2640*03f9172cSAndroid Build Coastguard Worker #else /* CONFIG_MESH */
2641*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mode, 0, 4) },
2642*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MESH */
2643*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(proactive_key_caching, 0, 1) },
2644*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disabled, 0, 2) },
2645*03f9172cSAndroid Build Coastguard Worker 	{ STR(id_str) },
2646*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ieee80211w, 0, 2) },
2647*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_OCV
2648*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(ocv) },
2649*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_OCV */
2650*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(peerkey) /* obsolete - removed */ },
2651*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mixed_cell, 0, 1) },
2652*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(frequency, 0, 70200) },
2653*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(fixed_freq, 0, 1) },
2654*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(enable_edmg, 0, 1) },
2655*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(edmg_channel, 9, 13) },
2656*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_ACS
2657*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(acs, 0, 1) },
2658*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_ACS */
2659*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MESH
2660*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(mesh_basic_rates) },
2661*03f9172cSAndroid Build Coastguard Worker 	{ INT(dot11MeshMaxRetries) },
2662*03f9172cSAndroid Build Coastguard Worker 	{ INT(dot11MeshRetryTimeout) },
2663*03f9172cSAndroid Build Coastguard Worker 	{ INT(dot11MeshConfirmTimeout) },
2664*03f9172cSAndroid Build Coastguard Worker 	{ INT(dot11MeshHoldingTimeout) },
2665*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MESH */
2666*03f9172cSAndroid Build Coastguard Worker 	{ INT(wpa_ptk_rekey) },
2667*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(wpa_deny_ptk0_rekey, 0, 2) },
2668*03f9172cSAndroid Build Coastguard Worker 	{ INT(group_rekey) },
2669*03f9172cSAndroid Build Coastguard Worker 	{ STR(bgscan) },
2670*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ignore_broadcast_ssid, 0, 2) },
2671*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_P2P
2672*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(go_p2p_dev_addr) },
2673*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(p2p_client_list) },
2674*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(psk_list) },
2675*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_P2P */
2676*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_HT_OVERRIDES
2677*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disable_ht, 0, 1) },
2678*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disable_ht40, 0, 1) },
2679*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disable_sgi, 0, 1) },
2680*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disable_ldpc, 0, 1) },
2681*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ht40_intolerant, 0, 1) },
2682*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(tx_stbc, -1, 1) },
2683*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(rx_stbc, -1, 3) },
2684*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disable_max_amsdu, -1, 1) },
2685*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ampdu_factor, -1, 3) },
2686*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ampdu_density, -1, 7) },
2687*03f9172cSAndroid Build Coastguard Worker 	{ STR(ht_mcs) },
2688*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_HT_OVERRIDES */
2689*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_VHT_OVERRIDES
2690*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disable_vht, 0, 1) },
2691*03f9172cSAndroid Build Coastguard Worker 	{ INT(vht_capa) },
2692*03f9172cSAndroid Build Coastguard Worker 	{ INT(vht_capa_mask) },
2693*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_rx_mcs_nss_1, -1, 3) },
2694*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_rx_mcs_nss_2, -1, 3) },
2695*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_rx_mcs_nss_3, -1, 3) },
2696*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_rx_mcs_nss_4, -1, 3) },
2697*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_rx_mcs_nss_5, -1, 3) },
2698*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_rx_mcs_nss_6, -1, 3) },
2699*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_rx_mcs_nss_7, -1, 3) },
2700*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_rx_mcs_nss_8, -1, 3) },
2701*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_tx_mcs_nss_1, -1, 3) },
2702*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_tx_mcs_nss_2, -1, 3) },
2703*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_tx_mcs_nss_3, -1, 3) },
2704*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_tx_mcs_nss_4, -1, 3) },
2705*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_tx_mcs_nss_5, -1, 3) },
2706*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_tx_mcs_nss_6, -1, 3) },
2707*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_tx_mcs_nss_7, -1, 3) },
2708*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(vht_tx_mcs_nss_8, -1, 3) },
2709*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_VHT_OVERRIDES */
2710*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_HE_OVERRIDES
2711*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disable_he, 0, 1)},
2712*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_HE_OVERRIDES */
2713*03f9172cSAndroid Build Coastguard Worker 	{ INT(ap_max_inactivity) },
2714*03f9172cSAndroid Build Coastguard Worker 	{ INT(dtim_period) },
2715*03f9172cSAndroid Build Coastguard Worker 	{ INT(beacon_int) },
2716*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MACSEC
2717*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(macsec_policy, 0, 1) },
2718*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(macsec_integ_only, 0, 1) },
2719*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(macsec_replay_protect, 0, 1) },
2720*03f9172cSAndroid Build Coastguard Worker 	{ INT(macsec_replay_window) },
2721*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(macsec_offload, 0, 2) },
2722*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(macsec_port, 1, 65534) },
2723*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mka_priority, 0, 255) },
2724*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(macsec_csindex, 0, 1) },
2725*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(mka_cak) },
2726*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(mka_ckn) },
2727*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MACSEC */
2728*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_HS20
2729*03f9172cSAndroid Build Coastguard Worker 	{ INT(update_identifier) },
2730*03f9172cSAndroid Build Coastguard Worker 	{ STR_RANGE(roaming_consortium_selection, 0, MAX_ROAMING_CONS_OI_LEN) },
2731*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_HS20 */
2732*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mac_addr, 0, 3) },
2733*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_KEY(mac_value) },
2734*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(pbss, 0, 2) },
2735*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(wps_disabled, 0, 1) },
2736*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(fils_dh_group, 0, 65535) },
2737*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_DPP
2738*03f9172cSAndroid Build Coastguard Worker 	{ STR(dpp_connector) },
2739*03f9172cSAndroid Build Coastguard Worker 	{ STR_LEN(dpp_netaccesskey) },
2740*03f9172cSAndroid Build Coastguard Worker 	{ INT(dpp_netaccesskey_expiry) },
2741*03f9172cSAndroid Build Coastguard Worker 	{ STR_LEN(dpp_csign) },
2742*03f9172cSAndroid Build Coastguard Worker 	{ STR_LEN(dpp_pp_key) },
2743*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(dpp_pfs, 0, 2) },
2744*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(dpp_connector_privacy, 0, 1) },
2745*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_DPP */
2746*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(owe_group, 0, 65535) },
2747*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(owe_only, 0, 1) },
2748*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(owe_ptk_workaround, 0, 1) },
2749*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(multi_ap_backhaul_sta, 0, 1) },
2750*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ft_eap_pmksa_caching, 0, 1) },
2751*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(multi_ap_profile, MULTI_AP_PROFILE_1,
2752*03f9172cSAndroid Build Coastguard Worker 		    MULTI_AP_PROFILE_MAX) },
2753*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(beacon_prot, 0, 1) },
2754*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(transition_disable, 0, 255) },
2755*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(sae_pk, 0, 2) },
2756*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disable_eht, 0, 1)},
2757*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(enable_4addr_mode, 0, 1)},
2758*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(max_idle, 0, 65535)},
2759*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ssid_protection, 0, 1)},
2760*03f9172cSAndroid Build Coastguard Worker };
2761*03f9172cSAndroid Build Coastguard Worker 
2762*03f9172cSAndroid Build Coastguard Worker #undef OFFSET
2763*03f9172cSAndroid Build Coastguard Worker #undef _STR
2764*03f9172cSAndroid Build Coastguard Worker #undef STR
2765*03f9172cSAndroid Build Coastguard Worker #undef STR_KEY
2766*03f9172cSAndroid Build Coastguard Worker #undef _STR_LEN
2767*03f9172cSAndroid Build Coastguard Worker #undef STR_LEN
2768*03f9172cSAndroid Build Coastguard Worker #undef STR_LEN_KEY
2769*03f9172cSAndroid Build Coastguard Worker #undef _STR_RANGE
2770*03f9172cSAndroid Build Coastguard Worker #undef STR_RANGE
2771*03f9172cSAndroid Build Coastguard Worker #undef STR_RANGE_KEY
2772*03f9172cSAndroid Build Coastguard Worker #undef _INT
2773*03f9172cSAndroid Build Coastguard Worker #undef INT
2774*03f9172cSAndroid Build Coastguard Worker #undef INT_RANGE
2775*03f9172cSAndroid Build Coastguard Worker #undef _FUNC
2776*03f9172cSAndroid Build Coastguard Worker #undef FUNC
2777*03f9172cSAndroid Build Coastguard Worker #undef FUNC_KEY
2778*03f9172cSAndroid Build Coastguard Worker #define NUM_SSID_FIELDS ARRAY_SIZE(ssid_fields)
2779*03f9172cSAndroid Build Coastguard Worker 
2780*03f9172cSAndroid Build Coastguard Worker 
2781*03f9172cSAndroid Build Coastguard Worker /**
2782*03f9172cSAndroid Build Coastguard Worker  * wpa_config_add_prio_network - Add a network to priority lists
2783*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
2784*03f9172cSAndroid Build Coastguard Worker  * @ssid: Pointer to the network configuration to be added to the list
2785*03f9172cSAndroid Build Coastguard Worker  * Returns: 0 on success, -1 on failure
2786*03f9172cSAndroid Build Coastguard Worker  *
2787*03f9172cSAndroid Build Coastguard Worker  * This function is used to add a network block to the priority list of
2788*03f9172cSAndroid Build Coastguard Worker  * networks. This must be called for each network when reading in the full
2789*03f9172cSAndroid Build Coastguard Worker  * configuration. In addition, this can be used indirectly when updating
2790*03f9172cSAndroid Build Coastguard Worker  * priorities by calling wpa_config_update_prio_list().
2791*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_add_prio_network(struct wpa_config * config,struct wpa_ssid * ssid)2792*03f9172cSAndroid Build Coastguard Worker int wpa_config_add_prio_network(struct wpa_config *config,
2793*03f9172cSAndroid Build Coastguard Worker 				struct wpa_ssid *ssid)
2794*03f9172cSAndroid Build Coastguard Worker {
2795*03f9172cSAndroid Build Coastguard Worker 	size_t prio;
2796*03f9172cSAndroid Build Coastguard Worker 	struct wpa_ssid *prev, **nlist;
2797*03f9172cSAndroid Build Coastguard Worker 
2798*03f9172cSAndroid Build Coastguard Worker 	/*
2799*03f9172cSAndroid Build Coastguard Worker 	 * Add to an existing priority list if one is available for the
2800*03f9172cSAndroid Build Coastguard Worker 	 * configured priority level for this network.
2801*03f9172cSAndroid Build Coastguard Worker 	 */
2802*03f9172cSAndroid Build Coastguard Worker 	for (prio = 0; prio < config->num_prio; prio++) {
2803*03f9172cSAndroid Build Coastguard Worker 		prev = config->pssid[prio];
2804*03f9172cSAndroid Build Coastguard Worker 		if (prev->priority == ssid->priority) {
2805*03f9172cSAndroid Build Coastguard Worker 			while (prev->pnext)
2806*03f9172cSAndroid Build Coastguard Worker 				prev = prev->pnext;
2807*03f9172cSAndroid Build Coastguard Worker 			prev->pnext = ssid;
2808*03f9172cSAndroid Build Coastguard Worker 			return 0;
2809*03f9172cSAndroid Build Coastguard Worker 		}
2810*03f9172cSAndroid Build Coastguard Worker 	}
2811*03f9172cSAndroid Build Coastguard Worker 
2812*03f9172cSAndroid Build Coastguard Worker 	/* First network for this priority - add a new priority list */
2813*03f9172cSAndroid Build Coastguard Worker 	nlist = os_realloc_array(config->pssid, config->num_prio + 1,
2814*03f9172cSAndroid Build Coastguard Worker 				 sizeof(struct wpa_ssid *));
2815*03f9172cSAndroid Build Coastguard Worker 	if (nlist == NULL)
2816*03f9172cSAndroid Build Coastguard Worker 		return -1;
2817*03f9172cSAndroid Build Coastguard Worker 
2818*03f9172cSAndroid Build Coastguard Worker 	for (prio = 0; prio < config->num_prio; prio++) {
2819*03f9172cSAndroid Build Coastguard Worker 		if (nlist[prio]->priority < ssid->priority) {
2820*03f9172cSAndroid Build Coastguard Worker 			os_memmove(&nlist[prio + 1], &nlist[prio],
2821*03f9172cSAndroid Build Coastguard Worker 				   (config->num_prio - prio) *
2822*03f9172cSAndroid Build Coastguard Worker 				   sizeof(struct wpa_ssid *));
2823*03f9172cSAndroid Build Coastguard Worker 			break;
2824*03f9172cSAndroid Build Coastguard Worker 		}
2825*03f9172cSAndroid Build Coastguard Worker 	}
2826*03f9172cSAndroid Build Coastguard Worker 
2827*03f9172cSAndroid Build Coastguard Worker 	nlist[prio] = ssid;
2828*03f9172cSAndroid Build Coastguard Worker 	config->num_prio++;
2829*03f9172cSAndroid Build Coastguard Worker 	config->pssid = nlist;
2830*03f9172cSAndroid Build Coastguard Worker 
2831*03f9172cSAndroid Build Coastguard Worker 	return 0;
2832*03f9172cSAndroid Build Coastguard Worker }
2833*03f9172cSAndroid Build Coastguard Worker 
2834*03f9172cSAndroid Build Coastguard Worker 
2835*03f9172cSAndroid Build Coastguard Worker /**
2836*03f9172cSAndroid Build Coastguard Worker  * wpa_config_update_prio_list - Update network priority list
2837*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
2838*03f9172cSAndroid Build Coastguard Worker  * Returns: 0 on success, -1 on failure
2839*03f9172cSAndroid Build Coastguard Worker  *
2840*03f9172cSAndroid Build Coastguard Worker  * This function is called to update the priority list of networks in the
2841*03f9172cSAndroid Build Coastguard Worker  * configuration when a network is being added or removed. This is also called
2842*03f9172cSAndroid Build Coastguard Worker  * if a priority for a network is changed.
2843*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_update_prio_list(struct wpa_config * config)2844*03f9172cSAndroid Build Coastguard Worker int wpa_config_update_prio_list(struct wpa_config *config)
2845*03f9172cSAndroid Build Coastguard Worker {
2846*03f9172cSAndroid Build Coastguard Worker 	struct wpa_ssid *ssid;
2847*03f9172cSAndroid Build Coastguard Worker 	int ret = 0;
2848*03f9172cSAndroid Build Coastguard Worker 
2849*03f9172cSAndroid Build Coastguard Worker 	os_free(config->pssid);
2850*03f9172cSAndroid Build Coastguard Worker 	config->pssid = NULL;
2851*03f9172cSAndroid Build Coastguard Worker 	config->num_prio = 0;
2852*03f9172cSAndroid Build Coastguard Worker 
2853*03f9172cSAndroid Build Coastguard Worker 	ssid = config->ssid;
2854*03f9172cSAndroid Build Coastguard Worker 	while (ssid) {
2855*03f9172cSAndroid Build Coastguard Worker 		ssid->pnext = NULL;
2856*03f9172cSAndroid Build Coastguard Worker 		if (wpa_config_add_prio_network(config, ssid) < 0)
2857*03f9172cSAndroid Build Coastguard Worker 			ret = -1;
2858*03f9172cSAndroid Build Coastguard Worker 		ssid = ssid->next;
2859*03f9172cSAndroid Build Coastguard Worker 	}
2860*03f9172cSAndroid Build Coastguard Worker 
2861*03f9172cSAndroid Build Coastguard Worker 	return ret;
2862*03f9172cSAndroid Build Coastguard Worker }
2863*03f9172cSAndroid Build Coastguard Worker 
2864*03f9172cSAndroid Build Coastguard Worker 
2865*03f9172cSAndroid Build Coastguard Worker #ifdef IEEE8021X_EAPOL
2866*03f9172cSAndroid Build Coastguard Worker 
eap_peer_config_free_cert(struct eap_peer_cert_config * cert)2867*03f9172cSAndroid Build Coastguard Worker static void eap_peer_config_free_cert(struct eap_peer_cert_config *cert)
2868*03f9172cSAndroid Build Coastguard Worker {
2869*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->ca_cert);
2870*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->ca_path);
2871*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->client_cert);
2872*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->private_key);
2873*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(cert->private_key_passwd);
2874*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->subject_match);
2875*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->check_cert_subject);
2876*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->altsubject_match);
2877*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->domain_suffix_match);
2878*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->domain_match);
2879*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(cert->pin);
2880*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->engine_id);
2881*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->key_id);
2882*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->cert_id);
2883*03f9172cSAndroid Build Coastguard Worker 	os_free(cert->ca_cert_id);
2884*03f9172cSAndroid Build Coastguard Worker }
2885*03f9172cSAndroid Build Coastguard Worker 
2886*03f9172cSAndroid Build Coastguard Worker 
eap_peer_config_free(struct eap_peer_config * eap)2887*03f9172cSAndroid Build Coastguard Worker static void eap_peer_config_free(struct eap_peer_config *eap)
2888*03f9172cSAndroid Build Coastguard Worker {
2889*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->eap_methods);
2890*03f9172cSAndroid Build Coastguard Worker 	bin_clear_free(eap->identity, eap->identity_len);
2891*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->anonymous_identity);
2892*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->imsi_identity);
2893*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->imsi_privacy_cert);
2894*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->imsi_privacy_attr);
2895*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->machine_identity);
2896*03f9172cSAndroid Build Coastguard Worker 	bin_clear_free(eap->password, eap->password_len);
2897*03f9172cSAndroid Build Coastguard Worker 	bin_clear_free(eap->machine_password, eap->machine_password_len);
2898*03f9172cSAndroid Build Coastguard Worker 	eap_peer_config_free_cert(&eap->cert);
2899*03f9172cSAndroid Build Coastguard Worker 	eap_peer_config_free_cert(&eap->phase2_cert);
2900*03f9172cSAndroid Build Coastguard Worker 	eap_peer_config_free_cert(&eap->machine_cert);
2901*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->phase1);
2902*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->phase2);
2903*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->machine_phase2);
2904*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->pcsc);
2905*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->otp);
2906*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->pending_req_otp);
2907*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->pac_file);
2908*03f9172cSAndroid Build Coastguard Worker 	bin_clear_free(eap->new_password, eap->new_password_len);
2909*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(eap->external_sim_resp);
2910*03f9172cSAndroid Build Coastguard Worker 	os_free(eap->openssl_ciphers);
2911*03f9172cSAndroid Build Coastguard Worker }
2912*03f9172cSAndroid Build Coastguard Worker 
2913*03f9172cSAndroid Build Coastguard Worker #endif /* IEEE8021X_EAPOL */
2914*03f9172cSAndroid Build Coastguard Worker 
2915*03f9172cSAndroid Build Coastguard Worker 
2916*03f9172cSAndroid Build Coastguard Worker /**
2917*03f9172cSAndroid Build Coastguard Worker  * wpa_config_free_ssid - Free network/ssid configuration data
2918*03f9172cSAndroid Build Coastguard Worker  * @ssid: Configuration data for the network
2919*03f9172cSAndroid Build Coastguard Worker  *
2920*03f9172cSAndroid Build Coastguard Worker  * This function frees all resources allocated for the network configuration
2921*03f9172cSAndroid Build Coastguard Worker  * data.
2922*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_free_ssid(struct wpa_ssid * ssid)2923*03f9172cSAndroid Build Coastguard Worker void wpa_config_free_ssid(struct wpa_ssid *ssid)
2924*03f9172cSAndroid Build Coastguard Worker {
2925*03f9172cSAndroid Build Coastguard Worker 	struct psk_list_entry *psk;
2926*03f9172cSAndroid Build Coastguard Worker 
2927*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->ssid);
2928*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(ssid->passphrase);
2929*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->ext_psk);
2930*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(ssid->sae_password);
2931*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->sae_password_id);
2932*03f9172cSAndroid Build Coastguard Worker #ifdef IEEE8021X_EAPOL
2933*03f9172cSAndroid Build Coastguard Worker 	eap_peer_config_free(&ssid->eap);
2934*03f9172cSAndroid Build Coastguard Worker #endif /* IEEE8021X_EAPOL */
2935*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->id_str);
2936*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->scan_freq);
2937*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->freq_list);
2938*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->bgscan);
2939*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->p2p_client_list);
2940*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->bssid_ignore);
2941*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->bssid_accept);
2942*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_HT_OVERRIDES
2943*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->ht_mcs);
2944*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_HT_OVERRIDES */
2945*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MESH
2946*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->mesh_basic_rates);
2947*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MESH */
2948*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_HS20
2949*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->roaming_consortium_selection);
2950*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_HS20 */
2951*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->dpp_connector);
2952*03f9172cSAndroid Build Coastguard Worker 	bin_clear_free(ssid->dpp_netaccesskey, ssid->dpp_netaccesskey_len);
2953*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->dpp_csign);
2954*03f9172cSAndroid Build Coastguard Worker 	os_free(ssid->dpp_pp_key);
2955*03f9172cSAndroid Build Coastguard Worker 	while ((psk = dl_list_first(&ssid->psk_list, struct psk_list_entry,
2956*03f9172cSAndroid Build Coastguard Worker 				    list))) {
2957*03f9172cSAndroid Build Coastguard Worker 		dl_list_del(&psk->list);
2958*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(psk, sizeof(*psk));
2959*03f9172cSAndroid Build Coastguard Worker 	}
2960*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SAE
2961*03f9172cSAndroid Build Coastguard Worker 	sae_deinit_pt(ssid->pt);
2962*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SAE */
2963*03f9172cSAndroid Build Coastguard Worker 	bin_clear_free(ssid, sizeof(*ssid));
2964*03f9172cSAndroid Build Coastguard Worker }
2965*03f9172cSAndroid Build Coastguard Worker 
2966*03f9172cSAndroid Build Coastguard Worker 
wpa_config_free_cred(struct wpa_cred * cred)2967*03f9172cSAndroid Build Coastguard Worker void wpa_config_free_cred(struct wpa_cred *cred)
2968*03f9172cSAndroid Build Coastguard Worker {
2969*03f9172cSAndroid Build Coastguard Worker 	size_t i;
2970*03f9172cSAndroid Build Coastguard Worker 
2971*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->realm);
2972*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(cred->username);
2973*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(cred->password);
2974*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->ca_cert);
2975*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->client_cert);
2976*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->private_key);
2977*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(cred->private_key_passwd);
2978*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->engine_id);
2979*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->ca_cert_id);
2980*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->cert_id);
2981*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->key_id);
2982*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->imsi);
2983*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(cred->milenage);
2984*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < cred->num_domain; i++)
2985*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->domain[i]);
2986*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->domain);
2987*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->domain_suffix_match);
2988*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->eap_method);
2989*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->phase1);
2990*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->phase2);
2991*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->excluded_ssid);
2992*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->roaming_partner);
2993*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->provisioning_sp);
2994*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < cred->num_req_conn_capab; i++)
2995*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->req_conn_capab_port[i]);
2996*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->req_conn_capab_port);
2997*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->req_conn_capab_proto);
2998*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->imsi_privacy_cert);
2999*03f9172cSAndroid Build Coastguard Worker 	os_free(cred->imsi_privacy_attr);
3000*03f9172cSAndroid Build Coastguard Worker 	os_free(cred);
3001*03f9172cSAndroid Build Coastguard Worker }
3002*03f9172cSAndroid Build Coastguard Worker 
3003*03f9172cSAndroid Build Coastguard Worker 
wpa_config_flush_blobs(struct wpa_config * config)3004*03f9172cSAndroid Build Coastguard Worker void wpa_config_flush_blobs(struct wpa_config *config)
3005*03f9172cSAndroid Build Coastguard Worker {
3006*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_NO_CONFIG_BLOBS
3007*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config_blob *blob, *prev;
3008*03f9172cSAndroid Build Coastguard Worker 
3009*03f9172cSAndroid Build Coastguard Worker 	blob = config->blobs;
3010*03f9172cSAndroid Build Coastguard Worker 	config->blobs = NULL;
3011*03f9172cSAndroid Build Coastguard Worker 	while (blob) {
3012*03f9172cSAndroid Build Coastguard Worker 		prev = blob;
3013*03f9172cSAndroid Build Coastguard Worker 		blob = blob->next;
3014*03f9172cSAndroid Build Coastguard Worker 		wpa_config_free_blob(prev);
3015*03f9172cSAndroid Build Coastguard Worker 	}
3016*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_CONFIG_BLOBS */
3017*03f9172cSAndroid Build Coastguard Worker }
3018*03f9172cSAndroid Build Coastguard Worker 
3019*03f9172cSAndroid Build Coastguard Worker 
3020*03f9172cSAndroid Build Coastguard Worker /**
3021*03f9172cSAndroid Build Coastguard Worker  * wpa_config_free - Free configuration data
3022*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
3023*03f9172cSAndroid Build Coastguard Worker  *
3024*03f9172cSAndroid Build Coastguard Worker  * This function frees all resources allocated for the configuration data by
3025*03f9172cSAndroid Build Coastguard Worker  * wpa_config_read().
3026*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_free(struct wpa_config * config)3027*03f9172cSAndroid Build Coastguard Worker void wpa_config_free(struct wpa_config *config)
3028*03f9172cSAndroid Build Coastguard Worker {
3029*03f9172cSAndroid Build Coastguard Worker 	struct wpa_ssid *ssid, *prev = NULL;
3030*03f9172cSAndroid Build Coastguard Worker 	struct wpa_cred *cred, *cprev;
3031*03f9172cSAndroid Build Coastguard Worker 	int i;
3032*03f9172cSAndroid Build Coastguard Worker 
3033*03f9172cSAndroid Build Coastguard Worker 	ssid = config->ssid;
3034*03f9172cSAndroid Build Coastguard Worker 	while (ssid) {
3035*03f9172cSAndroid Build Coastguard Worker 		prev = ssid;
3036*03f9172cSAndroid Build Coastguard Worker 		ssid = ssid->next;
3037*03f9172cSAndroid Build Coastguard Worker 		wpa_config_free_ssid(prev);
3038*03f9172cSAndroid Build Coastguard Worker 	}
3039*03f9172cSAndroid Build Coastguard Worker 
3040*03f9172cSAndroid Build Coastguard Worker 	cred = config->cred;
3041*03f9172cSAndroid Build Coastguard Worker 	while (cred) {
3042*03f9172cSAndroid Build Coastguard Worker 		cprev = cred;
3043*03f9172cSAndroid Build Coastguard Worker 		cred = cred->next;
3044*03f9172cSAndroid Build Coastguard Worker 		wpa_config_free_cred(cprev);
3045*03f9172cSAndroid Build Coastguard Worker 	}
3046*03f9172cSAndroid Build Coastguard Worker 
3047*03f9172cSAndroid Build Coastguard Worker 	wpa_config_flush_blobs(config);
3048*03f9172cSAndroid Build Coastguard Worker 
3049*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(config->wps_vendor_ext_m1);
3050*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < MAX_WPS_VENDOR_EXT; i++)
3051*03f9172cSAndroid Build Coastguard Worker 		wpabuf_free(config->wps_vendor_ext[i]);
3052*03f9172cSAndroid Build Coastguard Worker 	os_free(config->ctrl_interface);
3053*03f9172cSAndroid Build Coastguard Worker 	os_free(config->ctrl_interface_group);
3054*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_OPENSC_ENGINE_PATH
3055*03f9172cSAndroid Build Coastguard Worker 	os_free(config->opensc_engine_path);
3056*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_OPENSC_ENGINE_PATH */
3057*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_PKCS11_ENGINE_PATH
3058*03f9172cSAndroid Build Coastguard Worker 	os_free(config->pkcs11_engine_path);
3059*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_PKCS11_ENGINE_PATH */
3060*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_PKCS11_MODULE_PATH
3061*03f9172cSAndroid Build Coastguard Worker 	os_free(config->pkcs11_module_path);
3062*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_PKCS11_MODULE_PATH */
3063*03f9172cSAndroid Build Coastguard Worker 	os_free(config->openssl_ciphers);
3064*03f9172cSAndroid Build Coastguard Worker 	os_free(config->pcsc_reader);
3065*03f9172cSAndroid Build Coastguard Worker 	str_clear_free(config->pcsc_pin);
3066*03f9172cSAndroid Build Coastguard Worker 	os_free(config->driver_param);
3067*03f9172cSAndroid Build Coastguard Worker 	os_free(config->device_name);
3068*03f9172cSAndroid Build Coastguard Worker 	os_free(config->manufacturer);
3069*03f9172cSAndroid Build Coastguard Worker 	os_free(config->model_name);
3070*03f9172cSAndroid Build Coastguard Worker 	os_free(config->model_number);
3071*03f9172cSAndroid Build Coastguard Worker 	os_free(config->serial_number);
3072*03f9172cSAndroid Build Coastguard Worker 	os_free(config->config_methods);
3073*03f9172cSAndroid Build Coastguard Worker 	os_free(config->p2p_ssid_postfix);
3074*03f9172cSAndroid Build Coastguard Worker 	os_free(config->pssid);
3075*03f9172cSAndroid Build Coastguard Worker 	os_free(config->p2p_pref_chan);
3076*03f9172cSAndroid Build Coastguard Worker 	os_free(config->p2p_no_go_freq.range);
3077*03f9172cSAndroid Build Coastguard Worker 	os_free(config->autoscan);
3078*03f9172cSAndroid Build Coastguard Worker 	os_free(config->freq_list);
3079*03f9172cSAndroid Build Coastguard Worker 	os_free(config->initial_freq_list);
3080*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(config->wps_nfc_dh_pubkey);
3081*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(config->wps_nfc_dh_privkey);
3082*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(config->wps_nfc_dev_pw);
3083*03f9172cSAndroid Build Coastguard Worker 	os_free(config->ext_password_backend);
3084*03f9172cSAndroid Build Coastguard Worker 	os_free(config->sae_groups);
3085*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(config->ap_vendor_elements);
3086*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(config->ap_assocresp_elements);
3087*03f9172cSAndroid Build Coastguard Worker 	os_free(config->osu_dir);
3088*03f9172cSAndroid Build Coastguard Worker 	os_free(config->bgscan);
3089*03f9172cSAndroid Build Coastguard Worker 	os_free(config->wowlan_triggers);
3090*03f9172cSAndroid Build Coastguard Worker 	os_free(config->fst_group_id);
3091*03f9172cSAndroid Build Coastguard Worker 	os_free(config->sched_scan_plans);
3092*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MBO
3093*03f9172cSAndroid Build Coastguard Worker 	os_free(config->non_pref_chan);
3094*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MBO */
3095*03f9172cSAndroid Build Coastguard Worker 	os_free(config->dpp_name);
3096*03f9172cSAndroid Build Coastguard Worker 	os_free(config->dpp_mud_url);
3097*03f9172cSAndroid Build Coastguard Worker 	os_free(config->dpp_extra_conf_req_name);
3098*03f9172cSAndroid Build Coastguard Worker 	os_free(config->dpp_extra_conf_req_value);
3099*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(config->dik);
3100*03f9172cSAndroid Build Coastguard Worker 
3101*03f9172cSAndroid Build Coastguard Worker 	os_free(config);
3102*03f9172cSAndroid Build Coastguard Worker }
3103*03f9172cSAndroid Build Coastguard Worker 
3104*03f9172cSAndroid Build Coastguard Worker 
3105*03f9172cSAndroid Build Coastguard Worker /**
3106*03f9172cSAndroid Build Coastguard Worker  * wpa_config_foreach_network - Iterate over each configured network
3107*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
3108*03f9172cSAndroid Build Coastguard Worker  * @func: Callback function to process each network
3109*03f9172cSAndroid Build Coastguard Worker  * @arg: Opaque argument to pass to callback function
3110*03f9172cSAndroid Build Coastguard Worker  *
3111*03f9172cSAndroid Build Coastguard Worker  * Iterate over the set of configured networks calling the specified
3112*03f9172cSAndroid Build Coastguard Worker  * function for each item. We guard against callbacks removing the
3113*03f9172cSAndroid Build Coastguard Worker  * supplied network.
3114*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_foreach_network(struct wpa_config * config,void (* func)(void *,struct wpa_ssid *),void * arg)3115*03f9172cSAndroid Build Coastguard Worker void wpa_config_foreach_network(struct wpa_config *config,
3116*03f9172cSAndroid Build Coastguard Worker 				void (*func)(void *, struct wpa_ssid *),
3117*03f9172cSAndroid Build Coastguard Worker 				void *arg)
3118*03f9172cSAndroid Build Coastguard Worker {
3119*03f9172cSAndroid Build Coastguard Worker 	struct wpa_ssid *ssid, *next;
3120*03f9172cSAndroid Build Coastguard Worker 
3121*03f9172cSAndroid Build Coastguard Worker 	ssid = config->ssid;
3122*03f9172cSAndroid Build Coastguard Worker 	while (ssid) {
3123*03f9172cSAndroid Build Coastguard Worker 		next = ssid->next;
3124*03f9172cSAndroid Build Coastguard Worker 		func(arg, ssid);
3125*03f9172cSAndroid Build Coastguard Worker 		ssid = next;
3126*03f9172cSAndroid Build Coastguard Worker 	}
3127*03f9172cSAndroid Build Coastguard Worker }
3128*03f9172cSAndroid Build Coastguard Worker 
3129*03f9172cSAndroid Build Coastguard Worker 
3130*03f9172cSAndroid Build Coastguard Worker /**
3131*03f9172cSAndroid Build Coastguard Worker  * wpa_config_get_network - Get configured network based on id
3132*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
3133*03f9172cSAndroid Build Coastguard Worker  * @id: Unique network id to search for
3134*03f9172cSAndroid Build Coastguard Worker  * Returns: Network configuration or %NULL if not found
3135*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_get_network(struct wpa_config * config,int id)3136*03f9172cSAndroid Build Coastguard Worker struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id)
3137*03f9172cSAndroid Build Coastguard Worker {
3138*03f9172cSAndroid Build Coastguard Worker 	struct wpa_ssid *ssid;
3139*03f9172cSAndroid Build Coastguard Worker 
3140*03f9172cSAndroid Build Coastguard Worker 	ssid = config->ssid;
3141*03f9172cSAndroid Build Coastguard Worker 	while (ssid) {
3142*03f9172cSAndroid Build Coastguard Worker 		if (id == ssid->id)
3143*03f9172cSAndroid Build Coastguard Worker 			break;
3144*03f9172cSAndroid Build Coastguard Worker 		ssid = ssid->next;
3145*03f9172cSAndroid Build Coastguard Worker 	}
3146*03f9172cSAndroid Build Coastguard Worker 
3147*03f9172cSAndroid Build Coastguard Worker 	return ssid;
3148*03f9172cSAndroid Build Coastguard Worker }
3149*03f9172cSAndroid Build Coastguard Worker 
3150*03f9172cSAndroid Build Coastguard Worker 
3151*03f9172cSAndroid Build Coastguard Worker /**
3152*03f9172cSAndroid Build Coastguard Worker  * wpa_config_add_network - Add a new network with empty configuration
3153*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
3154*03f9172cSAndroid Build Coastguard Worker  * Returns: The new network configuration or %NULL if operation failed
3155*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_add_network(struct wpa_config * config)3156*03f9172cSAndroid Build Coastguard Worker struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
3157*03f9172cSAndroid Build Coastguard Worker {
3158*03f9172cSAndroid Build Coastguard Worker 	int id;
3159*03f9172cSAndroid Build Coastguard Worker 	struct wpa_ssid *ssid, *last = NULL;
3160*03f9172cSAndroid Build Coastguard Worker 
3161*03f9172cSAndroid Build Coastguard Worker 	id = -1;
3162*03f9172cSAndroid Build Coastguard Worker 	ssid = config->ssid;
3163*03f9172cSAndroid Build Coastguard Worker 	while (ssid) {
3164*03f9172cSAndroid Build Coastguard Worker 		if (ssid->id > id)
3165*03f9172cSAndroid Build Coastguard Worker 			id = ssid->id;
3166*03f9172cSAndroid Build Coastguard Worker 		last = ssid;
3167*03f9172cSAndroid Build Coastguard Worker 		ssid = ssid->next;
3168*03f9172cSAndroid Build Coastguard Worker 	}
3169*03f9172cSAndroid Build Coastguard Worker 	id++;
3170*03f9172cSAndroid Build Coastguard Worker 
3171*03f9172cSAndroid Build Coastguard Worker 	ssid = os_zalloc(sizeof(*ssid));
3172*03f9172cSAndroid Build Coastguard Worker 	if (ssid == NULL)
3173*03f9172cSAndroid Build Coastguard Worker 		return NULL;
3174*03f9172cSAndroid Build Coastguard Worker 	ssid->id = id;
3175*03f9172cSAndroid Build Coastguard Worker 	dl_list_init(&ssid->psk_list);
3176*03f9172cSAndroid Build Coastguard Worker 	if (last)
3177*03f9172cSAndroid Build Coastguard Worker 		last->next = ssid;
3178*03f9172cSAndroid Build Coastguard Worker 	else
3179*03f9172cSAndroid Build Coastguard Worker 		config->ssid = ssid;
3180*03f9172cSAndroid Build Coastguard Worker 
3181*03f9172cSAndroid Build Coastguard Worker 	wpa_config_update_prio_list(config);
3182*03f9172cSAndroid Build Coastguard Worker 
3183*03f9172cSAndroid Build Coastguard Worker 	return ssid;
3184*03f9172cSAndroid Build Coastguard Worker }
3185*03f9172cSAndroid Build Coastguard Worker 
3186*03f9172cSAndroid Build Coastguard Worker 
3187*03f9172cSAndroid Build Coastguard Worker /**
3188*03f9172cSAndroid Build Coastguard Worker  * wpa_config_remove_network - Remove a configured network based on id
3189*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
3190*03f9172cSAndroid Build Coastguard Worker  * @id: Unique network id to search for
3191*03f9172cSAndroid Build Coastguard Worker  * Returns: 0 on success, or -1 if the network was not found
3192*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_remove_network(struct wpa_config * config,int id)3193*03f9172cSAndroid Build Coastguard Worker int wpa_config_remove_network(struct wpa_config *config, int id)
3194*03f9172cSAndroid Build Coastguard Worker {
3195*03f9172cSAndroid Build Coastguard Worker 	struct wpa_ssid *ssid, *prev = NULL;
3196*03f9172cSAndroid Build Coastguard Worker 
3197*03f9172cSAndroid Build Coastguard Worker 	ssid = config->ssid;
3198*03f9172cSAndroid Build Coastguard Worker 	while (ssid) {
3199*03f9172cSAndroid Build Coastguard Worker 		if (id == ssid->id)
3200*03f9172cSAndroid Build Coastguard Worker 			break;
3201*03f9172cSAndroid Build Coastguard Worker 		prev = ssid;
3202*03f9172cSAndroid Build Coastguard Worker 		ssid = ssid->next;
3203*03f9172cSAndroid Build Coastguard Worker 	}
3204*03f9172cSAndroid Build Coastguard Worker 
3205*03f9172cSAndroid Build Coastguard Worker 	if (ssid == NULL)
3206*03f9172cSAndroid Build Coastguard Worker 		return -1;
3207*03f9172cSAndroid Build Coastguard Worker 
3208*03f9172cSAndroid Build Coastguard Worker 	if (prev)
3209*03f9172cSAndroid Build Coastguard Worker 		prev->next = ssid->next;
3210*03f9172cSAndroid Build Coastguard Worker 	else
3211*03f9172cSAndroid Build Coastguard Worker 		config->ssid = ssid->next;
3212*03f9172cSAndroid Build Coastguard Worker 
3213*03f9172cSAndroid Build Coastguard Worker 	wpa_config_update_prio_list(config);
3214*03f9172cSAndroid Build Coastguard Worker 	wpa_config_free_ssid(ssid);
3215*03f9172cSAndroid Build Coastguard Worker 	return 0;
3216*03f9172cSAndroid Build Coastguard Worker }
3217*03f9172cSAndroid Build Coastguard Worker 
3218*03f9172cSAndroid Build Coastguard Worker 
3219*03f9172cSAndroid Build Coastguard Worker /**
3220*03f9172cSAndroid Build Coastguard Worker  * wpa_config_set_network_defaults - Set network default values
3221*03f9172cSAndroid Build Coastguard Worker  * @ssid: Pointer to network configuration data
3222*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_set_network_defaults(struct wpa_ssid * ssid)3223*03f9172cSAndroid Build Coastguard Worker void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
3224*03f9172cSAndroid Build Coastguard Worker {
3225*03f9172cSAndroid Build Coastguard Worker 	ssid->proto = DEFAULT_PROTO;
3226*03f9172cSAndroid Build Coastguard Worker 	ssid->pairwise_cipher = DEFAULT_PAIRWISE;
3227*03f9172cSAndroid Build Coastguard Worker 	ssid->group_cipher = DEFAULT_GROUP;
3228*03f9172cSAndroid Build Coastguard Worker 	ssid->key_mgmt = DEFAULT_KEY_MGMT;
3229*03f9172cSAndroid Build Coastguard Worker 	ssid->wpa_deny_ptk0_rekey = PTK0_REKEY_ALLOW_ALWAYS;
3230*03f9172cSAndroid Build Coastguard Worker 	ssid->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
3231*03f9172cSAndroid Build Coastguard Worker 	ssid->ht = 1;
3232*03f9172cSAndroid Build Coastguard Worker 	ssid->vht = 1;
3233*03f9172cSAndroid Build Coastguard Worker 	ssid->he = 1;
3234*03f9172cSAndroid Build Coastguard Worker #ifdef IEEE8021X_EAPOL
3235*03f9172cSAndroid Build Coastguard Worker 	ssid->eapol_flags = DEFAULT_EAPOL_FLAGS;
3236*03f9172cSAndroid Build Coastguard Worker 	ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
3237*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.fragment_size = DEFAULT_FRAGMENT_SIZE;
3238*03f9172cSAndroid Build Coastguard Worker 	ssid->eap.sim_num = DEFAULT_USER_SELECTED_SIM;
3239*03f9172cSAndroid Build Coastguard Worker #endif /* IEEE8021X_EAPOL */
3240*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MESH
3241*03f9172cSAndroid Build Coastguard Worker 	ssid->dot11MeshMaxRetries = DEFAULT_MESH_MAX_RETRIES;
3242*03f9172cSAndroid Build Coastguard Worker 	ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT;
3243*03f9172cSAndroid Build Coastguard Worker 	ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT;
3244*03f9172cSAndroid Build Coastguard Worker 	ssid->dot11MeshHoldingTimeout = DEFAULT_MESH_HOLDING_TIMEOUT;
3245*03f9172cSAndroid Build Coastguard Worker 	ssid->mesh_fwding = DEFAULT_MESH_FWDING;
3246*03f9172cSAndroid Build Coastguard Worker 	ssid->mesh_rssi_threshold = DEFAULT_MESH_RSSI_THRESHOLD;
3247*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MESH */
3248*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_HT_OVERRIDES
3249*03f9172cSAndroid Build Coastguard Worker 	ssid->disable_ht = DEFAULT_DISABLE_HT;
3250*03f9172cSAndroid Build Coastguard Worker 	ssid->disable_ht40 = DEFAULT_DISABLE_HT40;
3251*03f9172cSAndroid Build Coastguard Worker 	ssid->disable_sgi = DEFAULT_DISABLE_SGI;
3252*03f9172cSAndroid Build Coastguard Worker 	ssid->disable_ldpc = DEFAULT_DISABLE_LDPC;
3253*03f9172cSAndroid Build Coastguard Worker 	ssid->tx_stbc = DEFAULT_TX_STBC;
3254*03f9172cSAndroid Build Coastguard Worker 	ssid->rx_stbc = DEFAULT_RX_STBC;
3255*03f9172cSAndroid Build Coastguard Worker 	ssid->disable_max_amsdu = DEFAULT_DISABLE_MAX_AMSDU;
3256*03f9172cSAndroid Build Coastguard Worker 	ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR;
3257*03f9172cSAndroid Build Coastguard Worker 	ssid->ampdu_density = DEFAULT_AMPDU_DENSITY;
3258*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_HT_OVERRIDES */
3259*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_VHT_OVERRIDES
3260*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_rx_mcs_nss_1 = -1;
3261*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_rx_mcs_nss_2 = -1;
3262*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_rx_mcs_nss_3 = -1;
3263*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_rx_mcs_nss_4 = -1;
3264*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_rx_mcs_nss_5 = -1;
3265*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_rx_mcs_nss_6 = -1;
3266*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_rx_mcs_nss_7 = -1;
3267*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_rx_mcs_nss_8 = -1;
3268*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_tx_mcs_nss_1 = -1;
3269*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_tx_mcs_nss_2 = -1;
3270*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_tx_mcs_nss_3 = -1;
3271*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_tx_mcs_nss_4 = -1;
3272*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_tx_mcs_nss_5 = -1;
3273*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_tx_mcs_nss_6 = -1;
3274*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_tx_mcs_nss_7 = -1;
3275*03f9172cSAndroid Build Coastguard Worker 	ssid->vht_tx_mcs_nss_8 = -1;
3276*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_VHT_OVERRIDES */
3277*03f9172cSAndroid Build Coastguard Worker 	ssid->proactive_key_caching = -1;
3278*03f9172cSAndroid Build Coastguard Worker 	ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT;
3279*03f9172cSAndroid Build Coastguard Worker 	ssid->sae_pwe = DEFAULT_SAE_PWE;
3280*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MACSEC
3281*03f9172cSAndroid Build Coastguard Worker 	ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
3282*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MACSEC */
3283*03f9172cSAndroid Build Coastguard Worker 	ssid->mac_addr = WPAS_MAC_ADDR_STYLE_NOT_SET;
3284*03f9172cSAndroid Build Coastguard Worker 	ssid->max_oper_chwidth = DEFAULT_MAX_OPER_CHWIDTH;
3285*03f9172cSAndroid Build Coastguard Worker }
3286*03f9172cSAndroid Build Coastguard Worker 
3287*03f9172cSAndroid Build Coastguard Worker 
3288*03f9172cSAndroid Build Coastguard Worker static const char *removed_fields[] = {
3289*03f9172cSAndroid Build Coastguard Worker 	"dh_file",
3290*03f9172cSAndroid Build Coastguard Worker 	"dh_file2",
3291*03f9172cSAndroid Build Coastguard Worker 	"machine_dh_file",
3292*03f9172cSAndroid Build Coastguard Worker 	NULL
3293*03f9172cSAndroid Build Coastguard Worker };
3294*03f9172cSAndroid Build Coastguard Worker 
removed_field(const char * field)3295*03f9172cSAndroid Build Coastguard Worker static bool removed_field(const char *field)
3296*03f9172cSAndroid Build Coastguard Worker {
3297*03f9172cSAndroid Build Coastguard Worker 	int i;
3298*03f9172cSAndroid Build Coastguard Worker 
3299*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; removed_fields[i]; i++) {
3300*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(field, removed_fields[i]) == 0)
3301*03f9172cSAndroid Build Coastguard Worker 			return true;
3302*03f9172cSAndroid Build Coastguard Worker 	}
3303*03f9172cSAndroid Build Coastguard Worker 
3304*03f9172cSAndroid Build Coastguard Worker 	return false;
3305*03f9172cSAndroid Build Coastguard Worker }
3306*03f9172cSAndroid Build Coastguard Worker 
3307*03f9172cSAndroid Build Coastguard Worker 
3308*03f9172cSAndroid Build Coastguard Worker /**
3309*03f9172cSAndroid Build Coastguard Worker  * wpa_config_set - Set a variable in network configuration
3310*03f9172cSAndroid Build Coastguard Worker  * @ssid: Pointer to network configuration data
3311*03f9172cSAndroid Build Coastguard Worker  * @var: Variable name, e.g., "ssid"
3312*03f9172cSAndroid Build Coastguard Worker  * @value: Variable value
3313*03f9172cSAndroid Build Coastguard Worker  * @line: Line number in configuration file or 0 if not used
3314*03f9172cSAndroid Build Coastguard Worker  * Returns: 0 on success with possible change in the value, 1 on success with
3315*03f9172cSAndroid Build Coastguard Worker  * no change to previously configured value, or -1 on failure
3316*03f9172cSAndroid Build Coastguard Worker  *
3317*03f9172cSAndroid Build Coastguard Worker  * This function can be used to set network configuration variables based on
3318*03f9172cSAndroid Build Coastguard Worker  * both the configuration file and management interface input. The value
3319*03f9172cSAndroid Build Coastguard Worker  * parameter must be in the same format as the text-based configuration file is
3320*03f9172cSAndroid Build Coastguard Worker  * using. For example, strings are using double quotation marks.
3321*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_set(struct wpa_ssid * ssid,const char * var,const char * value,int line)3322*03f9172cSAndroid Build Coastguard Worker int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
3323*03f9172cSAndroid Build Coastguard Worker 		   int line)
3324*03f9172cSAndroid Build Coastguard Worker {
3325*03f9172cSAndroid Build Coastguard Worker 	size_t i;
3326*03f9172cSAndroid Build Coastguard Worker 	int ret = 0;
3327*03f9172cSAndroid Build Coastguard Worker 
3328*03f9172cSAndroid Build Coastguard Worker 	if (ssid == NULL || var == NULL || value == NULL)
3329*03f9172cSAndroid Build Coastguard Worker 		return -1;
3330*03f9172cSAndroid Build Coastguard Worker 
3331*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
3332*03f9172cSAndroid Build Coastguard Worker 		const struct parse_data *field = &ssid_fields[i];
3333*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(var, field->name) != 0)
3334*03f9172cSAndroid Build Coastguard Worker 			continue;
3335*03f9172cSAndroid Build Coastguard Worker 
3336*03f9172cSAndroid Build Coastguard Worker 		ret = field->parser(field, ssid, line, value);
3337*03f9172cSAndroid Build Coastguard Worker 		if (ret < 0) {
3338*03f9172cSAndroid Build Coastguard Worker 			if (line) {
3339*03f9172cSAndroid Build Coastguard Worker 				wpa_printf(MSG_ERROR, "Line %d: failed to "
3340*03f9172cSAndroid Build Coastguard Worker 					   "parse %s '%s'.", line, var, value);
3341*03f9172cSAndroid Build Coastguard Worker 			}
3342*03f9172cSAndroid Build Coastguard Worker 			ret = -1;
3343*03f9172cSAndroid Build Coastguard Worker 		}
3344*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SAE
3345*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(var, "ssid") == 0 ||
3346*03f9172cSAndroid Build Coastguard Worker 		    os_strcmp(var, "psk") == 0 ||
3347*03f9172cSAndroid Build Coastguard Worker 		    os_strcmp(var, "sae_password") == 0 ||
3348*03f9172cSAndroid Build Coastguard Worker 		    os_strcmp(var, "sae_password_id") == 0) {
3349*03f9172cSAndroid Build Coastguard Worker 			sae_deinit_pt(ssid->pt);
3350*03f9172cSAndroid Build Coastguard Worker 			ssid->pt = NULL;
3351*03f9172cSAndroid Build Coastguard Worker 		}
3352*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SAE */
3353*03f9172cSAndroid Build Coastguard Worker 		break;
3354*03f9172cSAndroid Build Coastguard Worker 	}
3355*03f9172cSAndroid Build Coastguard Worker 	if (i == NUM_SSID_FIELDS) {
3356*03f9172cSAndroid Build Coastguard Worker 		if (removed_field(var)) {
3357*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_INFO,
3358*03f9172cSAndroid Build Coastguard Worker 				   "Line %d: Ignore removed configuration field '%s'",
3359*03f9172cSAndroid Build Coastguard Worker 				   line, var);
3360*03f9172cSAndroid Build Coastguard Worker 			return ret;
3361*03f9172cSAndroid Build Coastguard Worker 		}
3362*03f9172cSAndroid Build Coastguard Worker 		if (line) {
3363*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: unknown network field "
3364*03f9172cSAndroid Build Coastguard Worker 				   "'%s'.", line, var);
3365*03f9172cSAndroid Build Coastguard Worker 		}
3366*03f9172cSAndroid Build Coastguard Worker 		ret = -1;
3367*03f9172cSAndroid Build Coastguard Worker 	}
3368*03f9172cSAndroid Build Coastguard Worker 	ssid->was_recently_reconfigured = true;
3369*03f9172cSAndroid Build Coastguard Worker 
3370*03f9172cSAndroid Build Coastguard Worker 	return ret;
3371*03f9172cSAndroid Build Coastguard Worker }
3372*03f9172cSAndroid Build Coastguard Worker 
3373*03f9172cSAndroid Build Coastguard Worker 
wpa_config_set_quoted(struct wpa_ssid * ssid,const char * var,const char * value)3374*03f9172cSAndroid Build Coastguard Worker int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
3375*03f9172cSAndroid Build Coastguard Worker 			  const char *value)
3376*03f9172cSAndroid Build Coastguard Worker {
3377*03f9172cSAndroid Build Coastguard Worker 	size_t len;
3378*03f9172cSAndroid Build Coastguard Worker 	char *buf;
3379*03f9172cSAndroid Build Coastguard Worker 	int ret;
3380*03f9172cSAndroid Build Coastguard Worker 
3381*03f9172cSAndroid Build Coastguard Worker 	len = os_strlen(value);
3382*03f9172cSAndroid Build Coastguard Worker 	buf = os_malloc(len + 3);
3383*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
3384*03f9172cSAndroid Build Coastguard Worker 		return -1;
3385*03f9172cSAndroid Build Coastguard Worker 	buf[0] = '"';
3386*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf + 1, value, len);
3387*03f9172cSAndroid Build Coastguard Worker 	buf[len + 1] = '"';
3388*03f9172cSAndroid Build Coastguard Worker 	buf[len + 2] = '\0';
3389*03f9172cSAndroid Build Coastguard Worker 	ret = wpa_config_set(ssid, var, buf, 0);
3390*03f9172cSAndroid Build Coastguard Worker 	os_free(buf);
3391*03f9172cSAndroid Build Coastguard Worker 	return ret;
3392*03f9172cSAndroid Build Coastguard Worker }
3393*03f9172cSAndroid Build Coastguard Worker 
3394*03f9172cSAndroid Build Coastguard Worker 
3395*03f9172cSAndroid Build Coastguard Worker /**
3396*03f9172cSAndroid Build Coastguard Worker  * wpa_config_get_all - Get all options from network configuration
3397*03f9172cSAndroid Build Coastguard Worker  * @ssid: Pointer to network configuration data
3398*03f9172cSAndroid Build Coastguard Worker  * @get_keys: Determines if keys/passwords will be included in returned list
3399*03f9172cSAndroid Build Coastguard Worker  *	(if they may be exported)
3400*03f9172cSAndroid Build Coastguard Worker  * Returns: %NULL terminated list of all set keys and their values in the form
3401*03f9172cSAndroid Build Coastguard Worker  * of [key1, val1, key2, val2, ... , NULL]
3402*03f9172cSAndroid Build Coastguard Worker  *
3403*03f9172cSAndroid Build Coastguard Worker  * This function can be used to get list of all configured network properties.
3404*03f9172cSAndroid Build Coastguard Worker  * The caller is responsible for freeing the returned list and all its
3405*03f9172cSAndroid Build Coastguard Worker  * elements.
3406*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_get_all(struct wpa_ssid * ssid,int get_keys)3407*03f9172cSAndroid Build Coastguard Worker char ** wpa_config_get_all(struct wpa_ssid *ssid, int get_keys)
3408*03f9172cSAndroid Build Coastguard Worker {
3409*03f9172cSAndroid Build Coastguard Worker #ifdef NO_CONFIG_WRITE
3410*03f9172cSAndroid Build Coastguard Worker 	return NULL;
3411*03f9172cSAndroid Build Coastguard Worker #else /* NO_CONFIG_WRITE */
3412*03f9172cSAndroid Build Coastguard Worker 	const struct parse_data *field;
3413*03f9172cSAndroid Build Coastguard Worker 	char *key, *value;
3414*03f9172cSAndroid Build Coastguard Worker 	size_t i;
3415*03f9172cSAndroid Build Coastguard Worker 	char **props;
3416*03f9172cSAndroid Build Coastguard Worker 	int fields_num;
3417*03f9172cSAndroid Build Coastguard Worker 
3418*03f9172cSAndroid Build Coastguard Worker 	get_keys = get_keys && ssid->export_keys;
3419*03f9172cSAndroid Build Coastguard Worker 
3420*03f9172cSAndroid Build Coastguard Worker 	props = os_calloc(2 * NUM_SSID_FIELDS + 1, sizeof(char *));
3421*03f9172cSAndroid Build Coastguard Worker 	if (!props)
3422*03f9172cSAndroid Build Coastguard Worker 		return NULL;
3423*03f9172cSAndroid Build Coastguard Worker 
3424*03f9172cSAndroid Build Coastguard Worker 	fields_num = 0;
3425*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
3426*03f9172cSAndroid Build Coastguard Worker 		field = &ssid_fields[i];
3427*03f9172cSAndroid Build Coastguard Worker 		if (field->key_data && !get_keys)
3428*03f9172cSAndroid Build Coastguard Worker 			continue;
3429*03f9172cSAndroid Build Coastguard Worker 		value = field->writer(field, ssid);
3430*03f9172cSAndroid Build Coastguard Worker 		if (value == NULL)
3431*03f9172cSAndroid Build Coastguard Worker 			continue;
3432*03f9172cSAndroid Build Coastguard Worker 		if (os_strlen(value) == 0) {
3433*03f9172cSAndroid Build Coastguard Worker 			os_free(value);
3434*03f9172cSAndroid Build Coastguard Worker 			continue;
3435*03f9172cSAndroid Build Coastguard Worker 		}
3436*03f9172cSAndroid Build Coastguard Worker 
3437*03f9172cSAndroid Build Coastguard Worker 		key = os_strdup(field->name);
3438*03f9172cSAndroid Build Coastguard Worker 		if (key == NULL) {
3439*03f9172cSAndroid Build Coastguard Worker 			os_free(value);
3440*03f9172cSAndroid Build Coastguard Worker 			goto err;
3441*03f9172cSAndroid Build Coastguard Worker 		}
3442*03f9172cSAndroid Build Coastguard Worker 
3443*03f9172cSAndroid Build Coastguard Worker 		props[fields_num * 2] = key;
3444*03f9172cSAndroid Build Coastguard Worker 		props[fields_num * 2 + 1] = value;
3445*03f9172cSAndroid Build Coastguard Worker 
3446*03f9172cSAndroid Build Coastguard Worker 		fields_num++;
3447*03f9172cSAndroid Build Coastguard Worker 	}
3448*03f9172cSAndroid Build Coastguard Worker 
3449*03f9172cSAndroid Build Coastguard Worker 	return props;
3450*03f9172cSAndroid Build Coastguard Worker 
3451*03f9172cSAndroid Build Coastguard Worker err:
3452*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; props[i]; i++)
3453*03f9172cSAndroid Build Coastguard Worker 		os_free(props[i]);
3454*03f9172cSAndroid Build Coastguard Worker 	os_free(props);
3455*03f9172cSAndroid Build Coastguard Worker 	return NULL;
3456*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
3457*03f9172cSAndroid Build Coastguard Worker }
3458*03f9172cSAndroid Build Coastguard Worker 
3459*03f9172cSAndroid Build Coastguard Worker 
3460*03f9172cSAndroid Build Coastguard Worker #ifndef NO_CONFIG_WRITE
3461*03f9172cSAndroid Build Coastguard Worker /**
3462*03f9172cSAndroid Build Coastguard Worker  * wpa_config_get - Get a variable in network configuration
3463*03f9172cSAndroid Build Coastguard Worker  * @ssid: Pointer to network configuration data
3464*03f9172cSAndroid Build Coastguard Worker  * @var: Variable name, e.g., "ssid"
3465*03f9172cSAndroid Build Coastguard Worker  * Returns: Value of the variable or %NULL on failure
3466*03f9172cSAndroid Build Coastguard Worker  *
3467*03f9172cSAndroid Build Coastguard Worker  * This function can be used to get network configuration variables. The
3468*03f9172cSAndroid Build Coastguard Worker  * returned value is a copy of the configuration variable in text format, i.e,.
3469*03f9172cSAndroid Build Coastguard Worker  * the same format that the text-based configuration file and wpa_config_set()
3470*03f9172cSAndroid Build Coastguard Worker  * are using for the value. The caller is responsible for freeing the returned
3471*03f9172cSAndroid Build Coastguard Worker  * value.
3472*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_get(struct wpa_ssid * ssid,const char * var)3473*03f9172cSAndroid Build Coastguard Worker char * wpa_config_get(struct wpa_ssid *ssid, const char *var)
3474*03f9172cSAndroid Build Coastguard Worker {
3475*03f9172cSAndroid Build Coastguard Worker 	size_t i;
3476*03f9172cSAndroid Build Coastguard Worker 
3477*03f9172cSAndroid Build Coastguard Worker 	if (ssid == NULL || var == NULL)
3478*03f9172cSAndroid Build Coastguard Worker 		return NULL;
3479*03f9172cSAndroid Build Coastguard Worker 
3480*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
3481*03f9172cSAndroid Build Coastguard Worker 		const struct parse_data *field = &ssid_fields[i];
3482*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(var, field->name) == 0) {
3483*03f9172cSAndroid Build Coastguard Worker 			char *ret = field->writer(field, ssid);
3484*03f9172cSAndroid Build Coastguard Worker 
3485*03f9172cSAndroid Build Coastguard Worker 			if (ret && has_newline(ret)) {
3486*03f9172cSAndroid Build Coastguard Worker 				wpa_printf(MSG_ERROR,
3487*03f9172cSAndroid Build Coastguard Worker 					   "Found newline in value for %s; not returning it",
3488*03f9172cSAndroid Build Coastguard Worker 					   var);
3489*03f9172cSAndroid Build Coastguard Worker 				os_free(ret);
3490*03f9172cSAndroid Build Coastguard Worker 				ret = NULL;
3491*03f9172cSAndroid Build Coastguard Worker 			}
3492*03f9172cSAndroid Build Coastguard Worker 
3493*03f9172cSAndroid Build Coastguard Worker 			return ret;
3494*03f9172cSAndroid Build Coastguard Worker 		}
3495*03f9172cSAndroid Build Coastguard Worker 	}
3496*03f9172cSAndroid Build Coastguard Worker 
3497*03f9172cSAndroid Build Coastguard Worker 	return NULL;
3498*03f9172cSAndroid Build Coastguard Worker }
3499*03f9172cSAndroid Build Coastguard Worker 
3500*03f9172cSAndroid Build Coastguard Worker 
3501*03f9172cSAndroid Build Coastguard Worker /**
3502*03f9172cSAndroid Build Coastguard Worker  * wpa_config_get_no_key - Get a variable in network configuration (no keys)
3503*03f9172cSAndroid Build Coastguard Worker  * @ssid: Pointer to network configuration data
3504*03f9172cSAndroid Build Coastguard Worker  * @var: Variable name, e.g., "ssid"
3505*03f9172cSAndroid Build Coastguard Worker  * Returns: Value of the variable or %NULL on failure
3506*03f9172cSAndroid Build Coastguard Worker  *
3507*03f9172cSAndroid Build Coastguard Worker  * This function can be used to get network configuration variable like
3508*03f9172cSAndroid Build Coastguard Worker  * wpa_config_get(). The only difference is that this functions does not expose
3509*03f9172cSAndroid Build Coastguard Worker  * key/password material from the configuration. In case a key/password field
3510*03f9172cSAndroid Build Coastguard Worker  * is requested, the returned value is an empty string or %NULL if the variable
3511*03f9172cSAndroid Build Coastguard Worker  * is not set or "*" if the variable is set (regardless of its value). The
3512*03f9172cSAndroid Build Coastguard Worker  * returned value is a copy of the configuration variable in text format, i.e,.
3513*03f9172cSAndroid Build Coastguard Worker  * the same format that the text-based configuration file and wpa_config_set()
3514*03f9172cSAndroid Build Coastguard Worker  * are using for the value. The caller is responsible for freeing the returned
3515*03f9172cSAndroid Build Coastguard Worker  * value.
3516*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_get_no_key(struct wpa_ssid * ssid,const char * var)3517*03f9172cSAndroid Build Coastguard Worker char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var)
3518*03f9172cSAndroid Build Coastguard Worker {
3519*03f9172cSAndroid Build Coastguard Worker 	size_t i;
3520*03f9172cSAndroid Build Coastguard Worker 
3521*03f9172cSAndroid Build Coastguard Worker 	if (ssid == NULL || var == NULL)
3522*03f9172cSAndroid Build Coastguard Worker 		return NULL;
3523*03f9172cSAndroid Build Coastguard Worker 
3524*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
3525*03f9172cSAndroid Build Coastguard Worker 		const struct parse_data *field = &ssid_fields[i];
3526*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(var, field->name) == 0) {
3527*03f9172cSAndroid Build Coastguard Worker 			char *res = field->writer(field, ssid);
3528*03f9172cSAndroid Build Coastguard Worker 			if (field->key_data) {
3529*03f9172cSAndroid Build Coastguard Worker 				if (res && res[0]) {
3530*03f9172cSAndroid Build Coastguard Worker 					wpa_printf(MSG_DEBUG, "Do not allow "
3531*03f9172cSAndroid Build Coastguard Worker 						   "key_data field to be "
3532*03f9172cSAndroid Build Coastguard Worker 						   "exposed");
3533*03f9172cSAndroid Build Coastguard Worker 					str_clear_free(res);
3534*03f9172cSAndroid Build Coastguard Worker 					return os_strdup("*");
3535*03f9172cSAndroid Build Coastguard Worker 				}
3536*03f9172cSAndroid Build Coastguard Worker 
3537*03f9172cSAndroid Build Coastguard Worker 				os_free(res);
3538*03f9172cSAndroid Build Coastguard Worker 				return NULL;
3539*03f9172cSAndroid Build Coastguard Worker 			}
3540*03f9172cSAndroid Build Coastguard Worker 			return res;
3541*03f9172cSAndroid Build Coastguard Worker 		}
3542*03f9172cSAndroid Build Coastguard Worker 	}
3543*03f9172cSAndroid Build Coastguard Worker 
3544*03f9172cSAndroid Build Coastguard Worker 	return NULL;
3545*03f9172cSAndroid Build Coastguard Worker }
3546*03f9172cSAndroid Build Coastguard Worker #endif /* NO_CONFIG_WRITE */
3547*03f9172cSAndroid Build Coastguard Worker 
3548*03f9172cSAndroid Build Coastguard Worker 
3549*03f9172cSAndroid Build Coastguard Worker /**
3550*03f9172cSAndroid Build Coastguard Worker  * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
3551*03f9172cSAndroid Build Coastguard Worker  * @ssid: Pointer to network configuration data
3552*03f9172cSAndroid Build Coastguard Worker  *
3553*03f9172cSAndroid Build Coastguard Worker  * This function must be called to update WPA PSK when either SSID or the
3554*03f9172cSAndroid Build Coastguard Worker  * passphrase has changed for the network configuration.
3555*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_update_psk(struct wpa_ssid * ssid)3556*03f9172cSAndroid Build Coastguard Worker void wpa_config_update_psk(struct wpa_ssid *ssid)
3557*03f9172cSAndroid Build Coastguard Worker {
3558*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_NO_PBKDF2
3559*03f9172cSAndroid Build Coastguard Worker 	if (pbkdf2_sha1(ssid->passphrase, ssid->ssid, ssid->ssid_len, 4096,
3560*03f9172cSAndroid Build Coastguard Worker 			ssid->psk, PMK_LEN) != 0) {
3561*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Error in pbkdf2_sha1()");
3562*03f9172cSAndroid Build Coastguard Worker 		return;
3563*03f9172cSAndroid Build Coastguard Worker 	}
3564*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
3565*03f9172cSAndroid Build Coastguard Worker 			ssid->psk, PMK_LEN);
3566*03f9172cSAndroid Build Coastguard Worker 	ssid->psk_set = 1;
3567*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_PBKDF2 */
3568*03f9172cSAndroid Build Coastguard Worker }
3569*03f9172cSAndroid Build Coastguard Worker 
3570*03f9172cSAndroid Build Coastguard Worker 
wpa_config_set_cred_req_conn_capab(struct wpa_cred * cred,const char * value)3571*03f9172cSAndroid Build Coastguard Worker static int wpa_config_set_cred_req_conn_capab(struct wpa_cred *cred,
3572*03f9172cSAndroid Build Coastguard Worker 					      const char *value)
3573*03f9172cSAndroid Build Coastguard Worker {
3574*03f9172cSAndroid Build Coastguard Worker 	u8 *proto;
3575*03f9172cSAndroid Build Coastguard Worker 	int **port;
3576*03f9172cSAndroid Build Coastguard Worker 	int *ports, *nports;
3577*03f9172cSAndroid Build Coastguard Worker 	const char *pos;
3578*03f9172cSAndroid Build Coastguard Worker 	unsigned int num_ports;
3579*03f9172cSAndroid Build Coastguard Worker 
3580*03f9172cSAndroid Build Coastguard Worker 	proto = os_realloc_array(cred->req_conn_capab_proto,
3581*03f9172cSAndroid Build Coastguard Worker 				 cred->num_req_conn_capab + 1, sizeof(u8));
3582*03f9172cSAndroid Build Coastguard Worker 	if (proto == NULL)
3583*03f9172cSAndroid Build Coastguard Worker 		return -1;
3584*03f9172cSAndroid Build Coastguard Worker 	cred->req_conn_capab_proto = proto;
3585*03f9172cSAndroid Build Coastguard Worker 
3586*03f9172cSAndroid Build Coastguard Worker 	port = os_realloc_array(cred->req_conn_capab_port,
3587*03f9172cSAndroid Build Coastguard Worker 				cred->num_req_conn_capab + 1, sizeof(int *));
3588*03f9172cSAndroid Build Coastguard Worker 	if (port == NULL)
3589*03f9172cSAndroid Build Coastguard Worker 		return -1;
3590*03f9172cSAndroid Build Coastguard Worker 	cred->req_conn_capab_port = port;
3591*03f9172cSAndroid Build Coastguard Worker 
3592*03f9172cSAndroid Build Coastguard Worker 	proto[cred->num_req_conn_capab] = atoi(value);
3593*03f9172cSAndroid Build Coastguard Worker 
3594*03f9172cSAndroid Build Coastguard Worker 	pos = os_strchr(value, ':');
3595*03f9172cSAndroid Build Coastguard Worker 	if (pos == NULL) {
3596*03f9172cSAndroid Build Coastguard Worker 		port[cred->num_req_conn_capab] = NULL;
3597*03f9172cSAndroid Build Coastguard Worker 		cred->num_req_conn_capab++;
3598*03f9172cSAndroid Build Coastguard Worker 		return 0;
3599*03f9172cSAndroid Build Coastguard Worker 	}
3600*03f9172cSAndroid Build Coastguard Worker 	pos++;
3601*03f9172cSAndroid Build Coastguard Worker 
3602*03f9172cSAndroid Build Coastguard Worker 	ports = NULL;
3603*03f9172cSAndroid Build Coastguard Worker 	num_ports = 0;
3604*03f9172cSAndroid Build Coastguard Worker 
3605*03f9172cSAndroid Build Coastguard Worker 	while (*pos) {
3606*03f9172cSAndroid Build Coastguard Worker 		nports = os_realloc_array(ports, num_ports + 1, sizeof(int));
3607*03f9172cSAndroid Build Coastguard Worker 		if (nports == NULL) {
3608*03f9172cSAndroid Build Coastguard Worker 			os_free(ports);
3609*03f9172cSAndroid Build Coastguard Worker 			return -1;
3610*03f9172cSAndroid Build Coastguard Worker 		}
3611*03f9172cSAndroid Build Coastguard Worker 		ports = nports;
3612*03f9172cSAndroid Build Coastguard Worker 		ports[num_ports++] = atoi(pos);
3613*03f9172cSAndroid Build Coastguard Worker 
3614*03f9172cSAndroid Build Coastguard Worker 		pos = os_strchr(pos, ',');
3615*03f9172cSAndroid Build Coastguard Worker 		if (pos == NULL)
3616*03f9172cSAndroid Build Coastguard Worker 			break;
3617*03f9172cSAndroid Build Coastguard Worker 		pos++;
3618*03f9172cSAndroid Build Coastguard Worker 	}
3619*03f9172cSAndroid Build Coastguard Worker 
3620*03f9172cSAndroid Build Coastguard Worker 	nports = os_realloc_array(ports, num_ports + 1, sizeof(int));
3621*03f9172cSAndroid Build Coastguard Worker 	if (nports == NULL) {
3622*03f9172cSAndroid Build Coastguard Worker 		os_free(ports);
3623*03f9172cSAndroid Build Coastguard Worker 		return -1;
3624*03f9172cSAndroid Build Coastguard Worker 	}
3625*03f9172cSAndroid Build Coastguard Worker 	ports = nports;
3626*03f9172cSAndroid Build Coastguard Worker 	ports[num_ports] = -1;
3627*03f9172cSAndroid Build Coastguard Worker 
3628*03f9172cSAndroid Build Coastguard Worker 	port[cred->num_req_conn_capab] = ports;
3629*03f9172cSAndroid Build Coastguard Worker 	cred->num_req_conn_capab++;
3630*03f9172cSAndroid Build Coastguard Worker 	return 0;
3631*03f9172cSAndroid Build Coastguard Worker }
3632*03f9172cSAndroid Build Coastguard Worker 
3633*03f9172cSAndroid Build Coastguard Worker 
3634*03f9172cSAndroid Build Coastguard Worker static int
wpa_config_set_cred_ois(u8 cred_ois[MAX_ROAMING_CONS][MAX_ROAMING_CONS_OI_LEN],size_t cred_ois_len[MAX_ROAMING_CONS],unsigned int * cred_num_ois,const char * value)3635*03f9172cSAndroid Build Coastguard Worker wpa_config_set_cred_ois(u8 cred_ois[MAX_ROAMING_CONS][MAX_ROAMING_CONS_OI_LEN],
3636*03f9172cSAndroid Build Coastguard Worker 			size_t cred_ois_len[MAX_ROAMING_CONS],
3637*03f9172cSAndroid Build Coastguard Worker 			unsigned int *cred_num_ois,
3638*03f9172cSAndroid Build Coastguard Worker 			const char *value)
3639*03f9172cSAndroid Build Coastguard Worker {
3640*03f9172cSAndroid Build Coastguard Worker 	u8 ois[MAX_ROAMING_CONS][MAX_ROAMING_CONS_OI_LEN];
3641*03f9172cSAndroid Build Coastguard Worker 	size_t ois_len[MAX_ROAMING_CONS];
3642*03f9172cSAndroid Build Coastguard Worker 	unsigned int num_ois = 0;
3643*03f9172cSAndroid Build Coastguard Worker 	const char *pos, *end;
3644*03f9172cSAndroid Build Coastguard Worker 	size_t len;
3645*03f9172cSAndroid Build Coastguard Worker 
3646*03f9172cSAndroid Build Coastguard Worker 	len = os_strlen(value);
3647*03f9172cSAndroid Build Coastguard Worker 	if (len / 2 < 3) {
3648*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR,
3649*03f9172cSAndroid Build Coastguard Worker 			   "Invalid organisation identifier (OI) list: %s",
3650*03f9172cSAndroid Build Coastguard Worker 			   value);
3651*03f9172cSAndroid Build Coastguard Worker 		return -1;
3652*03f9172cSAndroid Build Coastguard Worker 	}
3653*03f9172cSAndroid Build Coastguard Worker 
3654*03f9172cSAndroid Build Coastguard Worker 	os_memset(ois, 0, sizeof(ois));
3655*03f9172cSAndroid Build Coastguard Worker 	os_memset(ois_len, 0, sizeof(ois_len));
3656*03f9172cSAndroid Build Coastguard Worker 
3657*03f9172cSAndroid Build Coastguard Worker 	for (pos = value;;) {
3658*03f9172cSAndroid Build Coastguard Worker 		end = os_strchr(pos, ',');
3659*03f9172cSAndroid Build Coastguard Worker 		len = end ? (size_t) (end - pos) : os_strlen(pos);
3660*03f9172cSAndroid Build Coastguard Worker 		if (!end && len == 0)
3661*03f9172cSAndroid Build Coastguard Worker 			break;
3662*03f9172cSAndroid Build Coastguard Worker 		if (len / 2 < 3 || (len & 1) != 0 ||
3663*03f9172cSAndroid Build Coastguard Worker 		    len / 2 > MAX_ROAMING_CONS_OI_LEN ||
3664*03f9172cSAndroid Build Coastguard Worker 		    hexstr2bin(pos,
3665*03f9172cSAndroid Build Coastguard Worker 			       ois[num_ois],
3666*03f9172cSAndroid Build Coastguard Worker 			       len / 2) < 0) {
3667*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_INFO,
3668*03f9172cSAndroid Build Coastguard Worker 				   "Invalid organisation identifier (OI) entry: %s",
3669*03f9172cSAndroid Build Coastguard Worker 				   pos);
3670*03f9172cSAndroid Build Coastguard Worker 			return -1;
3671*03f9172cSAndroid Build Coastguard Worker 		}
3672*03f9172cSAndroid Build Coastguard Worker 		ois_len[num_ois] = len / 2;
3673*03f9172cSAndroid Build Coastguard Worker 		num_ois++;
3674*03f9172cSAndroid Build Coastguard Worker 
3675*03f9172cSAndroid Build Coastguard Worker 		if (!end)
3676*03f9172cSAndroid Build Coastguard Worker 			break;
3677*03f9172cSAndroid Build Coastguard Worker 
3678*03f9172cSAndroid Build Coastguard Worker 		if (num_ois >= MAX_ROAMING_CONS) {
3679*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_INFO,
3680*03f9172cSAndroid Build Coastguard Worker 				   "Too many OIs");
3681*03f9172cSAndroid Build Coastguard Worker 			return -1;
3682*03f9172cSAndroid Build Coastguard Worker 		}
3683*03f9172cSAndroid Build Coastguard Worker 
3684*03f9172cSAndroid Build Coastguard Worker 		pos = end + 1;
3685*03f9172cSAndroid Build Coastguard Worker 	}
3686*03f9172cSAndroid Build Coastguard Worker 
3687*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(cred_ois, ois, sizeof(ois));
3688*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(cred_ois_len, ois_len, sizeof(ois_len));
3689*03f9172cSAndroid Build Coastguard Worker 	*cred_num_ois = num_ois;
3690*03f9172cSAndroid Build Coastguard Worker 
3691*03f9172cSAndroid Build Coastguard Worker 	return 0;
3692*03f9172cSAndroid Build Coastguard Worker }
3693*03f9172cSAndroid Build Coastguard Worker 
3694*03f9172cSAndroid Build Coastguard Worker 
wpa_config_set_cred(struct wpa_cred * cred,const char * var,const char * value,int line)3695*03f9172cSAndroid Build Coastguard Worker int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
3696*03f9172cSAndroid Build Coastguard Worker 			const char *value, int line)
3697*03f9172cSAndroid Build Coastguard Worker {
3698*03f9172cSAndroid Build Coastguard Worker 	char *val;
3699*03f9172cSAndroid Build Coastguard Worker 	size_t len;
3700*03f9172cSAndroid Build Coastguard Worker 	int res;
3701*03f9172cSAndroid Build Coastguard Worker 
3702*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "temporary") == 0) {
3703*03f9172cSAndroid Build Coastguard Worker 		cred->temporary = atoi(value);
3704*03f9172cSAndroid Build Coastguard Worker 		return 0;
3705*03f9172cSAndroid Build Coastguard Worker 	}
3706*03f9172cSAndroid Build Coastguard Worker 
3707*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "priority") == 0) {
3708*03f9172cSAndroid Build Coastguard Worker 		cred->priority = atoi(value);
3709*03f9172cSAndroid Build Coastguard Worker 		return 0;
3710*03f9172cSAndroid Build Coastguard Worker 	}
3711*03f9172cSAndroid Build Coastguard Worker 
3712*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "sp_priority") == 0) {
3713*03f9172cSAndroid Build Coastguard Worker 		int prio = atoi(value);
3714*03f9172cSAndroid Build Coastguard Worker 		if (prio < 0 || prio > 255)
3715*03f9172cSAndroid Build Coastguard Worker 			return -1;
3716*03f9172cSAndroid Build Coastguard Worker 		cred->sp_priority = prio;
3717*03f9172cSAndroid Build Coastguard Worker 		return 0;
3718*03f9172cSAndroid Build Coastguard Worker 	}
3719*03f9172cSAndroid Build Coastguard Worker 
3720*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "pcsc") == 0) {
3721*03f9172cSAndroid Build Coastguard Worker 		cred->pcsc = atoi(value);
3722*03f9172cSAndroid Build Coastguard Worker 		return 0;
3723*03f9172cSAndroid Build Coastguard Worker 	}
3724*03f9172cSAndroid Build Coastguard Worker 
3725*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "eap") == 0) {
3726*03f9172cSAndroid Build Coastguard Worker 		struct eap_method_type method;
3727*03f9172cSAndroid Build Coastguard Worker 		method.method = eap_peer_get_type(value, &method.vendor);
3728*03f9172cSAndroid Build Coastguard Worker 		if (method.vendor == EAP_VENDOR_IETF &&
3729*03f9172cSAndroid Build Coastguard Worker 		    method.method == EAP_TYPE_NONE) {
3730*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: unknown EAP type '%s' "
3731*03f9172cSAndroid Build Coastguard Worker 				   "for a credential", line, value);
3732*03f9172cSAndroid Build Coastguard Worker 			return -1;
3733*03f9172cSAndroid Build Coastguard Worker 		}
3734*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->eap_method);
3735*03f9172cSAndroid Build Coastguard Worker 		cred->eap_method = os_malloc(sizeof(*cred->eap_method));
3736*03f9172cSAndroid Build Coastguard Worker 		if (cred->eap_method == NULL)
3737*03f9172cSAndroid Build Coastguard Worker 			return -1;
3738*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(cred->eap_method, &method, sizeof(method));
3739*03f9172cSAndroid Build Coastguard Worker 		return 0;
3740*03f9172cSAndroid Build Coastguard Worker 	}
3741*03f9172cSAndroid Build Coastguard Worker 
3742*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "password") == 0 &&
3743*03f9172cSAndroid Build Coastguard Worker 	    os_strncmp(value, "ext:", 4) == 0) {
3744*03f9172cSAndroid Build Coastguard Worker 		if (has_newline(value))
3745*03f9172cSAndroid Build Coastguard Worker 			return -1;
3746*03f9172cSAndroid Build Coastguard Worker 		str_clear_free(cred->password);
3747*03f9172cSAndroid Build Coastguard Worker 		cred->password = os_strdup(value);
3748*03f9172cSAndroid Build Coastguard Worker 		cred->ext_password = 1;
3749*03f9172cSAndroid Build Coastguard Worker 		return 0;
3750*03f9172cSAndroid Build Coastguard Worker 	}
3751*03f9172cSAndroid Build Coastguard Worker 
3752*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "update_identifier") == 0) {
3753*03f9172cSAndroid Build Coastguard Worker 		cred->update_identifier = atoi(value);
3754*03f9172cSAndroid Build Coastguard Worker 		return 0;
3755*03f9172cSAndroid Build Coastguard Worker 	}
3756*03f9172cSAndroid Build Coastguard Worker 
3757*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "min_dl_bandwidth_home") == 0) {
3758*03f9172cSAndroid Build Coastguard Worker 		cred->min_dl_bandwidth_home = atoi(value);
3759*03f9172cSAndroid Build Coastguard Worker 		return 0;
3760*03f9172cSAndroid Build Coastguard Worker 	}
3761*03f9172cSAndroid Build Coastguard Worker 
3762*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "min_ul_bandwidth_home") == 0) {
3763*03f9172cSAndroid Build Coastguard Worker 		cred->min_ul_bandwidth_home = atoi(value);
3764*03f9172cSAndroid Build Coastguard Worker 		return 0;
3765*03f9172cSAndroid Build Coastguard Worker 	}
3766*03f9172cSAndroid Build Coastguard Worker 
3767*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "min_dl_bandwidth_roaming") == 0) {
3768*03f9172cSAndroid Build Coastguard Worker 		cred->min_dl_bandwidth_roaming = atoi(value);
3769*03f9172cSAndroid Build Coastguard Worker 		return 0;
3770*03f9172cSAndroid Build Coastguard Worker 	}
3771*03f9172cSAndroid Build Coastguard Worker 
3772*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "min_ul_bandwidth_roaming") == 0) {
3773*03f9172cSAndroid Build Coastguard Worker 		cred->min_ul_bandwidth_roaming = atoi(value);
3774*03f9172cSAndroid Build Coastguard Worker 		return 0;
3775*03f9172cSAndroid Build Coastguard Worker 	}
3776*03f9172cSAndroid Build Coastguard Worker 
3777*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "max_bss_load") == 0) {
3778*03f9172cSAndroid Build Coastguard Worker 		cred->max_bss_load = atoi(value);
3779*03f9172cSAndroid Build Coastguard Worker 		return 0;
3780*03f9172cSAndroid Build Coastguard Worker 	}
3781*03f9172cSAndroid Build Coastguard Worker 
3782*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "req_conn_capab") == 0)
3783*03f9172cSAndroid Build Coastguard Worker 		return wpa_config_set_cred_req_conn_capab(cred, value);
3784*03f9172cSAndroid Build Coastguard Worker 
3785*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "ocsp") == 0) {
3786*03f9172cSAndroid Build Coastguard Worker 		cred->ocsp = atoi(value);
3787*03f9172cSAndroid Build Coastguard Worker 		return 0;
3788*03f9172cSAndroid Build Coastguard Worker 	}
3789*03f9172cSAndroid Build Coastguard Worker 
3790*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "sim_num") == 0) {
3791*03f9172cSAndroid Build Coastguard Worker 		cred->sim_num = atoi(value);
3792*03f9172cSAndroid Build Coastguard Worker 		return 0;
3793*03f9172cSAndroid Build Coastguard Worker 	}
3794*03f9172cSAndroid Build Coastguard Worker 
3795*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "engine") == 0) {
3796*03f9172cSAndroid Build Coastguard Worker 		cred->engine = atoi(value);
3797*03f9172cSAndroid Build Coastguard Worker 		return 0;
3798*03f9172cSAndroid Build Coastguard Worker 	}
3799*03f9172cSAndroid Build Coastguard Worker 
3800*03f9172cSAndroid Build Coastguard Worker 	val = wpa_config_parse_string(value, &len);
3801*03f9172cSAndroid Build Coastguard Worker 	if (val == NULL ||
3802*03f9172cSAndroid Build Coastguard Worker 	    (os_strcmp(var, "excluded_ssid") != 0 &&
3803*03f9172cSAndroid Build Coastguard Worker 	     os_strcmp(var, "roaming_consortium") != 0 &&
3804*03f9172cSAndroid Build Coastguard Worker 	     os_strcmp(var, "required_roaming_consortium") != 0 &&
3805*03f9172cSAndroid Build Coastguard Worker 	     has_newline(val))) {
3806*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: invalid field '%s' string "
3807*03f9172cSAndroid Build Coastguard Worker 			   "value '%s'.", line, var, value);
3808*03f9172cSAndroid Build Coastguard Worker 		os_free(val);
3809*03f9172cSAndroid Build Coastguard Worker 		return -1;
3810*03f9172cSAndroid Build Coastguard Worker 	}
3811*03f9172cSAndroid Build Coastguard Worker 
3812*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "realm") == 0) {
3813*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->realm);
3814*03f9172cSAndroid Build Coastguard Worker 		cred->realm = val;
3815*03f9172cSAndroid Build Coastguard Worker 		return 0;
3816*03f9172cSAndroid Build Coastguard Worker 	}
3817*03f9172cSAndroid Build Coastguard Worker 
3818*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "username") == 0) {
3819*03f9172cSAndroid Build Coastguard Worker 		str_clear_free(cred->username);
3820*03f9172cSAndroid Build Coastguard Worker 		cred->username = val;
3821*03f9172cSAndroid Build Coastguard Worker 		return 0;
3822*03f9172cSAndroid Build Coastguard Worker 	}
3823*03f9172cSAndroid Build Coastguard Worker 
3824*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "password") == 0) {
3825*03f9172cSAndroid Build Coastguard Worker 		str_clear_free(cred->password);
3826*03f9172cSAndroid Build Coastguard Worker 		cred->password = val;
3827*03f9172cSAndroid Build Coastguard Worker 		cred->ext_password = 0;
3828*03f9172cSAndroid Build Coastguard Worker 		return 0;
3829*03f9172cSAndroid Build Coastguard Worker 	}
3830*03f9172cSAndroid Build Coastguard Worker 
3831*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "ca_cert") == 0) {
3832*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->ca_cert);
3833*03f9172cSAndroid Build Coastguard Worker 		cred->ca_cert = val;
3834*03f9172cSAndroid Build Coastguard Worker 		return 0;
3835*03f9172cSAndroid Build Coastguard Worker 	}
3836*03f9172cSAndroid Build Coastguard Worker 
3837*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "client_cert") == 0) {
3838*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->client_cert);
3839*03f9172cSAndroid Build Coastguard Worker 		cred->client_cert = val;
3840*03f9172cSAndroid Build Coastguard Worker 		return 0;
3841*03f9172cSAndroid Build Coastguard Worker 	}
3842*03f9172cSAndroid Build Coastguard Worker 
3843*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "private_key") == 0) {
3844*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->private_key);
3845*03f9172cSAndroid Build Coastguard Worker 		cred->private_key = val;
3846*03f9172cSAndroid Build Coastguard Worker 		return 0;
3847*03f9172cSAndroid Build Coastguard Worker 	}
3848*03f9172cSAndroid Build Coastguard Worker 
3849*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "private_key_passwd") == 0) {
3850*03f9172cSAndroid Build Coastguard Worker 		str_clear_free(cred->private_key_passwd);
3851*03f9172cSAndroid Build Coastguard Worker 		cred->private_key_passwd = val;
3852*03f9172cSAndroid Build Coastguard Worker 		return 0;
3853*03f9172cSAndroid Build Coastguard Worker 	}
3854*03f9172cSAndroid Build Coastguard Worker 
3855*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "engine_id") == 0) {
3856*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->engine_id);
3857*03f9172cSAndroid Build Coastguard Worker 		cred->engine_id = val;
3858*03f9172cSAndroid Build Coastguard Worker 		return 0;
3859*03f9172cSAndroid Build Coastguard Worker 	}
3860*03f9172cSAndroid Build Coastguard Worker 
3861*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "ca_cert_id") == 0) {
3862*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->ca_cert_id);
3863*03f9172cSAndroid Build Coastguard Worker 		cred->ca_cert_id = val;
3864*03f9172cSAndroid Build Coastguard Worker 		return 0;
3865*03f9172cSAndroid Build Coastguard Worker 	}
3866*03f9172cSAndroid Build Coastguard Worker 
3867*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "cert_id") == 0) {
3868*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->cert_id);
3869*03f9172cSAndroid Build Coastguard Worker 		cred->cert_id = val;
3870*03f9172cSAndroid Build Coastguard Worker 		return 0;
3871*03f9172cSAndroid Build Coastguard Worker 	}
3872*03f9172cSAndroid Build Coastguard Worker 
3873*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "key_id") == 0) {
3874*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->key_id);
3875*03f9172cSAndroid Build Coastguard Worker 		cred->key_id = val;
3876*03f9172cSAndroid Build Coastguard Worker 		return 0;
3877*03f9172cSAndroid Build Coastguard Worker 	}
3878*03f9172cSAndroid Build Coastguard Worker 
3879*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "imsi") == 0) {
3880*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->imsi);
3881*03f9172cSAndroid Build Coastguard Worker 		cred->imsi = val;
3882*03f9172cSAndroid Build Coastguard Worker 		return 0;
3883*03f9172cSAndroid Build Coastguard Worker 	}
3884*03f9172cSAndroid Build Coastguard Worker 
3885*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "milenage") == 0) {
3886*03f9172cSAndroid Build Coastguard Worker 		str_clear_free(cred->milenage);
3887*03f9172cSAndroid Build Coastguard Worker 		cred->milenage = val;
3888*03f9172cSAndroid Build Coastguard Worker 		return 0;
3889*03f9172cSAndroid Build Coastguard Worker 	}
3890*03f9172cSAndroid Build Coastguard Worker 
3891*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "domain_suffix_match") == 0) {
3892*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->domain_suffix_match);
3893*03f9172cSAndroid Build Coastguard Worker 		cred->domain_suffix_match = val;
3894*03f9172cSAndroid Build Coastguard Worker 		return 0;
3895*03f9172cSAndroid Build Coastguard Worker 	}
3896*03f9172cSAndroid Build Coastguard Worker 
3897*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "domain") == 0) {
3898*03f9172cSAndroid Build Coastguard Worker 		char **new_domain;
3899*03f9172cSAndroid Build Coastguard Worker 		new_domain = os_realloc_array(cred->domain,
3900*03f9172cSAndroid Build Coastguard Worker 					      cred->num_domain + 1,
3901*03f9172cSAndroid Build Coastguard Worker 					      sizeof(char *));
3902*03f9172cSAndroid Build Coastguard Worker 		if (new_domain == NULL) {
3903*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
3904*03f9172cSAndroid Build Coastguard Worker 			return -1;
3905*03f9172cSAndroid Build Coastguard Worker 		}
3906*03f9172cSAndroid Build Coastguard Worker 		new_domain[cred->num_domain++] = val;
3907*03f9172cSAndroid Build Coastguard Worker 		cred->domain = new_domain;
3908*03f9172cSAndroid Build Coastguard Worker 		return 0;
3909*03f9172cSAndroid Build Coastguard Worker 	}
3910*03f9172cSAndroid Build Coastguard Worker 
3911*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "phase1") == 0) {
3912*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->phase1);
3913*03f9172cSAndroid Build Coastguard Worker 		cred->phase1 = val;
3914*03f9172cSAndroid Build Coastguard Worker 		return 0;
3915*03f9172cSAndroid Build Coastguard Worker 	}
3916*03f9172cSAndroid Build Coastguard Worker 
3917*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "phase2") == 0) {
3918*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->phase2);
3919*03f9172cSAndroid Build Coastguard Worker 		cred->phase2 = val;
3920*03f9172cSAndroid Build Coastguard Worker 		return 0;
3921*03f9172cSAndroid Build Coastguard Worker 	}
3922*03f9172cSAndroid Build Coastguard Worker 
3923*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "roaming_consortium") == 0) {
3924*03f9172cSAndroid Build Coastguard Worker 		if (len < 3 || len > sizeof(cred->home_ois[0])) {
3925*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: invalid "
3926*03f9172cSAndroid Build Coastguard Worker 				   "roaming_consortium length %d (3..15 "
3927*03f9172cSAndroid Build Coastguard Worker 				   "expected)", line, (int) len);
3928*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
3929*03f9172cSAndroid Build Coastguard Worker 			return -1;
3930*03f9172cSAndroid Build Coastguard Worker 		}
3931*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_WARNING,
3932*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: option roaming_consortium is deprecated and will be removed in the future",
3933*03f9172cSAndroid Build Coastguard Worker 			   line);
3934*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(cred->home_ois[0], val, len);
3935*03f9172cSAndroid Build Coastguard Worker 		cred->home_ois_len[0] = len;
3936*03f9172cSAndroid Build Coastguard Worker 		cred->num_home_ois = 1;
3937*03f9172cSAndroid Build Coastguard Worker 		os_free(val);
3938*03f9172cSAndroid Build Coastguard Worker 		return 0;
3939*03f9172cSAndroid Build Coastguard Worker 	}
3940*03f9172cSAndroid Build Coastguard Worker 
3941*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "required_roaming_consortium") == 0) {
3942*03f9172cSAndroid Build Coastguard Worker 		if (len < 3 || len > sizeof(cred->required_home_ois[0])) {
3943*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: invalid "
3944*03f9172cSAndroid Build Coastguard Worker 				   "required_roaming_consortium length %d "
3945*03f9172cSAndroid Build Coastguard Worker 				   "(3..15 expected)", line, (int) len);
3946*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
3947*03f9172cSAndroid Build Coastguard Worker 			return -1;
3948*03f9172cSAndroid Build Coastguard Worker 		}
3949*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_WARNING,
3950*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: option required_roaming_consortium is deprecated and will be removed in the future",
3951*03f9172cSAndroid Build Coastguard Worker 			   line);
3952*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(cred->required_home_ois[0], val, len);
3953*03f9172cSAndroid Build Coastguard Worker 		cred->required_home_ois_len[0] = len;
3954*03f9172cSAndroid Build Coastguard Worker 		cred->num_required_home_ois = 1;
3955*03f9172cSAndroid Build Coastguard Worker 		os_free(val);
3956*03f9172cSAndroid Build Coastguard Worker 		return 0;
3957*03f9172cSAndroid Build Coastguard Worker 	}
3958*03f9172cSAndroid Build Coastguard Worker 
3959*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "home_ois") == 0) {
3960*03f9172cSAndroid Build Coastguard Worker 		res = wpa_config_set_cred_ois(cred->home_ois,
3961*03f9172cSAndroid Build Coastguard Worker 					      cred->home_ois_len,
3962*03f9172cSAndroid Build Coastguard Worker 					      &cred->num_home_ois,
3963*03f9172cSAndroid Build Coastguard Worker 					      val);
3964*03f9172cSAndroid Build Coastguard Worker 		if (res < 0)
3965*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: invalid home_ois",
3966*03f9172cSAndroid Build Coastguard Worker 				   line);
3967*03f9172cSAndroid Build Coastguard Worker 		os_free(val);
3968*03f9172cSAndroid Build Coastguard Worker 		return res;
3969*03f9172cSAndroid Build Coastguard Worker 	}
3970*03f9172cSAndroid Build Coastguard Worker 
3971*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "required_home_ois") == 0) {
3972*03f9172cSAndroid Build Coastguard Worker 		res = wpa_config_set_cred_ois(cred->required_home_ois,
3973*03f9172cSAndroid Build Coastguard Worker 					      cred->required_home_ois_len,
3974*03f9172cSAndroid Build Coastguard Worker 					      &cred->num_required_home_ois,
3975*03f9172cSAndroid Build Coastguard Worker 					      val);
3976*03f9172cSAndroid Build Coastguard Worker 		if (res < 0)
3977*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR,
3978*03f9172cSAndroid Build Coastguard Worker 				   "Line %d: invalid required_home_ois", line);
3979*03f9172cSAndroid Build Coastguard Worker 		os_free(val);
3980*03f9172cSAndroid Build Coastguard Worker 		return res;
3981*03f9172cSAndroid Build Coastguard Worker 	}
3982*03f9172cSAndroid Build Coastguard Worker 
3983*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "roaming_consortiums") == 0) {
3984*03f9172cSAndroid Build Coastguard Worker 		res = wpa_config_set_cred_ois(cred->roaming_consortiums,
3985*03f9172cSAndroid Build Coastguard Worker 					      cred->roaming_consortiums_len,
3986*03f9172cSAndroid Build Coastguard Worker 					      &cred->num_roaming_consortiums,
3987*03f9172cSAndroid Build Coastguard Worker 					      val);
3988*03f9172cSAndroid Build Coastguard Worker 		if (res < 0)
3989*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR,
3990*03f9172cSAndroid Build Coastguard Worker 				   "Line %d: invalid roaming_consortiums",
3991*03f9172cSAndroid Build Coastguard Worker 				   line);
3992*03f9172cSAndroid Build Coastguard Worker 		os_free(val);
3993*03f9172cSAndroid Build Coastguard Worker 		return res;
3994*03f9172cSAndroid Build Coastguard Worker 	}
3995*03f9172cSAndroid Build Coastguard Worker 
3996*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "excluded_ssid") == 0) {
3997*03f9172cSAndroid Build Coastguard Worker 		struct excluded_ssid *e;
3998*03f9172cSAndroid Build Coastguard Worker 
3999*03f9172cSAndroid Build Coastguard Worker 		if (len > SSID_MAX_LEN) {
4000*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: invalid "
4001*03f9172cSAndroid Build Coastguard Worker 				   "excluded_ssid length %d", line, (int) len);
4002*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
4003*03f9172cSAndroid Build Coastguard Worker 			return -1;
4004*03f9172cSAndroid Build Coastguard Worker 		}
4005*03f9172cSAndroid Build Coastguard Worker 
4006*03f9172cSAndroid Build Coastguard Worker 		e = os_realloc_array(cred->excluded_ssid,
4007*03f9172cSAndroid Build Coastguard Worker 				     cred->num_excluded_ssid + 1,
4008*03f9172cSAndroid Build Coastguard Worker 				     sizeof(struct excluded_ssid));
4009*03f9172cSAndroid Build Coastguard Worker 		if (e == NULL) {
4010*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
4011*03f9172cSAndroid Build Coastguard Worker 			return -1;
4012*03f9172cSAndroid Build Coastguard Worker 		}
4013*03f9172cSAndroid Build Coastguard Worker 		cred->excluded_ssid = e;
4014*03f9172cSAndroid Build Coastguard Worker 
4015*03f9172cSAndroid Build Coastguard Worker 		e = &cred->excluded_ssid[cred->num_excluded_ssid++];
4016*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(e->ssid, val, len);
4017*03f9172cSAndroid Build Coastguard Worker 		e->ssid_len = len;
4018*03f9172cSAndroid Build Coastguard Worker 
4019*03f9172cSAndroid Build Coastguard Worker 		os_free(val);
4020*03f9172cSAndroid Build Coastguard Worker 
4021*03f9172cSAndroid Build Coastguard Worker 		return 0;
4022*03f9172cSAndroid Build Coastguard Worker 	}
4023*03f9172cSAndroid Build Coastguard Worker 
4024*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "roaming_partner") == 0) {
4025*03f9172cSAndroid Build Coastguard Worker 		struct roaming_partner *p;
4026*03f9172cSAndroid Build Coastguard Worker 		char *pos;
4027*03f9172cSAndroid Build Coastguard Worker 
4028*03f9172cSAndroid Build Coastguard Worker 		p = os_realloc_array(cred->roaming_partner,
4029*03f9172cSAndroid Build Coastguard Worker 				     cred->num_roaming_partner + 1,
4030*03f9172cSAndroid Build Coastguard Worker 				     sizeof(struct roaming_partner));
4031*03f9172cSAndroid Build Coastguard Worker 		if (p == NULL) {
4032*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
4033*03f9172cSAndroid Build Coastguard Worker 			return -1;
4034*03f9172cSAndroid Build Coastguard Worker 		}
4035*03f9172cSAndroid Build Coastguard Worker 		cred->roaming_partner = p;
4036*03f9172cSAndroid Build Coastguard Worker 
4037*03f9172cSAndroid Build Coastguard Worker 		p = &cred->roaming_partner[cred->num_roaming_partner];
4038*03f9172cSAndroid Build Coastguard Worker 
4039*03f9172cSAndroid Build Coastguard Worker 		pos = os_strchr(val, ',');
4040*03f9172cSAndroid Build Coastguard Worker 		if (pos == NULL) {
4041*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
4042*03f9172cSAndroid Build Coastguard Worker 			return -1;
4043*03f9172cSAndroid Build Coastguard Worker 		}
4044*03f9172cSAndroid Build Coastguard Worker 		*pos++ = '\0';
4045*03f9172cSAndroid Build Coastguard Worker 		if (pos - val - 1 >= (int) sizeof(p->fqdn)) {
4046*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
4047*03f9172cSAndroid Build Coastguard Worker 			return -1;
4048*03f9172cSAndroid Build Coastguard Worker 		}
4049*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(p->fqdn, val, pos - val);
4050*03f9172cSAndroid Build Coastguard Worker 
4051*03f9172cSAndroid Build Coastguard Worker 		p->exact_match = atoi(pos);
4052*03f9172cSAndroid Build Coastguard Worker 
4053*03f9172cSAndroid Build Coastguard Worker 		pos = os_strchr(pos, ',');
4054*03f9172cSAndroid Build Coastguard Worker 		if (pos == NULL) {
4055*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
4056*03f9172cSAndroid Build Coastguard Worker 			return -1;
4057*03f9172cSAndroid Build Coastguard Worker 		}
4058*03f9172cSAndroid Build Coastguard Worker 		*pos++ = '\0';
4059*03f9172cSAndroid Build Coastguard Worker 
4060*03f9172cSAndroid Build Coastguard Worker 		p->priority = atoi(pos);
4061*03f9172cSAndroid Build Coastguard Worker 
4062*03f9172cSAndroid Build Coastguard Worker 		pos = os_strchr(pos, ',');
4063*03f9172cSAndroid Build Coastguard Worker 		if (pos == NULL) {
4064*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
4065*03f9172cSAndroid Build Coastguard Worker 			return -1;
4066*03f9172cSAndroid Build Coastguard Worker 		}
4067*03f9172cSAndroid Build Coastguard Worker 		*pos++ = '\0';
4068*03f9172cSAndroid Build Coastguard Worker 
4069*03f9172cSAndroid Build Coastguard Worker 		if (os_strlen(pos) >= sizeof(p->country)) {
4070*03f9172cSAndroid Build Coastguard Worker 			os_free(val);
4071*03f9172cSAndroid Build Coastguard Worker 			return -1;
4072*03f9172cSAndroid Build Coastguard Worker 		}
4073*03f9172cSAndroid Build Coastguard Worker 		os_memcpy(p->country, pos, os_strlen(pos) + 1);
4074*03f9172cSAndroid Build Coastguard Worker 
4075*03f9172cSAndroid Build Coastguard Worker 		cred->num_roaming_partner++;
4076*03f9172cSAndroid Build Coastguard Worker 		os_free(val);
4077*03f9172cSAndroid Build Coastguard Worker 
4078*03f9172cSAndroid Build Coastguard Worker 		return 0;
4079*03f9172cSAndroid Build Coastguard Worker 	}
4080*03f9172cSAndroid Build Coastguard Worker 
4081*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "provisioning_sp") == 0) {
4082*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->provisioning_sp);
4083*03f9172cSAndroid Build Coastguard Worker 		cred->provisioning_sp = val;
4084*03f9172cSAndroid Build Coastguard Worker 		return 0;
4085*03f9172cSAndroid Build Coastguard Worker 	}
4086*03f9172cSAndroid Build Coastguard Worker 
4087*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "imsi_privacy_cert") == 0) {
4088*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->imsi_privacy_cert);
4089*03f9172cSAndroid Build Coastguard Worker 		cred->imsi_privacy_cert = val;
4090*03f9172cSAndroid Build Coastguard Worker 		return 0;
4091*03f9172cSAndroid Build Coastguard Worker 	}
4092*03f9172cSAndroid Build Coastguard Worker 
4093*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "imsi_privacy_attr") == 0) {
4094*03f9172cSAndroid Build Coastguard Worker 		os_free(cred->imsi_privacy_attr);
4095*03f9172cSAndroid Build Coastguard Worker 		cred->imsi_privacy_attr = val;
4096*03f9172cSAndroid Build Coastguard Worker 		return 0;
4097*03f9172cSAndroid Build Coastguard Worker 	}
4098*03f9172cSAndroid Build Coastguard Worker 
4099*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "strict_conservative_peer_mode") == 0) {
4100*03f9172cSAndroid Build Coastguard Worker 		cred->strict_conservative_peer_mode = atoi(val);
4101*03f9172cSAndroid Build Coastguard Worker 		return 0;
4102*03f9172cSAndroid Build Coastguard Worker 	}
4103*03f9172cSAndroid Build Coastguard Worker 
4104*03f9172cSAndroid Build Coastguard Worker 	if (line) {
4105*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
4106*03f9172cSAndroid Build Coastguard Worker 			   line, var);
4107*03f9172cSAndroid Build Coastguard Worker 	}
4108*03f9172cSAndroid Build Coastguard Worker 
4109*03f9172cSAndroid Build Coastguard Worker 	os_free(val);
4110*03f9172cSAndroid Build Coastguard Worker 
4111*03f9172cSAndroid Build Coastguard Worker 	return -1;
4112*03f9172cSAndroid Build Coastguard Worker }
4113*03f9172cSAndroid Build Coastguard Worker 
4114*03f9172cSAndroid Build Coastguard Worker 
alloc_int_str(int val)4115*03f9172cSAndroid Build Coastguard Worker static char * alloc_int_str(int val)
4116*03f9172cSAndroid Build Coastguard Worker {
4117*03f9172cSAndroid Build Coastguard Worker 	const unsigned int bufsize = 20;
4118*03f9172cSAndroid Build Coastguard Worker 	char *buf;
4119*03f9172cSAndroid Build Coastguard Worker 	int res;
4120*03f9172cSAndroid Build Coastguard Worker 
4121*03f9172cSAndroid Build Coastguard Worker 	buf = os_malloc(bufsize);
4122*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
4123*03f9172cSAndroid Build Coastguard Worker 		return NULL;
4124*03f9172cSAndroid Build Coastguard Worker 	res = os_snprintf(buf, bufsize, "%d", val);
4125*03f9172cSAndroid Build Coastguard Worker 	if (os_snprintf_error(bufsize, res)) {
4126*03f9172cSAndroid Build Coastguard Worker 		os_free(buf);
4127*03f9172cSAndroid Build Coastguard Worker 		buf = NULL;
4128*03f9172cSAndroid Build Coastguard Worker 	}
4129*03f9172cSAndroid Build Coastguard Worker 	return buf;
4130*03f9172cSAndroid Build Coastguard Worker }
4131*03f9172cSAndroid Build Coastguard Worker 
4132*03f9172cSAndroid Build Coastguard Worker 
alloc_strdup(const char * str)4133*03f9172cSAndroid Build Coastguard Worker static char * alloc_strdup(const char *str)
4134*03f9172cSAndroid Build Coastguard Worker {
4135*03f9172cSAndroid Build Coastguard Worker 	if (str == NULL)
4136*03f9172cSAndroid Build Coastguard Worker 		return NULL;
4137*03f9172cSAndroid Build Coastguard Worker 	return os_strdup(str);
4138*03f9172cSAndroid Build Coastguard Worker }
4139*03f9172cSAndroid Build Coastguard Worker 
4140*03f9172cSAndroid Build Coastguard Worker 
wpa_config_get_cred_no_key(struct wpa_cred * cred,const char * var)4141*03f9172cSAndroid Build Coastguard Worker char * wpa_config_get_cred_no_key(struct wpa_cred *cred, const char *var)
4142*03f9172cSAndroid Build Coastguard Worker {
4143*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "temporary") == 0)
4144*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->temporary);
4145*03f9172cSAndroid Build Coastguard Worker 
4146*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "priority") == 0)
4147*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->priority);
4148*03f9172cSAndroid Build Coastguard Worker 
4149*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "sp_priority") == 0)
4150*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->sp_priority);
4151*03f9172cSAndroid Build Coastguard Worker 
4152*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "pcsc") == 0)
4153*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->pcsc);
4154*03f9172cSAndroid Build Coastguard Worker 
4155*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "eap") == 0) {
4156*03f9172cSAndroid Build Coastguard Worker 		if (!cred->eap_method)
4157*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4158*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(eap_get_name(cred->eap_method[0].vendor,
4159*03f9172cSAndroid Build Coastguard Worker 						 cred->eap_method[0].method));
4160*03f9172cSAndroid Build Coastguard Worker 	}
4161*03f9172cSAndroid Build Coastguard Worker 
4162*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "update_identifier") == 0)
4163*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->update_identifier);
4164*03f9172cSAndroid Build Coastguard Worker 
4165*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "min_dl_bandwidth_home") == 0)
4166*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->min_dl_bandwidth_home);
4167*03f9172cSAndroid Build Coastguard Worker 
4168*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "min_ul_bandwidth_home") == 0)
4169*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->min_ul_bandwidth_home);
4170*03f9172cSAndroid Build Coastguard Worker 
4171*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "min_dl_bandwidth_roaming") == 0)
4172*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->min_dl_bandwidth_roaming);
4173*03f9172cSAndroid Build Coastguard Worker 
4174*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "min_ul_bandwidth_roaming") == 0)
4175*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->min_ul_bandwidth_roaming);
4176*03f9172cSAndroid Build Coastguard Worker 
4177*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "max_bss_load") == 0)
4178*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->max_bss_load);
4179*03f9172cSAndroid Build Coastguard Worker 
4180*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "req_conn_capab") == 0) {
4181*03f9172cSAndroid Build Coastguard Worker 		unsigned int i;
4182*03f9172cSAndroid Build Coastguard Worker 		char *buf, *end, *pos;
4183*03f9172cSAndroid Build Coastguard Worker 		int ret;
4184*03f9172cSAndroid Build Coastguard Worker 
4185*03f9172cSAndroid Build Coastguard Worker 		if (!cred->num_req_conn_capab)
4186*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4187*03f9172cSAndroid Build Coastguard Worker 
4188*03f9172cSAndroid Build Coastguard Worker 		buf = os_malloc(4000);
4189*03f9172cSAndroid Build Coastguard Worker 		if (buf == NULL)
4190*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4191*03f9172cSAndroid Build Coastguard Worker 		pos = buf;
4192*03f9172cSAndroid Build Coastguard Worker 		end = pos + 4000;
4193*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; i < cred->num_req_conn_capab; i++) {
4194*03f9172cSAndroid Build Coastguard Worker 			int *ports;
4195*03f9172cSAndroid Build Coastguard Worker 
4196*03f9172cSAndroid Build Coastguard Worker 			ret = os_snprintf(pos, end - pos, "%s%u",
4197*03f9172cSAndroid Build Coastguard Worker 					  i > 0 ? "\n" : "",
4198*03f9172cSAndroid Build Coastguard Worker 					  cred->req_conn_capab_proto[i]);
4199*03f9172cSAndroid Build Coastguard Worker 			if (os_snprintf_error(end - pos, ret))
4200*03f9172cSAndroid Build Coastguard Worker 				return buf;
4201*03f9172cSAndroid Build Coastguard Worker 			pos += ret;
4202*03f9172cSAndroid Build Coastguard Worker 
4203*03f9172cSAndroid Build Coastguard Worker 			ports = cred->req_conn_capab_port[i];
4204*03f9172cSAndroid Build Coastguard Worker 			if (ports) {
4205*03f9172cSAndroid Build Coastguard Worker 				int j;
4206*03f9172cSAndroid Build Coastguard Worker 				for (j = 0; ports[j] != -1; j++) {
4207*03f9172cSAndroid Build Coastguard Worker 					ret = os_snprintf(pos, end - pos,
4208*03f9172cSAndroid Build Coastguard Worker 							  "%s%d",
4209*03f9172cSAndroid Build Coastguard Worker 							  j > 0 ? "," : ":",
4210*03f9172cSAndroid Build Coastguard Worker 							  ports[j]);
4211*03f9172cSAndroid Build Coastguard Worker 					if (os_snprintf_error(end - pos, ret))
4212*03f9172cSAndroid Build Coastguard Worker 						return buf;
4213*03f9172cSAndroid Build Coastguard Worker 					pos += ret;
4214*03f9172cSAndroid Build Coastguard Worker 				}
4215*03f9172cSAndroid Build Coastguard Worker 			}
4216*03f9172cSAndroid Build Coastguard Worker 		}
4217*03f9172cSAndroid Build Coastguard Worker 
4218*03f9172cSAndroid Build Coastguard Worker 		return buf;
4219*03f9172cSAndroid Build Coastguard Worker 	}
4220*03f9172cSAndroid Build Coastguard Worker 
4221*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "ocsp") == 0)
4222*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->ocsp);
4223*03f9172cSAndroid Build Coastguard Worker 
4224*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "realm") == 0)
4225*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->realm);
4226*03f9172cSAndroid Build Coastguard Worker 
4227*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "username") == 0)
4228*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->username);
4229*03f9172cSAndroid Build Coastguard Worker 
4230*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "password") == 0) {
4231*03f9172cSAndroid Build Coastguard Worker 		if (!cred->password)
4232*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4233*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup("*");
4234*03f9172cSAndroid Build Coastguard Worker 	}
4235*03f9172cSAndroid Build Coastguard Worker 
4236*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "ca_cert") == 0)
4237*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->ca_cert);
4238*03f9172cSAndroid Build Coastguard Worker 
4239*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "client_cert") == 0)
4240*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->client_cert);
4241*03f9172cSAndroid Build Coastguard Worker 
4242*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "private_key") == 0)
4243*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->private_key);
4244*03f9172cSAndroid Build Coastguard Worker 
4245*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "private_key_passwd") == 0) {
4246*03f9172cSAndroid Build Coastguard Worker 		if (!cred->private_key_passwd)
4247*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4248*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup("*");
4249*03f9172cSAndroid Build Coastguard Worker 	}
4250*03f9172cSAndroid Build Coastguard Worker 
4251*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "imsi") == 0)
4252*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->imsi);
4253*03f9172cSAndroid Build Coastguard Worker 
4254*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "imsi_privacy_cert") == 0)
4255*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->imsi_privacy_cert);
4256*03f9172cSAndroid Build Coastguard Worker 
4257*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "imsi_privacy_attr") == 0)
4258*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->imsi_privacy_attr);
4259*03f9172cSAndroid Build Coastguard Worker 
4260*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "strict_conservative_peer_mode") == 0)
4261*03f9172cSAndroid Build Coastguard Worker 		return alloc_int_str(cred->strict_conservative_peer_mode);
4262*03f9172cSAndroid Build Coastguard Worker 
4263*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "milenage") == 0) {
4264*03f9172cSAndroid Build Coastguard Worker 		if (!(cred->milenage))
4265*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4266*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup("*");
4267*03f9172cSAndroid Build Coastguard Worker 	}
4268*03f9172cSAndroid Build Coastguard Worker 
4269*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "domain_suffix_match") == 0)
4270*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->domain_suffix_match);
4271*03f9172cSAndroid Build Coastguard Worker 
4272*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "domain") == 0) {
4273*03f9172cSAndroid Build Coastguard Worker 		unsigned int i;
4274*03f9172cSAndroid Build Coastguard Worker 		char *buf, *end, *pos;
4275*03f9172cSAndroid Build Coastguard Worker 		int ret;
4276*03f9172cSAndroid Build Coastguard Worker 
4277*03f9172cSAndroid Build Coastguard Worker 		if (!cred->num_domain)
4278*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4279*03f9172cSAndroid Build Coastguard Worker 
4280*03f9172cSAndroid Build Coastguard Worker 		buf = os_malloc(4000);
4281*03f9172cSAndroid Build Coastguard Worker 		if (buf == NULL)
4282*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4283*03f9172cSAndroid Build Coastguard Worker 		pos = buf;
4284*03f9172cSAndroid Build Coastguard Worker 		end = pos + 4000;
4285*03f9172cSAndroid Build Coastguard Worker 
4286*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; i < cred->num_domain; i++) {
4287*03f9172cSAndroid Build Coastguard Worker 			ret = os_snprintf(pos, end - pos, "%s%s",
4288*03f9172cSAndroid Build Coastguard Worker 					  i > 0 ? "\n" : "", cred->domain[i]);
4289*03f9172cSAndroid Build Coastguard Worker 			if (os_snprintf_error(end - pos, ret))
4290*03f9172cSAndroid Build Coastguard Worker 				return buf;
4291*03f9172cSAndroid Build Coastguard Worker 			pos += ret;
4292*03f9172cSAndroid Build Coastguard Worker 		}
4293*03f9172cSAndroid Build Coastguard Worker 
4294*03f9172cSAndroid Build Coastguard Worker 		return buf;
4295*03f9172cSAndroid Build Coastguard Worker 	}
4296*03f9172cSAndroid Build Coastguard Worker 
4297*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "phase1") == 0)
4298*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->phase1);
4299*03f9172cSAndroid Build Coastguard Worker 
4300*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "phase2") == 0)
4301*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->phase2);
4302*03f9172cSAndroid Build Coastguard Worker 
4303*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "roaming_consortium") == 0) {
4304*03f9172cSAndroid Build Coastguard Worker 		size_t buflen;
4305*03f9172cSAndroid Build Coastguard Worker 		char *buf;
4306*03f9172cSAndroid Build Coastguard Worker 
4307*03f9172cSAndroid Build Coastguard Worker 		if (!cred->num_home_ois || !cred->home_ois_len[0])
4308*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4309*03f9172cSAndroid Build Coastguard Worker 		buflen = cred->home_ois_len[0] * 2 + 1;
4310*03f9172cSAndroid Build Coastguard Worker 		buf = os_malloc(buflen);
4311*03f9172cSAndroid Build Coastguard Worker 		if (buf == NULL)
4312*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4313*03f9172cSAndroid Build Coastguard Worker 		wpa_snprintf_hex(buf, buflen, cred->home_ois[0],
4314*03f9172cSAndroid Build Coastguard Worker 				 cred->home_ois_len[0]);
4315*03f9172cSAndroid Build Coastguard Worker 		return buf;
4316*03f9172cSAndroid Build Coastguard Worker 	}
4317*03f9172cSAndroid Build Coastguard Worker 
4318*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "required_roaming_consortium") == 0) {
4319*03f9172cSAndroid Build Coastguard Worker 		size_t buflen;
4320*03f9172cSAndroid Build Coastguard Worker 		char *buf;
4321*03f9172cSAndroid Build Coastguard Worker 
4322*03f9172cSAndroid Build Coastguard Worker 		if (!cred->num_required_home_ois ||
4323*03f9172cSAndroid Build Coastguard Worker 		    !cred->required_home_ois_len[0])
4324*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4325*03f9172cSAndroid Build Coastguard Worker 		buflen = cred->required_home_ois_len[0] * 2 + 1;
4326*03f9172cSAndroid Build Coastguard Worker 		buf = os_malloc(buflen);
4327*03f9172cSAndroid Build Coastguard Worker 		if (buf == NULL)
4328*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4329*03f9172cSAndroid Build Coastguard Worker 		wpa_snprintf_hex(buf, buflen, cred->required_home_ois[0],
4330*03f9172cSAndroid Build Coastguard Worker 				 cred->required_home_ois_len[0]);
4331*03f9172cSAndroid Build Coastguard Worker 		return buf;
4332*03f9172cSAndroid Build Coastguard Worker 	}
4333*03f9172cSAndroid Build Coastguard Worker 
4334*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "home_ois") == 0) {
4335*03f9172cSAndroid Build Coastguard Worker 		size_t buflen;
4336*03f9172cSAndroid Build Coastguard Worker 		char *buf, *pos;
4337*03f9172cSAndroid Build Coastguard Worker 		size_t i;
4338*03f9172cSAndroid Build Coastguard Worker 
4339*03f9172cSAndroid Build Coastguard Worker 		if (!cred->num_home_ois)
4340*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4341*03f9172cSAndroid Build Coastguard Worker 		buflen = cred->num_home_ois * MAX_ROAMING_CONS_OI_LEN * 2 + 1;
4342*03f9172cSAndroid Build Coastguard Worker 		buf = os_malloc(buflen);
4343*03f9172cSAndroid Build Coastguard Worker 		if (!buf)
4344*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4345*03f9172cSAndroid Build Coastguard Worker 		pos = buf;
4346*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; i < cred->num_home_ois; i++) {
4347*03f9172cSAndroid Build Coastguard Worker 			if (i > 0)
4348*03f9172cSAndroid Build Coastguard Worker 				*pos++ = ',';
4349*03f9172cSAndroid Build Coastguard Worker 			pos += wpa_snprintf_hex(
4350*03f9172cSAndroid Build Coastguard Worker 				pos, buf + buflen - pos,
4351*03f9172cSAndroid Build Coastguard Worker 				cred->home_ois[i],
4352*03f9172cSAndroid Build Coastguard Worker 				cred->home_ois_len[i]);
4353*03f9172cSAndroid Build Coastguard Worker 		}
4354*03f9172cSAndroid Build Coastguard Worker 		*pos = '\0';
4355*03f9172cSAndroid Build Coastguard Worker 		return buf;
4356*03f9172cSAndroid Build Coastguard Worker 	}
4357*03f9172cSAndroid Build Coastguard Worker 
4358*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "required_home_ois") == 0) {
4359*03f9172cSAndroid Build Coastguard Worker 		size_t buflen;
4360*03f9172cSAndroid Build Coastguard Worker 		char *buf, *pos;
4361*03f9172cSAndroid Build Coastguard Worker 		size_t i;
4362*03f9172cSAndroid Build Coastguard Worker 
4363*03f9172cSAndroid Build Coastguard Worker 		if (!cred->num_required_home_ois)
4364*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4365*03f9172cSAndroid Build Coastguard Worker 		buflen = cred->num_required_home_ois *
4366*03f9172cSAndroid Build Coastguard Worker 			MAX_ROAMING_CONS_OI_LEN * 2 + 1;
4367*03f9172cSAndroid Build Coastguard Worker 		buf = os_malloc(buflen);
4368*03f9172cSAndroid Build Coastguard Worker 		if (!buf)
4369*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4370*03f9172cSAndroid Build Coastguard Worker 		pos = buf;
4371*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; i < cred->num_required_home_ois; i++) {
4372*03f9172cSAndroid Build Coastguard Worker 			if (i > 0)
4373*03f9172cSAndroid Build Coastguard Worker 				*pos++ = ',';
4374*03f9172cSAndroid Build Coastguard Worker 			pos += wpa_snprintf_hex(
4375*03f9172cSAndroid Build Coastguard Worker 				pos, buf + buflen - pos,
4376*03f9172cSAndroid Build Coastguard Worker 				cred->required_home_ois[i],
4377*03f9172cSAndroid Build Coastguard Worker 				cred->required_home_ois_len[i]);
4378*03f9172cSAndroid Build Coastguard Worker 		}
4379*03f9172cSAndroid Build Coastguard Worker 		*pos = '\0';
4380*03f9172cSAndroid Build Coastguard Worker 		return buf;
4381*03f9172cSAndroid Build Coastguard Worker 	}
4382*03f9172cSAndroid Build Coastguard Worker 
4383*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "roaming_consortiums") == 0) {
4384*03f9172cSAndroid Build Coastguard Worker 		size_t buflen;
4385*03f9172cSAndroid Build Coastguard Worker 		char *buf, *pos;
4386*03f9172cSAndroid Build Coastguard Worker 		size_t i;
4387*03f9172cSAndroid Build Coastguard Worker 
4388*03f9172cSAndroid Build Coastguard Worker 		if (!cred->num_roaming_consortiums)
4389*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4390*03f9172cSAndroid Build Coastguard Worker 		buflen = cred->num_roaming_consortiums *
4391*03f9172cSAndroid Build Coastguard Worker 			MAX_ROAMING_CONS_OI_LEN * 2 + 1;
4392*03f9172cSAndroid Build Coastguard Worker 		buf = os_malloc(buflen);
4393*03f9172cSAndroid Build Coastguard Worker 		if (!buf)
4394*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4395*03f9172cSAndroid Build Coastguard Worker 		pos = buf;
4396*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; i < cred->num_roaming_consortiums; i++) {
4397*03f9172cSAndroid Build Coastguard Worker 			if (i > 0)
4398*03f9172cSAndroid Build Coastguard Worker 				*pos++ = ',';
4399*03f9172cSAndroid Build Coastguard Worker 			pos += wpa_snprintf_hex(
4400*03f9172cSAndroid Build Coastguard Worker 				pos, buf + buflen - pos,
4401*03f9172cSAndroid Build Coastguard Worker 				cred->roaming_consortiums[i],
4402*03f9172cSAndroid Build Coastguard Worker 				cred->roaming_consortiums_len[i]);
4403*03f9172cSAndroid Build Coastguard Worker 		}
4404*03f9172cSAndroid Build Coastguard Worker 		*pos = '\0';
4405*03f9172cSAndroid Build Coastguard Worker 		return buf;
4406*03f9172cSAndroid Build Coastguard Worker 	}
4407*03f9172cSAndroid Build Coastguard Worker 
4408*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "excluded_ssid") == 0) {
4409*03f9172cSAndroid Build Coastguard Worker 		unsigned int i;
4410*03f9172cSAndroid Build Coastguard Worker 		char *buf, *end, *pos;
4411*03f9172cSAndroid Build Coastguard Worker 
4412*03f9172cSAndroid Build Coastguard Worker 		if (!cred->num_excluded_ssid)
4413*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4414*03f9172cSAndroid Build Coastguard Worker 
4415*03f9172cSAndroid Build Coastguard Worker 		buf = os_malloc(4000);
4416*03f9172cSAndroid Build Coastguard Worker 		if (buf == NULL)
4417*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4418*03f9172cSAndroid Build Coastguard Worker 		pos = buf;
4419*03f9172cSAndroid Build Coastguard Worker 		end = pos + 4000;
4420*03f9172cSAndroid Build Coastguard Worker 
4421*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; i < cred->num_excluded_ssid; i++) {
4422*03f9172cSAndroid Build Coastguard Worker 			struct excluded_ssid *e;
4423*03f9172cSAndroid Build Coastguard Worker 			int ret;
4424*03f9172cSAndroid Build Coastguard Worker 
4425*03f9172cSAndroid Build Coastguard Worker 			e = &cred->excluded_ssid[i];
4426*03f9172cSAndroid Build Coastguard Worker 			ret = os_snprintf(pos, end - pos, "%s%s",
4427*03f9172cSAndroid Build Coastguard Worker 					  i > 0 ? "\n" : "",
4428*03f9172cSAndroid Build Coastguard Worker 					  wpa_ssid_txt(e->ssid, e->ssid_len));
4429*03f9172cSAndroid Build Coastguard Worker 			if (os_snprintf_error(end - pos, ret))
4430*03f9172cSAndroid Build Coastguard Worker 				return buf;
4431*03f9172cSAndroid Build Coastguard Worker 			pos += ret;
4432*03f9172cSAndroid Build Coastguard Worker 		}
4433*03f9172cSAndroid Build Coastguard Worker 
4434*03f9172cSAndroid Build Coastguard Worker 		return buf;
4435*03f9172cSAndroid Build Coastguard Worker 	}
4436*03f9172cSAndroid Build Coastguard Worker 
4437*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "roaming_partner") == 0) {
4438*03f9172cSAndroid Build Coastguard Worker 		unsigned int i;
4439*03f9172cSAndroid Build Coastguard Worker 		char *buf, *end, *pos;
4440*03f9172cSAndroid Build Coastguard Worker 
4441*03f9172cSAndroid Build Coastguard Worker 		if (!cred->num_roaming_partner)
4442*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4443*03f9172cSAndroid Build Coastguard Worker 
4444*03f9172cSAndroid Build Coastguard Worker 		buf = os_malloc(4000);
4445*03f9172cSAndroid Build Coastguard Worker 		if (buf == NULL)
4446*03f9172cSAndroid Build Coastguard Worker 			return NULL;
4447*03f9172cSAndroid Build Coastguard Worker 		pos = buf;
4448*03f9172cSAndroid Build Coastguard Worker 		end = pos + 4000;
4449*03f9172cSAndroid Build Coastguard Worker 
4450*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; i < cred->num_roaming_partner; i++) {
4451*03f9172cSAndroid Build Coastguard Worker 			struct roaming_partner *p;
4452*03f9172cSAndroid Build Coastguard Worker 			int ret;
4453*03f9172cSAndroid Build Coastguard Worker 
4454*03f9172cSAndroid Build Coastguard Worker 			p = &cred->roaming_partner[i];
4455*03f9172cSAndroid Build Coastguard Worker 			ret = os_snprintf(pos, end - pos, "%s%s,%d,%u,%s",
4456*03f9172cSAndroid Build Coastguard Worker 					  i > 0 ? "\n" : "",
4457*03f9172cSAndroid Build Coastguard Worker 					  p->fqdn, p->exact_match, p->priority,
4458*03f9172cSAndroid Build Coastguard Worker 					  p->country);
4459*03f9172cSAndroid Build Coastguard Worker 			if (os_snprintf_error(end - pos, ret))
4460*03f9172cSAndroid Build Coastguard Worker 				return buf;
4461*03f9172cSAndroid Build Coastguard Worker 			pos += ret;
4462*03f9172cSAndroid Build Coastguard Worker 		}
4463*03f9172cSAndroid Build Coastguard Worker 
4464*03f9172cSAndroid Build Coastguard Worker 		return buf;
4465*03f9172cSAndroid Build Coastguard Worker 	}
4466*03f9172cSAndroid Build Coastguard Worker 
4467*03f9172cSAndroid Build Coastguard Worker 	if (os_strcmp(var, "provisioning_sp") == 0)
4468*03f9172cSAndroid Build Coastguard Worker 		return alloc_strdup(cred->provisioning_sp);
4469*03f9172cSAndroid Build Coastguard Worker 
4470*03f9172cSAndroid Build Coastguard Worker 	return NULL;
4471*03f9172cSAndroid Build Coastguard Worker }
4472*03f9172cSAndroid Build Coastguard Worker 
4473*03f9172cSAndroid Build Coastguard Worker 
wpa_config_get_cred(struct wpa_config * config,int id)4474*03f9172cSAndroid Build Coastguard Worker struct wpa_cred * wpa_config_get_cred(struct wpa_config *config, int id)
4475*03f9172cSAndroid Build Coastguard Worker {
4476*03f9172cSAndroid Build Coastguard Worker 	struct wpa_cred *cred;
4477*03f9172cSAndroid Build Coastguard Worker 
4478*03f9172cSAndroid Build Coastguard Worker 	cred = config->cred;
4479*03f9172cSAndroid Build Coastguard Worker 	while (cred) {
4480*03f9172cSAndroid Build Coastguard Worker 		if (id == cred->id)
4481*03f9172cSAndroid Build Coastguard Worker 			break;
4482*03f9172cSAndroid Build Coastguard Worker 		cred = cred->next;
4483*03f9172cSAndroid Build Coastguard Worker 	}
4484*03f9172cSAndroid Build Coastguard Worker 
4485*03f9172cSAndroid Build Coastguard Worker 	return cred;
4486*03f9172cSAndroid Build Coastguard Worker }
4487*03f9172cSAndroid Build Coastguard Worker 
4488*03f9172cSAndroid Build Coastguard Worker 
wpa_config_add_cred(struct wpa_config * config)4489*03f9172cSAndroid Build Coastguard Worker struct wpa_cred * wpa_config_add_cred(struct wpa_config *config)
4490*03f9172cSAndroid Build Coastguard Worker {
4491*03f9172cSAndroid Build Coastguard Worker 	int id;
4492*03f9172cSAndroid Build Coastguard Worker 	struct wpa_cred *cred, *last = NULL;
4493*03f9172cSAndroid Build Coastguard Worker 
4494*03f9172cSAndroid Build Coastguard Worker 	id = -1;
4495*03f9172cSAndroid Build Coastguard Worker 	cred = config->cred;
4496*03f9172cSAndroid Build Coastguard Worker 	while (cred) {
4497*03f9172cSAndroid Build Coastguard Worker 		if (cred->id > id)
4498*03f9172cSAndroid Build Coastguard Worker 			id = cred->id;
4499*03f9172cSAndroid Build Coastguard Worker 		last = cred;
4500*03f9172cSAndroid Build Coastguard Worker 		cred = cred->next;
4501*03f9172cSAndroid Build Coastguard Worker 	}
4502*03f9172cSAndroid Build Coastguard Worker 	id++;
4503*03f9172cSAndroid Build Coastguard Worker 
4504*03f9172cSAndroid Build Coastguard Worker 	cred = os_zalloc(sizeof(*cred));
4505*03f9172cSAndroid Build Coastguard Worker 	if (cred == NULL)
4506*03f9172cSAndroid Build Coastguard Worker 		return NULL;
4507*03f9172cSAndroid Build Coastguard Worker 	cred->id = id;
4508*03f9172cSAndroid Build Coastguard Worker 	cred->sim_num = DEFAULT_USER_SELECTED_SIM;
4509*03f9172cSAndroid Build Coastguard Worker 	if (last)
4510*03f9172cSAndroid Build Coastguard Worker 		last->next = cred;
4511*03f9172cSAndroid Build Coastguard Worker 	else
4512*03f9172cSAndroid Build Coastguard Worker 		config->cred = cred;
4513*03f9172cSAndroid Build Coastguard Worker 
4514*03f9172cSAndroid Build Coastguard Worker 	return cred;
4515*03f9172cSAndroid Build Coastguard Worker }
4516*03f9172cSAndroid Build Coastguard Worker 
4517*03f9172cSAndroid Build Coastguard Worker 
wpa_config_remove_cred(struct wpa_config * config,int id)4518*03f9172cSAndroid Build Coastguard Worker int wpa_config_remove_cred(struct wpa_config *config, int id)
4519*03f9172cSAndroid Build Coastguard Worker {
4520*03f9172cSAndroid Build Coastguard Worker 	struct wpa_cred *cred, *prev = NULL;
4521*03f9172cSAndroid Build Coastguard Worker 
4522*03f9172cSAndroid Build Coastguard Worker 	cred = config->cred;
4523*03f9172cSAndroid Build Coastguard Worker 	while (cred) {
4524*03f9172cSAndroid Build Coastguard Worker 		if (id == cred->id)
4525*03f9172cSAndroid Build Coastguard Worker 			break;
4526*03f9172cSAndroid Build Coastguard Worker 		prev = cred;
4527*03f9172cSAndroid Build Coastguard Worker 		cred = cred->next;
4528*03f9172cSAndroid Build Coastguard Worker 	}
4529*03f9172cSAndroid Build Coastguard Worker 
4530*03f9172cSAndroid Build Coastguard Worker 	if (cred == NULL)
4531*03f9172cSAndroid Build Coastguard Worker 		return -1;
4532*03f9172cSAndroid Build Coastguard Worker 
4533*03f9172cSAndroid Build Coastguard Worker 	if (prev)
4534*03f9172cSAndroid Build Coastguard Worker 		prev->next = cred->next;
4535*03f9172cSAndroid Build Coastguard Worker 	else
4536*03f9172cSAndroid Build Coastguard Worker 		config->cred = cred->next;
4537*03f9172cSAndroid Build Coastguard Worker 
4538*03f9172cSAndroid Build Coastguard Worker 	wpa_config_free_cred(cred);
4539*03f9172cSAndroid Build Coastguard Worker 	return 0;
4540*03f9172cSAndroid Build Coastguard Worker }
4541*03f9172cSAndroid Build Coastguard Worker 
4542*03f9172cSAndroid Build Coastguard Worker 
4543*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_NO_CONFIG_BLOBS
4544*03f9172cSAndroid Build Coastguard Worker /**
4545*03f9172cSAndroid Build Coastguard Worker  * wpa_config_get_blob - Get a named configuration blob
4546*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
4547*03f9172cSAndroid Build Coastguard Worker  * @name: Name of the blob
4548*03f9172cSAndroid Build Coastguard Worker  * Returns: Pointer to blob data or %NULL if not found
4549*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_get_blob(struct wpa_config * config,const char * name)4550*03f9172cSAndroid Build Coastguard Worker const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
4551*03f9172cSAndroid Build Coastguard Worker 						   const char *name)
4552*03f9172cSAndroid Build Coastguard Worker {
4553*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config_blob *blob = config->blobs;
4554*03f9172cSAndroid Build Coastguard Worker 
4555*03f9172cSAndroid Build Coastguard Worker 	while (blob) {
4556*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(blob->name, name) == 0)
4557*03f9172cSAndroid Build Coastguard Worker 			return blob;
4558*03f9172cSAndroid Build Coastguard Worker 		blob = blob->next;
4559*03f9172cSAndroid Build Coastguard Worker 	}
4560*03f9172cSAndroid Build Coastguard Worker 	return NULL;
4561*03f9172cSAndroid Build Coastguard Worker }
4562*03f9172cSAndroid Build Coastguard Worker 
4563*03f9172cSAndroid Build Coastguard Worker 
4564*03f9172cSAndroid Build Coastguard Worker /**
4565*03f9172cSAndroid Build Coastguard Worker  * wpa_config_set_blob - Set or add a named configuration blob
4566*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
4567*03f9172cSAndroid Build Coastguard Worker  * @blob: New value for the blob
4568*03f9172cSAndroid Build Coastguard Worker  *
4569*03f9172cSAndroid Build Coastguard Worker  * Adds a new configuration blob or replaces the current value of an existing
4570*03f9172cSAndroid Build Coastguard Worker  * blob.
4571*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_set_blob(struct wpa_config * config,struct wpa_config_blob * blob)4572*03f9172cSAndroid Build Coastguard Worker void wpa_config_set_blob(struct wpa_config *config,
4573*03f9172cSAndroid Build Coastguard Worker 			 struct wpa_config_blob *blob)
4574*03f9172cSAndroid Build Coastguard Worker {
4575*03f9172cSAndroid Build Coastguard Worker 	wpa_config_remove_blob(config, blob->name);
4576*03f9172cSAndroid Build Coastguard Worker 	blob->next = config->blobs;
4577*03f9172cSAndroid Build Coastguard Worker 	config->blobs = blob;
4578*03f9172cSAndroid Build Coastguard Worker }
4579*03f9172cSAndroid Build Coastguard Worker 
4580*03f9172cSAndroid Build Coastguard Worker 
4581*03f9172cSAndroid Build Coastguard Worker /**
4582*03f9172cSAndroid Build Coastguard Worker  * wpa_config_free_blob - Free blob data
4583*03f9172cSAndroid Build Coastguard Worker  * @blob: Pointer to blob to be freed
4584*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_free_blob(struct wpa_config_blob * blob)4585*03f9172cSAndroid Build Coastguard Worker void wpa_config_free_blob(struct wpa_config_blob *blob)
4586*03f9172cSAndroid Build Coastguard Worker {
4587*03f9172cSAndroid Build Coastguard Worker 	if (blob) {
4588*03f9172cSAndroid Build Coastguard Worker 		os_free(blob->name);
4589*03f9172cSAndroid Build Coastguard Worker 		bin_clear_free(blob->data, blob->len);
4590*03f9172cSAndroid Build Coastguard Worker 		os_free(blob);
4591*03f9172cSAndroid Build Coastguard Worker 	}
4592*03f9172cSAndroid Build Coastguard Worker }
4593*03f9172cSAndroid Build Coastguard Worker 
4594*03f9172cSAndroid Build Coastguard Worker 
4595*03f9172cSAndroid Build Coastguard Worker /**
4596*03f9172cSAndroid Build Coastguard Worker  * wpa_config_remove_blob - Remove a named configuration blob
4597*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
4598*03f9172cSAndroid Build Coastguard Worker  * @name: Name of the blob to remove
4599*03f9172cSAndroid Build Coastguard Worker  * Returns: 0 if blob was removed or -1 if blob was not found
4600*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_remove_blob(struct wpa_config * config,const char * name)4601*03f9172cSAndroid Build Coastguard Worker int wpa_config_remove_blob(struct wpa_config *config, const char *name)
4602*03f9172cSAndroid Build Coastguard Worker {
4603*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config_blob *pos = config->blobs, *prev = NULL;
4604*03f9172cSAndroid Build Coastguard Worker 
4605*03f9172cSAndroid Build Coastguard Worker 	while (pos) {
4606*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(pos->name, name) == 0) {
4607*03f9172cSAndroid Build Coastguard Worker 			if (prev)
4608*03f9172cSAndroid Build Coastguard Worker 				prev->next = pos->next;
4609*03f9172cSAndroid Build Coastguard Worker 			else
4610*03f9172cSAndroid Build Coastguard Worker 				config->blobs = pos->next;
4611*03f9172cSAndroid Build Coastguard Worker 			wpa_config_free_blob(pos);
4612*03f9172cSAndroid Build Coastguard Worker 			return 0;
4613*03f9172cSAndroid Build Coastguard Worker 		}
4614*03f9172cSAndroid Build Coastguard Worker 		prev = pos;
4615*03f9172cSAndroid Build Coastguard Worker 		pos = pos->next;
4616*03f9172cSAndroid Build Coastguard Worker 	}
4617*03f9172cSAndroid Build Coastguard Worker 
4618*03f9172cSAndroid Build Coastguard Worker 	return -1;
4619*03f9172cSAndroid Build Coastguard Worker }
4620*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_CONFIG_BLOBS */
4621*03f9172cSAndroid Build Coastguard Worker 
4622*03f9172cSAndroid Build Coastguard Worker 
4623*03f9172cSAndroid Build Coastguard Worker /**
4624*03f9172cSAndroid Build Coastguard Worker  * wpa_config_alloc_empty - Allocate an empty configuration
4625*03f9172cSAndroid Build Coastguard Worker  * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
4626*03f9172cSAndroid Build Coastguard Worker  * socket
4627*03f9172cSAndroid Build Coastguard Worker  * @driver_param: Driver parameters
4628*03f9172cSAndroid Build Coastguard Worker  * Returns: Pointer to allocated configuration data or %NULL on failure
4629*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_alloc_empty(const char * ctrl_interface,const char * driver_param)4630*03f9172cSAndroid Build Coastguard Worker struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
4631*03f9172cSAndroid Build Coastguard Worker 					   const char *driver_param)
4632*03f9172cSAndroid Build Coastguard Worker {
4633*03f9172cSAndroid Build Coastguard Worker #define ecw2cw(ecw) ((1 << (ecw)) - 1)
4634*03f9172cSAndroid Build Coastguard Worker 
4635*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config;
4636*03f9172cSAndroid Build Coastguard Worker 	const int aCWmin = 4, aCWmax = 10;
4637*03f9172cSAndroid Build Coastguard Worker 	const struct hostapd_wmm_ac_params ac_bk =
4638*03f9172cSAndroid Build Coastguard Worker 		{ aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
4639*03f9172cSAndroid Build Coastguard Worker 	const struct hostapd_wmm_ac_params ac_be =
4640*03f9172cSAndroid Build Coastguard Worker 		{ aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
4641*03f9172cSAndroid Build Coastguard Worker 	const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
4642*03f9172cSAndroid Build Coastguard Worker 		{ aCWmin - 1, aCWmin, 2, 3008 / 32, 0 };
4643*03f9172cSAndroid Build Coastguard Worker 	const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
4644*03f9172cSAndroid Build Coastguard Worker 		{ aCWmin - 2, aCWmin - 1, 2, 1504 / 32, 0 };
4645*03f9172cSAndroid Build Coastguard Worker 	const struct hostapd_tx_queue_params txq_bk =
4646*03f9172cSAndroid Build Coastguard Worker 		{ 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 };
4647*03f9172cSAndroid Build Coastguard Worker 	const struct hostapd_tx_queue_params txq_be =
4648*03f9172cSAndroid Build Coastguard Worker 		{ 3, ecw2cw(aCWmin), 4 * (ecw2cw(aCWmin) + 1) - 1, 0 };
4649*03f9172cSAndroid Build Coastguard Worker 	const struct hostapd_tx_queue_params txq_vi =
4650*03f9172cSAndroid Build Coastguard Worker 		{ 1, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30 };
4651*03f9172cSAndroid Build Coastguard Worker 	const struct hostapd_tx_queue_params txq_vo =
4652*03f9172cSAndroid Build Coastguard Worker 		{ 1, (ecw2cw(aCWmin) + 1) / 4 - 1,
4653*03f9172cSAndroid Build Coastguard Worker 		  (ecw2cw(aCWmin) + 1) / 2 - 1, 15 };
4654*03f9172cSAndroid Build Coastguard Worker 
4655*03f9172cSAndroid Build Coastguard Worker #undef ecw2cw
4656*03f9172cSAndroid Build Coastguard Worker 
4657*03f9172cSAndroid Build Coastguard Worker 	config = os_zalloc(sizeof(*config));
4658*03f9172cSAndroid Build Coastguard Worker 	if (config == NULL)
4659*03f9172cSAndroid Build Coastguard Worker 		return NULL;
4660*03f9172cSAndroid Build Coastguard Worker 	config->eapol_version = DEFAULT_EAPOL_VERSION;
4661*03f9172cSAndroid Build Coastguard Worker 	config->ap_scan = DEFAULT_AP_SCAN;
4662*03f9172cSAndroid Build Coastguard Worker 	config->user_mpm = DEFAULT_USER_MPM;
4663*03f9172cSAndroid Build Coastguard Worker 	config->max_peer_links = DEFAULT_MAX_PEER_LINKS;
4664*03f9172cSAndroid Build Coastguard Worker 	config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY;
4665*03f9172cSAndroid Build Coastguard Worker 	config->mesh_fwding = DEFAULT_MESH_FWDING;
4666*03f9172cSAndroid Build Coastguard Worker 	config->dot11RSNASAERetransPeriod =
4667*03f9172cSAndroid Build Coastguard Worker 		DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD;
4668*03f9172cSAndroid Build Coastguard Worker 	config->fast_reauth = DEFAULT_FAST_REAUTH;
4669*03f9172cSAndroid Build Coastguard Worker 	config->p2p_go_intent = DEFAULT_P2P_GO_INTENT;
4670*03f9172cSAndroid Build Coastguard Worker 	config->p2p_intra_bss = DEFAULT_P2P_INTRA_BSS;
4671*03f9172cSAndroid Build Coastguard Worker 	config->p2p_go_freq_change_policy = DEFAULT_P2P_GO_FREQ_MOVE;
4672*03f9172cSAndroid Build Coastguard Worker 	config->p2p_go_max_inactivity = DEFAULT_P2P_GO_MAX_INACTIVITY;
4673*03f9172cSAndroid Build Coastguard Worker 	config->p2p_optimize_listen_chan = DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN;
4674*03f9172cSAndroid Build Coastguard Worker 	config->p2p_go_ctwindow = DEFAULT_P2P_GO_CTWINDOW;
4675*03f9172cSAndroid Build Coastguard Worker 	config->bss_max_count = DEFAULT_BSS_MAX_COUNT;
4676*03f9172cSAndroid Build Coastguard Worker 	config->bss_expiration_age = DEFAULT_BSS_EXPIRATION_AGE;
4677*03f9172cSAndroid Build Coastguard Worker 	config->bss_expiration_scan_count = DEFAULT_BSS_EXPIRATION_SCAN_COUNT;
4678*03f9172cSAndroid Build Coastguard Worker 	config->max_num_sta = DEFAULT_MAX_NUM_STA;
4679*03f9172cSAndroid Build Coastguard Worker 	config->ap_isolate = DEFAULT_AP_ISOLATE;
4680*03f9172cSAndroid Build Coastguard Worker 	config->access_network_type = DEFAULT_ACCESS_NETWORK_TYPE;
4681*03f9172cSAndroid Build Coastguard Worker 	config->scan_cur_freq = DEFAULT_SCAN_CUR_FREQ;
4682*03f9172cSAndroid Build Coastguard Worker 	config->scan_res_valid_for_connect = DEFAULT_SCAN_RES_VALID_FOR_CONNECT;
4683*03f9172cSAndroid Build Coastguard Worker 	config->wmm_ac_params[0] = ac_be;
4684*03f9172cSAndroid Build Coastguard Worker 	config->wmm_ac_params[1] = ac_bk;
4685*03f9172cSAndroid Build Coastguard Worker 	config->wmm_ac_params[2] = ac_vi;
4686*03f9172cSAndroid Build Coastguard Worker 	config->wmm_ac_params[3] = ac_vo;
4687*03f9172cSAndroid Build Coastguard Worker 	config->tx_queue[0] = txq_vo;
4688*03f9172cSAndroid Build Coastguard Worker 	config->tx_queue[1] = txq_vi;
4689*03f9172cSAndroid Build Coastguard Worker 	config->tx_queue[2] = txq_be;
4690*03f9172cSAndroid Build Coastguard Worker 	config->tx_queue[3] = txq_bk;
4691*03f9172cSAndroid Build Coastguard Worker 	config->p2p_search_delay = DEFAULT_P2P_SEARCH_DELAY;
4692*03f9172cSAndroid Build Coastguard Worker 	config->rand_addr_lifetime = DEFAULT_RAND_ADDR_LIFETIME;
4693*03f9172cSAndroid Build Coastguard Worker 	config->key_mgmt_offload = DEFAULT_KEY_MGMT_OFFLOAD;
4694*03f9172cSAndroid Build Coastguard Worker 	config->cert_in_cb = DEFAULT_CERT_IN_CB;
4695*03f9172cSAndroid Build Coastguard Worker 	config->wpa_rsc_relaxation = DEFAULT_WPA_RSC_RELAXATION;
4696*03f9172cSAndroid Build Coastguard Worker 	config->extended_key_id = DEFAULT_EXTENDED_KEY_ID;
4697*03f9172cSAndroid Build Coastguard Worker 
4698*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MBO
4699*03f9172cSAndroid Build Coastguard Worker 	config->mbo_cell_capa = DEFAULT_MBO_CELL_CAPA;
4700*03f9172cSAndroid Build Coastguard Worker 	config->disassoc_imminent_rssi_threshold =
4701*03f9172cSAndroid Build Coastguard Worker 		DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD;
4702*03f9172cSAndroid Build Coastguard Worker 	config->oce = DEFAULT_OCE_SUPPORT;
4703*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MBO */
4704*03f9172cSAndroid Build Coastguard Worker 	config->btm_offload = DEFAULT_BTM_OFFLOAD;
4705*03f9172cSAndroid Build Coastguard Worker 
4706*03f9172cSAndroid Build Coastguard Worker 	if (ctrl_interface)
4707*03f9172cSAndroid Build Coastguard Worker 		config->ctrl_interface = os_strdup(ctrl_interface);
4708*03f9172cSAndroid Build Coastguard Worker 	if (driver_param)
4709*03f9172cSAndroid Build Coastguard Worker 		config->driver_param = os_strdup(driver_param);
4710*03f9172cSAndroid Build Coastguard Worker 	config->gas_rand_addr_lifetime = DEFAULT_RAND_ADDR_LIFETIME;
4711*03f9172cSAndroid Build Coastguard Worker 
4712*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_TESTING_OPTIONS
4713*03f9172cSAndroid Build Coastguard Worker 	config->mld_connect_band_pref = DEFAULT_MLD_CONNECT_BAND_PREF;
4714*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_TESTING_OPTIONS */
4715*03f9172cSAndroid Build Coastguard Worker 
4716*03f9172cSAndroid Build Coastguard Worker 	return config;
4717*03f9172cSAndroid Build Coastguard Worker }
4718*03f9172cSAndroid Build Coastguard Worker 
4719*03f9172cSAndroid Build Coastguard Worker 
4720*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_NO_STDOUT_DEBUG
4721*03f9172cSAndroid Build Coastguard Worker /**
4722*03f9172cSAndroid Build Coastguard Worker  * wpa_config_debug_dump_networks - Debug dump of configured networks
4723*03f9172cSAndroid Build Coastguard Worker  * @config: Configuration data from wpa_config_read()
4724*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_debug_dump_networks(struct wpa_config * config)4725*03f9172cSAndroid Build Coastguard Worker void wpa_config_debug_dump_networks(struct wpa_config *config)
4726*03f9172cSAndroid Build Coastguard Worker {
4727*03f9172cSAndroid Build Coastguard Worker 	size_t prio;
4728*03f9172cSAndroid Build Coastguard Worker 	struct wpa_ssid *ssid;
4729*03f9172cSAndroid Build Coastguard Worker 
4730*03f9172cSAndroid Build Coastguard Worker 	for (prio = 0; prio < config->num_prio; prio++) {
4731*03f9172cSAndroid Build Coastguard Worker 		ssid = config->pssid[prio];
4732*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_DEBUG, "Priority group %d",
4733*03f9172cSAndroid Build Coastguard Worker 			   ssid->priority);
4734*03f9172cSAndroid Build Coastguard Worker 		while (ssid) {
4735*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_DEBUG, "   id=%d ssid='%s'",
4736*03f9172cSAndroid Build Coastguard Worker 				   ssid->id,
4737*03f9172cSAndroid Build Coastguard Worker 				   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
4738*03f9172cSAndroid Build Coastguard Worker 			ssid = ssid->pnext;
4739*03f9172cSAndroid Build Coastguard Worker 		}
4740*03f9172cSAndroid Build Coastguard Worker 	}
4741*03f9172cSAndroid Build Coastguard Worker }
4742*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_STDOUT_DEBUG */
4743*03f9172cSAndroid Build Coastguard Worker 
4744*03f9172cSAndroid Build Coastguard Worker 
4745*03f9172cSAndroid Build Coastguard Worker /**
4746*03f9172cSAndroid Build Coastguard Worker  * Structure for global configuration parsing. This data is used to implement a
4747*03f9172cSAndroid Build Coastguard Worker  * generic parser for the global interface configuration. The table of variables
4748*03f9172cSAndroid Build Coastguard Worker  * is defined below in this file (global_fields[]).
4749*03f9172cSAndroid Build Coastguard Worker  */
4750*03f9172cSAndroid Build Coastguard Worker struct global_parse_data {
4751*03f9172cSAndroid Build Coastguard Worker 	/* Configuration variable name */
4752*03f9172cSAndroid Build Coastguard Worker 	char *name;
4753*03f9172cSAndroid Build Coastguard Worker 
4754*03f9172cSAndroid Build Coastguard Worker 	/* Parser function for this variable. The parser functions return 0 or 1
4755*03f9172cSAndroid Build Coastguard Worker 	 * to indicate success. Value 0 indicates that the parameter value may
4756*03f9172cSAndroid Build Coastguard Worker 	 * have changed while value 1 means that the value did not change.
4757*03f9172cSAndroid Build Coastguard Worker 	 * Error cases (failure to parse the string) are indicated by returning
4758*03f9172cSAndroid Build Coastguard Worker 	 * -1. */
4759*03f9172cSAndroid Build Coastguard Worker 	int (*parser)(const struct global_parse_data *data,
4760*03f9172cSAndroid Build Coastguard Worker 		      struct wpa_config *config, int line, const char *value);
4761*03f9172cSAndroid Build Coastguard Worker 
4762*03f9172cSAndroid Build Coastguard Worker 	/* Getter function to print the variable in text format to buf. */
4763*03f9172cSAndroid Build Coastguard Worker 	int (*get)(const char *name, struct wpa_config *config, long offset,
4764*03f9172cSAndroid Build Coastguard Worker 		   char *buf, size_t buflen, int pretty_print);
4765*03f9172cSAndroid Build Coastguard Worker 
4766*03f9172cSAndroid Build Coastguard Worker 	/* Variable specific parameters for the parser. */
4767*03f9172cSAndroid Build Coastguard Worker 	void *param1, *param2, *param3;
4768*03f9172cSAndroid Build Coastguard Worker 
4769*03f9172cSAndroid Build Coastguard Worker 	/* Indicates which configuration variable has changed. */
4770*03f9172cSAndroid Build Coastguard Worker 	unsigned int changed_flag;
4771*03f9172cSAndroid Build Coastguard Worker };
4772*03f9172cSAndroid Build Coastguard Worker 
4773*03f9172cSAndroid Build Coastguard Worker 
4774*03f9172cSAndroid Build Coastguard Worker static int
wpa_global_config_parse_int_impl(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos,bool check_range)4775*03f9172cSAndroid Build Coastguard Worker wpa_global_config_parse_int_impl(const struct global_parse_data *data,
4776*03f9172cSAndroid Build Coastguard Worker 				 struct wpa_config *config, int line,
4777*03f9172cSAndroid Build Coastguard Worker 				 const char *pos, bool check_range)
4778*03f9172cSAndroid Build Coastguard Worker {
4779*03f9172cSAndroid Build Coastguard Worker 	int val, *dst;
4780*03f9172cSAndroid Build Coastguard Worker 	char *end;
4781*03f9172cSAndroid Build Coastguard Worker 	bool same;
4782*03f9172cSAndroid Build Coastguard Worker 
4783*03f9172cSAndroid Build Coastguard Worker 	dst = (int *) (((u8 *) config) + (long) data->param1);
4784*03f9172cSAndroid Build Coastguard Worker 	val = strtol(pos, &end, 0);
4785*03f9172cSAndroid Build Coastguard Worker 	if (*end) {
4786*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: invalid number \"%s\"",
4787*03f9172cSAndroid Build Coastguard Worker 			   line, pos);
4788*03f9172cSAndroid Build Coastguard Worker 		return -1;
4789*03f9172cSAndroid Build Coastguard Worker 	}
4790*03f9172cSAndroid Build Coastguard Worker 
4791*03f9172cSAndroid Build Coastguard Worker 	if (check_range && val < (long) data->param2) {
4792*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
4793*03f9172cSAndroid Build Coastguard Worker 			   "min_value=%ld)", line, data->name, val,
4794*03f9172cSAndroid Build Coastguard Worker 			   (long) data->param2);
4795*03f9172cSAndroid Build Coastguard Worker 		return -1;
4796*03f9172cSAndroid Build Coastguard Worker 	}
4797*03f9172cSAndroid Build Coastguard Worker 
4798*03f9172cSAndroid Build Coastguard Worker 	if (check_range && val > (long) data->param3) {
4799*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
4800*03f9172cSAndroid Build Coastguard Worker 			   "max_value=%ld)", line, data->name, val,
4801*03f9172cSAndroid Build Coastguard Worker 			   (long) data->param3);
4802*03f9172cSAndroid Build Coastguard Worker 		return -1;
4803*03f9172cSAndroid Build Coastguard Worker 	}
4804*03f9172cSAndroid Build Coastguard Worker 
4805*03f9172cSAndroid Build Coastguard Worker 	same = *dst == val;
4806*03f9172cSAndroid Build Coastguard Worker 	*dst = val;
4807*03f9172cSAndroid Build Coastguard Worker 
4808*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "%s=%d", data->name, *dst);
4809*03f9172cSAndroid Build Coastguard Worker 
4810*03f9172cSAndroid Build Coastguard Worker 	return same;
4811*03f9172cSAndroid Build Coastguard Worker }
4812*03f9172cSAndroid Build Coastguard Worker 
4813*03f9172cSAndroid Build Coastguard Worker 
wpa_global_config_parse_int(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)4814*03f9172cSAndroid Build Coastguard Worker static int wpa_global_config_parse_int(const struct global_parse_data *data,
4815*03f9172cSAndroid Build Coastguard Worker 				       struct wpa_config *config, int line,
4816*03f9172cSAndroid Build Coastguard Worker 				       const char *pos)
4817*03f9172cSAndroid Build Coastguard Worker {
4818*03f9172cSAndroid Build Coastguard Worker 	return wpa_global_config_parse_int_impl(data, config, line, pos, false);
4819*03f9172cSAndroid Build Coastguard Worker }
4820*03f9172cSAndroid Build Coastguard Worker 
4821*03f9172cSAndroid Build Coastguard Worker 
4822*03f9172cSAndroid Build Coastguard Worker static int
wpa_global_config_parse_int_range(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)4823*03f9172cSAndroid Build Coastguard Worker wpa_global_config_parse_int_range(const struct global_parse_data *data,
4824*03f9172cSAndroid Build Coastguard Worker 				  struct wpa_config *config, int line,
4825*03f9172cSAndroid Build Coastguard Worker 				  const char *pos)
4826*03f9172cSAndroid Build Coastguard Worker {
4827*03f9172cSAndroid Build Coastguard Worker 	return wpa_global_config_parse_int_impl(data, config, line, pos, true);
4828*03f9172cSAndroid Build Coastguard Worker }
4829*03f9172cSAndroid Build Coastguard Worker 
4830*03f9172cSAndroid Build Coastguard Worker 
wpa_global_config_parse_str(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)4831*03f9172cSAndroid Build Coastguard Worker static int wpa_global_config_parse_str(const struct global_parse_data *data,
4832*03f9172cSAndroid Build Coastguard Worker 				       struct wpa_config *config, int line,
4833*03f9172cSAndroid Build Coastguard Worker 				       const char *pos)
4834*03f9172cSAndroid Build Coastguard Worker {
4835*03f9172cSAndroid Build Coastguard Worker 	size_t len, prev_len;
4836*03f9172cSAndroid Build Coastguard Worker 	char **dst, *tmp;
4837*03f9172cSAndroid Build Coastguard Worker 
4838*03f9172cSAndroid Build Coastguard Worker 	len = os_strlen(pos);
4839*03f9172cSAndroid Build Coastguard Worker 	if (data->param2 && len < (size_t) data->param2) {
4840*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
4841*03f9172cSAndroid Build Coastguard Worker 			   "min_len=%ld)", line, data->name,
4842*03f9172cSAndroid Build Coastguard Worker 			   (unsigned long) len, (long) data->param2);
4843*03f9172cSAndroid Build Coastguard Worker 		return -1;
4844*03f9172cSAndroid Build Coastguard Worker 	}
4845*03f9172cSAndroid Build Coastguard Worker 
4846*03f9172cSAndroid Build Coastguard Worker 	if (data->param3 && len > (size_t) data->param3) {
4847*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
4848*03f9172cSAndroid Build Coastguard Worker 			   "max_len=%ld)", line, data->name,
4849*03f9172cSAndroid Build Coastguard Worker 			   (unsigned long) len, (long) data->param3);
4850*03f9172cSAndroid Build Coastguard Worker 		return -1;
4851*03f9172cSAndroid Build Coastguard Worker 	}
4852*03f9172cSAndroid Build Coastguard Worker 
4853*03f9172cSAndroid Build Coastguard Worker 	if (has_newline(pos)) {
4854*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: invalid %s value with newline",
4855*03f9172cSAndroid Build Coastguard Worker 			   line, data->name);
4856*03f9172cSAndroid Build Coastguard Worker 		return -1;
4857*03f9172cSAndroid Build Coastguard Worker 	}
4858*03f9172cSAndroid Build Coastguard Worker 
4859*03f9172cSAndroid Build Coastguard Worker 	dst = (char **) (((u8 *) config) + (long) data->param1);
4860*03f9172cSAndroid Build Coastguard Worker 	if (*dst)
4861*03f9172cSAndroid Build Coastguard Worker 		prev_len = os_strlen(*dst);
4862*03f9172cSAndroid Build Coastguard Worker 	else
4863*03f9172cSAndroid Build Coastguard Worker 		prev_len = 0;
4864*03f9172cSAndroid Build Coastguard Worker 
4865*03f9172cSAndroid Build Coastguard Worker 	/* No change to the previously configured value */
4866*03f9172cSAndroid Build Coastguard Worker 	if (*dst && prev_len == len && os_memcmp(*dst, pos, len) == 0)
4867*03f9172cSAndroid Build Coastguard Worker 		return 1;
4868*03f9172cSAndroid Build Coastguard Worker 
4869*03f9172cSAndroid Build Coastguard Worker 	tmp = os_strdup(pos);
4870*03f9172cSAndroid Build Coastguard Worker 	if (tmp == NULL)
4871*03f9172cSAndroid Build Coastguard Worker 		return -1;
4872*03f9172cSAndroid Build Coastguard Worker 
4873*03f9172cSAndroid Build Coastguard Worker 	os_free(*dst);
4874*03f9172cSAndroid Build Coastguard Worker 	*dst = tmp;
4875*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "%s='%s'", data->name, *dst);
4876*03f9172cSAndroid Build Coastguard Worker 
4877*03f9172cSAndroid Build Coastguard Worker 	return 0;
4878*03f9172cSAndroid Build Coastguard Worker }
4879*03f9172cSAndroid Build Coastguard Worker 
4880*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_bgscan(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)4881*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_bgscan(const struct global_parse_data *data,
4882*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_config *config, int line,
4883*03f9172cSAndroid Build Coastguard Worker 				     const char *pos)
4884*03f9172cSAndroid Build Coastguard Worker {
4885*03f9172cSAndroid Build Coastguard Worker 	size_t len;
4886*03f9172cSAndroid Build Coastguard Worker 	char *tmp;
4887*03f9172cSAndroid Build Coastguard Worker 	int res;
4888*03f9172cSAndroid Build Coastguard Worker 
4889*03f9172cSAndroid Build Coastguard Worker 	tmp = wpa_config_parse_string(pos, &len);
4890*03f9172cSAndroid Build Coastguard Worker 	if (tmp == NULL) {
4891*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: failed to parse %s",
4892*03f9172cSAndroid Build Coastguard Worker 			   line, data->name);
4893*03f9172cSAndroid Build Coastguard Worker 		return -1;
4894*03f9172cSAndroid Build Coastguard Worker 	}
4895*03f9172cSAndroid Build Coastguard Worker 
4896*03f9172cSAndroid Build Coastguard Worker 	res = wpa_global_config_parse_str(data, config, line, tmp);
4897*03f9172cSAndroid Build Coastguard Worker 	os_free(tmp);
4898*03f9172cSAndroid Build Coastguard Worker 	return res;
4899*03f9172cSAndroid Build Coastguard Worker }
4900*03f9172cSAndroid Build Coastguard Worker 
4901*03f9172cSAndroid Build Coastguard Worker 
wpa_global_config_parse_bin(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)4902*03f9172cSAndroid Build Coastguard Worker static int wpa_global_config_parse_bin(const struct global_parse_data *data,
4903*03f9172cSAndroid Build Coastguard Worker 				       struct wpa_config *config, int line,
4904*03f9172cSAndroid Build Coastguard Worker 				       const char *pos)
4905*03f9172cSAndroid Build Coastguard Worker {
4906*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf **dst, *tmp;
4907*03f9172cSAndroid Build Coastguard Worker 
4908*03f9172cSAndroid Build Coastguard Worker 	tmp = wpabuf_parse_bin(pos);
4909*03f9172cSAndroid Build Coastguard Worker 	if (!tmp)
4910*03f9172cSAndroid Build Coastguard Worker 		return -1;
4911*03f9172cSAndroid Build Coastguard Worker 
4912*03f9172cSAndroid Build Coastguard Worker 	dst = (struct wpabuf **) (((u8 *) config) + (long) data->param1);
4913*03f9172cSAndroid Build Coastguard Worker 	if (wpabuf_cmp(*dst, tmp) == 0) {
4914*03f9172cSAndroid Build Coastguard Worker 		wpabuf_free(tmp);
4915*03f9172cSAndroid Build Coastguard Worker 		return 1;
4916*03f9172cSAndroid Build Coastguard Worker 	}
4917*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(*dst);
4918*03f9172cSAndroid Build Coastguard Worker 	*dst = tmp;
4919*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "%s", data->name);
4920*03f9172cSAndroid Build Coastguard Worker 
4921*03f9172cSAndroid Build Coastguard Worker 	return 0;
4922*03f9172cSAndroid Build Coastguard Worker }
4923*03f9172cSAndroid Build Coastguard Worker 
4924*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_freq_list(const struct global_parse_data * data,struct wpa_config * config,int line,const char * value)4925*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_freq_list(const struct global_parse_data *data,
4926*03f9172cSAndroid Build Coastguard Worker 					struct wpa_config *config, int line,
4927*03f9172cSAndroid Build Coastguard Worker 					const char *value)
4928*03f9172cSAndroid Build Coastguard Worker {
4929*03f9172cSAndroid Build Coastguard Worker 	int *freqs;
4930*03f9172cSAndroid Build Coastguard Worker 
4931*03f9172cSAndroid Build Coastguard Worker 	freqs = wpa_config_parse_int_array(value);
4932*03f9172cSAndroid Build Coastguard Worker 	if (freqs == NULL)
4933*03f9172cSAndroid Build Coastguard Worker 		return -1;
4934*03f9172cSAndroid Build Coastguard Worker 	if (freqs[0] == 0) {
4935*03f9172cSAndroid Build Coastguard Worker 		os_free(freqs);
4936*03f9172cSAndroid Build Coastguard Worker 		freqs = NULL;
4937*03f9172cSAndroid Build Coastguard Worker 	}
4938*03f9172cSAndroid Build Coastguard Worker 	os_free(config->freq_list);
4939*03f9172cSAndroid Build Coastguard Worker 	config->freq_list = freqs;
4940*03f9172cSAndroid Build Coastguard Worker 	return 0;
4941*03f9172cSAndroid Build Coastguard Worker }
4942*03f9172cSAndroid Build Coastguard Worker 
4943*03f9172cSAndroid Build Coastguard Worker 
4944*03f9172cSAndroid Build Coastguard Worker static int
wpa_config_process_initial_freq_list(const struct global_parse_data * data,struct wpa_config * config,int line,const char * value)4945*03f9172cSAndroid Build Coastguard Worker wpa_config_process_initial_freq_list(const struct global_parse_data *data,
4946*03f9172cSAndroid Build Coastguard Worker 				     struct wpa_config *config, int line,
4947*03f9172cSAndroid Build Coastguard Worker 				     const char *value)
4948*03f9172cSAndroid Build Coastguard Worker {
4949*03f9172cSAndroid Build Coastguard Worker 	int *freqs;
4950*03f9172cSAndroid Build Coastguard Worker 
4951*03f9172cSAndroid Build Coastguard Worker 	freqs = wpa_config_parse_int_array(value);
4952*03f9172cSAndroid Build Coastguard Worker 	if (!freqs)
4953*03f9172cSAndroid Build Coastguard Worker 		return -1;
4954*03f9172cSAndroid Build Coastguard Worker 	if (freqs[0] == 0) {
4955*03f9172cSAndroid Build Coastguard Worker 		os_free(freqs);
4956*03f9172cSAndroid Build Coastguard Worker 		freqs = NULL;
4957*03f9172cSAndroid Build Coastguard Worker 	}
4958*03f9172cSAndroid Build Coastguard Worker 	os_free(config->initial_freq_list);
4959*03f9172cSAndroid Build Coastguard Worker 	config->initial_freq_list = freqs;
4960*03f9172cSAndroid Build Coastguard Worker 	return 0;
4961*03f9172cSAndroid Build Coastguard Worker }
4962*03f9172cSAndroid Build Coastguard Worker 
4963*03f9172cSAndroid Build Coastguard Worker 
4964*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_P2P
wpa_global_config_parse_ipv4(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)4965*03f9172cSAndroid Build Coastguard Worker static int wpa_global_config_parse_ipv4(const struct global_parse_data *data,
4966*03f9172cSAndroid Build Coastguard Worker 					struct wpa_config *config, int line,
4967*03f9172cSAndroid Build Coastguard Worker 					const char *pos)
4968*03f9172cSAndroid Build Coastguard Worker {
4969*03f9172cSAndroid Build Coastguard Worker 	u32 *dst;
4970*03f9172cSAndroid Build Coastguard Worker 	struct hostapd_ip_addr addr;
4971*03f9172cSAndroid Build Coastguard Worker 
4972*03f9172cSAndroid Build Coastguard Worker 	if (hostapd_parse_ip_addr(pos, &addr) < 0)
4973*03f9172cSAndroid Build Coastguard Worker 		return -1;
4974*03f9172cSAndroid Build Coastguard Worker 	if (addr.af != AF_INET)
4975*03f9172cSAndroid Build Coastguard Worker 		return -1;
4976*03f9172cSAndroid Build Coastguard Worker 
4977*03f9172cSAndroid Build Coastguard Worker 	dst = (u32 *) (((u8 *) config) + (long) data->param1);
4978*03f9172cSAndroid Build Coastguard Worker 	if (os_memcmp(dst, &addr.u.v4.s_addr, 4) == 0)
4979*03f9172cSAndroid Build Coastguard Worker 		return 1;
4980*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(dst, &addr.u.v4.s_addr, 4);
4981*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "%s = 0x%x", data->name,
4982*03f9172cSAndroid Build Coastguard Worker 		   WPA_GET_BE32((u8 *) dst));
4983*03f9172cSAndroid Build Coastguard Worker 
4984*03f9172cSAndroid Build Coastguard Worker 	return 0;
4985*03f9172cSAndroid Build Coastguard Worker }
4986*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_P2P */
4987*03f9172cSAndroid Build Coastguard Worker 
4988*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_country(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)4989*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_country(const struct global_parse_data *data,
4990*03f9172cSAndroid Build Coastguard Worker 				      struct wpa_config *config, int line,
4991*03f9172cSAndroid Build Coastguard Worker 				      const char *pos)
4992*03f9172cSAndroid Build Coastguard Worker {
4993*03f9172cSAndroid Build Coastguard Worker 	if (!pos[0] || !pos[1]) {
4994*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_DEBUG, "Invalid country set");
4995*03f9172cSAndroid Build Coastguard Worker 		return -1;
4996*03f9172cSAndroid Build Coastguard Worker 	}
4997*03f9172cSAndroid Build Coastguard Worker 	if (pos[0] == config->country[0] && pos[1] == config->country[1])
4998*03f9172cSAndroid Build Coastguard Worker 		return 1;
4999*03f9172cSAndroid Build Coastguard Worker 	config->country[0] = pos[0];
5000*03f9172cSAndroid Build Coastguard Worker 	config->country[1] = pos[1];
5001*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "country='%c%c'",
5002*03f9172cSAndroid Build Coastguard Worker 		   config->country[0], config->country[1]);
5003*03f9172cSAndroid Build Coastguard Worker 	return 0;
5004*03f9172cSAndroid Build Coastguard Worker }
5005*03f9172cSAndroid Build Coastguard Worker 
5006*03f9172cSAndroid Build Coastguard Worker 
5007*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_NO_LOAD_DYNAMIC_EAP
wpa_config_process_load_dynamic_eap(const struct global_parse_data * data,struct wpa_config * config,int line,const char * so)5008*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_load_dynamic_eap(
5009*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data, struct wpa_config *config,
5010*03f9172cSAndroid Build Coastguard Worker 	int line, const char *so)
5011*03f9172cSAndroid Build Coastguard Worker {
5012*03f9172cSAndroid Build Coastguard Worker 	int ret;
5013*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "load_dynamic_eap=%s", so);
5014*03f9172cSAndroid Build Coastguard Worker 	ret = eap_peer_method_load(so);
5015*03f9172cSAndroid Build Coastguard Worker 	if (ret == -2) {
5016*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_DEBUG, "This EAP type was already loaded - not "
5017*03f9172cSAndroid Build Coastguard Worker 			   "reloading.");
5018*03f9172cSAndroid Build Coastguard Worker 	} else if (ret) {
5019*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Failed to load dynamic EAP "
5020*03f9172cSAndroid Build Coastguard Worker 			   "method '%s'.", line, so);
5021*03f9172cSAndroid Build Coastguard Worker 		return -1;
5022*03f9172cSAndroid Build Coastguard Worker 	}
5023*03f9172cSAndroid Build Coastguard Worker 
5024*03f9172cSAndroid Build Coastguard Worker 	return 0;
5025*03f9172cSAndroid Build Coastguard Worker }
5026*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_LOAD_DYNAMIC_EAP */
5027*03f9172cSAndroid Build Coastguard Worker 
5028*03f9172cSAndroid Build Coastguard Worker 
5029*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_WPS
5030*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_uuid(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5031*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_uuid(const struct global_parse_data *data,
5032*03f9172cSAndroid Build Coastguard Worker 				   struct wpa_config *config, int line,
5033*03f9172cSAndroid Build Coastguard Worker 				   const char *pos)
5034*03f9172cSAndroid Build Coastguard Worker {
5035*03f9172cSAndroid Build Coastguard Worker 	char buf[40];
5036*03f9172cSAndroid Build Coastguard Worker 	if (uuid_str2bin(pos, config->uuid)) {
5037*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: invalid UUID", line);
5038*03f9172cSAndroid Build Coastguard Worker 		return -1;
5039*03f9172cSAndroid Build Coastguard Worker 	}
5040*03f9172cSAndroid Build Coastguard Worker 	uuid_bin2str(config->uuid, buf, sizeof(buf));
5041*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "uuid=%s", buf);
5042*03f9172cSAndroid Build Coastguard Worker 	return 0;
5043*03f9172cSAndroid Build Coastguard Worker }
5044*03f9172cSAndroid Build Coastguard Worker 
5045*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_device_type(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5046*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_device_type(
5047*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5048*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5049*03f9172cSAndroid Build Coastguard Worker {
5050*03f9172cSAndroid Build Coastguard Worker 	return wps_dev_type_str2bin(pos, config->device_type);
5051*03f9172cSAndroid Build Coastguard Worker }
5052*03f9172cSAndroid Build Coastguard Worker 
5053*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_os_version(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5054*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_os_version(const struct global_parse_data *data,
5055*03f9172cSAndroid Build Coastguard Worker 					 struct wpa_config *config, int line,
5056*03f9172cSAndroid Build Coastguard Worker 					 const char *pos)
5057*03f9172cSAndroid Build Coastguard Worker {
5058*03f9172cSAndroid Build Coastguard Worker 	if (hexstr2bin(pos, config->os_version, 4)) {
5059*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: invalid os_version", line);
5060*03f9172cSAndroid Build Coastguard Worker 		return -1;
5061*03f9172cSAndroid Build Coastguard Worker 	}
5062*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "os_version=%08x",
5063*03f9172cSAndroid Build Coastguard Worker 		   WPA_GET_BE32(config->os_version));
5064*03f9172cSAndroid Build Coastguard Worker 	return 0;
5065*03f9172cSAndroid Build Coastguard Worker }
5066*03f9172cSAndroid Build Coastguard Worker 
5067*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_wps_vendor_ext_m1(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5068*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_wps_vendor_ext_m1(
5069*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5070*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5071*03f9172cSAndroid Build Coastguard Worker {
5072*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf *tmp;
5073*03f9172cSAndroid Build Coastguard Worker 	int len = os_strlen(pos) / 2;
5074*03f9172cSAndroid Build Coastguard Worker 	u8 *p;
5075*03f9172cSAndroid Build Coastguard Worker 
5076*03f9172cSAndroid Build Coastguard Worker 	if (!len) {
5077*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: "
5078*03f9172cSAndroid Build Coastguard Worker 			   "invalid wps_vendor_ext_m1", line);
5079*03f9172cSAndroid Build Coastguard Worker 		return -1;
5080*03f9172cSAndroid Build Coastguard Worker 	}
5081*03f9172cSAndroid Build Coastguard Worker 
5082*03f9172cSAndroid Build Coastguard Worker 	tmp = wpabuf_alloc(len);
5083*03f9172cSAndroid Build Coastguard Worker 	if (tmp) {
5084*03f9172cSAndroid Build Coastguard Worker 		p = wpabuf_put(tmp, len);
5085*03f9172cSAndroid Build Coastguard Worker 
5086*03f9172cSAndroid Build Coastguard Worker 		if (hexstr2bin(pos, p, len)) {
5087*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: "
5088*03f9172cSAndroid Build Coastguard Worker 				   "invalid wps_vendor_ext_m1", line);
5089*03f9172cSAndroid Build Coastguard Worker 			wpabuf_free(tmp);
5090*03f9172cSAndroid Build Coastguard Worker 			return -1;
5091*03f9172cSAndroid Build Coastguard Worker 		}
5092*03f9172cSAndroid Build Coastguard Worker 
5093*03f9172cSAndroid Build Coastguard Worker 		wpabuf_free(config->wps_vendor_ext_m1);
5094*03f9172cSAndroid Build Coastguard Worker 		config->wps_vendor_ext_m1 = tmp;
5095*03f9172cSAndroid Build Coastguard Worker 	} else {
5096*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Can not allocate "
5097*03f9172cSAndroid Build Coastguard Worker 			   "memory for wps_vendor_ext_m1");
5098*03f9172cSAndroid Build Coastguard Worker 		return -1;
5099*03f9172cSAndroid Build Coastguard Worker 	}
5100*03f9172cSAndroid Build Coastguard Worker 
5101*03f9172cSAndroid Build Coastguard Worker 	return 0;
5102*03f9172cSAndroid Build Coastguard Worker }
5103*03f9172cSAndroid Build Coastguard Worker 
5104*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_WPS */
5105*03f9172cSAndroid Build Coastguard Worker 
5106*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_P2P
wpa_config_process_sec_device_type(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5107*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_sec_device_type(
5108*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5109*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5110*03f9172cSAndroid Build Coastguard Worker {
5111*03f9172cSAndroid Build Coastguard Worker 	int idx;
5112*03f9172cSAndroid Build Coastguard Worker 
5113*03f9172cSAndroid Build Coastguard Worker 	if (config->num_sec_device_types >= MAX_SEC_DEVICE_TYPES) {
5114*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: too many sec_device_type "
5115*03f9172cSAndroid Build Coastguard Worker 			   "items", line);
5116*03f9172cSAndroid Build Coastguard Worker 		return -1;
5117*03f9172cSAndroid Build Coastguard Worker 	}
5118*03f9172cSAndroid Build Coastguard Worker 
5119*03f9172cSAndroid Build Coastguard Worker 	idx = config->num_sec_device_types;
5120*03f9172cSAndroid Build Coastguard Worker 
5121*03f9172cSAndroid Build Coastguard Worker 	if (wps_dev_type_str2bin(pos, config->sec_device_type[idx]))
5122*03f9172cSAndroid Build Coastguard Worker 		return -1;
5123*03f9172cSAndroid Build Coastguard Worker 
5124*03f9172cSAndroid Build Coastguard Worker 	config->num_sec_device_types++;
5125*03f9172cSAndroid Build Coastguard Worker 	return 0;
5126*03f9172cSAndroid Build Coastguard Worker }
5127*03f9172cSAndroid Build Coastguard Worker 
5128*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_p2p_pref_chan(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5129*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_p2p_pref_chan(
5130*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5131*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5132*03f9172cSAndroid Build Coastguard Worker {
5133*03f9172cSAndroid Build Coastguard Worker 	struct p2p_channel *pref = NULL, *n;
5134*03f9172cSAndroid Build Coastguard Worker 	size_t num = 0;
5135*03f9172cSAndroid Build Coastguard Worker 	const char *pos2;
5136*03f9172cSAndroid Build Coastguard Worker 	u8 op_class, chan;
5137*03f9172cSAndroid Build Coastguard Worker 
5138*03f9172cSAndroid Build Coastguard Worker 	/* format: class:chan,class:chan,... */
5139*03f9172cSAndroid Build Coastguard Worker 
5140*03f9172cSAndroid Build Coastguard Worker 	while (*pos) {
5141*03f9172cSAndroid Build Coastguard Worker 		op_class = atoi(pos);
5142*03f9172cSAndroid Build Coastguard Worker 		pos2 = os_strchr(pos, ':');
5143*03f9172cSAndroid Build Coastguard Worker 		if (pos2 == NULL)
5144*03f9172cSAndroid Build Coastguard Worker 			goto fail;
5145*03f9172cSAndroid Build Coastguard Worker 		pos2++;
5146*03f9172cSAndroid Build Coastguard Worker 		chan = atoi(pos2);
5147*03f9172cSAndroid Build Coastguard Worker 
5148*03f9172cSAndroid Build Coastguard Worker 		n = os_realloc_array(pref, num + 1,
5149*03f9172cSAndroid Build Coastguard Worker 				     sizeof(struct p2p_channel));
5150*03f9172cSAndroid Build Coastguard Worker 		if (n == NULL)
5151*03f9172cSAndroid Build Coastguard Worker 			goto fail;
5152*03f9172cSAndroid Build Coastguard Worker 		pref = n;
5153*03f9172cSAndroid Build Coastguard Worker 		pref[num].op_class = op_class;
5154*03f9172cSAndroid Build Coastguard Worker 		pref[num].chan = chan;
5155*03f9172cSAndroid Build Coastguard Worker 		num++;
5156*03f9172cSAndroid Build Coastguard Worker 
5157*03f9172cSAndroid Build Coastguard Worker 		pos = os_strchr(pos2, ',');
5158*03f9172cSAndroid Build Coastguard Worker 		if (pos == NULL)
5159*03f9172cSAndroid Build Coastguard Worker 			break;
5160*03f9172cSAndroid Build Coastguard Worker 		pos++;
5161*03f9172cSAndroid Build Coastguard Worker 	}
5162*03f9172cSAndroid Build Coastguard Worker 
5163*03f9172cSAndroid Build Coastguard Worker 	os_free(config->p2p_pref_chan);
5164*03f9172cSAndroid Build Coastguard Worker 	config->p2p_pref_chan = pref;
5165*03f9172cSAndroid Build Coastguard Worker 	config->num_p2p_pref_chan = num;
5166*03f9172cSAndroid Build Coastguard Worker 	wpa_hexdump(MSG_DEBUG, "P2P: Preferred class/channel pairs",
5167*03f9172cSAndroid Build Coastguard Worker 		    (u8 *) config->p2p_pref_chan,
5168*03f9172cSAndroid Build Coastguard Worker 		    config->num_p2p_pref_chan * sizeof(struct p2p_channel));
5169*03f9172cSAndroid Build Coastguard Worker 
5170*03f9172cSAndroid Build Coastguard Worker 	return 0;
5171*03f9172cSAndroid Build Coastguard Worker 
5172*03f9172cSAndroid Build Coastguard Worker fail:
5173*03f9172cSAndroid Build Coastguard Worker 	os_free(pref);
5174*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_ERROR, "Line %d: Invalid p2p_pref_chan list", line);
5175*03f9172cSAndroid Build Coastguard Worker 	return -1;
5176*03f9172cSAndroid Build Coastguard Worker }
5177*03f9172cSAndroid Build Coastguard Worker 
5178*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_p2p_no_go_freq(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5179*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_p2p_no_go_freq(
5180*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5181*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5182*03f9172cSAndroid Build Coastguard Worker {
5183*03f9172cSAndroid Build Coastguard Worker 	int ret;
5184*03f9172cSAndroid Build Coastguard Worker 
5185*03f9172cSAndroid Build Coastguard Worker 	ret = freq_range_list_parse(&config->p2p_no_go_freq, pos);
5186*03f9172cSAndroid Build Coastguard Worker 	if (ret < 0) {
5187*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid p2p_no_go_freq", line);
5188*03f9172cSAndroid Build Coastguard Worker 		return -1;
5189*03f9172cSAndroid Build Coastguard Worker 	}
5190*03f9172cSAndroid Build Coastguard Worker 
5191*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "P2P: p2p_no_go_freq with %u items",
5192*03f9172cSAndroid Build Coastguard Worker 		   config->p2p_no_go_freq.num);
5193*03f9172cSAndroid Build Coastguard Worker 
5194*03f9172cSAndroid Build Coastguard Worker 	return 0;
5195*03f9172cSAndroid Build Coastguard Worker }
5196*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_p2p_device_persistent_mac_addr(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5197*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_p2p_device_persistent_mac_addr(
5198*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5199*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5200*03f9172cSAndroid Build Coastguard Worker {
5201*03f9172cSAndroid Build Coastguard Worker 	if (hwaddr_aton2(pos, config->p2p_device_persistent_mac_addr) < 0) {
5202*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR,
5203*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: Invalid p2p_device_persistent_mac_addr '%s'",
5204*03f9172cSAndroid Build Coastguard Worker 			   line, pos);
5205*03f9172cSAndroid Build Coastguard Worker 		return -1;
5206*03f9172cSAndroid Build Coastguard Worker 	}
5207*03f9172cSAndroid Build Coastguard Worker 
5208*03f9172cSAndroid Build Coastguard Worker 	return 0;
5209*03f9172cSAndroid Build Coastguard Worker }
5210*03f9172cSAndroid Build Coastguard Worker 
5211*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_P2P */
5212*03f9172cSAndroid Build Coastguard Worker 
5213*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_hessid(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5214*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_hessid(
5215*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5216*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5217*03f9172cSAndroid Build Coastguard Worker {
5218*03f9172cSAndroid Build Coastguard Worker 	if (hwaddr_aton2(pos, config->hessid) < 0) {
5219*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid hessid '%s'",
5220*03f9172cSAndroid Build Coastguard Worker 			   line, pos);
5221*03f9172cSAndroid Build Coastguard Worker 		return -1;
5222*03f9172cSAndroid Build Coastguard Worker 	}
5223*03f9172cSAndroid Build Coastguard Worker 
5224*03f9172cSAndroid Build Coastguard Worker 	return 0;
5225*03f9172cSAndroid Build Coastguard Worker }
5226*03f9172cSAndroid Build Coastguard Worker 
5227*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_sae_groups(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5228*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_sae_groups(
5229*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5230*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5231*03f9172cSAndroid Build Coastguard Worker {
5232*03f9172cSAndroid Build Coastguard Worker 	int *groups = wpa_config_parse_int_array(pos);
5233*03f9172cSAndroid Build Coastguard Worker 	if (groups == NULL) {
5234*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: Invalid sae_groups '%s'",
5235*03f9172cSAndroid Build Coastguard Worker 			   line, pos);
5236*03f9172cSAndroid Build Coastguard Worker 		return -1;
5237*03f9172cSAndroid Build Coastguard Worker 	}
5238*03f9172cSAndroid Build Coastguard Worker 
5239*03f9172cSAndroid Build Coastguard Worker 	os_free(config->sae_groups);
5240*03f9172cSAndroid Build Coastguard Worker 	config->sae_groups = groups;
5241*03f9172cSAndroid Build Coastguard Worker 
5242*03f9172cSAndroid Build Coastguard Worker 	return 0;
5243*03f9172cSAndroid Build Coastguard Worker }
5244*03f9172cSAndroid Build Coastguard Worker 
5245*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_ap_vendor_elements(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5246*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_ap_vendor_elements(
5247*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5248*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5249*03f9172cSAndroid Build Coastguard Worker {
5250*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf *tmp;
5251*03f9172cSAndroid Build Coastguard Worker 
5252*03f9172cSAndroid Build Coastguard Worker 	if (!*pos) {
5253*03f9172cSAndroid Build Coastguard Worker 		wpabuf_free(config->ap_vendor_elements);
5254*03f9172cSAndroid Build Coastguard Worker 		config->ap_vendor_elements = NULL;
5255*03f9172cSAndroid Build Coastguard Worker 		return 0;
5256*03f9172cSAndroid Build Coastguard Worker 	}
5257*03f9172cSAndroid Build Coastguard Worker 
5258*03f9172cSAndroid Build Coastguard Worker 	tmp = wpabuf_parse_bin(pos);
5259*03f9172cSAndroid Build Coastguard Worker 	if (!tmp) {
5260*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: invalid ap_vendor_elements",
5261*03f9172cSAndroid Build Coastguard Worker 			   line);
5262*03f9172cSAndroid Build Coastguard Worker 		return -1;
5263*03f9172cSAndroid Build Coastguard Worker 	}
5264*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(config->ap_vendor_elements);
5265*03f9172cSAndroid Build Coastguard Worker 	config->ap_vendor_elements = tmp;
5266*03f9172cSAndroid Build Coastguard Worker 
5267*03f9172cSAndroid Build Coastguard Worker 	return 0;
5268*03f9172cSAndroid Build Coastguard Worker }
5269*03f9172cSAndroid Build Coastguard Worker 
5270*03f9172cSAndroid Build Coastguard Worker 
wpa_config_process_ap_assocresp_elements(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5271*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_ap_assocresp_elements(
5272*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5273*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5274*03f9172cSAndroid Build Coastguard Worker {
5275*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf *tmp;
5276*03f9172cSAndroid Build Coastguard Worker 
5277*03f9172cSAndroid Build Coastguard Worker 	if (!*pos) {
5278*03f9172cSAndroid Build Coastguard Worker 		wpabuf_free(config->ap_assocresp_elements);
5279*03f9172cSAndroid Build Coastguard Worker 		config->ap_assocresp_elements = NULL;
5280*03f9172cSAndroid Build Coastguard Worker 		return 0;
5281*03f9172cSAndroid Build Coastguard Worker 	}
5282*03f9172cSAndroid Build Coastguard Worker 
5283*03f9172cSAndroid Build Coastguard Worker 	tmp = wpabuf_parse_bin(pos);
5284*03f9172cSAndroid Build Coastguard Worker 	if (!tmp) {
5285*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: invalid ap_assocresp_elements",
5286*03f9172cSAndroid Build Coastguard Worker 			   line);
5287*03f9172cSAndroid Build Coastguard Worker 		return -1;
5288*03f9172cSAndroid Build Coastguard Worker 	}
5289*03f9172cSAndroid Build Coastguard Worker 	wpabuf_free(config->ap_assocresp_elements);
5290*03f9172cSAndroid Build Coastguard Worker 	config->ap_assocresp_elements = tmp;
5291*03f9172cSAndroid Build Coastguard Worker 
5292*03f9172cSAndroid Build Coastguard Worker 	return 0;
5293*03f9172cSAndroid Build Coastguard Worker }
5294*03f9172cSAndroid Build Coastguard Worker 
5295*03f9172cSAndroid Build Coastguard Worker 
5296*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_CTRL_IFACE
wpa_config_process_no_ctrl_interface(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5297*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_no_ctrl_interface(
5298*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5299*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5300*03f9172cSAndroid Build Coastguard Worker {
5301*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "no_ctrl_interface -> ctrl_interface=NULL");
5302*03f9172cSAndroid Build Coastguard Worker 	os_free(config->ctrl_interface);
5303*03f9172cSAndroid Build Coastguard Worker 	config->ctrl_interface = NULL;
5304*03f9172cSAndroid Build Coastguard Worker 	return 0;
5305*03f9172cSAndroid Build Coastguard Worker }
5306*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_CTRL_IFACE */
5307*03f9172cSAndroid Build Coastguard Worker 
5308*03f9172cSAndroid Build Coastguard Worker 
wpa_config_get_int(const char * name,struct wpa_config * config,long offset,char * buf,size_t buflen,int pretty_print)5309*03f9172cSAndroid Build Coastguard Worker static int wpa_config_get_int(const char *name, struct wpa_config *config,
5310*03f9172cSAndroid Build Coastguard Worker 			      long offset, char *buf, size_t buflen,
5311*03f9172cSAndroid Build Coastguard Worker 			      int pretty_print)
5312*03f9172cSAndroid Build Coastguard Worker {
5313*03f9172cSAndroid Build Coastguard Worker 	int *val = (int *) (((u8 *) config) + (long) offset);
5314*03f9172cSAndroid Build Coastguard Worker 
5315*03f9172cSAndroid Build Coastguard Worker 	if (pretty_print)
5316*03f9172cSAndroid Build Coastguard Worker 		return os_snprintf(buf, buflen, "%s=%d\n", name, *val);
5317*03f9172cSAndroid Build Coastguard Worker 	return os_snprintf(buf, buflen, "%d", *val);
5318*03f9172cSAndroid Build Coastguard Worker }
5319*03f9172cSAndroid Build Coastguard Worker 
5320*03f9172cSAndroid Build Coastguard Worker 
wpa_config_get_str(const char * name,struct wpa_config * config,long offset,char * buf,size_t buflen,int pretty_print)5321*03f9172cSAndroid Build Coastguard Worker static int wpa_config_get_str(const char *name, struct wpa_config *config,
5322*03f9172cSAndroid Build Coastguard Worker 			      long offset, char *buf, size_t buflen,
5323*03f9172cSAndroid Build Coastguard Worker 			      int pretty_print)
5324*03f9172cSAndroid Build Coastguard Worker {
5325*03f9172cSAndroid Build Coastguard Worker 	char **val = (char **) (((u8 *) config) + (long) offset);
5326*03f9172cSAndroid Build Coastguard Worker 	int res;
5327*03f9172cSAndroid Build Coastguard Worker 
5328*03f9172cSAndroid Build Coastguard Worker 	if (pretty_print)
5329*03f9172cSAndroid Build Coastguard Worker 		res = os_snprintf(buf, buflen, "%s=%s\n", name,
5330*03f9172cSAndroid Build Coastguard Worker 				  *val ? *val : "null");
5331*03f9172cSAndroid Build Coastguard Worker 	else if (!*val)
5332*03f9172cSAndroid Build Coastguard Worker 		return -1;
5333*03f9172cSAndroid Build Coastguard Worker 	else
5334*03f9172cSAndroid Build Coastguard Worker 		res = os_snprintf(buf, buflen, "%s", *val);
5335*03f9172cSAndroid Build Coastguard Worker 	if (os_snprintf_error(buflen, res))
5336*03f9172cSAndroid Build Coastguard Worker 		res = -1;
5337*03f9172cSAndroid Build Coastguard Worker 
5338*03f9172cSAndroid Build Coastguard Worker 	return res;
5339*03f9172cSAndroid Build Coastguard Worker }
5340*03f9172cSAndroid Build Coastguard Worker 
5341*03f9172cSAndroid Build Coastguard Worker 
5342*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_P2P
wpa_config_get_ipv4(const char * name,struct wpa_config * config,long offset,char * buf,size_t buflen,int pretty_print)5343*03f9172cSAndroid Build Coastguard Worker static int wpa_config_get_ipv4(const char *name, struct wpa_config *config,
5344*03f9172cSAndroid Build Coastguard Worker 			       long offset, char *buf, size_t buflen,
5345*03f9172cSAndroid Build Coastguard Worker 			       int pretty_print)
5346*03f9172cSAndroid Build Coastguard Worker {
5347*03f9172cSAndroid Build Coastguard Worker 	void *val = ((u8 *) config) + (long) offset;
5348*03f9172cSAndroid Build Coastguard Worker 	int res;
5349*03f9172cSAndroid Build Coastguard Worker 	char addr[INET_ADDRSTRLEN];
5350*03f9172cSAndroid Build Coastguard Worker 
5351*03f9172cSAndroid Build Coastguard Worker 	if (!val || !inet_ntop(AF_INET, val, addr, sizeof(addr)))
5352*03f9172cSAndroid Build Coastguard Worker 		return -1;
5353*03f9172cSAndroid Build Coastguard Worker 
5354*03f9172cSAndroid Build Coastguard Worker 	if (pretty_print)
5355*03f9172cSAndroid Build Coastguard Worker 		res = os_snprintf(buf, buflen, "%s=%s\n", name, addr);
5356*03f9172cSAndroid Build Coastguard Worker 	else
5357*03f9172cSAndroid Build Coastguard Worker 		res = os_snprintf(buf, buflen, "%s", addr);
5358*03f9172cSAndroid Build Coastguard Worker 
5359*03f9172cSAndroid Build Coastguard Worker 	if (os_snprintf_error(buflen, res))
5360*03f9172cSAndroid Build Coastguard Worker 		res = -1;
5361*03f9172cSAndroid Build Coastguard Worker 
5362*03f9172cSAndroid Build Coastguard Worker 	return res;
5363*03f9172cSAndroid Build Coastguard Worker }
5364*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_P2P */
5365*03f9172cSAndroid Build Coastguard Worker 
5366*03f9172cSAndroid Build Coastguard Worker 
5367*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_TESTING_OPTIONS
wpa_config_process_mld_connect_bssid_pref(const struct global_parse_data * data,struct wpa_config * config,int line,const char * pos)5368*03f9172cSAndroid Build Coastguard Worker static int wpa_config_process_mld_connect_bssid_pref(
5369*03f9172cSAndroid Build Coastguard Worker 	const struct global_parse_data *data,
5370*03f9172cSAndroid Build Coastguard Worker 	struct wpa_config *config, int line, const char *pos)
5371*03f9172cSAndroid Build Coastguard Worker {
5372*03f9172cSAndroid Build Coastguard Worker 	if (hwaddr_aton2(pos, config->mld_connect_bssid_pref) < 0) {
5373*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR,
5374*03f9172cSAndroid Build Coastguard Worker 			   "Line %d: Invalid mld_connect_bssid_pref '%s'",
5375*03f9172cSAndroid Build Coastguard Worker 			   line, pos);
5376*03f9172cSAndroid Build Coastguard Worker 		return -1;
5377*03f9172cSAndroid Build Coastguard Worker 	}
5378*03f9172cSAndroid Build Coastguard Worker 
5379*03f9172cSAndroid Build Coastguard Worker 	return 0;
5380*03f9172cSAndroid Build Coastguard Worker }
5381*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_TESTING_OPTIONS */
5382*03f9172cSAndroid Build Coastguard Worker 
5383*03f9172cSAndroid Build Coastguard Worker 
5384*03f9172cSAndroid Build Coastguard Worker #ifdef OFFSET
5385*03f9172cSAndroid Build Coastguard Worker #undef OFFSET
5386*03f9172cSAndroid Build Coastguard Worker #endif /* OFFSET */
5387*03f9172cSAndroid Build Coastguard Worker /* OFFSET: Get offset of a variable within the wpa_config structure */
5388*03f9172cSAndroid Build Coastguard Worker #define OFFSET(v) ((void *) &((struct wpa_config *) 0)->v)
5389*03f9172cSAndroid Build Coastguard Worker 
5390*03f9172cSAndroid Build Coastguard Worker #define FUNC(f) #f, wpa_config_process_ ## f, NULL, OFFSET(f), NULL, NULL
5391*03f9172cSAndroid Build Coastguard Worker #define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL, NULL
5392*03f9172cSAndroid Build Coastguard Worker #define _INT(f) #f, wpa_global_config_parse_int, wpa_config_get_int, OFFSET(f)
5393*03f9172cSAndroid Build Coastguard Worker #define INT(f) _INT(f), NULL, NULL
5394*03f9172cSAndroid Build Coastguard Worker #define INT_RANGE(f, min, max) #f, wpa_global_config_parse_int_range, \
5395*03f9172cSAndroid Build Coastguard Worker 	wpa_config_get_int, OFFSET(f), (void *) min, (void *) max
5396*03f9172cSAndroid Build Coastguard Worker #define _STR(f) #f, wpa_global_config_parse_str, wpa_config_get_str, OFFSET(f)
5397*03f9172cSAndroid Build Coastguard Worker #define STR(f) _STR(f), NULL, NULL
5398*03f9172cSAndroid Build Coastguard Worker #define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
5399*03f9172cSAndroid Build Coastguard Worker #define BIN(f) #f, wpa_global_config_parse_bin, NULL, OFFSET(f), NULL, NULL
5400*03f9172cSAndroid Build Coastguard Worker #define IPV4(f) #f, wpa_global_config_parse_ipv4, wpa_config_get_ipv4,  \
5401*03f9172cSAndroid Build Coastguard Worker 	OFFSET(f), NULL, NULL
5402*03f9172cSAndroid Build Coastguard Worker 
5403*03f9172cSAndroid Build Coastguard Worker static const struct global_parse_data global_fields[] = {
5404*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_CTRL_IFACE
5405*03f9172cSAndroid Build Coastguard Worker 	{ STR(ctrl_interface), 0 },
5406*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_NO_VAR(no_ctrl_interface), 0 },
5407*03f9172cSAndroid Build Coastguard Worker 	{ STR(ctrl_interface_group), 0 } /* deprecated */,
5408*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_CTRL_IFACE */
5409*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MACSEC
5410*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(eapol_version, 1, 3), 0 },
5411*03f9172cSAndroid Build Coastguard Worker #else /* CONFIG_MACSEC */
5412*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(eapol_version, 1, 2), 0 },
5413*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MACSEC */
5414*03f9172cSAndroid Build Coastguard Worker 	{ INT(ap_scan), 0 },
5415*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(bgscan), CFG_CHANGED_BGSCAN },
5416*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MESH
5417*03f9172cSAndroid Build Coastguard Worker 	{ INT(user_mpm), 0 },
5418*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(max_peer_links, 0, 255), 0 },
5419*03f9172cSAndroid Build Coastguard Worker 	{ INT(mesh_max_inactivity), 0 },
5420*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mesh_fwding, 0, 1), 0 },
5421*03f9172cSAndroid Build Coastguard Worker 	{ INT(dot11RSNASAERetransPeriod), 0 },
5422*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MESH */
5423*03f9172cSAndroid Build Coastguard Worker 	{ INT(disable_scan_offload), 0 },
5424*03f9172cSAndroid Build Coastguard Worker 	{ INT(fast_reauth), 0 },
5425*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_OPENSC_ENGINE_PATH
5426*03f9172cSAndroid Build Coastguard Worker 	{ STR(opensc_engine_path), 0 },
5427*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_OPENSC_ENGINE_PATH */
5428*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_PKCS11_ENGINE_PATH
5429*03f9172cSAndroid Build Coastguard Worker 	{ STR(pkcs11_engine_path), 0 },
5430*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_PKCS11_ENGINE_PATH */
5431*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_PKCS11_MODULE_PATH
5432*03f9172cSAndroid Build Coastguard Worker 	{ STR(pkcs11_module_path), 0 },
5433*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_PKCS11_MODULE_PATH */
5434*03f9172cSAndroid Build Coastguard Worker 	{ STR(openssl_ciphers), 0 },
5435*03f9172cSAndroid Build Coastguard Worker 	{ STR(pcsc_reader), 0 },
5436*03f9172cSAndroid Build Coastguard Worker 	{ STR(pcsc_pin), 0 },
5437*03f9172cSAndroid Build Coastguard Worker 	{ INT(external_sim), 0 },
5438*03f9172cSAndroid Build Coastguard Worker 	{ STR(driver_param), 0 },
5439*03f9172cSAndroid Build Coastguard Worker 	{ INT(dot11RSNAConfigPMKLifetime), 0 },
5440*03f9172cSAndroid Build Coastguard Worker 	{ INT(dot11RSNAConfigPMKReauthThreshold), 0 },
5441*03f9172cSAndroid Build Coastguard Worker 	{ INT(dot11RSNAConfigSATimeout), 0 },
5442*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_NO_CONFIG_WRITE
5443*03f9172cSAndroid Build Coastguard Worker 	{ INT(update_config), 0 },
5444*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_CONFIG_WRITE */
5445*03f9172cSAndroid Build Coastguard Worker #ifndef CONFIG_NO_LOAD_DYNAMIC_EAP
5446*03f9172cSAndroid Build Coastguard Worker 	{ FUNC_NO_VAR(load_dynamic_eap), 0 },
5447*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_NO_LOAD_DYNAMIC_EAP */
5448*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_WPS
5449*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(uuid), CFG_CHANGED_UUID },
5450*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(auto_uuid, 0, 1), 0 },
5451*03f9172cSAndroid Build Coastguard Worker 	{ STR_RANGE(device_name, 0, WPS_DEV_NAME_MAX_LEN),
5452*03f9172cSAndroid Build Coastguard Worker 	  CFG_CHANGED_DEVICE_NAME },
5453*03f9172cSAndroid Build Coastguard Worker 	{ STR_RANGE(manufacturer, 0, 64), CFG_CHANGED_WPS_STRING },
5454*03f9172cSAndroid Build Coastguard Worker 	{ STR_RANGE(model_name, 0, 32), CFG_CHANGED_WPS_STRING },
5455*03f9172cSAndroid Build Coastguard Worker 	{ STR_RANGE(model_number, 0, 32), CFG_CHANGED_WPS_STRING },
5456*03f9172cSAndroid Build Coastguard Worker 	{ STR_RANGE(serial_number, 0, 32), CFG_CHANGED_WPS_STRING },
5457*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(device_type), CFG_CHANGED_DEVICE_TYPE },
5458*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(os_version), CFG_CHANGED_OS_VERSION },
5459*03f9172cSAndroid Build Coastguard Worker 	{ STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
5460*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(wps_cred_processing, 0, 2), 0 },
5461*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(wps_cred_add_sae, 0, 1), 0 },
5462*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(wps_vendor_ext_m1), CFG_CHANGED_VENDOR_EXTENSION },
5463*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_WPS */
5464*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_P2P
5465*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(sec_device_type), CFG_CHANGED_SEC_DEVICE_TYPE },
5466*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_listen_reg_class), CFG_CHANGED_P2P_LISTEN_CHANNEL },
5467*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_listen_channel), CFG_CHANGED_P2P_LISTEN_CHANNEL },
5468*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_oper_reg_class), CFG_CHANGED_P2P_OPER_CHANNEL },
5469*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_oper_channel), CFG_CHANGED_P2P_OPER_CHANNEL },
5470*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(p2p_go_intent, 0, 15), 0 },
5471*03f9172cSAndroid Build Coastguard Worker 	{ STR(p2p_ssid_postfix), CFG_CHANGED_P2P_SSID_POSTFIX },
5472*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(persistent_reconnect, 0, 1), 0 },
5473*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(p2p_intra_bss, 0, 1), CFG_CHANGED_P2P_INTRA_BSS },
5474*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_group_idle), 0 },
5475*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(p2p_go_freq_change_policy, 0, P2P_GO_FREQ_MOVE_MAX), 0 },
5476*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(p2p_passphrase_len, 8, 63),
5477*03f9172cSAndroid Build Coastguard Worker 	  CFG_CHANGED_P2P_PASSPHRASE_LEN },
5478*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(p2p_pref_chan), CFG_CHANGED_P2P_PREF_CHAN },
5479*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(p2p_no_go_freq), CFG_CHANGED_P2P_PREF_CHAN },
5480*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(p2p_add_cli_chan, 0, 1), 0 },
5481*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(p2p_optimize_listen_chan, 0, 1), 0 },
5482*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_go_ht40), 0 },
5483*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_go_vht), 0 },
5484*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_go_he), 0 },
5485*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_go_edmg), 0 },
5486*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_disabled), 0 },
5487*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(p2p_go_ctwindow, 0, 127), 0 },
5488*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_no_group_iface), 0 },
5489*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(p2p_ignore_shared_freq, 0, 1), 0 },
5490*03f9172cSAndroid Build Coastguard Worker 	{ IPV4(ip_addr_go), 0 },
5491*03f9172cSAndroid Build Coastguard Worker 	{ IPV4(ip_addr_mask), 0 },
5492*03f9172cSAndroid Build Coastguard Worker 	{ IPV4(ip_addr_start), 0 },
5493*03f9172cSAndroid Build Coastguard Worker 	{ IPV4(ip_addr_end), 0 },
5494*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(p2p_cli_probe, 0, 1), 0 },
5495*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_device_random_mac_addr), 0 },
5496*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(p2p_device_persistent_mac_addr), 0 },
5497*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_interface_random_mac_addr), 0 },
5498*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_6ghz_disable), 0 },
5499*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_dfs_chan_enable), 0 },
5500*03f9172cSAndroid Build Coastguard Worker 	{ INT(dik_cipher), 0},
5501*03f9172cSAndroid Build Coastguard Worker 	{ BIN(dik), 0 },
5502*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_P2P */
5503*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(country), CFG_CHANGED_COUNTRY },
5504*03f9172cSAndroid Build Coastguard Worker 	{ INT(bss_max_count), 0 },
5505*03f9172cSAndroid Build Coastguard Worker 	{ INT(bss_expiration_age), 0 },
5506*03f9172cSAndroid Build Coastguard Worker 	{ INT(bss_expiration_scan_count), 0 },
5507*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(filter_ssids, 0, 1), 0 },
5508*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(filter_rssi, -100, 0), 0 },
5509*03f9172cSAndroid Build Coastguard Worker 	{ INT(max_num_sta), 0 },
5510*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ap_isolate, 0, 1), 0 },
5511*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disassoc_low_ack, 0, 1), 0 },
5512*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_HS20
5513*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(hs20, 0, 1), 0 },
5514*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_HS20 */
5515*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(interworking, 0, 1), 0 },
5516*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(hessid), 0 },
5517*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(access_network_type, 0, 15), 0 },
5518*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(go_interworking, 0, 1), 0 },
5519*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(go_access_network_type, 0, 15), 0 },
5520*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(go_internet, 0, 1), 0 },
5521*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(go_venue_group, 0, 255), 0 },
5522*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(go_venue_type, 0, 255), 0 },
5523*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(pbc_in_m1, 0, 1), 0 },
5524*03f9172cSAndroid Build Coastguard Worker 	{ STR(autoscan), 0 },
5525*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(wps_nfc_dev_pw_id, 0x10, 0xffff),
5526*03f9172cSAndroid Build Coastguard Worker 	  CFG_CHANGED_NFC_PASSWORD_TOKEN },
5527*03f9172cSAndroid Build Coastguard Worker 	{ BIN(wps_nfc_dh_pubkey), CFG_CHANGED_NFC_PASSWORD_TOKEN },
5528*03f9172cSAndroid Build Coastguard Worker 	{ BIN(wps_nfc_dh_privkey), CFG_CHANGED_NFC_PASSWORD_TOKEN },
5529*03f9172cSAndroid Build Coastguard Worker 	{ BIN(wps_nfc_dev_pw), CFG_CHANGED_NFC_PASSWORD_TOKEN },
5530*03f9172cSAndroid Build Coastguard Worker 	{ STR(ext_password_backend), CFG_CHANGED_EXT_PW_BACKEND },
5531*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_go_max_inactivity), 0 },
5532*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(auto_interworking, 0, 1), 0 },
5533*03f9172cSAndroid Build Coastguard Worker 	{ INT(okc), 0 },
5534*03f9172cSAndroid Build Coastguard Worker 	{ INT(pmf), 0 },
5535*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(sae_check_mfp, 0, 1), 0 },
5536*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(sae_groups), 0 },
5537*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(sae_pwe, 0, 3), 0 },
5538*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(sae_pmkid_in_assoc, 0, 1), 0 },
5539*03f9172cSAndroid Build Coastguard Worker 	{ INT(dtim_period), 0 },
5540*03f9172cSAndroid Build Coastguard Worker 	{ INT(beacon_int), 0 },
5541*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(ap_assocresp_elements), 0 },
5542*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(ap_vendor_elements), 0 },
5543*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ignore_old_scan_res, 0, 1), 0 },
5544*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(freq_list), 0 },
5545*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(initial_freq_list), 0},
5546*03f9172cSAndroid Build Coastguard Worker 	{ INT(scan_cur_freq), 0 },
5547*03f9172cSAndroid Build Coastguard Worker 	{ INT(scan_res_valid_for_connect), 0},
5548*03f9172cSAndroid Build Coastguard Worker 	{ INT(sched_scan_interval), 0 },
5549*03f9172cSAndroid Build Coastguard Worker 	{ INT(sched_scan_start_delay), 0 },
5550*03f9172cSAndroid Build Coastguard Worker 	{ INT(tdls_external_control), 0},
5551*03f9172cSAndroid Build Coastguard Worker 	{ STR(osu_dir), 0 },
5552*03f9172cSAndroid Build Coastguard Worker 	{ STR(wowlan_triggers), CFG_CHANGED_WOWLAN_TRIGGERS },
5553*03f9172cSAndroid Build Coastguard Worker 	{ INT(p2p_search_delay), 0},
5554*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mac_addr, 0, 2), 0 },
5555*03f9172cSAndroid Build Coastguard Worker 	{ INT(rand_addr_lifetime), 0 },
5556*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(preassoc_mac_addr, 0, 2), 0 },
5557*03f9172cSAndroid Build Coastguard Worker 	{ INT(key_mgmt_offload), 0},
5558*03f9172cSAndroid Build Coastguard Worker 	{ INT(passive_scan), 0 },
5559*03f9172cSAndroid Build Coastguard Worker 	{ INT(reassoc_same_bss_optim), 0 },
5560*03f9172cSAndroid Build Coastguard Worker 	{ INT(wps_priority), 0},
5561*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_FST
5562*03f9172cSAndroid Build Coastguard Worker 	{ STR_RANGE(fst_group_id, 1, FST_MAX_GROUP_ID_LEN), 0 },
5563*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(fst_priority, 1, FST_MAX_PRIO_VALUE), 0 },
5564*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(fst_llt, 1, FST_MAX_LLT_MS), 0 },
5565*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_FST */
5566*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(cert_in_cb, 0, 1), 0 },
5567*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(wpa_rsc_relaxation, 0, 1), 0 },
5568*03f9172cSAndroid Build Coastguard Worker 	{ STR(sched_scan_plans), CFG_CHANGED_SCHED_SCAN_PLANS },
5569*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_MBO
5570*03f9172cSAndroid Build Coastguard Worker 	{ STR(non_pref_chan), 0 },
5571*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mbo_cell_capa, MBO_CELL_CAPA_AVAILABLE,
5572*03f9172cSAndroid Build Coastguard Worker 		    MBO_CELL_CAPA_NOT_SUPPORTED), 0 },
5573*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disassoc_imminent_rssi_threshold, -120, 0), 0 },
5574*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(oce, 0, 3), 0 },
5575*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_MBO */
5576*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(btm_offload, 0, 1), CFG_CHANGED_DISABLE_BTM_NOTIFY },
5577*03f9172cSAndroid Build Coastguard Worker 	{ INT(gas_address3), 0 },
5578*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ftm_responder, 0, 1), 0 },
5579*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ftm_initiator, 0, 1), 0 },
5580*03f9172cSAndroid Build Coastguard Worker 	{ INT(gas_rand_addr_lifetime), 0 },
5581*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
5582*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_DPP
5583*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(dpp_config_processing, 0, 2), 0 },
5584*03f9172cSAndroid Build Coastguard Worker 	{ STR(dpp_name), 0 },
5585*03f9172cSAndroid Build Coastguard Worker 	{ STR(dpp_mud_url), 0 },
5586*03f9172cSAndroid Build Coastguard Worker 	{ STR(dpp_extra_conf_req_name), 0 },
5587*03f9172cSAndroid Build Coastguard Worker 	{ STR(dpp_extra_conf_req_value), 0 },
5588*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(dpp_connector_privacy_default, 0, 1), 0 },
5589*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_DPP */
5590*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(coloc_intf_reporting, 0, 1), 0 },
5591*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(bss_no_flush_when_down, 0, 1), 0 },
5592*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_WNM
5593*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(disable_btm, 0, 1), CFG_CHANGED_DISABLE_BTM },
5594*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(extended_key_id, 0, 1), 0 },
5595*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_WNM */
5596*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(wowlan_disconnect_on_deinit, 0, 1), 0},
5597*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(rsn_overriding, 0, 2), 0},
5598*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_PASN
5599*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_TESTING_OPTIONS
5600*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(force_kdk_derivation, 0, 1), 0 },
5601*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(pasn_corrupt_mic, 0, 1), 0 },
5602*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_TESTING_OPTIONS */
5603*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_PASN */
5604*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_TESTING_OPTIONS
5605*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mld_force_single_link, 0, 1), 0 },
5606*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(mld_connect_band_pref, 0, MLD_CONNECT_BAND_PREF_MAX), 0 },
5607*03f9172cSAndroid Build Coastguard Worker 	{ FUNC(mld_connect_bssid_pref), 0 },
5608*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_TESTING_OPTIONS */
5609*03f9172cSAndroid Build Coastguard Worker 	{ INT_RANGE(ft_prepend_pmkid, 0, 1), CFG_CHANGED_FT_PREPEND_PMKID },
5610*03f9172cSAndroid Build Coastguard Worker 	/* NOTE: When adding new parameters here, add_interface() in
5611*03f9172cSAndroid Build Coastguard Worker 	 * wpa_supplicant/dbus_new_introspect.c may need to be modified to
5612*03f9172cSAndroid Build Coastguard Worker 	 * increase the size of the iface->xml buffer. */
5613*03f9172cSAndroid Build Coastguard Worker };
5614*03f9172cSAndroid Build Coastguard Worker 
5615*03f9172cSAndroid Build Coastguard Worker #undef FUNC
5616*03f9172cSAndroid Build Coastguard Worker #undef _INT
5617*03f9172cSAndroid Build Coastguard Worker #undef INT
5618*03f9172cSAndroid Build Coastguard Worker #undef INT_RANGE
5619*03f9172cSAndroid Build Coastguard Worker #undef _STR
5620*03f9172cSAndroid Build Coastguard Worker #undef STR
5621*03f9172cSAndroid Build Coastguard Worker #undef STR_RANGE
5622*03f9172cSAndroid Build Coastguard Worker #undef BIN
5623*03f9172cSAndroid Build Coastguard Worker #undef IPV4
5624*03f9172cSAndroid Build Coastguard Worker #define NUM_GLOBAL_FIELDS ARRAY_SIZE(global_fields)
5625*03f9172cSAndroid Build Coastguard Worker 
5626*03f9172cSAndroid Build Coastguard Worker 
wpa_config_dump_values(struct wpa_config * config,char * buf,size_t buflen)5627*03f9172cSAndroid Build Coastguard Worker int wpa_config_dump_values(struct wpa_config *config, char *buf, size_t buflen)
5628*03f9172cSAndroid Build Coastguard Worker {
5629*03f9172cSAndroid Build Coastguard Worker 	int result = 0;
5630*03f9172cSAndroid Build Coastguard Worker 	size_t i;
5631*03f9172cSAndroid Build Coastguard Worker 
5632*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
5633*03f9172cSAndroid Build Coastguard Worker 		const struct global_parse_data *field = &global_fields[i];
5634*03f9172cSAndroid Build Coastguard Worker 		int tmp;
5635*03f9172cSAndroid Build Coastguard Worker 
5636*03f9172cSAndroid Build Coastguard Worker 		if (!field->get)
5637*03f9172cSAndroid Build Coastguard Worker 			continue;
5638*03f9172cSAndroid Build Coastguard Worker 
5639*03f9172cSAndroid Build Coastguard Worker 		tmp = field->get(field->name, config, (long) field->param1,
5640*03f9172cSAndroid Build Coastguard Worker 				 buf, buflen, 1);
5641*03f9172cSAndroid Build Coastguard Worker 		if (tmp < 0)
5642*03f9172cSAndroid Build Coastguard Worker 			return -1;
5643*03f9172cSAndroid Build Coastguard Worker 		buf += tmp;
5644*03f9172cSAndroid Build Coastguard Worker 		buflen -= tmp;
5645*03f9172cSAndroid Build Coastguard Worker 		result += tmp;
5646*03f9172cSAndroid Build Coastguard Worker 	}
5647*03f9172cSAndroid Build Coastguard Worker 	return result;
5648*03f9172cSAndroid Build Coastguard Worker }
5649*03f9172cSAndroid Build Coastguard Worker 
5650*03f9172cSAndroid Build Coastguard Worker 
wpa_config_get_value(const char * name,struct wpa_config * config,char * buf,size_t buflen)5651*03f9172cSAndroid Build Coastguard Worker int wpa_config_get_value(const char *name, struct wpa_config *config,
5652*03f9172cSAndroid Build Coastguard Worker 			 char *buf, size_t buflen)
5653*03f9172cSAndroid Build Coastguard Worker {
5654*03f9172cSAndroid Build Coastguard Worker 	size_t i;
5655*03f9172cSAndroid Build Coastguard Worker 
5656*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
5657*03f9172cSAndroid Build Coastguard Worker 		const struct global_parse_data *field = &global_fields[i];
5658*03f9172cSAndroid Build Coastguard Worker 
5659*03f9172cSAndroid Build Coastguard Worker 		if (os_strcmp(name, field->name) != 0)
5660*03f9172cSAndroid Build Coastguard Worker 			continue;
5661*03f9172cSAndroid Build Coastguard Worker 		if (!field->get)
5662*03f9172cSAndroid Build Coastguard Worker 			break;
5663*03f9172cSAndroid Build Coastguard Worker 		return field->get(name, config, (long) field->param1,
5664*03f9172cSAndroid Build Coastguard Worker 				  buf, buflen, 0);
5665*03f9172cSAndroid Build Coastguard Worker 	}
5666*03f9172cSAndroid Build Coastguard Worker 
5667*03f9172cSAndroid Build Coastguard Worker 	return -1;
5668*03f9172cSAndroid Build Coastguard Worker }
5669*03f9172cSAndroid Build Coastguard Worker 
5670*03f9172cSAndroid Build Coastguard Worker 
wpa_config_get_num_global_field_names(void)5671*03f9172cSAndroid Build Coastguard Worker int wpa_config_get_num_global_field_names(void)
5672*03f9172cSAndroid Build Coastguard Worker {
5673*03f9172cSAndroid Build Coastguard Worker 	return NUM_GLOBAL_FIELDS;
5674*03f9172cSAndroid Build Coastguard Worker }
5675*03f9172cSAndroid Build Coastguard Worker 
5676*03f9172cSAndroid Build Coastguard Worker 
wpa_config_get_global_field_name(unsigned int i,int * no_var)5677*03f9172cSAndroid Build Coastguard Worker const char * wpa_config_get_global_field_name(unsigned int i, int *no_var)
5678*03f9172cSAndroid Build Coastguard Worker {
5679*03f9172cSAndroid Build Coastguard Worker 	if (i >= NUM_GLOBAL_FIELDS)
5680*03f9172cSAndroid Build Coastguard Worker 		return NULL;
5681*03f9172cSAndroid Build Coastguard Worker 
5682*03f9172cSAndroid Build Coastguard Worker 	if (no_var)
5683*03f9172cSAndroid Build Coastguard Worker 		*no_var = !global_fields[i].param1;
5684*03f9172cSAndroid Build Coastguard Worker 	return global_fields[i].name;
5685*03f9172cSAndroid Build Coastguard Worker }
5686*03f9172cSAndroid Build Coastguard Worker 
5687*03f9172cSAndroid Build Coastguard Worker 
5688*03f9172cSAndroid Build Coastguard Worker /**
5689*03f9172cSAndroid Build Coastguard Worker  * wpa_config_process_global - Set a variable in global configuration
5690*03f9172cSAndroid Build Coastguard Worker  * @config: Pointer to global configuration data
5691*03f9172cSAndroid Build Coastguard Worker  * @pos: Name and value in the format "{name}={value}"
5692*03f9172cSAndroid Build Coastguard Worker  * @line: Line number in configuration file or 0 if not used
5693*03f9172cSAndroid Build Coastguard Worker  * Returns: 0 on success with a possible change in value, 1 on success with no
5694*03f9172cSAndroid Build Coastguard Worker  * change to previously configured value, or -1 on failure
5695*03f9172cSAndroid Build Coastguard Worker  *
5696*03f9172cSAndroid Build Coastguard Worker  * This function can be used to set global configuration variables based on
5697*03f9172cSAndroid Build Coastguard Worker  * both the configuration file and management interface input. The value
5698*03f9172cSAndroid Build Coastguard Worker  * parameter must be in the same format as the text-based configuration file is
5699*03f9172cSAndroid Build Coastguard Worker  * using. For example, strings are using double quotation marks.
5700*03f9172cSAndroid Build Coastguard Worker  */
wpa_config_process_global(struct wpa_config * config,char * pos,int line)5701*03f9172cSAndroid Build Coastguard Worker int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
5702*03f9172cSAndroid Build Coastguard Worker {
5703*03f9172cSAndroid Build Coastguard Worker 	size_t i;
5704*03f9172cSAndroid Build Coastguard Worker 	int ret = 0;
5705*03f9172cSAndroid Build Coastguard Worker 
5706*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
5707*03f9172cSAndroid Build Coastguard Worker 		const struct global_parse_data *field = &global_fields[i];
5708*03f9172cSAndroid Build Coastguard Worker 		size_t flen = os_strlen(field->name);
5709*03f9172cSAndroid Build Coastguard Worker 		if (os_strncmp(pos, field->name, flen) != 0 ||
5710*03f9172cSAndroid Build Coastguard Worker 		    pos[flen] != '=')
5711*03f9172cSAndroid Build Coastguard Worker 			continue;
5712*03f9172cSAndroid Build Coastguard Worker 
5713*03f9172cSAndroid Build Coastguard Worker 		ret = field->parser(field, config, line, pos + flen + 1);
5714*03f9172cSAndroid Build Coastguard Worker 		if (ret < 0) {
5715*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Line %d: failed to "
5716*03f9172cSAndroid Build Coastguard Worker 				   "parse '%s'.", line, pos);
5717*03f9172cSAndroid Build Coastguard Worker 			ret = -1;
5718*03f9172cSAndroid Build Coastguard Worker 		}
5719*03f9172cSAndroid Build Coastguard Worker 		if (ret == 1)
5720*03f9172cSAndroid Build Coastguard Worker 			break;
5721*03f9172cSAndroid Build Coastguard Worker 		if (field->changed_flag == CFG_CHANGED_NFC_PASSWORD_TOKEN)
5722*03f9172cSAndroid Build Coastguard Worker 			config->wps_nfc_pw_from_config = 1;
5723*03f9172cSAndroid Build Coastguard Worker 		config->changed_parameters |= field->changed_flag;
5724*03f9172cSAndroid Build Coastguard Worker 		break;
5725*03f9172cSAndroid Build Coastguard Worker 	}
5726*03f9172cSAndroid Build Coastguard Worker 	if (i == NUM_GLOBAL_FIELDS) {
5727*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_AP
5728*03f9172cSAndroid Build Coastguard Worker 		if (os_strncmp(pos, "tx_queue_", 9) == 0) {
5729*03f9172cSAndroid Build Coastguard Worker 			char *tmp = os_strchr(pos, '=');
5730*03f9172cSAndroid Build Coastguard Worker 
5731*03f9172cSAndroid Build Coastguard Worker 			if (!tmp) {
5732*03f9172cSAndroid Build Coastguard Worker 				if (line < 0)
5733*03f9172cSAndroid Build Coastguard Worker 					wpa_printf(MSG_ERROR,
5734*03f9172cSAndroid Build Coastguard Worker 						   "Line %d: invalid line %s",
5735*03f9172cSAndroid Build Coastguard Worker 						   line, pos);
5736*03f9172cSAndroid Build Coastguard Worker 				return -1;
5737*03f9172cSAndroid Build Coastguard Worker 			}
5738*03f9172cSAndroid Build Coastguard Worker 			*tmp++ = '\0';
5739*03f9172cSAndroid Build Coastguard Worker 			if (hostapd_config_tx_queue(config->tx_queue, pos,
5740*03f9172cSAndroid Build Coastguard Worker 						    tmp)) {
5741*03f9172cSAndroid Build Coastguard Worker 				wpa_printf(MSG_ERROR,
5742*03f9172cSAndroid Build Coastguard Worker 					   "Line %d: invalid TX queue item",
5743*03f9172cSAndroid Build Coastguard Worker 					   line);
5744*03f9172cSAndroid Build Coastguard Worker 				return -1;
5745*03f9172cSAndroid Build Coastguard Worker 			}
5746*03f9172cSAndroid Build Coastguard Worker 			return ret;
5747*03f9172cSAndroid Build Coastguard Worker 		}
5748*03f9172cSAndroid Build Coastguard Worker 
5749*03f9172cSAndroid Build Coastguard Worker 		if (os_strncmp(pos, "wmm_ac_", 7) == 0) {
5750*03f9172cSAndroid Build Coastguard Worker 			char *tmp = os_strchr(pos, '=');
5751*03f9172cSAndroid Build Coastguard Worker 			if (tmp == NULL) {
5752*03f9172cSAndroid Build Coastguard Worker 				if (line < 0)
5753*03f9172cSAndroid Build Coastguard Worker 					return -1;
5754*03f9172cSAndroid Build Coastguard Worker 				wpa_printf(MSG_ERROR, "Line %d: invalid line "
5755*03f9172cSAndroid Build Coastguard Worker 					   "'%s'", line, pos);
5756*03f9172cSAndroid Build Coastguard Worker 				return -1;
5757*03f9172cSAndroid Build Coastguard Worker 			}
5758*03f9172cSAndroid Build Coastguard Worker 			*tmp++ = '\0';
5759*03f9172cSAndroid Build Coastguard Worker 			if (hostapd_config_wmm_ac(config->wmm_ac_params, pos,
5760*03f9172cSAndroid Build Coastguard Worker 						  tmp)) {
5761*03f9172cSAndroid Build Coastguard Worker 				wpa_printf(MSG_ERROR, "Line %d: invalid WMM "
5762*03f9172cSAndroid Build Coastguard Worker 					   "AC item", line);
5763*03f9172cSAndroid Build Coastguard Worker 				return -1;
5764*03f9172cSAndroid Build Coastguard Worker 			}
5765*03f9172cSAndroid Build Coastguard Worker 			return ret;
5766*03f9172cSAndroid Build Coastguard Worker 		}
5767*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_AP */
5768*03f9172cSAndroid Build Coastguard Worker 		if (line < 0)
5769*03f9172cSAndroid Build Coastguard Worker 			return -1;
5770*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Line %d: unknown global field '%s'.",
5771*03f9172cSAndroid Build Coastguard Worker 			   line, pos);
5772*03f9172cSAndroid Build Coastguard Worker 		ret = -1;
5773*03f9172cSAndroid Build Coastguard Worker 	}
5774*03f9172cSAndroid Build Coastguard Worker 
5775*03f9172cSAndroid Build Coastguard Worker 	return ret;
5776*03f9172cSAndroid Build Coastguard Worker }
5777