• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WPA Supplicant / Configuration parser and common functions
3  * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include "includes.h"
16 
17 #include "common.h"
18 #include "wpa.h"
19 #include "crypto/sha1.h"
20 #include "eap_peer/eap.h"
21 #include "config.h"
22 
23 
24 #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE)
25 #define NO_CONFIG_WRITE
26 #endif
27 
28 /*
29  * Structure for network configuration parsing. This data is used to implement
30  * a generic parser for each network block variable. The table of configuration
31  * variables is defined below in this file (ssid_fields[]).
32  */
33 struct parse_data {
34 	/* Configuration variable name */
35 	char *name;
36 
37 	/* Parser function for this variable */
38 	int (*parser)(const struct parse_data *data, struct wpa_ssid *ssid,
39 		      int line, const char *value);
40 
41 #ifndef NO_CONFIG_WRITE
42 	/* Writer function (i.e., to get the variable in text format from
43 	 * internal presentation). */
44 	char * (*writer)(const struct parse_data *data, struct wpa_ssid *ssid);
45 #endif /* NO_CONFIG_WRITE */
46 
47 	/* Variable specific parameters for the parser. */
48 	void *param1, *param2, *param3, *param4;
49 
50 	/* 0 = this variable can be included in debug output and ctrl_iface
51 	 * 1 = this variable contains key/private data and it must not be
52 	 *     included in debug output unless explicitly requested. In
53 	 *     addition, this variable will not be readable through the
54 	 *     ctrl_iface.
55 	 */
56 	int key_data;
57 };
58 
59 
wpa_config_parse_string(const char * value,size_t * len)60 static char * wpa_config_parse_string(const char *value, size_t *len)
61 {
62 	if (*value == '"') {
63 		const char *pos;
64 		char *str;
65 		value++;
66 		pos = os_strrchr(value, '"');
67 		if (pos == NULL || pos[1] != '\0')
68 			return NULL;
69 		*len = pos - value;
70 		str = os_malloc(*len + 1);
71 		if (str == NULL)
72 			return NULL;
73 		os_memcpy(str, value, *len);
74 		str[*len] = '\0';
75 		return str;
76 	} else {
77 		u8 *str;
78 		size_t tlen, hlen = os_strlen(value);
79 		if (hlen & 1)
80 			return NULL;
81 		tlen = hlen / 2;
82 		str = os_malloc(tlen + 1);
83 		if (str == NULL)
84 			return NULL;
85 		if (hexstr2bin(value, str, tlen)) {
86 			os_free(str);
87 			return NULL;
88 		}
89 		str[tlen] = '\0';
90 		*len = tlen;
91 		return (char *) str;
92 	}
93 }
94 
95 
wpa_config_parse_str(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)96 static int wpa_config_parse_str(const struct parse_data *data,
97 				struct wpa_ssid *ssid,
98 				int line, const char *value)
99 {
100 	size_t res_len, *dst_len;
101 	char **dst, *tmp;
102 
103 	if (os_strcmp(value, "NULL") == 0) {
104 		wpa_printf(MSG_DEBUG, "Unset configuration string '%s'",
105 			   data->name);
106 		tmp = NULL;
107 		res_len = 0;
108 		goto set;
109 	}
110 
111 	tmp = wpa_config_parse_string(value, &res_len);
112 	if (tmp == NULL) {
113 		wpa_printf(MSG_ERROR, "Line %d: failed to parse %s '%s'.",
114 			   line, data->name,
115 			   data->key_data ? "[KEY DATA REMOVED]" : value);
116 		return -1;
117 	}
118 
119 	if (data->key_data) {
120 		wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
121 				      (u8 *) tmp, res_len);
122 	} else {
123 		wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
124 				  (u8 *) tmp, res_len);
125 	}
126 
127 	if (data->param3 && res_len < (size_t) data->param3) {
128 		wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
129 			   "min_len=%ld)", line, data->name,
130 			   (unsigned long) res_len, (long) data->param3);
131 		os_free(tmp);
132 		return -1;
133 	}
134 
135 	if (data->param4 && res_len > (size_t) data->param4) {
136 		wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
137 			   "max_len=%ld)", line, data->name,
138 			   (unsigned long) res_len, (long) data->param4);
139 		os_free(tmp);
140 		return -1;
141 	}
142 
143 set:
144 	dst = (char **) (((u8 *) ssid) + (long) data->param1);
145 	dst_len = (size_t *) (((u8 *) ssid) + (long) data->param2);
146 	os_free(*dst);
147 	*dst = tmp;
148 	if (data->param2)
149 		*dst_len = res_len;
150 
151 	return 0;
152 }
153 
154 
155 #ifndef NO_CONFIG_WRITE
is_hex(const u8 * data,size_t len)156 static int is_hex(const u8 *data, size_t len)
157 {
158 	size_t i;
159 
160 	for (i = 0; i < len; i++) {
161 		if (data[i] < 32 || data[i] >= 127)
162 			return 1;
163 	}
164 	return 0;
165 }
166 
167 
wpa_config_write_string_ascii(const u8 * value,size_t len)168 static char * wpa_config_write_string_ascii(const u8 *value, size_t len)
169 {
170 	char *buf;
171 
172 	buf = os_malloc(len + 3);
173 	if (buf == NULL)
174 		return NULL;
175 	buf[0] = '"';
176 	os_memcpy(buf + 1, value, len);
177 	buf[len + 1] = '"';
178 	buf[len + 2] = '\0';
179 
180 	return buf;
181 }
182 
183 
wpa_config_write_string_hex(const u8 * value,size_t len)184 static char * wpa_config_write_string_hex(const u8 *value, size_t len)
185 {
186 	char *buf;
187 
188 	buf = os_zalloc(2 * len + 1);
189 	if (buf == NULL)
190 		return NULL;
191 	wpa_snprintf_hex(buf, 2 * len + 1, value, len);
192 
193 	return buf;
194 }
195 
196 
wpa_config_write_string(const u8 * value,size_t len)197 static char * wpa_config_write_string(const u8 *value, size_t len)
198 {
199 	if (value == NULL)
200 		return NULL;
201 
202 	if (is_hex(value, len))
203 		return wpa_config_write_string_hex(value, len);
204 	else
205 		return wpa_config_write_string_ascii(value, len);
206 }
207 
208 
wpa_config_write_str(const struct parse_data * data,struct wpa_ssid * ssid)209 static char * wpa_config_write_str(const struct parse_data *data,
210 				   struct wpa_ssid *ssid)
211 {
212 	size_t len;
213 	char **src;
214 
215 	src = (char **) (((u8 *) ssid) + (long) data->param1);
216 	if (*src == NULL)
217 		return NULL;
218 
219 	if (data->param2)
220 		len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
221 	else
222 		len = os_strlen(*src);
223 
224 	return wpa_config_write_string((const u8 *) *src, len);
225 }
226 
227 #ifdef WPA_UNICODE_SSID
wpa_config_write_str_unicode(const struct parse_data * data,struct wpa_ssid * ssid)228 static char * wpa_config_write_str_unicode(const struct parse_data *data,
229 						struct wpa_ssid *ssid)
230 {
231 	size_t len;
232 	char **src;
233 
234 	src = (char **) (((u8 *) ssid) + (long) data->param1);
235 	if (*src == NULL)
236 		return NULL;
237 
238 	if (data->param2)
239 		len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
240 	else
241 		len = os_strlen(*src);
242 
243 	return wpa_config_write_string_ascii((const u8 *) *src, len);
244 }
245 #endif
246 #endif /* NO_CONFIG_WRITE */
247 
248 
wpa_config_parse_int(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)249 static int wpa_config_parse_int(const struct parse_data *data,
250 				struct wpa_ssid *ssid,
251 				int line, const char *value)
252 {
253 	int *dst;
254 
255 	dst = (int *) (((u8 *) ssid) + (long) data->param1);
256 	*dst = atoi(value);
257 	wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst);
258 
259 	if (data->param3 && *dst < (long) data->param3) {
260 		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
261 			   "min_value=%ld)", line, data->name, *dst,
262 			   (long) data->param3);
263 		*dst = (long) data->param3;
264 		return -1;
265 	}
266 
267 	if (data->param4 && *dst > (long) data->param4) {
268 		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
269 			   "max_value=%ld)", line, data->name, *dst,
270 			   (long) data->param4);
271 		*dst = (long) data->param4;
272 		return -1;
273 	}
274 
275 	return 0;
276 }
277 
278 
279 #ifndef NO_CONFIG_WRITE
wpa_config_write_int(const struct parse_data * data,struct wpa_ssid * ssid)280 static char * wpa_config_write_int(const struct parse_data *data,
281 				   struct wpa_ssid *ssid)
282 {
283 	int *src, res;
284 	char *value;
285 
286 	src = (int *) (((u8 *) ssid) + (long) data->param1);
287 
288 	value = os_malloc(20);
289 	if (value == NULL)
290 		return NULL;
291 	res = os_snprintf(value, 20, "%d", *src);
292 	if (res < 0 || res >= 20) {
293 		os_free(value);
294 		return NULL;
295 	}
296 	value[20 - 1] = '\0';
297 	return value;
298 }
299 #endif /* NO_CONFIG_WRITE */
300 
301 
wpa_config_parse_bssid(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)302 static int wpa_config_parse_bssid(const struct parse_data *data,
303 				  struct wpa_ssid *ssid, int line,
304 				  const char *value)
305 {
306 	if (hwaddr_aton(value, ssid->bssid)) {
307 		wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.",
308 			   line, value);
309 		return -1;
310 	}
311 	ssid->bssid_set = 1;
312 	wpa_hexdump(MSG_MSGDUMP, "BSSID", ssid->bssid, ETH_ALEN);
313 	return 0;
314 }
315 
316 
317 #ifndef NO_CONFIG_WRITE
wpa_config_write_bssid(const struct parse_data * data,struct wpa_ssid * ssid)318 static char * wpa_config_write_bssid(const struct parse_data *data,
319 				     struct wpa_ssid *ssid)
320 {
321 	char *value;
322 	int res;
323 
324 	if (!ssid->bssid_set)
325 		return NULL;
326 
327 	value = os_malloc(20);
328 	if (value == NULL)
329 		return NULL;
330 	res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid));
331 	if (res < 0 || res >= 20) {
332 		os_free(value);
333 		return NULL;
334 	}
335 	value[20 - 1] = '\0';
336 	return value;
337 }
338 #endif /* NO_CONFIG_WRITE */
339 
340 
wpa_config_parse_psk(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)341 static int wpa_config_parse_psk(const struct parse_data *data,
342 				struct wpa_ssid *ssid, int line,
343 				const char *value)
344 {
345 	if (*value == '"') {
346 #ifndef CONFIG_NO_PBKDF2
347 		const char *pos;
348 		size_t len;
349 
350 		value++;
351 		pos = os_strrchr(value, '"');
352 		if (pos)
353 			len = pos - value;
354 		else
355 			len = os_strlen(value);
356 		if (len < 8 || len > 63) {
357 			wpa_printf(MSG_ERROR, "Line %d: Invalid passphrase "
358 				   "length %lu (expected: 8..63) '%s'.",
359 				   line, (unsigned long) len, value);
360 			return -1;
361 		}
362 		wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)",
363 				      (u8 *) value, len);
364 		if (ssid->passphrase && os_strlen(ssid->passphrase) == len &&
365 		    os_memcmp(ssid->passphrase, value, len) == 0)
366 			return 0;
367 		ssid->psk_set = 0;
368 		os_free(ssid->passphrase);
369 		ssid->passphrase = os_malloc(len + 1);
370 		if (ssid->passphrase == NULL)
371 			return -1;
372 		os_memcpy(ssid->passphrase, value, len);
373 		ssid->passphrase[len] = '\0';
374 		return 0;
375 #else /* CONFIG_NO_PBKDF2 */
376 		wpa_printf(MSG_ERROR, "Line %d: ASCII passphrase not "
377 			   "supported.", line);
378 		return -1;
379 #endif /* CONFIG_NO_PBKDF2 */
380 	}
381 
382 	if (hexstr2bin(value, ssid->psk, PMK_LEN) ||
383 	    value[PMK_LEN * 2] != '\0') {
384 		wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
385 			   line, value);
386 		return -1;
387 	}
388 
389 	os_free(ssid->passphrase);
390 	ssid->passphrase = NULL;
391 
392 	ssid->psk_set = 1;
393 	wpa_hexdump_key(MSG_MSGDUMP, "PSK", ssid->psk, PMK_LEN);
394 	return 0;
395 }
396 
397 
398 #ifndef NO_CONFIG_WRITE
wpa_config_write_psk(const struct parse_data * data,struct wpa_ssid * ssid)399 static char * wpa_config_write_psk(const struct parse_data *data,
400 				   struct wpa_ssid *ssid)
401 {
402 	if (ssid->passphrase)
403 		return wpa_config_write_string_ascii(
404 			(const u8 *) ssid->passphrase,
405 			os_strlen(ssid->passphrase));
406 
407 	if (ssid->psk_set)
408 		return wpa_config_write_string_hex(ssid->psk, PMK_LEN);
409 
410 	return NULL;
411 }
412 #endif /* NO_CONFIG_WRITE */
413 
414 
wpa_config_parse_proto(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)415 static int wpa_config_parse_proto(const struct parse_data *data,
416 				  struct wpa_ssid *ssid, int line,
417 				  const char *value)
418 {
419 	int val = 0, last, errors = 0;
420 	char *start, *end, *buf;
421 
422 	buf = os_strdup(value);
423 	if (buf == NULL)
424 		return -1;
425 	start = buf;
426 
427 	while (*start != '\0') {
428 		while (*start == ' ' || *start == '\t')
429 			start++;
430 		if (*start == '\0')
431 			break;
432 		end = start;
433 		while (*end != ' ' && *end != '\t' && *end != '\0')
434 			end++;
435 		last = *end == '\0';
436 		*end = '\0';
437 		if (os_strcmp(start, "WPA") == 0)
438 			val |= WPA_PROTO_WPA;
439 		else if (os_strcmp(start, "RSN") == 0 ||
440 			 os_strcmp(start, "WPA2") == 0)
441 			val |= WPA_PROTO_RSN;
442 		else {
443 			wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'",
444 				   line, start);
445 			errors++;
446 		}
447 
448 		if (last)
449 			break;
450 		start = end + 1;
451 	}
452 	os_free(buf);
453 
454 	if (val == 0) {
455 		wpa_printf(MSG_ERROR,
456 			   "Line %d: no proto values configured.", line);
457 		errors++;
458 	}
459 
460 	wpa_printf(MSG_MSGDUMP, "proto: 0x%x", val);
461 	ssid->proto = val;
462 	return errors ? -1 : 0;
463 }
464 
465 
466 #ifndef NO_CONFIG_WRITE
wpa_config_write_proto(const struct parse_data * data,struct wpa_ssid * ssid)467 static char * wpa_config_write_proto(const struct parse_data *data,
468 				     struct wpa_ssid *ssid)
469 {
470 	int first = 1, ret;
471 	char *buf, *pos, *end;
472 
473 	pos = buf = os_zalloc(10);
474 	if (buf == NULL)
475 		return NULL;
476 	end = buf + 10;
477 
478 	if (ssid->proto & WPA_PROTO_WPA) {
479 		ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
480 		if (ret < 0 || ret >= end - pos)
481 			return buf;
482 		pos += ret;
483 		first = 0;
484 	}
485 
486 	if (ssid->proto & WPA_PROTO_RSN) {
487 		ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
488 		if (ret < 0 || ret >= end - pos)
489 			return buf;
490 		pos += ret;
491 		first = 0;
492 	}
493 
494 	return buf;
495 }
496 #endif /* NO_CONFIG_WRITE */
497 
498 
wpa_config_parse_key_mgmt(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)499 static int wpa_config_parse_key_mgmt(const struct parse_data *data,
500 				     struct wpa_ssid *ssid, int line,
501 				     const char *value)
502 {
503 	int val = 0, last, errors = 0;
504 	char *start, *end, *buf;
505 
506 	buf = os_strdup(value);
507 	if (buf == NULL)
508 		return -1;
509 	start = buf;
510 
511 	while (*start != '\0') {
512 		while (*start == ' ' || *start == '\t')
513 			start++;
514 		if (*start == '\0')
515 			break;
516 		end = start;
517 		while (*end != ' ' && *end != '\t' && *end != '\0')
518 			end++;
519 		last = *end == '\0';
520 		*end = '\0';
521 		if (os_strcmp(start, "WPA-PSK") == 0)
522 			val |= WPA_KEY_MGMT_PSK;
523 		else if (os_strcmp(start, "WPA-EAP") == 0)
524 			val |= WPA_KEY_MGMT_IEEE8021X;
525 		else if (os_strcmp(start, "IEEE8021X") == 0)
526 			val |= WPA_KEY_MGMT_IEEE8021X_NO_WPA;
527 		else if (os_strcmp(start, "NONE") == 0)
528 			val |= WPA_KEY_MGMT_NONE;
529 		else if (os_strcmp(start, "WPA-NONE") == 0)
530 			val |= WPA_KEY_MGMT_WPA_NONE;
531 #ifdef CONFIG_IEEE80211R
532 		else if (os_strcmp(start, "FT-PSK") == 0)
533 			val |= WPA_KEY_MGMT_FT_PSK;
534 		else if (os_strcmp(start, "FT-EAP") == 0)
535 			val |= WPA_KEY_MGMT_FT_IEEE8021X;
536 #endif /* CONFIG_IEEE80211R */
537 #ifdef CONFIG_IEEE80211W
538 		else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
539 			val |= WPA_KEY_MGMT_PSK_SHA256;
540 		else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
541 			val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
542 #endif /* CONFIG_IEEE80211W */
543 #ifdef CONFIG_WPS
544 		else if (os_strcmp(start, "WPS") == 0)
545 			val |= WPA_KEY_MGMT_WPS;
546 #endif /* CONFIG_WPS */
547 		else {
548 			wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
549 				   line, start);
550 			errors++;
551 		}
552 
553 		if (last)
554 			break;
555 		start = end + 1;
556 	}
557 	os_free(buf);
558 
559 	if (val == 0) {
560 		wpa_printf(MSG_ERROR,
561 			   "Line %d: no key_mgmt values configured.", line);
562 		errors++;
563 	}
564 
565 	wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val);
566 	ssid->key_mgmt = val;
567 	return errors ? -1 : 0;
568 }
569 
570 
571 #ifndef NO_CONFIG_WRITE
wpa_config_write_key_mgmt(const struct parse_data * data,struct wpa_ssid * ssid)572 static char * wpa_config_write_key_mgmt(const struct parse_data *data,
573 					struct wpa_ssid *ssid)
574 {
575 	char *buf, *pos, *end;
576 	int ret;
577 
578 	pos = buf = os_zalloc(50);
579 	if (buf == NULL)
580 		return NULL;
581 	end = buf + 50;
582 
583 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
584 		ret = os_snprintf(pos, end - pos, "%sWPA-PSK",
585 				  pos == buf ? "" : " ");
586 		if (ret < 0 || ret >= end - pos) {
587 			end[-1] = '\0';
588 			return buf;
589 		}
590 		pos += ret;
591 	}
592 
593 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
594 		ret = os_snprintf(pos, end - pos, "%sWPA-EAP",
595 				  pos == buf ? "" : " ");
596 		if (ret < 0 || ret >= end - pos) {
597 			end[-1] = '\0';
598 			return buf;
599 		}
600 		pos += ret;
601 	}
602 
603 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
604 		ret = os_snprintf(pos, end - pos, "%sIEEE8021X",
605 				  pos == buf ? "" : " ");
606 		if (ret < 0 || ret >= end - pos) {
607 			end[-1] = '\0';
608 			return buf;
609 		}
610 		pos += ret;
611 	}
612 
613 	if (ssid->key_mgmt & WPA_KEY_MGMT_NONE) {
614 		ret = os_snprintf(pos, end - pos, "%sNONE",
615 				  pos == buf ? "" : " ");
616 		if (ret < 0 || ret >= end - pos) {
617 			end[-1] = '\0';
618 			return buf;
619 		}
620 		pos += ret;
621 	}
622 
623 	if (ssid->key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
624 		ret = os_snprintf(pos, end - pos, "%sWPA-NONE",
625 				  pos == buf ? "" : " ");
626 		if (ret < 0 || ret >= end - pos) {
627 			end[-1] = '\0';
628 			return buf;
629 		}
630 		pos += ret;
631 	}
632 
633 #ifdef CONFIG_IEEE80211R
634 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK)
635 		pos += os_snprintf(pos, end - pos, "%sFT-PSK",
636 				   pos == buf ? "" : " ");
637 
638 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
639 		pos += os_snprintf(pos, end - pos, "%sFT-EAP",
640 				   pos == buf ? "" : " ");
641 #endif /* CONFIG_IEEE80211R */
642 
643 #ifdef CONFIG_IEEE80211W
644 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
645 		pos += os_snprintf(pos, end - pos, "%sWPA-PSK-SHA256",
646 				   pos == buf ? "" : " ");
647 
648 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
649 		pos += os_snprintf(pos, end - pos, "%sWPA-EAP-SHA256",
650 				   pos == buf ? "" : " ");
651 #endif /* CONFIG_IEEE80211W */
652 
653 #ifdef CONFIG_WPS
654 	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
655 		pos += os_snprintf(pos, end - pos, "%sWPS",
656 				   pos == buf ? "" : " ");
657 #endif /* CONFIG_WPS */
658 
659 	return buf;
660 }
661 #endif /* NO_CONFIG_WRITE */
662 
663 
wpa_config_parse_cipher(int line,const char * value)664 static int wpa_config_parse_cipher(int line, const char *value)
665 {
666 	int val = 0, last;
667 	char *start, *end, *buf;
668 
669 	buf = os_strdup(value);
670 	if (buf == NULL)
671 		return -1;
672 	start = buf;
673 
674 	while (*start != '\0') {
675 		while (*start == ' ' || *start == '\t')
676 			start++;
677 		if (*start == '\0')
678 			break;
679 		end = start;
680 		while (*end != ' ' && *end != '\t' && *end != '\0')
681 			end++;
682 		last = *end == '\0';
683 		*end = '\0';
684 		if (os_strcmp(start, "CCMP") == 0)
685 			val |= WPA_CIPHER_CCMP;
686 		else if (os_strcmp(start, "TKIP") == 0)
687 			val |= WPA_CIPHER_TKIP;
688 		else if (os_strcmp(start, "WEP104") == 0)
689 			val |= WPA_CIPHER_WEP104;
690 		else if (os_strcmp(start, "WEP40") == 0)
691 			val |= WPA_CIPHER_WEP40;
692 		else if (os_strcmp(start, "NONE") == 0)
693 			val |= WPA_CIPHER_NONE;
694 		else {
695 			wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
696 				   line, start);
697 			os_free(buf);
698 			return -1;
699 		}
700 
701 		if (last)
702 			break;
703 		start = end + 1;
704 	}
705 	os_free(buf);
706 
707 	if (val == 0) {
708 		wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
709 			   line);
710 		return -1;
711 	}
712 	return val;
713 }
714 
715 
716 #ifndef NO_CONFIG_WRITE
wpa_config_write_cipher(int cipher)717 static char * wpa_config_write_cipher(int cipher)
718 {
719 	char *buf, *pos, *end;
720 	int ret;
721 
722 	pos = buf = os_zalloc(50);
723 	if (buf == NULL)
724 		return NULL;
725 	end = buf + 50;
726 
727 	if (cipher & WPA_CIPHER_CCMP) {
728 		ret = os_snprintf(pos, end - pos, "%sCCMP",
729 				  pos == buf ? "" : " ");
730 		if (ret < 0 || ret >= end - pos) {
731 			end[-1] = '\0';
732 			return buf;
733 		}
734 		pos += ret;
735 	}
736 
737 	if (cipher & WPA_CIPHER_TKIP) {
738 		ret = os_snprintf(pos, end - pos, "%sTKIP",
739 				  pos == buf ? "" : " ");
740 		if (ret < 0 || ret >= end - pos) {
741 			end[-1] = '\0';
742 			return buf;
743 		}
744 		pos += ret;
745 	}
746 
747 	if (cipher & WPA_CIPHER_WEP104) {
748 		ret = os_snprintf(pos, end - pos, "%sWEP104",
749 				  pos == buf ? "" : " ");
750 		if (ret < 0 || ret >= end - pos) {
751 			end[-1] = '\0';
752 			return buf;
753 		}
754 		pos += ret;
755 	}
756 
757 	if (cipher & WPA_CIPHER_WEP40) {
758 		ret = os_snprintf(pos, end - pos, "%sWEP40",
759 				  pos == buf ? "" : " ");
760 		if (ret < 0 || ret >= end - pos) {
761 			end[-1] = '\0';
762 			return buf;
763 		}
764 		pos += ret;
765 	}
766 
767 	if (cipher & WPA_CIPHER_NONE) {
768 		ret = os_snprintf(pos, end - pos, "%sNONE",
769 				  pos == buf ? "" : " ");
770 		if (ret < 0 || ret >= end - pos) {
771 			end[-1] = '\0';
772 			return buf;
773 		}
774 		pos += ret;
775 	}
776 
777 	return buf;
778 }
779 #endif /* NO_CONFIG_WRITE */
780 
781 
wpa_config_parse_pairwise(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)782 static int wpa_config_parse_pairwise(const struct parse_data *data,
783 				     struct wpa_ssid *ssid, int line,
784 				     const char *value)
785 {
786 	int val;
787 	val = wpa_config_parse_cipher(line, value);
788 	if (val == -1)
789 		return -1;
790 	if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_NONE)) {
791 		wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
792 			   "(0x%x).", line, val);
793 		return -1;
794 	}
795 
796 	wpa_printf(MSG_MSGDUMP, "pairwise: 0x%x", val);
797 	ssid->pairwise_cipher = val;
798 	return 0;
799 }
800 
801 
802 #ifndef NO_CONFIG_WRITE
wpa_config_write_pairwise(const struct parse_data * data,struct wpa_ssid * ssid)803 static char * wpa_config_write_pairwise(const struct parse_data *data,
804 					struct wpa_ssid *ssid)
805 {
806 	return wpa_config_write_cipher(ssid->pairwise_cipher);
807 }
808 #endif /* NO_CONFIG_WRITE */
809 
810 
wpa_config_parse_group(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)811 static int wpa_config_parse_group(const struct parse_data *data,
812 				  struct wpa_ssid *ssid, int line,
813 				  const char *value)
814 {
815 	int val;
816 	val = wpa_config_parse_cipher(line, value);
817 	if (val == -1)
818 		return -1;
819 	if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 |
820 		    WPA_CIPHER_WEP40)) {
821 		wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
822 			   "(0x%x).", line, val);
823 		return -1;
824 	}
825 
826 	wpa_printf(MSG_MSGDUMP, "group: 0x%x", val);
827 	ssid->group_cipher = val;
828 	return 0;
829 }
830 
831 
832 #ifndef NO_CONFIG_WRITE
wpa_config_write_group(const struct parse_data * data,struct wpa_ssid * ssid)833 static char * wpa_config_write_group(const struct parse_data *data,
834 				     struct wpa_ssid *ssid)
835 {
836 	return wpa_config_write_cipher(ssid->group_cipher);
837 }
838 #endif /* NO_CONFIG_WRITE */
839 
840 
wpa_config_parse_auth_alg(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)841 static int wpa_config_parse_auth_alg(const struct parse_data *data,
842 				     struct wpa_ssid *ssid, int line,
843 				     const char *value)
844 {
845 	int val = 0, last, errors = 0;
846 	char *start, *end, *buf;
847 
848 	buf = os_strdup(value);
849 	if (buf == NULL)
850 		return -1;
851 	start = buf;
852 
853 	while (*start != '\0') {
854 		while (*start == ' ' || *start == '\t')
855 			start++;
856 		if (*start == '\0')
857 			break;
858 		end = start;
859 		while (*end != ' ' && *end != '\t' && *end != '\0')
860 			end++;
861 		last = *end == '\0';
862 		*end = '\0';
863 		if (os_strcmp(start, "OPEN") == 0)
864 			val |= WPA_AUTH_ALG_OPEN;
865 		else if (os_strcmp(start, "SHARED") == 0)
866 			val |= WPA_AUTH_ALG_SHARED;
867 		else if (os_strcmp(start, "LEAP") == 0)
868 			val |= WPA_AUTH_ALG_LEAP;
869 		else {
870 			wpa_printf(MSG_ERROR, "Line %d: invalid auth_alg '%s'",
871 				   line, start);
872 			errors++;
873 		}
874 
875 		if (last)
876 			break;
877 		start = end + 1;
878 	}
879 	os_free(buf);
880 
881 	if (val == 0) {
882 		wpa_printf(MSG_ERROR,
883 			   "Line %d: no auth_alg values configured.", line);
884 		errors++;
885 	}
886 
887 	wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", val);
888 	ssid->auth_alg = val;
889 	return errors ? -1 : 0;
890 }
891 
892 
893 #ifndef NO_CONFIG_WRITE
wpa_config_write_auth_alg(const struct parse_data * data,struct wpa_ssid * ssid)894 static char * wpa_config_write_auth_alg(const struct parse_data *data,
895 					struct wpa_ssid *ssid)
896 {
897 	char *buf, *pos, *end;
898 	int ret;
899 
900 	pos = buf = os_zalloc(30);
901 	if (buf == NULL)
902 		return NULL;
903 	end = buf + 30;
904 
905 	if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) {
906 		ret = os_snprintf(pos, end - pos, "%sOPEN",
907 				  pos == buf ? "" : " ");
908 		if (ret < 0 || ret >= end - pos) {
909 			end[-1] = '\0';
910 			return buf;
911 		}
912 		pos += ret;
913 	}
914 
915 	if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) {
916 		ret = os_snprintf(pos, end - pos, "%sSHARED",
917 				  pos == buf ? "" : " ");
918 		if (ret < 0 || ret >= end - pos) {
919 			end[-1] = '\0';
920 			return buf;
921 		}
922 		pos += ret;
923 	}
924 
925 	if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) {
926 		ret = os_snprintf(pos, end - pos, "%sLEAP",
927 				  pos == buf ? "" : " ");
928 		if (ret < 0 || ret >= end - pos) {
929 			end[-1] = '\0';
930 			return buf;
931 		}
932 		pos += ret;
933 	}
934 
935 	return buf;
936 }
937 #endif /* NO_CONFIG_WRITE */
938 
939 
940 #ifdef IEEE8021X_EAPOL
wpa_config_parse_eap(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)941 static int wpa_config_parse_eap(const struct parse_data *data,
942 				struct wpa_ssid *ssid, int line,
943 				const char *value)
944 {
945 	int last, errors = 0;
946 	char *start, *end, *buf;
947 	struct eap_method_type *methods = NULL, *tmp;
948 	size_t num_methods = 0;
949 
950 	buf = os_strdup(value);
951 	if (buf == NULL)
952 		return -1;
953 	start = buf;
954 
955 	while (*start != '\0') {
956 		while (*start == ' ' || *start == '\t')
957 			start++;
958 		if (*start == '\0')
959 			break;
960 		end = start;
961 		while (*end != ' ' && *end != '\t' && *end != '\0')
962 			end++;
963 		last = *end == '\0';
964 		*end = '\0';
965 		tmp = methods;
966 		methods = os_realloc(methods,
967 				     (num_methods + 1) * sizeof(*methods));
968 		if (methods == NULL) {
969 			os_free(tmp);
970 			os_free(buf);
971 			return -1;
972 		}
973 		methods[num_methods].method = eap_peer_get_type(
974 			start, &methods[num_methods].vendor);
975 		if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
976 		    methods[num_methods].method == EAP_TYPE_NONE) {
977 			wpa_printf(MSG_ERROR, "Line %d: unknown EAP method "
978 				   "'%s'", line, start);
979 			wpa_printf(MSG_ERROR, "You may need to add support for"
980 				   " this EAP method during wpa_supplicant\n"
981 				   "build time configuration.\n"
982 				   "See README for more information.");
983 			errors++;
984 		} else if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
985 			   methods[num_methods].method == EAP_TYPE_LEAP)
986 			ssid->leap++;
987 		else
988 			ssid->non_leap++;
989 		num_methods++;
990 		if (last)
991 			break;
992 		start = end + 1;
993 	}
994 	os_free(buf);
995 
996 	tmp = methods;
997 	methods = os_realloc(methods, (num_methods + 1) * sizeof(*methods));
998 	if (methods == NULL) {
999 		os_free(tmp);
1000 		return -1;
1001 	}
1002 	methods[num_methods].vendor = EAP_VENDOR_IETF;
1003 	methods[num_methods].method = EAP_TYPE_NONE;
1004 	num_methods++;
1005 
1006 	wpa_hexdump(MSG_MSGDUMP, "eap methods",
1007 		    (u8 *) methods, num_methods * sizeof(*methods));
1008 	ssid->eap.eap_methods = methods;
1009 	return errors ? -1 : 0;
1010 }
1011 
1012 
wpa_config_write_eap(const struct parse_data * data,struct wpa_ssid * ssid)1013 static char * wpa_config_write_eap(const struct parse_data *data,
1014 				   struct wpa_ssid *ssid)
1015 {
1016 	int i, ret;
1017 	char *buf, *pos, *end;
1018 	const struct eap_method_type *eap_methods = ssid->eap.eap_methods;
1019 	const char *name;
1020 
1021 	if (eap_methods == NULL)
1022 		return NULL;
1023 
1024 	pos = buf = os_zalloc(100);
1025 	if (buf == NULL)
1026 		return NULL;
1027 	end = buf + 100;
1028 
1029 	for (i = 0; eap_methods[i].vendor != EAP_VENDOR_IETF ||
1030 		     eap_methods[i].method != EAP_TYPE_NONE; i++) {
1031 		name = eap_get_name(eap_methods[i].vendor,
1032 				    eap_methods[i].method);
1033 		if (name) {
1034 			ret = os_snprintf(pos, end - pos, "%s%s",
1035 					  pos == buf ? "" : " ", name);
1036 			if (ret < 0 || ret >= end - pos)
1037 				break;
1038 			pos += ret;
1039 		}
1040 	}
1041 
1042 	end[-1] = '\0';
1043 
1044 	return buf;
1045 }
1046 
1047 
wpa_config_parse_password(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1048 static int wpa_config_parse_password(const struct parse_data *data,
1049 				     struct wpa_ssid *ssid, int line,
1050 				     const char *value)
1051 {
1052 	u8 *hash;
1053 
1054 	if (os_strcmp(value, "NULL") == 0) {
1055 		wpa_printf(MSG_DEBUG, "Unset configuration string 'password'");
1056 		os_free(ssid->eap.password);
1057 		ssid->eap.password = NULL;
1058 		ssid->eap.password_len = 0;
1059 		return 0;
1060 	}
1061 
1062 	if (os_strncmp(value, "hash:", 5) != 0) {
1063 		char *tmp;
1064 		size_t res_len;
1065 
1066 		tmp = wpa_config_parse_string(value, &res_len);
1067 		if (tmp == NULL) {
1068 			wpa_printf(MSG_ERROR, "Line %d: failed to parse "
1069 				   "password.", line);
1070 			return -1;
1071 		}
1072 		wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
1073 				      (u8 *) tmp, res_len);
1074 
1075 		os_free(ssid->eap.password);
1076 		ssid->eap.password = (u8 *) tmp;
1077 		ssid->eap.password_len = res_len;
1078 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
1079 
1080 		return 0;
1081 	}
1082 
1083 
1084 	/* NtPasswordHash: hash:<32 hex digits> */
1085 	if (os_strlen(value + 5) != 2 * 16) {
1086 		wpa_printf(MSG_ERROR, "Line %d: Invalid password hash length "
1087 			   "(expected 32 hex digits)", line);
1088 		return -1;
1089 	}
1090 
1091 	hash = os_malloc(16);
1092 	if (hash == NULL)
1093 		return -1;
1094 
1095 	if (hexstr2bin(value + 5, hash, 16)) {
1096 		os_free(hash);
1097 		wpa_printf(MSG_ERROR, "Line %d: Invalid password hash", line);
1098 		return -1;
1099 	}
1100 
1101 	wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
1102 
1103 	os_free(ssid->eap.password);
1104 	ssid->eap.password = hash;
1105 	ssid->eap.password_len = 16;
1106 	ssid->eap.flags |= EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
1107 
1108 	return 0;
1109 }
1110 
1111 
wpa_config_write_password(const struct parse_data * data,struct wpa_ssid * ssid)1112 static char * wpa_config_write_password(const struct parse_data *data,
1113 					struct wpa_ssid *ssid)
1114 {
1115 	char *buf;
1116 
1117 	if (ssid->eap.password == NULL)
1118 		return NULL;
1119 
1120 	if (!(ssid->eap.flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH)) {
1121 		return wpa_config_write_string(
1122 			ssid->eap.password, ssid->eap.password_len);
1123 	}
1124 
1125 	buf = os_malloc(5 + 32 + 1);
1126 	if (buf == NULL)
1127 		return NULL;
1128 
1129 	os_memcpy(buf, "hash:", 5);
1130 	wpa_snprintf_hex(buf + 5, 32 + 1, ssid->eap.password, 16);
1131 
1132 	return buf;
1133 }
1134 #endif /* IEEE8021X_EAPOL */
1135 
1136 
wpa_config_parse_wep_key(u8 * key,size_t * len,int line,const char * value,int idx)1137 static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line,
1138 				    const char *value, int idx)
1139 {
1140 	char *buf, title[20];
1141 	int res;
1142 
1143 	buf = wpa_config_parse_string(value, len);
1144 	if (buf == NULL) {
1145 		wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key %d '%s'.",
1146 			   line, idx, value);
1147 		return -1;
1148 	}
1149 	if (*len > MAX_WEP_KEY_LEN) {
1150 		wpa_printf(MSG_ERROR, "Line %d: Too long WEP key %d '%s'.",
1151 			   line, idx, value);
1152 		os_free(buf);
1153 		return -1;
1154 	}
1155 	os_memcpy(key, buf, *len);
1156 	os_free(buf);
1157 	res = os_snprintf(title, sizeof(title), "wep_key%d", idx);
1158 	if (res >= 0 && (size_t) res < sizeof(title))
1159 		wpa_hexdump_key(MSG_MSGDUMP, title, key, *len);
1160 	return 0;
1161 }
1162 
1163 
wpa_config_parse_wep_key0(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1164 static int wpa_config_parse_wep_key0(const struct parse_data *data,
1165 				     struct wpa_ssid *ssid, int line,
1166 				     const char *value)
1167 {
1168 	return wpa_config_parse_wep_key(ssid->wep_key[0],
1169 					&ssid->wep_key_len[0], line,
1170 					value, 0);
1171 }
1172 
1173 
wpa_config_parse_wep_key1(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1174 static int wpa_config_parse_wep_key1(const struct parse_data *data,
1175 				     struct wpa_ssid *ssid, int line,
1176 				     const char *value)
1177 {
1178 	return wpa_config_parse_wep_key(ssid->wep_key[1],
1179 					&ssid->wep_key_len[1], line,
1180 					value, 1);
1181 }
1182 
1183 
wpa_config_parse_wep_key2(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1184 static int wpa_config_parse_wep_key2(const struct parse_data *data,
1185 				     struct wpa_ssid *ssid, int line,
1186 				     const char *value)
1187 {
1188 	return wpa_config_parse_wep_key(ssid->wep_key[2],
1189 					&ssid->wep_key_len[2], line,
1190 					value, 2);
1191 }
1192 
1193 
wpa_config_parse_wep_key3(const struct parse_data * data,struct wpa_ssid * ssid,int line,const char * value)1194 static int wpa_config_parse_wep_key3(const struct parse_data *data,
1195 				     struct wpa_ssid *ssid, int line,
1196 				     const char *value)
1197 {
1198 	return wpa_config_parse_wep_key(ssid->wep_key[3],
1199 					&ssid->wep_key_len[3], line,
1200 					value, 3);
1201 }
1202 
1203 
1204 #ifndef NO_CONFIG_WRITE
wpa_config_write_wep_key(struct wpa_ssid * ssid,int idx)1205 static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx)
1206 {
1207 	if (ssid->wep_key_len[idx] == 0)
1208 		return NULL;
1209 	return wpa_config_write_string(ssid->wep_key[idx],
1210 				       ssid->wep_key_len[idx]);
1211 }
1212 
1213 
wpa_config_write_wep_key0(const struct parse_data * data,struct wpa_ssid * ssid)1214 static char * wpa_config_write_wep_key0(const struct parse_data *data,
1215 					struct wpa_ssid *ssid)
1216 {
1217 	return wpa_config_write_wep_key(ssid, 0);
1218 }
1219 
1220 
wpa_config_write_wep_key1(const struct parse_data * data,struct wpa_ssid * ssid)1221 static char * wpa_config_write_wep_key1(const struct parse_data *data,
1222 					struct wpa_ssid *ssid)
1223 {
1224 	return wpa_config_write_wep_key(ssid, 1);
1225 }
1226 
1227 
wpa_config_write_wep_key2(const struct parse_data * data,struct wpa_ssid * ssid)1228 static char * wpa_config_write_wep_key2(const struct parse_data *data,
1229 					struct wpa_ssid *ssid)
1230 {
1231 	return wpa_config_write_wep_key(ssid, 2);
1232 }
1233 
1234 
wpa_config_write_wep_key3(const struct parse_data * data,struct wpa_ssid * ssid)1235 static char * wpa_config_write_wep_key3(const struct parse_data *data,
1236 					struct wpa_ssid *ssid)
1237 {
1238 	return wpa_config_write_wep_key(ssid, 3);
1239 }
1240 #endif /* NO_CONFIG_WRITE */
1241 
1242 
1243 /* Helper macros for network block parser */
1244 
1245 #ifdef OFFSET
1246 #undef OFFSET
1247 #endif /* OFFSET */
1248 /* OFFSET: Get offset of a variable within the wpa_ssid structure */
1249 #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
1250 
1251 /* STR: Define a string variable for an ASCII string; f = field name */
1252 #ifdef NO_CONFIG_WRITE
1253 #define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
1254 #define _STRe(f) #f, wpa_config_parse_str, OFFSET(eap.f)
1255 #else /* NO_CONFIG_WRITE */
1256 #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
1257 #define _STRe(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(eap.f)
1258 #endif /* NO_CONFIG_WRITE */
1259 #define STR(f) _STR(f), NULL, NULL, NULL, 0
1260 #define STRe(f) _STRe(f), NULL, NULL, NULL, 0
1261 #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
1262 #define STR_KEYe(f) _STRe(f), NULL, NULL, NULL, 1
1263 
1264 /* STR_LEN: Define a string variable with a separate variable for storing the
1265  * data length. Unlike STR(), this can be used to store arbitrary binary data
1266  * (i.e., even nul termination character). */
1267 #define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
1268 #define _STR_LENe(f) _STRe(f), OFFSET(eap.f ## _len)
1269 #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
1270 #define STR_LENe(f) _STR_LENe(f), NULL, NULL, 0
1271 #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
1272 
1273 /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
1274  * explicitly specified. */
1275 #define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max)
1276 #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
1277 #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
1278 
1279 #ifdef NO_CONFIG_WRITE
1280 #define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
1281 #define _INTe(f) #f, wpa_config_parse_int, OFFSET(eap.f), (void *) 0
1282 #else /* NO_CONFIG_WRITE */
1283 #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
1284 	OFFSET(f), (void *) 0
1285 #define _INTe(f) #f, wpa_config_parse_int, wpa_config_write_int, \
1286 	OFFSET(eap.f), (void *) 0
1287 #ifdef WPA_UNICODE_SSID
1288 /* STR_* variants that do not force conversion to ASCII */
1289 #define _STR_UNICODE(f) #f, wpa_config_parse_str, wpa_config_write_str_unicode, OFFSET(f)
1290 #define STR_UNICODE(f) _STR_UNICODE(f), NULL, NULL, NULL, 0
1291 #define _STR_LEN_UNICODE(f) _STR_UNICODE(f), OFFSET(f ## _len)
1292 #define STR_LEN_UNICODE(f) _STR_LEN_UNICODE(f), NULL, NULL, 0
1293 #define _STR_RANGE_UNICODE(f, min, max) _STR_LEN_UNICODE(f), (void *) (min), (void *) (max)
1294 #define STR_RANGE_UNICODE(f, min, max) _STR_RANGE_UNICODE(f, min, max), 0
1295 #endif
1296 #endif /* NO_CONFIG_WRITE */
1297 
1298 /* INT: Define an integer variable */
1299 #define INT(f) _INT(f), NULL, NULL, 0
1300 #define INTe(f) _INTe(f), NULL, NULL, 0
1301 
1302 /* INT_RANGE: Define an integer variable with allowed value range */
1303 #define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
1304 
1305 /* FUNC: Define a configuration variable that uses a custom function for
1306  * parsing and writing the value. */
1307 #ifdef NO_CONFIG_WRITE
1308 #define _FUNC(f) #f, wpa_config_parse_ ## f, NULL, NULL, NULL, NULL
1309 #else /* NO_CONFIG_WRITE */
1310 #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
1311 	NULL, NULL, NULL, NULL
1312 #endif /* NO_CONFIG_WRITE */
1313 #define FUNC(f) _FUNC(f), 0
1314 #define FUNC_KEY(f) _FUNC(f), 1
1315 
1316 /*
1317  * Table of network configuration variables. This table is used to parse each
1318  * network configuration variable, e.g., each line in wpa_supplicant.conf file
1319  * that is inside a network block.
1320  *
1321  * This table is generated using the helper macros defined above and with
1322  * generous help from the C pre-processor. The field name is stored as a string
1323  * into .name and for STR and INT types, the offset of the target buffer within
1324  * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
1325  * offset to the field containing the length of the configuration variable.
1326  * .param3 and .param4 can be used to mark the allowed range (length for STR
1327  * and value for INT).
1328  *
1329  * For each configuration line in wpa_supplicant.conf, the parser goes through
1330  * this table and select the entry that matches with the field name. The parser
1331  * function (.parser) is then called to parse the actual value of the field.
1332  *
1333  * This kind of mechanism makes it easy to add new configuration parameters,
1334  * since only one line needs to be added into this table and into the
1335  * struct wpa_ssid definition if the new variable is either a string or
1336  * integer. More complex types will need to use their own parser and writer
1337  * functions.
1338  */
1339 static const struct parse_data ssid_fields[] = {
1340 #ifdef WPA_UNICODE_SSID
1341 	{ STR_RANGE_UNICODE(ssid, 0, MAX_SSID_LEN) },
1342 #else
1343 	{ STR_RANGE(ssid, 0, MAX_SSID_LEN) },
1344 #endif
1345 	{ INT_RANGE(scan_ssid, 0, 1) },
1346 	{ FUNC(bssid) },
1347 	{ FUNC_KEY(psk) },
1348 	{ FUNC(proto) },
1349 	{ FUNC(key_mgmt) },
1350 	{ FUNC(pairwise) },
1351 	{ FUNC(group) },
1352 	{ FUNC(auth_alg) },
1353 #ifdef IEEE8021X_EAPOL
1354 	{ FUNC(eap) },
1355 	{ STR_LENe(identity) },
1356 	{ STR_LENe(anonymous_identity) },
1357 	{ FUNC_KEY(password) },
1358 	{ STRe(ca_cert) },
1359 	{ STRe(ca_path) },
1360 	{ STRe(client_cert) },
1361 	{ STRe(private_key) },
1362 	{ STR_KEYe(private_key_passwd) },
1363 	{ STRe(dh_file) },
1364 	{ STRe(subject_match) },
1365 	{ STRe(altsubject_match) },
1366 	{ STRe(ca_cert2) },
1367 	{ STRe(ca_path2) },
1368 	{ STRe(client_cert2) },
1369 	{ STRe(private_key2) },
1370 	{ STR_KEYe(private_key2_passwd) },
1371 	{ STRe(dh_file2) },
1372 	{ STRe(subject_match2) },
1373 	{ STRe(altsubject_match2) },
1374 	{ STRe(phase1) },
1375 	{ STRe(phase2) },
1376 	{ STRe(pcsc) },
1377 	{ STR_KEYe(pin) },
1378 	{ STRe(engine_id) },
1379 	{ STRe(key_id) },
1380 	{ STRe(cert_id) },
1381 	{ STRe(ca_cert_id) },
1382 	{ STR_KEYe(pin2) },
1383 	{ STRe(engine2_id) },
1384 	{ STRe(key2_id) },
1385 	{ STRe(cert2_id) },
1386 	{ STRe(ca_cert2_id) },
1387 	{ INTe(engine) },
1388 	{ INTe(engine2) },
1389 	{ INT(eapol_flags) },
1390 #endif /* IEEE8021X_EAPOL */
1391 	{ FUNC_KEY(wep_key0) },
1392 	{ FUNC_KEY(wep_key1) },
1393 	{ FUNC_KEY(wep_key2) },
1394 	{ FUNC_KEY(wep_key3) },
1395 	{ INT(wep_tx_keyidx) },
1396 	{ INT(priority) },
1397 #ifdef IEEE8021X_EAPOL
1398 	{ INT(eap_workaround) },
1399 	{ STRe(pac_file) },
1400 	{ INTe(fragment_size) },
1401 #endif /* IEEE8021X_EAPOL */
1402 	{ INT_RANGE(mode, 0, 1) },
1403 	{ INT_RANGE(proactive_key_caching, 0, 1) },
1404 	{ INT_RANGE(disabled, 0, 1) },
1405 	{ STR(id_str) },
1406 #ifdef CONFIG_IEEE80211W
1407 	{ INT_RANGE(ieee80211w, 0, 2) },
1408 #endif /* CONFIG_IEEE80211W */
1409 	{ INT_RANGE(peerkey, 0, 1) },
1410 	{ INT_RANGE(mixed_cell, 0, 1) },
1411 	{ INT_RANGE(frequency, 0, 10000) },
1412 	{ INT(wpa_ptk_rekey) }
1413 };
1414 
1415 #ifdef WPA_UNICODE_SSID
1416 #undef _STR_UNICODE
1417 #undef STR_UNICODE
1418 #undef _STR_LEN_UNICODE
1419 #undef STR_LEN_UNICODE
1420 #undef _STR_RANGE_UNICODE
1421 #undef STR_RANGE_UNICODE
1422 #endif
1423 
1424 #undef OFFSET
1425 #undef _STR
1426 #undef STR
1427 #undef STR_KEY
1428 #undef _STR_LEN
1429 #undef STR_LEN
1430 #undef STR_LEN_KEY
1431 #undef _STR_RANGE
1432 #undef STR_RANGE
1433 #undef STR_RANGE_KEY
1434 #undef _INT
1435 #undef INT
1436 #undef INT_RANGE
1437 #undef _FUNC
1438 #undef FUNC
1439 #undef FUNC_KEY
1440 #define NUM_SSID_FIELDS (sizeof(ssid_fields) / sizeof(ssid_fields[0]))
1441 
1442 
1443 /**
1444  * wpa_config_add_prio_network - Add a network to priority lists
1445  * @config: Configuration data from wpa_config_read()
1446  * @ssid: Pointer to the network configuration to be added to the list
1447  * Returns: 0 on success, -1 on failure
1448  *
1449  * This function is used to add a network block to the priority list of
1450  * networks. This must be called for each network when reading in the full
1451  * configuration. In addition, this can be used indirectly when updating
1452  * priorities by calling wpa_config_update_prio_list().
1453  */
wpa_config_add_prio_network(struct wpa_config * config,struct wpa_ssid * ssid)1454 int wpa_config_add_prio_network(struct wpa_config *config,
1455 				struct wpa_ssid *ssid)
1456 {
1457 	int prio;
1458 	struct wpa_ssid *prev, **nlist;
1459 
1460 	/*
1461 	 * Add to an existing priority list if one is available for the
1462 	 * configured priority level for this network.
1463 	 */
1464 	for (prio = 0; prio < config->num_prio; prio++) {
1465 		prev = config->pssid[prio];
1466 		if (prev->priority == ssid->priority) {
1467 			while (prev->pnext)
1468 				prev = prev->pnext;
1469 			prev->pnext = ssid;
1470 			return 0;
1471 		}
1472 	}
1473 
1474 	/* First network for this priority - add a new priority list */
1475 	nlist = os_realloc(config->pssid,
1476 			   (config->num_prio + 1) * sizeof(struct wpa_ssid *));
1477 	if (nlist == NULL)
1478 		return -1;
1479 
1480 	for (prio = 0; prio < config->num_prio; prio++) {
1481 		if (nlist[prio]->priority < ssid->priority)
1482 			break;
1483 	}
1484 
1485 	os_memmove(&nlist[prio + 1], &nlist[prio],
1486 		   (config->num_prio - prio) * sizeof(struct wpa_ssid *));
1487 
1488 	nlist[prio] = ssid;
1489 	config->num_prio++;
1490 	config->pssid = nlist;
1491 
1492 	return 0;
1493 }
1494 
1495 
1496 /**
1497  * wpa_config_update_prio_list - Update network priority list
1498  * @config: Configuration data from wpa_config_read()
1499  * Returns: 0 on success, -1 on failure
1500  *
1501  * This function is called to update the priority list of networks in the
1502  * configuration when a network is being added or removed. This is also called
1503  * if a priority for a network is changed.
1504  */
wpa_config_update_prio_list(struct wpa_config * config)1505 int wpa_config_update_prio_list(struct wpa_config *config)
1506 {
1507 	struct wpa_ssid *ssid;
1508 	int ret = 0;
1509 
1510 	os_free(config->pssid);
1511 	config->pssid = NULL;
1512 	config->num_prio = 0;
1513 
1514 	ssid = config->ssid;
1515 	while (ssid) {
1516 		ssid->pnext = NULL;
1517 		if (wpa_config_add_prio_network(config, ssid) < 0)
1518 			ret = -1;
1519 		ssid = ssid->next;
1520 	}
1521 
1522 	return ret;
1523 }
1524 
1525 
1526 #ifdef IEEE8021X_EAPOL
eap_peer_config_free(struct eap_peer_config * eap)1527 static void eap_peer_config_free(struct eap_peer_config *eap)
1528 {
1529 	os_free(eap->eap_methods);
1530 	os_free(eap->identity);
1531 	os_free(eap->anonymous_identity);
1532 	os_free(eap->password);
1533 	os_free(eap->ca_cert);
1534 	os_free(eap->ca_path);
1535 	os_free(eap->client_cert);
1536 	os_free(eap->private_key);
1537 	os_free(eap->private_key_passwd);
1538 	os_free(eap->dh_file);
1539 	os_free(eap->subject_match);
1540 	os_free(eap->altsubject_match);
1541 	os_free(eap->ca_cert2);
1542 	os_free(eap->ca_path2);
1543 	os_free(eap->client_cert2);
1544 	os_free(eap->private_key2);
1545 	os_free(eap->private_key2_passwd);
1546 	os_free(eap->dh_file2);
1547 	os_free(eap->subject_match2);
1548 	os_free(eap->altsubject_match2);
1549 	os_free(eap->phase1);
1550 	os_free(eap->phase2);
1551 	os_free(eap->pcsc);
1552 	os_free(eap->pin);
1553 	os_free(eap->engine_id);
1554 	os_free(eap->key_id);
1555 	os_free(eap->cert_id);
1556 	os_free(eap->ca_cert_id);
1557 	os_free(eap->key2_id);
1558 	os_free(eap->cert2_id);
1559 	os_free(eap->ca_cert2_id);
1560 	os_free(eap->pin2);
1561 	os_free(eap->engine2_id);
1562 	os_free(eap->otp);
1563 	os_free(eap->pending_req_otp);
1564 	os_free(eap->pac_file);
1565 	os_free(eap->new_password);
1566 }
1567 #endif /* IEEE8021X_EAPOL */
1568 
1569 
1570 /**
1571  * wpa_config_free_ssid - Free network/ssid configuration data
1572  * @ssid: Configuration data for the network
1573  *
1574  * This function frees all resources allocated for the network configuration
1575  * data.
1576  */
wpa_config_free_ssid(struct wpa_ssid * ssid)1577 void wpa_config_free_ssid(struct wpa_ssid *ssid)
1578 {
1579 	os_free(ssid->ssid);
1580 	os_free(ssid->passphrase);
1581 #ifdef IEEE8021X_EAPOL
1582 	eap_peer_config_free(&ssid->eap);
1583 #endif /* IEEE8021X_EAPOL */
1584 	os_free(ssid->id_str);
1585 	os_free(ssid);
1586 }
1587 
1588 
1589 /**
1590  * wpa_config_free - Free configuration data
1591  * @config: Configuration data from wpa_config_read()
1592  *
1593  * This function frees all resources allocated for the configuration data by
1594  * wpa_config_read().
1595  */
wpa_config_free(struct wpa_config * config)1596 void wpa_config_free(struct wpa_config *config)
1597 {
1598 #ifndef CONFIG_NO_CONFIG_BLOBS
1599 	struct wpa_config_blob *blob, *prevblob;
1600 #endif /* CONFIG_NO_CONFIG_BLOBS */
1601 	struct wpa_ssid *ssid, *prev = NULL;
1602 	ssid = config->ssid;
1603 	while (ssid) {
1604 		prev = ssid;
1605 		ssid = ssid->next;
1606 		wpa_config_free_ssid(prev);
1607 	}
1608 
1609 #ifndef CONFIG_NO_CONFIG_BLOBS
1610 	blob = config->blobs;
1611 	prevblob = NULL;
1612 	while (blob) {
1613 		prevblob = blob;
1614 		blob = blob->next;
1615 		wpa_config_free_blob(prevblob);
1616 	}
1617 #endif /* CONFIG_NO_CONFIG_BLOBS */
1618 
1619 	os_free(config->ctrl_interface);
1620 	os_free(config->ctrl_interface_group);
1621 #ifdef EAP_TLS_OPENSSL
1622 	os_free(config->opensc_engine_path);
1623 	os_free(config->pkcs11_engine_path);
1624 	os_free(config->pkcs11_module_path);
1625 #endif /* EAP_TLS_OPENSSL */
1626 	os_free(config->driver_param);
1627 	os_free(config->device_name);
1628 	os_free(config->manufacturer);
1629 	os_free(config->model_name);
1630 	os_free(config->model_number);
1631 	os_free(config->serial_number);
1632 	os_free(config->device_type);
1633 	os_free(config->pssid);
1634 	os_free(config);
1635 }
1636 
1637 
1638 /**
1639  * wpa_config_get_network - Get configured network based on id
1640  * @config: Configuration data from wpa_config_read()
1641  * @id: Unique network id to search for
1642  * Returns: Network configuration or %NULL if not found
1643  */
wpa_config_get_network(struct wpa_config * config,int id)1644 struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id)
1645 {
1646 	struct wpa_ssid *ssid;
1647 
1648 	ssid = config->ssid;
1649 	while (ssid) {
1650 		if (id == ssid->id)
1651 			break;
1652 		ssid = ssid->next;
1653 	}
1654 
1655 	return ssid;
1656 }
1657 
1658 
1659 /**
1660  * wpa_config_add_network - Add a new network with empty configuration
1661  * @config: Configuration data from wpa_config_read()
1662  * Returns: The new network configuration or %NULL if operation failed
1663  */
wpa_config_add_network(struct wpa_config * config)1664 struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
1665 {
1666 	int id;
1667 	struct wpa_ssid *ssid, *last = NULL;
1668 
1669 	id = -1;
1670 	ssid = config->ssid;
1671 	while (ssid) {
1672 		if (ssid->id > id)
1673 			id = ssid->id;
1674 		last = ssid;
1675 		ssid = ssid->next;
1676 	}
1677 	id++;
1678 
1679 	ssid = os_zalloc(sizeof(*ssid));
1680 	if (ssid == NULL)
1681 		return NULL;
1682 	ssid->id = id;
1683 	if (last)
1684 		last->next = ssid;
1685 	else
1686 		config->ssid = ssid;
1687 
1688 	wpa_config_update_prio_list(config);
1689 
1690 	return ssid;
1691 }
1692 
1693 
1694 /**
1695  * wpa_config_remove_network - Remove a configured network based on id
1696  * @config: Configuration data from wpa_config_read()
1697  * @id: Unique network id to search for
1698  * Returns: 0 on success, or -1 if the network was not found
1699  */
wpa_config_remove_network(struct wpa_config * config,int id)1700 int wpa_config_remove_network(struct wpa_config *config, int id)
1701 {
1702 	struct wpa_ssid *ssid, *prev = NULL;
1703 
1704 	ssid = config->ssid;
1705 	while (ssid) {
1706 		if (id == ssid->id)
1707 			break;
1708 		prev = ssid;
1709 		ssid = ssid->next;
1710 	}
1711 
1712 	if (ssid == NULL)
1713 		return -1;
1714 
1715 	if (prev)
1716 		prev->next = ssid->next;
1717 	else
1718 		config->ssid = ssid->next;
1719 
1720 	wpa_config_update_prio_list(config);
1721 	wpa_config_free_ssid(ssid);
1722 	return 0;
1723 }
1724 
1725 
1726 /**
1727  * wpa_config_set_network_defaults - Set network default values
1728  * @ssid: Pointer to network configuration data
1729  */
wpa_config_set_network_defaults(struct wpa_ssid * ssid)1730 void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
1731 {
1732 	ssid->proto = DEFAULT_PROTO;
1733 	ssid->pairwise_cipher = DEFAULT_PAIRWISE;
1734 	ssid->group_cipher = DEFAULT_GROUP;
1735 	ssid->key_mgmt = DEFAULT_KEY_MGMT;
1736 #ifdef IEEE8021X_EAPOL
1737 	ssid->eapol_flags = DEFAULT_EAPOL_FLAGS;
1738 	ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
1739 	ssid->eap.fragment_size = DEFAULT_FRAGMENT_SIZE;
1740 #endif /* IEEE8021X_EAPOL */
1741 }
1742 
1743 
1744 /**
1745  * wpa_config_set - Set a variable in network configuration
1746  * @ssid: Pointer to network configuration data
1747  * @var: Variable name, e.g., "ssid"
1748  * @value: Variable value
1749  * @line: Line number in configuration file or 0 if not used
1750  * Returns: 0 on success, -1 on failure
1751  *
1752  * This function can be used to set network configuration variables based on
1753  * both the configuration file and management interface input. The value
1754  * parameter must be in the same format as the text-based configuration file is
1755  * using. For example, strings are using double quotation marks.
1756  */
wpa_config_set(struct wpa_ssid * ssid,const char * var,const char * value,int line)1757 int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
1758 		   int line)
1759 {
1760 	size_t i;
1761 	int ret = 0;
1762 
1763 	if (ssid == NULL || var == NULL || value == NULL)
1764 		return -1;
1765 
1766 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
1767 		const struct parse_data *field = &ssid_fields[i];
1768 		if (os_strcmp(var, field->name) != 0)
1769 			continue;
1770 
1771 		if (field->parser(field, ssid, line, value)) {
1772 			if (line) {
1773 				wpa_printf(MSG_ERROR, "Line %d: failed to "
1774 					   "parse %s '%s'.", line, var, value);
1775 			}
1776 			ret = -1;
1777 		}
1778 		break;
1779 	}
1780 	if (i == NUM_SSID_FIELDS) {
1781 		if (line) {
1782 			wpa_printf(MSG_ERROR, "Line %d: unknown network field "
1783 				   "'%s'.", line, var);
1784 		}
1785 		ret = -1;
1786 	}
1787 
1788 	return ret;
1789 }
1790 
1791 
1792 #ifndef NO_CONFIG_WRITE
1793 /**
1794  * wpa_config_get - Get a variable in network configuration
1795  * @ssid: Pointer to network configuration data
1796  * @var: Variable name, e.g., "ssid"
1797  * Returns: Value of the variable or %NULL on failure
1798  *
1799  * This function can be used to get network configuration variables. The
1800  * returned value is a copy of the configuration variable in text format, i.e,.
1801  * the same format that the text-based configuration file and wpa_config_set()
1802  * are using for the value. The caller is responsible for freeing the returned
1803  * value.
1804  */
wpa_config_get(struct wpa_ssid * ssid,const char * var)1805 char * wpa_config_get(struct wpa_ssid *ssid, const char *var)
1806 {
1807 	size_t i;
1808 
1809 	if (ssid == NULL || var == NULL)
1810 		return NULL;
1811 
1812 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
1813 		const struct parse_data *field = &ssid_fields[i];
1814 		if (os_strcmp(var, field->name) == 0)
1815 			return field->writer(field, ssid);
1816 	}
1817 
1818 	return NULL;
1819 }
1820 
1821 
1822 /**
1823  * wpa_config_get_no_key - Get a variable in network configuration (no keys)
1824  * @ssid: Pointer to network configuration data
1825  * @var: Variable name, e.g., "ssid"
1826  * Returns: Value of the variable or %NULL on failure
1827  *
1828  * This function can be used to get network configuration variable like
1829  * wpa_config_get(). The only difference is that this functions does not expose
1830  * key/password material from the configuration. In case a key/password field
1831  * is requested, the returned value is an empty string or %NULL if the variable
1832  * is not set or "*" if the variable is set (regardless of its value). The
1833  * returned value is a copy of the configuration variable in text format, i.e,.
1834  * the same format that the text-based configuration file and wpa_config_set()
1835  * are using for the value. The caller is responsible for freeing the returned
1836  * value.
1837  */
wpa_config_get_no_key(struct wpa_ssid * ssid,const char * var)1838 char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var)
1839 {
1840 	size_t i;
1841 
1842 	if (ssid == NULL || var == NULL)
1843 		return NULL;
1844 
1845 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
1846 		const struct parse_data *field = &ssid_fields[i];
1847 		if (os_strcmp(var, field->name) == 0) {
1848 			char *res = field->writer(field, ssid);
1849 			if (field->key_data) {
1850 				if (res && res[0]) {
1851 					wpa_printf(MSG_DEBUG, "Do not allow "
1852 						   "key_data field to be "
1853 						   "exposed");
1854 					os_free(res);
1855 					return os_strdup("*");
1856 				}
1857 
1858 				os_free(res);
1859 				return NULL;
1860 			}
1861 			return res;
1862 		}
1863 	}
1864 
1865 	return NULL;
1866 }
1867 #endif /* NO_CONFIG_WRITE */
1868 
1869 
1870 /**
1871  * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
1872  * @ssid: Pointer to network configuration data
1873  *
1874  * This function must be called to update WPA PSK when either SSID or the
1875  * passphrase has changed for the network configuration.
1876  */
wpa_config_update_psk(struct wpa_ssid * ssid)1877 void wpa_config_update_psk(struct wpa_ssid *ssid)
1878 {
1879 #ifndef CONFIG_NO_PBKDF2
1880 	pbkdf2_sha1(ssid->passphrase,
1881 		    (char *) ssid->ssid, ssid->ssid_len, 4096,
1882 		    ssid->psk, PMK_LEN);
1883 	wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1884 			ssid->psk, PMK_LEN);
1885 	ssid->psk_set = 1;
1886 #endif /* CONFIG_NO_PBKDF2 */
1887 }
1888 
1889 
1890 #ifndef CONFIG_NO_CONFIG_BLOBS
1891 /**
1892  * wpa_config_get_blob - Get a named configuration blob
1893  * @config: Configuration data from wpa_config_read()
1894  * @name: Name of the blob
1895  * Returns: Pointer to blob data or %NULL if not found
1896  */
wpa_config_get_blob(struct wpa_config * config,const char * name)1897 const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
1898 						   const char *name)
1899 {
1900 	struct wpa_config_blob *blob = config->blobs;
1901 
1902 	while (blob) {
1903 		if (os_strcmp(blob->name, name) == 0)
1904 			return blob;
1905 		blob = blob->next;
1906 	}
1907 	return NULL;
1908 }
1909 
1910 
1911 /**
1912  * wpa_config_set_blob - Set or add a named configuration blob
1913  * @config: Configuration data from wpa_config_read()
1914  * @blob: New value for the blob
1915  *
1916  * Adds a new configuration blob or replaces the current value of an existing
1917  * blob.
1918  */
wpa_config_set_blob(struct wpa_config * config,struct wpa_config_blob * blob)1919 void wpa_config_set_blob(struct wpa_config *config,
1920 			 struct wpa_config_blob *blob)
1921 {
1922 	wpa_config_remove_blob(config, blob->name);
1923 	blob->next = config->blobs;
1924 	config->blobs = blob;
1925 }
1926 
1927 
1928 /**
1929  * wpa_config_free_blob - Free blob data
1930  * @blob: Pointer to blob to be freed
1931  */
wpa_config_free_blob(struct wpa_config_blob * blob)1932 void wpa_config_free_blob(struct wpa_config_blob *blob)
1933 {
1934 	if (blob) {
1935 		os_free(blob->name);
1936 		os_free(blob->data);
1937 		os_free(blob);
1938 	}
1939 }
1940 
1941 
1942 /**
1943  * wpa_config_remove_blob - Remove a named configuration blob
1944  * @config: Configuration data from wpa_config_read()
1945  * @name: Name of the blob to remove
1946  * Returns: 0 if blob was removed or -1 if blob was not found
1947  */
wpa_config_remove_blob(struct wpa_config * config,const char * name)1948 int wpa_config_remove_blob(struct wpa_config *config, const char *name)
1949 {
1950 	struct wpa_config_blob *pos = config->blobs, *prev = NULL;
1951 
1952 	while (pos) {
1953 		if (os_strcmp(pos->name, name) == 0) {
1954 			if (prev)
1955 				prev->next = pos->next;
1956 			else
1957 				config->blobs = pos->next;
1958 			wpa_config_free_blob(pos);
1959 			return 0;
1960 		}
1961 		prev = pos;
1962 		pos = pos->next;
1963 	}
1964 
1965 	return -1;
1966 }
1967 #endif /* CONFIG_NO_CONFIG_BLOBS */
1968 
1969 
1970 /**
1971  * wpa_config_alloc_empty - Allocate an empty configuration
1972  * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
1973  * socket
1974  * @driver_param: Driver parameters
1975  * Returns: Pointer to allocated configuration data or %NULL on failure
1976  */
wpa_config_alloc_empty(const char * ctrl_interface,const char * driver_param)1977 struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
1978 					   const char *driver_param)
1979 {
1980 	struct wpa_config *config;
1981 
1982 	config = os_zalloc(sizeof(*config));
1983 	if (config == NULL)
1984 		return NULL;
1985 	config->eapol_version = DEFAULT_EAPOL_VERSION;
1986 	config->ap_scan = DEFAULT_AP_SCAN;
1987 	config->fast_reauth = DEFAULT_FAST_REAUTH;
1988 
1989 	if (ctrl_interface)
1990 		config->ctrl_interface = os_strdup(ctrl_interface);
1991 	if (driver_param)
1992 		config->driver_param = os_strdup(driver_param);
1993 
1994 	return config;
1995 }
1996 
1997 
1998 #ifndef CONFIG_NO_STDOUT_DEBUG
1999 /**
2000  * wpa_config_debug_dump_networks - Debug dump of configured networks
2001  * @config: Configuration data from wpa_config_read()
2002  */
wpa_config_debug_dump_networks(struct wpa_config * config)2003 void wpa_config_debug_dump_networks(struct wpa_config *config)
2004 {
2005 	int prio;
2006 	struct wpa_ssid *ssid;
2007 
2008 	for (prio = 0; prio < config->num_prio; prio++) {
2009 		ssid = config->pssid[prio];
2010 		wpa_printf(MSG_DEBUG, "Priority group %d",
2011 			   ssid->priority);
2012 		while (ssid) {
2013 			wpa_printf(MSG_DEBUG, "   id=%d ssid='%s'",
2014 				   ssid->id,
2015 				   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
2016 			ssid = ssid->pnext;
2017 		}
2018 	}
2019 }
2020 #endif /* CONFIG_NO_STDOUT_DEBUG */
2021