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