Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant / Configuration parser and common functions
      3  * Copyright (c) 2003-2012, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 
     11 #include "common.h"
     12 #include "utils/uuid.h"
     13 #include "crypto/sha1.h"
     14 #include "rsn_supp/wpa.h"
     15 #include "eap_peer/eap.h"
     16 #include "p2p/p2p.h"
     17 #include "config.h"
     18 
     19 
     20 #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE)
     21 #define NO_CONFIG_WRITE
     22 #endif
     23 
     24 /*
     25  * Structure for network configuration parsing. This data is used to implement
     26  * a generic parser for each network block variable. The table of configuration
     27  * variables is defined below in this file (ssid_fields[]).
     28  */
     29 struct parse_data {
     30 	/* Configuration variable name */
     31 	char *name;
     32 
     33 	/* Parser function for this variable */
     34 	int (*parser)(const struct parse_data *data, struct wpa_ssid *ssid,
     35 		      int line, const char *value);
     36 
     37 #ifndef NO_CONFIG_WRITE
     38 	/* Writer function (i.e., to get the variable in text format from
     39 	 * internal presentation). */
     40 	char * (*writer)(const struct parse_data *data, struct wpa_ssid *ssid);
     41 #endif /* NO_CONFIG_WRITE */
     42 
     43 	/* Variable specific parameters for the parser. */
     44 	void *param1, *param2, *param3, *param4;
     45 
     46 	/* 0 = this variable can be included in debug output and ctrl_iface
     47 	 * 1 = this variable contains key/private data and it must not be
     48 	 *     included in debug output unless explicitly requested. In
     49 	 *     addition, this variable will not be readable through the
     50 	 *     ctrl_iface.
     51 	 */
     52 	int key_data;
     53 };
     54 
     55 
     56 static int wpa_config_parse_str(const struct parse_data *data,
     57 				struct wpa_ssid *ssid,
     58 				int line, const char *value)
     59 {
     60 	size_t res_len, *dst_len;
     61 	char **dst, *tmp;
     62 
     63 	if (os_strcmp(value, "NULL") == 0) {
     64 		wpa_printf(MSG_DEBUG, "Unset configuration string '%s'",
     65 			   data->name);
     66 		tmp = NULL;
     67 		res_len = 0;
     68 		goto set;
     69 	}
     70 
     71 	tmp = wpa_config_parse_string(value, &res_len);
     72 	if (tmp == NULL) {
     73 		wpa_printf(MSG_ERROR, "Line %d: failed to parse %s '%s'.",
     74 			   line, data->name,
     75 			   data->key_data ? "[KEY DATA REMOVED]" : value);
     76 		return -1;
     77 	}
     78 
     79 	if (data->key_data) {
     80 		wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
     81 				      (u8 *) tmp, res_len);
     82 	} else {
     83 		wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
     84 				  (u8 *) tmp, res_len);
     85 	}
     86 
     87 	if (data->param3 && res_len < (size_t) data->param3) {
     88 		wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
     89 			   "min_len=%ld)", line, data->name,
     90 			   (unsigned long) res_len, (long) data->param3);
     91 		os_free(tmp);
     92 		return -1;
     93 	}
     94 
     95 	if (data->param4 && res_len > (size_t) data->param4) {
     96 		wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
     97 			   "max_len=%ld)", line, data->name,
     98 			   (unsigned long) res_len, (long) data->param4);
     99 		os_free(tmp);
    100 		return -1;
    101 	}
    102 
    103 set:
    104 	dst = (char **) (((u8 *) ssid) + (long) data->param1);
    105 	dst_len = (size_t *) (((u8 *) ssid) + (long) data->param2);
    106 	os_free(*dst);
    107 	*dst = tmp;
    108 	if (data->param2)
    109 		*dst_len = res_len;
    110 
    111 	return 0;
    112 }
    113 
    114 
    115 #ifndef NO_CONFIG_WRITE
    116 static char * wpa_config_write_string_ascii(const u8 *value, size_t len)
    117 {
    118 	char *buf;
    119 
    120 	buf = os_malloc(len + 3);
    121 	if (buf == NULL)
    122 		return NULL;
    123 	buf[0] = '"';
    124 	os_memcpy(buf + 1, value, len);
    125 	buf[len + 1] = '"';
    126 	buf[len + 2] = '\0';
    127 
    128 	return buf;
    129 }
    130 
    131 
    132 static char * wpa_config_write_string_hex(const u8 *value, size_t len)
    133 {
    134 	char *buf;
    135 
    136 	buf = os_zalloc(2 * len + 1);
    137 	if (buf == NULL)
    138 		return NULL;
    139 	wpa_snprintf_hex(buf, 2 * len + 1, value, len);
    140 
    141 	return buf;
    142 }
    143 
    144 
    145 static char * wpa_config_write_string(const u8 *value, size_t len)
    146 {
    147 	if (value == NULL)
    148 		return NULL;
    149 
    150 	if (is_hex(value, len))
    151 		return wpa_config_write_string_hex(value, len);
    152 	else
    153 		return wpa_config_write_string_ascii(value, len);
    154 }
    155 
    156 
    157 static char * wpa_config_write_str(const struct parse_data *data,
    158 				   struct wpa_ssid *ssid)
    159 {
    160 	size_t len;
    161 	char **src;
    162 
    163 	src = (char **) (((u8 *) ssid) + (long) data->param1);
    164 	if (*src == NULL)
    165 		return NULL;
    166 
    167 	if (data->param2)
    168 		len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
    169 	else
    170 		len = os_strlen(*src);
    171 
    172 	return wpa_config_write_string((const u8 *) *src, len);
    173 }
    174 #endif /* NO_CONFIG_WRITE */
    175 
    176 
    177 static int wpa_config_parse_int(const struct parse_data *data,
    178 				struct wpa_ssid *ssid,
    179 				int line, const char *value)
    180 {
    181 	int *dst;
    182 
    183 	dst = (int *) (((u8 *) ssid) + (long) data->param1);
    184 	*dst = atoi(value);
    185 	wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst);
    186 
    187 	if (data->param3 && *dst < (long) data->param3) {
    188 		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
    189 			   "min_value=%ld)", line, data->name, *dst,
    190 			   (long) data->param3);
    191 		*dst = (long) data->param3;
    192 		return -1;
    193 	}
    194 
    195 	if (data->param4 && *dst > (long) data->param4) {
    196 		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
    197 			   "max_value=%ld)", line, data->name, *dst,
    198 			   (long) data->param4);
    199 		*dst = (long) data->param4;
    200 		return -1;
    201 	}
    202 
    203 	return 0;
    204 }
    205 
    206 
    207 #ifndef NO_CONFIG_WRITE
    208 static char * wpa_config_write_int(const struct parse_data *data,
    209 				   struct wpa_ssid *ssid)
    210 {
    211 	int *src, res;
    212 	char *value;
    213 
    214 	src = (int *) (((u8 *) ssid) + (long) data->param1);
    215 
    216 	value = os_malloc(20);
    217 	if (value == NULL)
    218 		return NULL;
    219 	res = os_snprintf(value, 20, "%d", *src);
    220 	if (res < 0 || res >= 20) {
    221 		os_free(value);
    222 		return NULL;
    223 	}
    224 	value[20 - 1] = '\0';
    225 	return value;
    226 }
    227 #endif /* NO_CONFIG_WRITE */
    228 
    229 
    230 static int wpa_config_parse_bssid(const struct parse_data *data,
    231 				  struct wpa_ssid *ssid, int line,
    232 				  const char *value)
    233 {
    234 	if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 ||
    235 	    os_strcmp(value, "any") == 0) {
    236 		ssid->bssid_set = 0;
    237 		wpa_printf(MSG_MSGDUMP, "BSSID any");
    238 		return 0;
    239 	}
    240 	if (hwaddr_aton(value, ssid->bssid)) {
    241 		wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.",
    242 			   line, value);
    243 		return -1;
    244 	}
    245 	ssid->bssid_set = 1;
    246 	wpa_hexdump(MSG_MSGDUMP, "BSSID", ssid->bssid, ETH_ALEN);
    247 	return 0;
    248 }
    249 
    250 
    251 #ifndef NO_CONFIG_WRITE
    252 static char * wpa_config_write_bssid(const struct parse_data *data,
    253 				     struct wpa_ssid *ssid)
    254 {
    255 	char *value;
    256 	int res;
    257 
    258 	if (!ssid->bssid_set)
    259 		return NULL;
    260 
    261 	value = os_malloc(20);
    262 	if (value == NULL)
    263 		return NULL;
    264 	res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid));
    265 	if (res < 0 || res >= 20) {
    266 		os_free(value);
    267 		return NULL;
    268 	}
    269 	value[20 - 1] = '\0';
    270 	return value;
    271 }
    272 #endif /* NO_CONFIG_WRITE */
    273 
    274 
    275 static int wpa_config_parse_psk(const struct parse_data *data,
    276 				struct wpa_ssid *ssid, int line,
    277 				const char *value)
    278 {
    279 #ifdef CONFIG_EXT_PASSWORD
    280 	if (os_strncmp(value, "ext:", 4) == 0) {
    281 		os_free(ssid->passphrase);
    282 		ssid->passphrase = NULL;
    283 		ssid->psk_set = 0;
    284 		os_free(ssid->ext_psk);
    285 		ssid->ext_psk = os_strdup(value + 4);
    286 		if (ssid->ext_psk == NULL)
    287 			return -1;
    288 		wpa_printf(MSG_DEBUG, "PSK: External password '%s'",
    289 			   ssid->ext_psk);
    290 		return 0;
    291 	}
    292 #endif /* CONFIG_EXT_PASSWORD */
    293 
    294 	if (*value == '"') {
    295 #ifndef CONFIG_NO_PBKDF2
    296 		const char *pos;
    297 		size_t len;
    298 
    299 		value++;
    300 		pos = os_strrchr(value, '"');
    301 		if (pos)
    302 			len = pos - value;
    303 		else
    304 			len = os_strlen(value);
    305 		if (len < 8 || len > 63) {
    306 			wpa_printf(MSG_ERROR, "Line %d: Invalid passphrase "
    307 				   "length %lu (expected: 8..63) '%s'.",
    308 				   line, (unsigned long) len, value);
    309 			return -1;
    310 		}
    311 		wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)",
    312 				      (u8 *) value, len);
    313 		if (ssid->passphrase && os_strlen(ssid->passphrase) == len &&
    314 		    os_memcmp(ssid->passphrase, value, len) == 0)
    315 			return 0;
    316 		ssid->psk_set = 0;
    317 		os_free(ssid->passphrase);
    318 		ssid->passphrase = os_malloc(len + 1);
    319 		if (ssid->passphrase == NULL)
    320 			return -1;
    321 		os_memcpy(ssid->passphrase, value, len);
    322 		ssid->passphrase[len] = '\0';
    323 		return 0;
    324 #else /* CONFIG_NO_PBKDF2 */
    325 		wpa_printf(MSG_ERROR, "Line %d: ASCII passphrase not "
    326 			   "supported.", line);
    327 		return -1;
    328 #endif /* CONFIG_NO_PBKDF2 */
    329 	}
    330 
    331 	if (hexstr2bin(value, ssid->psk, PMK_LEN) ||
    332 	    value[PMK_LEN * 2] != '\0') {
    333 		wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
    334 			   line, value);
    335 		return -1;
    336 	}
    337 
    338 	os_free(ssid->passphrase);
    339 	ssid->passphrase = NULL;
    340 
    341 	ssid->psk_set = 1;
    342 	wpa_hexdump_key(MSG_MSGDUMP, "PSK", ssid->psk, PMK_LEN);
    343 	return 0;
    344 }
    345 
    346 
    347 #ifndef NO_CONFIG_WRITE
    348 static char * wpa_config_write_psk(const struct parse_data *data,
    349 				   struct wpa_ssid *ssid)
    350 {
    351 #ifdef CONFIG_EXT_PASSWORD
    352 	if (ssid->ext_psk) {
    353 		size_t len = 4 + os_strlen(ssid->ext_psk) + 1;
    354 		char *buf = os_malloc(len);
    355 		if (buf == NULL)
    356 			return NULL;
    357 		os_snprintf(buf, len, "ext:%s", ssid->ext_psk);
    358 		return buf;
    359 	}
    360 #endif /* CONFIG_EXT_PASSWORD */
    361 
    362 	if (ssid->passphrase)
    363 		return wpa_config_write_string_ascii(
    364 			(const u8 *) ssid->passphrase,
    365 			os_strlen(ssid->passphrase));
    366 
    367 	if (ssid->psk_set)
    368 		return wpa_config_write_string_hex(ssid->psk, PMK_LEN);
    369 
    370 	return NULL;
    371 }
    372 #endif /* NO_CONFIG_WRITE */
    373 
    374 
    375 static int wpa_config_parse_proto(const struct parse_data *data,
    376 				  struct wpa_ssid *ssid, int line,
    377 				  const char *value)
    378 {
    379 	int val = 0, last, errors = 0;
    380 	char *start, *end, *buf;
    381 
    382 	buf = os_strdup(value);
    383 	if (buf == NULL)
    384 		return -1;
    385 	start = buf;
    386 
    387 	while (*start != '\0') {
    388 		while (*start == ' ' || *start == '\t')
    389 			start++;
    390 		if (*start == '\0')
    391 			break;
    392 		end = start;
    393 		while (*end != ' ' && *end != '\t' && *end != '\0')
    394 			end++;
    395 		last = *end == '\0';
    396 		*end = '\0';
    397 		if (os_strcmp(start, "WPA") == 0)
    398 			val |= WPA_PROTO_WPA;
    399 		else if (os_strcmp(start, "RSN") == 0 ||
    400 			 os_strcmp(start, "WPA2") == 0)
    401 			val |= WPA_PROTO_RSN;
    402 		else {
    403 			wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'",
    404 				   line, start);
    405 			errors++;
    406 		}
    407 
    408 		if (last)
    409 			break;
    410 		start = end + 1;
    411 	}
    412 	os_free(buf);
    413 
    414 	if (val == 0) {
    415 		wpa_printf(MSG_ERROR,
    416 			   "Line %d: no proto values configured.", line);
    417 		errors++;
    418 	}
    419 
    420 	wpa_printf(MSG_MSGDUMP, "proto: 0x%x", val);
    421 	ssid->proto = val;
    422 	return errors ? -1 : 0;
    423 }
    424 
    425 
    426 #ifndef NO_CONFIG_WRITE
    427 static char * wpa_config_write_proto(const struct parse_data *data,
    428 				     struct wpa_ssid *ssid)
    429 {
    430 	int first = 1, ret;
    431 	char *buf, *pos, *end;
    432 
    433 	pos = buf = os_zalloc(10);
    434 	if (buf == NULL)
    435 		return NULL;
    436 	end = buf + 10;
    437 
    438 	if (ssid->proto & WPA_PROTO_WPA) {
    439 		ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
    440 		if (ret < 0 || ret >= end - pos)
    441 			return buf;
    442 		pos += ret;
    443 		first = 0;
    444 	}
    445 
    446 	if (ssid->proto & WPA_PROTO_RSN) {
    447 		ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
    448 		if (ret < 0 || ret >= end - pos)
    449 			return buf;
    450 		pos += ret;
    451 		first = 0;
    452 	}
    453 
    454 	return buf;
    455 }
    456 #endif /* NO_CONFIG_WRITE */
    457 
    458 
    459 static int wpa_config_parse_key_mgmt(const struct parse_data *data,
    460 				     struct wpa_ssid *ssid, int line,
    461 				     const char *value)
    462 {
    463 	int val = 0, last, errors = 0;
    464 	char *start, *end, *buf;
    465 
    466 	buf = os_strdup(value);
    467 	if (buf == NULL)
    468 		return -1;
    469 	start = buf;
    470 
    471 	while (*start != '\0') {
    472 		while (*start == ' ' || *start == '\t')
    473 			start++;
    474 		if (*start == '\0')
    475 			break;
    476 		end = start;
    477 		while (*end != ' ' && *end != '\t' && *end != '\0')
    478 			end++;
    479 		last = *end == '\0';
    480 		*end = '\0';
    481 		if (os_strcmp(start, "WPA-PSK") == 0)
    482 			val |= WPA_KEY_MGMT_PSK;
    483 		else if (os_strcmp(start, "WPA-EAP") == 0)
    484 			val |= WPA_KEY_MGMT_IEEE8021X;
    485 		else if (os_strcmp(start, "IEEE8021X") == 0)
    486 			val |= WPA_KEY_MGMT_IEEE8021X_NO_WPA;
    487 		else if (os_strcmp(start, "NONE") == 0)
    488 			val |= WPA_KEY_MGMT_NONE;
    489 		else if (os_strcmp(start, "WPA-NONE") == 0)
    490 			val |= WPA_KEY_MGMT_WPA_NONE;
    491 #ifdef CONFIG_IEEE80211R
    492 		else if (os_strcmp(start, "FT-PSK") == 0)
    493 			val |= WPA_KEY_MGMT_FT_PSK;
    494 		else if (os_strcmp(start, "FT-EAP") == 0)
    495 			val |= WPA_KEY_MGMT_FT_IEEE8021X;
    496 #endif /* CONFIG_IEEE80211R */
    497 #ifdef CONFIG_IEEE80211W
    498 		else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
    499 			val |= WPA_KEY_MGMT_PSK_SHA256;
    500 		else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
    501 			val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
    502 #endif /* CONFIG_IEEE80211W */
    503 #ifdef CONFIG_WPS
    504 		else if (os_strcmp(start, "WPS") == 0)
    505 			val |= WPA_KEY_MGMT_WPS;
    506 #endif /* CONFIG_WPS */
    507 		else {
    508 			wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
    509 				   line, start);
    510 			errors++;
    511 		}
    512 
    513 		if (last)
    514 			break;
    515 		start = end + 1;
    516 	}
    517 	os_free(buf);
    518 
    519 	if (val == 0) {
    520 		wpa_printf(MSG_ERROR,
    521 			   "Line %d: no key_mgmt values configured.", line);
    522 		errors++;
    523 	}
    524 
    525 	wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val);
    526 	ssid->key_mgmt = val;
    527 	return errors ? -1 : 0;
    528 }
    529 
    530 
    531 #ifndef NO_CONFIG_WRITE
    532 static char * wpa_config_write_key_mgmt(const struct parse_data *data,
    533 					struct wpa_ssid *ssid)
    534 {
    535 	char *buf, *pos, *end;
    536 	int ret;
    537 
    538 	pos = buf = os_zalloc(50);
    539 	if (buf == NULL)
    540 		return NULL;
    541 	end = buf + 50;
    542 
    543 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
    544 		ret = os_snprintf(pos, end - pos, "%sWPA-PSK",
    545 				  pos == buf ? "" : " ");
    546 		if (ret < 0 || ret >= end - pos) {
    547 			end[-1] = '\0';
    548 			return buf;
    549 		}
    550 		pos += ret;
    551 	}
    552 
    553 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
    554 		ret = os_snprintf(pos, end - pos, "%sWPA-EAP",
    555 				  pos == buf ? "" : " ");
    556 		if (ret < 0 || ret >= end - pos) {
    557 			end[-1] = '\0';
    558 			return buf;
    559 		}
    560 		pos += ret;
    561 	}
    562 
    563 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
    564 		ret = os_snprintf(pos, end - pos, "%sIEEE8021X",
    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_NONE) {
    574 		ret = os_snprintf(pos, end - pos, "%sNONE",
    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_WPA_NONE) {
    584 		ret = os_snprintf(pos, end - pos, "%sWPA-NONE",
    585 				  pos == buf ? "" : " ");
    586 		if (ret < 0 || ret >= end - pos) {
    587 			end[-1] = '\0';
    588 			return buf;
    589 		}
    590 		pos += ret;
    591 	}
    592 
    593 #ifdef CONFIG_IEEE80211R
    594 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK)
    595 		pos += os_snprintf(pos, end - pos, "%sFT-PSK",
    596 				   pos == buf ? "" : " ");
    597 
    598 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
    599 		pos += os_snprintf(pos, end - pos, "%sFT-EAP",
    600 				   pos == buf ? "" : " ");
    601 #endif /* CONFIG_IEEE80211R */
    602 
    603 #ifdef CONFIG_IEEE80211W
    604 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
    605 		pos += os_snprintf(pos, end - pos, "%sWPA-PSK-SHA256",
    606 				   pos == buf ? "" : " ");
    607 
    608 	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
    609 		pos += os_snprintf(pos, end - pos, "%sWPA-EAP-SHA256",
    610 				   pos == buf ? "" : " ");
    611 #endif /* CONFIG_IEEE80211W */
    612 
    613 #ifdef CONFIG_WPS
    614 	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
    615 		pos += os_snprintf(pos, end - pos, "%sWPS",
    616 				   pos == buf ? "" : " ");
    617 #endif /* CONFIG_WPS */
    618 
    619 	return buf;
    620 }
    621 #endif /* NO_CONFIG_WRITE */
    622 
    623 
    624 static int wpa_config_parse_cipher(int line, const char *value)
    625 {
    626 	int val = 0, last;
    627 	char *start, *end, *buf;
    628 
    629 	buf = os_strdup(value);
    630 	if (buf == NULL)
    631 		return -1;
    632 	start = buf;
    633 
    634 	while (*start != '\0') {
    635 		while (*start == ' ' || *start == '\t')
    636 			start++;
    637 		if (*start == '\0')
    638 			break;
    639 		end = start;
    640 		while (*end != ' ' && *end != '\t' && *end != '\0')
    641 			end++;
    642 		last = *end == '\0';
    643 		*end = '\0';
    644 		if (os_strcmp(start, "CCMP") == 0)
    645 			val |= WPA_CIPHER_CCMP;
    646 		else if (os_strcmp(start, "GCMP") == 0)
    647 			val |= WPA_CIPHER_GCMP;
    648 		else if (os_strcmp(start, "TKIP") == 0)
    649 			val |= WPA_CIPHER_TKIP;
    650 		else if (os_strcmp(start, "WEP104") == 0)
    651 			val |= WPA_CIPHER_WEP104;
    652 		else if (os_strcmp(start, "WEP40") == 0)
    653 			val |= WPA_CIPHER_WEP40;
    654 		else if (os_strcmp(start, "NONE") == 0)
    655 			val |= WPA_CIPHER_NONE;
    656 		else {
    657 			wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
    658 				   line, start);
    659 			os_free(buf);
    660 			return -1;
    661 		}
    662 
    663 		if (last)
    664 			break;
    665 		start = end + 1;
    666 	}
    667 	os_free(buf);
    668 
    669 	if (val == 0) {
    670 		wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
    671 			   line);
    672 		return -1;
    673 	}
    674 	return val;
    675 }
    676 
    677 
    678 #ifndef NO_CONFIG_WRITE
    679 static char * wpa_config_write_cipher(int cipher)
    680 {
    681 	char *buf, *pos, *end;
    682 	int ret;
    683 
    684 	pos = buf = os_zalloc(50);
    685 	if (buf == NULL)
    686 		return NULL;
    687 	end = buf + 50;
    688 
    689 	if (cipher & WPA_CIPHER_CCMP) {
    690 		ret = os_snprintf(pos, end - pos, "%sCCMP",
    691 				  pos == buf ? "" : " ");
    692 		if (ret < 0 || ret >= end - pos) {
    693 			end[-1] = '\0';
    694 			return buf;
    695 		}
    696 		pos += ret;
    697 	}
    698 
    699 	if (cipher & WPA_CIPHER_GCMP) {
    700 		ret = os_snprintf(pos, end - pos, "%sGCMP",
    701 				  pos == buf ? "" : " ");
    702 		if (ret < 0 || ret >= end - pos) {
    703 			end[-1] = '\0';
    704 			return buf;
    705 		}
    706 		pos += ret;
    707 	}
    708 
    709 	if (cipher & WPA_CIPHER_TKIP) {
    710 		ret = os_snprintf(pos, end - pos, "%sTKIP",
    711 				  pos == buf ? "" : " ");
    712 		if (ret < 0 || ret >= end - pos) {
    713 			end[-1] = '\0';
    714 			return buf;
    715 		}
    716 		pos += ret;
    717 	}
    718 
    719 	if (cipher & WPA_CIPHER_WEP104) {
    720 		ret = os_snprintf(pos, end - pos, "%sWEP104",
    721 				  pos == buf ? "" : " ");
    722 		if (ret < 0 || ret >= end - pos) {
    723 			end[-1] = '\0';
    724 			return buf;
    725 		}
    726 		pos += ret;
    727 	}
    728 
    729 	if (cipher & WPA_CIPHER_WEP40) {
    730 		ret = os_snprintf(pos, end - pos, "%sWEP40",
    731 				  pos == buf ? "" : " ");
    732 		if (ret < 0 || ret >= end - pos) {
    733 			end[-1] = '\0';
    734 			return buf;
    735 		}
    736 		pos += ret;
    737 	}
    738 
    739 	if (cipher & WPA_CIPHER_NONE) {
    740 		ret = os_snprintf(pos, end - pos, "%sNONE",
    741 				  pos == buf ? "" : " ");
    742 		if (ret < 0 || ret >= end - pos) {
    743 			end[-1] = '\0';
    744 			return buf;
    745 		}
    746 		pos += ret;
    747 	}
    748 
    749 	return buf;
    750 }
    751 #endif /* NO_CONFIG_WRITE */
    752 
    753 
    754 static int wpa_config_parse_pairwise(const struct parse_data *data,
    755 				     struct wpa_ssid *ssid, int line,
    756 				     const char *value)
    757 {
    758 	int val;
    759 	val = wpa_config_parse_cipher(line, value);
    760 	if (val == -1)
    761 		return -1;
    762 	if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP |
    763 		    WPA_CIPHER_NONE)) {
    764 		wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
    765 			   "(0x%x).", line, val);
    766 		return -1;
    767 	}
    768 
    769 	wpa_printf(MSG_MSGDUMP, "pairwise: 0x%x", val);
    770 	ssid->pairwise_cipher = val;
    771 	return 0;
    772 }
    773 
    774 
    775 #ifndef NO_CONFIG_WRITE
    776 static char * wpa_config_write_pairwise(const struct parse_data *data,
    777 					struct wpa_ssid *ssid)
    778 {
    779 	return wpa_config_write_cipher(ssid->pairwise_cipher);
    780 }
    781 #endif /* NO_CONFIG_WRITE */
    782 
    783 
    784 static int wpa_config_parse_group(const struct parse_data *data,
    785 				  struct wpa_ssid *ssid, int line,
    786 				  const char *value)
    787 {
    788 	int val;
    789 	val = wpa_config_parse_cipher(line, value);
    790 	if (val == -1)
    791 		return -1;
    792 	if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP |
    793 		    WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40)) {
    794 		wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
    795 			   "(0x%x).", line, val);
    796 		return -1;
    797 	}
    798 
    799 	wpa_printf(MSG_MSGDUMP, "group: 0x%x", val);
    800 	ssid->group_cipher = val;
    801 	return 0;
    802 }
    803 
    804 
    805 #ifndef NO_CONFIG_WRITE
    806 static char * wpa_config_write_group(const struct parse_data *data,
    807 				     struct wpa_ssid *ssid)
    808 {
    809 	return wpa_config_write_cipher(ssid->group_cipher);
    810 }
    811 #endif /* NO_CONFIG_WRITE */
    812 
    813 
    814 static int wpa_config_parse_auth_alg(const struct parse_data *data,
    815 				     struct wpa_ssid *ssid, int line,
    816 				     const char *value)
    817 {
    818 	int val = 0, last, errors = 0;
    819 	char *start, *end, *buf;
    820 
    821 	buf = os_strdup(value);
    822 	if (buf == NULL)
    823 		return -1;
    824 	start = buf;
    825 
    826 	while (*start != '\0') {
    827 		while (*start == ' ' || *start == '\t')
    828 			start++;
    829 		if (*start == '\0')
    830 			break;
    831 		end = start;
    832 		while (*end != ' ' && *end != '\t' && *end != '\0')
    833 			end++;
    834 		last = *end == '\0';
    835 		*end = '\0';
    836 		if (os_strcmp(start, "OPEN") == 0)
    837 			val |= WPA_AUTH_ALG_OPEN;
    838 		else if (os_strcmp(start, "SHARED") == 0)
    839 			val |= WPA_AUTH_ALG_SHARED;
    840 		else if (os_strcmp(start, "LEAP") == 0)
    841 			val |= WPA_AUTH_ALG_LEAP;
    842 		else {
    843 			wpa_printf(MSG_ERROR, "Line %d: invalid auth_alg '%s'",
    844 				   line, start);
    845 			errors++;
    846 		}
    847 
    848 		if (last)
    849 			break;
    850 		start = end + 1;
    851 	}
    852 	os_free(buf);
    853 
    854 	if (val == 0) {
    855 		wpa_printf(MSG_ERROR,
    856 			   "Line %d: no auth_alg values configured.", line);
    857 		errors++;
    858 	}
    859 
    860 	wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", val);
    861 	ssid->auth_alg = val;
    862 	return errors ? -1 : 0;
    863 }
    864 
    865 
    866 #ifndef NO_CONFIG_WRITE
    867 static char * wpa_config_write_auth_alg(const struct parse_data *data,
    868 					struct wpa_ssid *ssid)
    869 {
    870 	char *buf, *pos, *end;
    871 	int ret;
    872 
    873 	pos = buf = os_zalloc(30);
    874 	if (buf == NULL)
    875 		return NULL;
    876 	end = buf + 30;
    877 
    878 	if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) {
    879 		ret = os_snprintf(pos, end - pos, "%sOPEN",
    880 				  pos == buf ? "" : " ");
    881 		if (ret < 0 || ret >= end - pos) {
    882 			end[-1] = '\0';
    883 			return buf;
    884 		}
    885 		pos += ret;
    886 	}
    887 
    888 	if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) {
    889 		ret = os_snprintf(pos, end - pos, "%sSHARED",
    890 				  pos == buf ? "" : " ");
    891 		if (ret < 0 || ret >= end - pos) {
    892 			end[-1] = '\0';
    893 			return buf;
    894 		}
    895 		pos += ret;
    896 	}
    897 
    898 	if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) {
    899 		ret = os_snprintf(pos, end - pos, "%sLEAP",
    900 				  pos == buf ? "" : " ");
    901 		if (ret < 0 || ret >= end - pos) {
    902 			end[-1] = '\0';
    903 			return buf;
    904 		}
    905 		pos += ret;
    906 	}
    907 
    908 	return buf;
    909 }
    910 #endif /* NO_CONFIG_WRITE */
    911 
    912 
    913 static int * wpa_config_parse_freqs(const struct parse_data *data,
    914 				    struct wpa_ssid *ssid, int line,
    915 				    const char *value)
    916 {
    917 	int *freqs;
    918 	size_t used, len;
    919 	const char *pos;
    920 
    921 	used = 0;
    922 	len = 10;
    923 	freqs = os_calloc(len + 1, sizeof(int));
    924 	if (freqs == NULL)
    925 		return NULL;
    926 
    927 	pos = value;
    928 	while (pos) {
    929 		while (*pos == ' ')
    930 			pos++;
    931 		if (used == len) {
    932 			int *n;
    933 			size_t i;
    934 			n = os_realloc_array(freqs, len * 2 + 1, sizeof(int));
    935 			if (n == NULL) {
    936 				os_free(freqs);
    937 				return NULL;
    938 			}
    939 			for (i = len; i <= len * 2; i++)
    940 				n[i] = 0;
    941 			freqs = n;
    942 			len *= 2;
    943 		}
    944 
    945 		freqs[used] = atoi(pos);
    946 		if (freqs[used] == 0)
    947 			break;
    948 		used++;
    949 		pos = os_strchr(pos + 1, ' ');
    950 	}
    951 
    952 	return freqs;
    953 }
    954 
    955 
    956 static int wpa_config_parse_scan_freq(const struct parse_data *data,
    957 				      struct wpa_ssid *ssid, int line,
    958 				      const char *value)
    959 {
    960 	int *freqs;
    961 
    962 	freqs = wpa_config_parse_freqs(data, ssid, line, value);
    963 	if (freqs == NULL)
    964 		return -1;
    965 	os_free(ssid->scan_freq);
    966 	ssid->scan_freq = freqs;
    967 
    968 	return 0;
    969 }
    970 
    971 
    972 static int wpa_config_parse_freq_list(const struct parse_data *data,
    973 				      struct wpa_ssid *ssid, int line,
    974 				      const char *value)
    975 {
    976 	int *freqs;
    977 
    978 	freqs = wpa_config_parse_freqs(data, ssid, line, value);
    979 	if (freqs == NULL)
    980 		return -1;
    981 	os_free(ssid->freq_list);
    982 	ssid->freq_list = freqs;
    983 
    984 	return 0;
    985 }
    986 
    987 
    988 #ifndef NO_CONFIG_WRITE
    989 static char * wpa_config_write_freqs(const struct parse_data *data,
    990 				     const int *freqs)
    991 {
    992 	char *buf, *pos, *end;
    993 	int i, ret;
    994 	size_t count;
    995 
    996 	if (freqs == NULL)
    997 		return NULL;
    998 
    999 	count = 0;
   1000 	for (i = 0; freqs[i]; i++)
   1001 		count++;
   1002 
   1003 	pos = buf = os_zalloc(10 * count + 1);
   1004 	if (buf == NULL)
   1005 		return NULL;
   1006 	end = buf + 10 * count + 1;
   1007 
   1008 	for (i = 0; freqs[i]; i++) {
   1009 		ret = os_snprintf(pos, end - pos, "%s%u",
   1010 				  i == 0 ? "" : " ", freqs[i]);
   1011 		if (ret < 0 || ret >= end - pos) {
   1012 			end[-1] = '\0';
   1013 			return buf;
   1014 		}
   1015 		pos += ret;
   1016 	}
   1017 
   1018 	return buf;
   1019 }
   1020 
   1021 
   1022 static char * wpa_config_write_scan_freq(const struct parse_data *data,
   1023 					 struct wpa_ssid *ssid)
   1024 {
   1025 	return wpa_config_write_freqs(data, ssid->scan_freq);
   1026 }
   1027 
   1028 
   1029 static char * wpa_config_write_freq_list(const struct parse_data *data,
   1030 					 struct wpa_ssid *ssid)
   1031 {
   1032 	return wpa_config_write_freqs(data, ssid->freq_list);
   1033 }
   1034 #endif /* NO_CONFIG_WRITE */
   1035 
   1036 
   1037 #ifdef IEEE8021X_EAPOL
   1038 static int wpa_config_parse_eap(const struct parse_data *data,
   1039 				struct wpa_ssid *ssid, int line,
   1040 				const char *value)
   1041 {
   1042 	int last, errors = 0;
   1043 	char *start, *end, *buf;
   1044 	struct eap_method_type *methods = NULL, *tmp;
   1045 	size_t num_methods = 0;
   1046 
   1047 	buf = os_strdup(value);
   1048 	if (buf == NULL)
   1049 		return -1;
   1050 	start = buf;
   1051 
   1052 	while (*start != '\0') {
   1053 		while (*start == ' ' || *start == '\t')
   1054 			start++;
   1055 		if (*start == '\0')
   1056 			break;
   1057 		end = start;
   1058 		while (*end != ' ' && *end != '\t' && *end != '\0')
   1059 			end++;
   1060 		last = *end == '\0';
   1061 		*end = '\0';
   1062 		tmp = methods;
   1063 		methods = os_realloc_array(methods, num_methods + 1,
   1064 					   sizeof(*methods));
   1065 		if (methods == NULL) {
   1066 			os_free(tmp);
   1067 			os_free(buf);
   1068 			return -1;
   1069 		}
   1070 		methods[num_methods].method = eap_peer_get_type(
   1071 			start, &methods[num_methods].vendor);
   1072 		if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
   1073 		    methods[num_methods].method == EAP_TYPE_NONE) {
   1074 			wpa_printf(MSG_ERROR, "Line %d: unknown EAP method "
   1075 				   "'%s'", line, start);
   1076 			wpa_printf(MSG_ERROR, "You may need to add support for"
   1077 				   " this EAP method during wpa_supplicant\n"
   1078 				   "build time configuration.\n"
   1079 				   "See README for more information.");
   1080 			errors++;
   1081 		} else if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
   1082 			   methods[num_methods].method == EAP_TYPE_LEAP)
   1083 			ssid->leap++;
   1084 		else
   1085 			ssid->non_leap++;
   1086 		num_methods++;
   1087 		if (last)
   1088 			break;
   1089 		start = end + 1;
   1090 	}
   1091 	os_free(buf);
   1092 
   1093 	tmp = methods;
   1094 	methods = os_realloc_array(methods, num_methods + 1, sizeof(*methods));
   1095 	if (methods == NULL) {
   1096 		os_free(tmp);
   1097 		return -1;
   1098 	}
   1099 	methods[num_methods].vendor = EAP_VENDOR_IETF;
   1100 	methods[num_methods].method = EAP_TYPE_NONE;
   1101 	num_methods++;
   1102 
   1103 	wpa_hexdump(MSG_MSGDUMP, "eap methods",
   1104 		    (u8 *) methods, num_methods * sizeof(*methods));
   1105 	os_free(ssid->eap.eap_methods);
   1106 	ssid->eap.eap_methods = methods;
   1107 	return errors ? -1 : 0;
   1108 }
   1109 
   1110 
   1111 static char * wpa_config_write_eap(const struct parse_data *data,
   1112 				   struct wpa_ssid *ssid)
   1113 {
   1114 	int i, ret;
   1115 	char *buf, *pos, *end;
   1116 	const struct eap_method_type *eap_methods = ssid->eap.eap_methods;
   1117 	const char *name;
   1118 
   1119 	if (eap_methods == NULL)
   1120 		return NULL;
   1121 
   1122 	pos = buf = os_zalloc(100);
   1123 	if (buf == NULL)
   1124 		return NULL;
   1125 	end = buf + 100;
   1126 
   1127 	for (i = 0; eap_methods[i].vendor != EAP_VENDOR_IETF ||
   1128 		     eap_methods[i].method != EAP_TYPE_NONE; i++) {
   1129 		name = eap_get_name(eap_methods[i].vendor,
   1130 				    eap_methods[i].method);
   1131 		if (name) {
   1132 			ret = os_snprintf(pos, end - pos, "%s%s",
   1133 					  pos == buf ? "" : " ", name);
   1134 			if (ret < 0 || ret >= end - pos)
   1135 				break;
   1136 			pos += ret;
   1137 		}
   1138 	}
   1139 
   1140 	end[-1] = '\0';
   1141 
   1142 	return buf;
   1143 }
   1144 
   1145 
   1146 static int wpa_config_parse_password(const struct parse_data *data,
   1147 				     struct wpa_ssid *ssid, int line,
   1148 				     const char *value)
   1149 {
   1150 	u8 *hash;
   1151 
   1152 	if (os_strcmp(value, "NULL") == 0) {
   1153 		wpa_printf(MSG_DEBUG, "Unset configuration string 'password'");
   1154 		os_free(ssid->eap.password);
   1155 		ssid->eap.password = NULL;
   1156 		ssid->eap.password_len = 0;
   1157 		return 0;
   1158 	}
   1159 
   1160 #ifdef CONFIG_EXT_PASSWORD
   1161 	if (os_strncmp(value, "ext:", 4) == 0) {
   1162 		char *name = os_strdup(value + 4);
   1163 		if (name == NULL)
   1164 			return -1;
   1165 		os_free(ssid->eap.password);
   1166 		ssid->eap.password = (u8 *) name;
   1167 		ssid->eap.password_len = os_strlen(name);
   1168 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
   1169 		ssid->eap.flags |= EAP_CONFIG_FLAGS_EXT_PASSWORD;
   1170 		return 0;
   1171 	}
   1172 #endif /* CONFIG_EXT_PASSWORD */
   1173 
   1174 	if (os_strncmp(value, "hash:", 5) != 0) {
   1175 		char *tmp;
   1176 		size_t res_len;
   1177 
   1178 		tmp = wpa_config_parse_string(value, &res_len);
   1179 		if (tmp == NULL) {
   1180 			wpa_printf(MSG_ERROR, "Line %d: failed to parse "
   1181 				   "password.", line);
   1182 			return -1;
   1183 		}
   1184 		wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
   1185 				      (u8 *) tmp, res_len);
   1186 
   1187 		os_free(ssid->eap.password);
   1188 		ssid->eap.password = (u8 *) tmp;
   1189 		ssid->eap.password_len = res_len;
   1190 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
   1191 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
   1192 
   1193 		return 0;
   1194 	}
   1195 
   1196 
   1197 	/* NtPasswordHash: hash:<32 hex digits> */
   1198 	if (os_strlen(value + 5) != 2 * 16) {
   1199 		wpa_printf(MSG_ERROR, "Line %d: Invalid password hash length "
   1200 			   "(expected 32 hex digits)", line);
   1201 		return -1;
   1202 	}
   1203 
   1204 	hash = os_malloc(16);
   1205 	if (hash == NULL)
   1206 		return -1;
   1207 
   1208 	if (hexstr2bin(value + 5, hash, 16)) {
   1209 		os_free(hash);
   1210 		wpa_printf(MSG_ERROR, "Line %d: Invalid password hash", line);
   1211 		return -1;
   1212 	}
   1213 
   1214 	wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
   1215 
   1216 	os_free(ssid->eap.password);
   1217 	ssid->eap.password = hash;
   1218 	ssid->eap.password_len = 16;
   1219 	ssid->eap.flags |= EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
   1220 	ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
   1221 
   1222 	return 0;
   1223 }
   1224 
   1225 
   1226 static char * wpa_config_write_password(const struct parse_data *data,
   1227 					struct wpa_ssid *ssid)
   1228 {
   1229 	char *buf;
   1230 
   1231 	if (ssid->eap.password == NULL)
   1232 		return NULL;
   1233 
   1234 #ifdef CONFIG_EXT_PASSWORD
   1235 	if (ssid->eap.flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
   1236 		buf = os_zalloc(4 + ssid->eap.password_len + 1);
   1237 		if (buf == NULL)
   1238 			return NULL;
   1239 		os_memcpy(buf, "ext:", 4);
   1240 		os_memcpy(buf + 4, ssid->eap.password, ssid->eap.password_len);
   1241 		return buf;
   1242 	}
   1243 #endif /* CONFIG_EXT_PASSWORD */
   1244 
   1245 	if (!(ssid->eap.flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH)) {
   1246 		return wpa_config_write_string(
   1247 			ssid->eap.password, ssid->eap.password_len);
   1248 	}
   1249 
   1250 	buf = os_malloc(5 + 32 + 1);
   1251 	if (buf == NULL)
   1252 		return NULL;
   1253 
   1254 	os_memcpy(buf, "hash:", 5);
   1255 	wpa_snprintf_hex(buf + 5, 32 + 1, ssid->eap.password, 16);
   1256 
   1257 	return buf;
   1258 }
   1259 #endif /* IEEE8021X_EAPOL */
   1260 
   1261 
   1262 static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line,
   1263 				    const char *value, int idx)
   1264 {
   1265 	char *buf, title[20];
   1266 	int res;
   1267 
   1268 	buf = wpa_config_parse_string(value, len);
   1269 	if (buf == NULL) {
   1270 		wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key %d '%s'.",
   1271 			   line, idx, value);
   1272 		return -1;
   1273 	}
   1274 	if (*len > MAX_WEP_KEY_LEN) {
   1275 		wpa_printf(MSG_ERROR, "Line %d: Too long WEP key %d '%s'.",
   1276 			   line, idx, value);
   1277 		os_free(buf);
   1278 		return -1;
   1279 	}
   1280 	if (*len && *len != 5 && *len != 13 && *len != 16) {
   1281 		wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key length %u - "
   1282 			   "this network block will be ignored",
   1283 			   line, (unsigned int) *len);
   1284 	}
   1285 	os_memcpy(key, buf, *len);
   1286 	os_free(buf);
   1287 	res = os_snprintf(title, sizeof(title), "wep_key%d", idx);
   1288 	if (res >= 0 && (size_t) res < sizeof(title))
   1289 		wpa_hexdump_key(MSG_MSGDUMP, title, key, *len);
   1290 	return 0;
   1291 }
   1292 
   1293 
   1294 static int wpa_config_parse_wep_key0(const struct parse_data *data,
   1295 				     struct wpa_ssid *ssid, int line,
   1296 				     const char *value)
   1297 {
   1298 	return wpa_config_parse_wep_key(ssid->wep_key[0],
   1299 					&ssid->wep_key_len[0], line,
   1300 					value, 0);
   1301 }
   1302 
   1303 
   1304 static int wpa_config_parse_wep_key1(const struct parse_data *data,
   1305 				     struct wpa_ssid *ssid, int line,
   1306 				     const char *value)
   1307 {
   1308 	return wpa_config_parse_wep_key(ssid->wep_key[1],
   1309 					&ssid->wep_key_len[1], line,
   1310 					value, 1);
   1311 }
   1312 
   1313 
   1314 static int wpa_config_parse_wep_key2(const struct parse_data *data,
   1315 				     struct wpa_ssid *ssid, int line,
   1316 				     const char *value)
   1317 {
   1318 	return wpa_config_parse_wep_key(ssid->wep_key[2],
   1319 					&ssid->wep_key_len[2], line,
   1320 					value, 2);
   1321 }
   1322 
   1323 
   1324 static int wpa_config_parse_wep_key3(const struct parse_data *data,
   1325 				     struct wpa_ssid *ssid, int line,
   1326 				     const char *value)
   1327 {
   1328 	return wpa_config_parse_wep_key(ssid->wep_key[3],
   1329 					&ssid->wep_key_len[3], line,
   1330 					value, 3);
   1331 }
   1332 
   1333 
   1334 #ifndef NO_CONFIG_WRITE
   1335 static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx)
   1336 {
   1337 	if (ssid->wep_key_len[idx] == 0)
   1338 		return NULL;
   1339 	return wpa_config_write_string(ssid->wep_key[idx],
   1340 				       ssid->wep_key_len[idx]);
   1341 }
   1342 
   1343 
   1344 static char * wpa_config_write_wep_key0(const struct parse_data *data,
   1345 					struct wpa_ssid *ssid)
   1346 {
   1347 	return wpa_config_write_wep_key(ssid, 0);
   1348 }
   1349 
   1350 
   1351 static char * wpa_config_write_wep_key1(const struct parse_data *data,
   1352 					struct wpa_ssid *ssid)
   1353 {
   1354 	return wpa_config_write_wep_key(ssid, 1);
   1355 }
   1356 
   1357 
   1358 static char * wpa_config_write_wep_key2(const struct parse_data *data,
   1359 					struct wpa_ssid *ssid)
   1360 {
   1361 	return wpa_config_write_wep_key(ssid, 2);
   1362 }
   1363 
   1364 
   1365 static char * wpa_config_write_wep_key3(const struct parse_data *data,
   1366 					struct wpa_ssid *ssid)
   1367 {
   1368 	return wpa_config_write_wep_key(ssid, 3);
   1369 }
   1370 #endif /* NO_CONFIG_WRITE */
   1371 
   1372 
   1373 #ifdef CONFIG_P2P
   1374 
   1375 static int wpa_config_parse_p2p_client_list(const struct parse_data *data,
   1376 					    struct wpa_ssid *ssid, int line,
   1377 					    const char *value)
   1378 {
   1379 	const char *pos;
   1380 	u8 *buf, *n, addr[ETH_ALEN];
   1381 	size_t count;
   1382 
   1383 	buf = NULL;
   1384 	count = 0;
   1385 
   1386 	pos = value;
   1387 	while (pos && *pos) {
   1388 		while (*pos == ' ')
   1389 			pos++;
   1390 
   1391 		if (hwaddr_aton(pos, addr)) {
   1392 			if (count == 0) {
   1393 				wpa_printf(MSG_ERROR, "Line %d: Invalid "
   1394 					   "p2p_client_list address '%s'.",
   1395 					   line, value);
   1396 				os_free(buf);
   1397 				return -1;
   1398 			}
   1399 			/* continue anyway since this could have been from a
   1400 			 * truncated configuration file line */
   1401 			wpa_printf(MSG_INFO, "Line %d: Ignore likely "
   1402 				   "truncated p2p_client_list address '%s'",
   1403 				   line, pos);
   1404 		} else {
   1405 			n = os_realloc_array(buf, count + 1, ETH_ALEN);
   1406 			if (n == NULL) {
   1407 				os_free(buf);
   1408 				return -1;
   1409 			}
   1410 			buf = n;
   1411 			os_memmove(buf + ETH_ALEN, buf, count * ETH_ALEN);
   1412 			os_memcpy(buf, addr, ETH_ALEN);
   1413 			count++;
   1414 			wpa_hexdump(MSG_MSGDUMP, "p2p_client_list",
   1415 				    addr, ETH_ALEN);
   1416 		}
   1417 
   1418 		pos = os_strchr(pos, ' ');
   1419 	}
   1420 
   1421 	os_free(ssid->p2p_client_list);
   1422 	ssid->p2p_client_list = buf;
   1423 	ssid->num_p2p_clients = count;
   1424 
   1425 	return 0;
   1426 }
   1427 
   1428 
   1429 #ifndef NO_CONFIG_WRITE
   1430 static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
   1431 					       struct wpa_ssid *ssid)
   1432 {
   1433 	char *value, *end, *pos;
   1434 	int res;
   1435 	size_t i;
   1436 
   1437 	if (ssid->p2p_client_list == NULL || ssid->num_p2p_clients == 0)
   1438 		return NULL;
   1439 
   1440 	value = os_malloc(20 * ssid->num_p2p_clients);
   1441 	if (value == NULL)
   1442 		return NULL;
   1443 	pos = value;
   1444 	end = value + 20 * ssid->num_p2p_clients;
   1445 
   1446 	for (i = ssid->num_p2p_clients; i > 0; i--) {
   1447 		res = os_snprintf(pos, end - pos, MACSTR " ",
   1448 				  MAC2STR(ssid->p2p_client_list +
   1449 					  (i - 1) * ETH_ALEN));
   1450 		if (res < 0 || res >= end - pos) {
   1451 			os_free(value);
   1452 			return NULL;
   1453 		}
   1454 		pos += res;
   1455 	}
   1456 
   1457 	if (pos > value)
   1458 		pos[-1] = '\0';
   1459 
   1460 	return value;
   1461 }
   1462 #endif /* NO_CONFIG_WRITE */
   1463 
   1464 #endif /* CONFIG_P2P */
   1465 
   1466 /* Helper macros for network block parser */
   1467 
   1468 #ifdef OFFSET
   1469 #undef OFFSET
   1470 #endif /* OFFSET */
   1471 /* OFFSET: Get offset of a variable within the wpa_ssid structure */
   1472 #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
   1473 
   1474 /* STR: Define a string variable for an ASCII string; f = field name */
   1475 #ifdef NO_CONFIG_WRITE
   1476 #define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
   1477 #define _STRe(f) #f, wpa_config_parse_str, OFFSET(eap.f)
   1478 #else /* NO_CONFIG_WRITE */
   1479 #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
   1480 #define _STRe(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(eap.f)
   1481 #endif /* NO_CONFIG_WRITE */
   1482 #define STR(f) _STR(f), NULL, NULL, NULL, 0
   1483 #define STRe(f) _STRe(f), NULL, NULL, NULL, 0
   1484 #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
   1485 #define STR_KEYe(f) _STRe(f), NULL, NULL, NULL, 1
   1486 
   1487 /* STR_LEN: Define a string variable with a separate variable for storing the
   1488  * data length. Unlike STR(), this can be used to store arbitrary binary data
   1489  * (i.e., even nul termination character). */
   1490 #define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
   1491 #define _STR_LENe(f) _STRe(f), OFFSET(eap.f ## _len)
   1492 #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
   1493 #define STR_LENe(f) _STR_LENe(f), NULL, NULL, 0
   1494 #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
   1495 
   1496 /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
   1497  * explicitly specified. */
   1498 #define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max)
   1499 #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
   1500 #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
   1501 
   1502 #ifdef NO_CONFIG_WRITE
   1503 #define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
   1504 #define _INTe(f) #f, wpa_config_parse_int, OFFSET(eap.f), (void *) 0
   1505 #else /* NO_CONFIG_WRITE */
   1506 #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
   1507 	OFFSET(f), (void *) 0
   1508 #define _INTe(f) #f, wpa_config_parse_int, wpa_config_write_int, \
   1509 	OFFSET(eap.f), (void *) 0
   1510 #endif /* NO_CONFIG_WRITE */
   1511 
   1512 /* INT: Define an integer variable */
   1513 #define INT(f) _INT(f), NULL, NULL, 0
   1514 #define INTe(f) _INTe(f), NULL, NULL, 0
   1515 
   1516 /* INT_RANGE: Define an integer variable with allowed value range */
   1517 #define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
   1518 
   1519 /* FUNC: Define a configuration variable that uses a custom function for
   1520  * parsing and writing the value. */
   1521 #ifdef NO_CONFIG_WRITE
   1522 #define _FUNC(f) #f, wpa_config_parse_ ## f, NULL, NULL, NULL, NULL
   1523 #else /* NO_CONFIG_WRITE */
   1524 #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
   1525 	NULL, NULL, NULL, NULL
   1526 #endif /* NO_CONFIG_WRITE */
   1527 #define FUNC(f) _FUNC(f), 0
   1528 #define FUNC_KEY(f) _FUNC(f), 1
   1529 
   1530 /*
   1531  * Table of network configuration variables. This table is used to parse each
   1532  * network configuration variable, e.g., each line in wpa_supplicant.conf file
   1533  * that is inside a network block.
   1534  *
   1535  * This table is generated using the helper macros defined above and with
   1536  * generous help from the C pre-processor. The field name is stored as a string
   1537  * into .name and for STR and INT types, the offset of the target buffer within
   1538  * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
   1539  * offset to the field containing the length of the configuration variable.
   1540  * .param3 and .param4 can be used to mark the allowed range (length for STR
   1541  * and value for INT).
   1542  *
   1543  * For each configuration line in wpa_supplicant.conf, the parser goes through
   1544  * this table and select the entry that matches with the field name. The parser
   1545  * function (.parser) is then called to parse the actual value of the field.
   1546  *
   1547  * This kind of mechanism makes it easy to add new configuration parameters,
   1548  * since only one line needs to be added into this table and into the
   1549  * struct wpa_ssid definition if the new variable is either a string or
   1550  * integer. More complex types will need to use their own parser and writer
   1551  * functions.
   1552  */
   1553 static const struct parse_data ssid_fields[] = {
   1554 	{ STR_RANGE(ssid, 0, MAX_SSID_LEN) },
   1555 	{ INT_RANGE(scan_ssid, 0, 1) },
   1556 	{ FUNC(bssid) },
   1557 	{ FUNC_KEY(psk) },
   1558 	{ FUNC(proto) },
   1559 	{ FUNC(key_mgmt) },
   1560 	{ INT(bg_scan_period) },
   1561 	{ FUNC(pairwise) },
   1562 	{ FUNC(group) },
   1563 	{ FUNC(auth_alg) },
   1564 	{ FUNC(scan_freq) },
   1565 	{ FUNC(freq_list) },
   1566 #ifdef IEEE8021X_EAPOL
   1567 	{ FUNC(eap) },
   1568 	{ STR_LENe(identity) },
   1569 	{ STR_LENe(anonymous_identity) },
   1570 	{ FUNC_KEY(password) },
   1571 	{ STRe(ca_cert) },
   1572 	{ STRe(ca_path) },
   1573 	{ STRe(client_cert) },
   1574 	{ STRe(private_key) },
   1575 	{ STR_KEYe(private_key_passwd) },
   1576 	{ STRe(dh_file) },
   1577 	{ STRe(subject_match) },
   1578 	{ STRe(altsubject_match) },
   1579 	{ STRe(ca_cert2) },
   1580 	{ STRe(ca_path2) },
   1581 	{ STRe(client_cert2) },
   1582 	{ STRe(private_key2) },
   1583 	{ STR_KEYe(private_key2_passwd) },
   1584 	{ STRe(dh_file2) },
   1585 	{ STRe(subject_match2) },
   1586 	{ STRe(altsubject_match2) },
   1587 	{ STRe(phase1) },
   1588 	{ STRe(phase2) },
   1589 	{ STRe(pcsc) },
   1590 	{ STR_KEYe(pin) },
   1591 	{ STRe(engine_id) },
   1592 	{ STRe(key_id) },
   1593 	{ STRe(cert_id) },
   1594 	{ STRe(ca_cert_id) },
   1595 	{ STR_KEYe(pin2) },
   1596 	{ STRe(engine2_id) },
   1597 	{ STRe(key2_id) },
   1598 	{ STRe(cert2_id) },
   1599 	{ STRe(ca_cert2_id) },
   1600 	{ INTe(engine) },
   1601 	{ INTe(engine2) },
   1602 	{ INT(eapol_flags) },
   1603 #endif /* IEEE8021X_EAPOL */
   1604 	{ FUNC_KEY(wep_key0) },
   1605 	{ FUNC_KEY(wep_key1) },
   1606 	{ FUNC_KEY(wep_key2) },
   1607 	{ FUNC_KEY(wep_key3) },
   1608 	{ INT(wep_tx_keyidx) },
   1609 	{ INT(priority) },
   1610 #ifdef IEEE8021X_EAPOL
   1611 	{ INT(eap_workaround) },
   1612 	{ STRe(pac_file) },
   1613 	{ INTe(fragment_size) },
   1614 #endif /* IEEE8021X_EAPOL */
   1615 	{ INT_RANGE(mode, 0, 4) },
   1616 	{ INT_RANGE(proactive_key_caching, 0, 1) },
   1617 	{ INT_RANGE(disabled, 0, 2) },
   1618 	{ STR(id_str) },
   1619 #ifdef CONFIG_IEEE80211W
   1620 	{ INT_RANGE(ieee80211w, 0, 2) },
   1621 #endif /* CONFIG_IEEE80211W */
   1622 	{ INT_RANGE(peerkey, 0, 1) },
   1623 	{ INT_RANGE(mixed_cell, 0, 1) },
   1624 	{ INT_RANGE(frequency, 0, 10000) },
   1625 	{ INT(wpa_ptk_rekey) },
   1626 	{ STR(bgscan) },
   1627 	{ INT_RANGE(ignore_broadcast_ssid, 0, 2) },
   1628 #ifdef CONFIG_P2P
   1629 	{ FUNC(p2p_client_list) },
   1630 #endif /* CONFIG_P2P */
   1631 #ifdef CONFIG_HT_OVERRIDES
   1632 	{ INT_RANGE(disable_ht, 0, 1) },
   1633 	{ INT_RANGE(disable_ht40, -1, 1) },
   1634 	{ INT_RANGE(disable_max_amsdu, -1, 1) },
   1635 	{ INT_RANGE(ampdu_factor, -1, 3) },
   1636 	{ INT_RANGE(ampdu_density, -1, 7) },
   1637 	{ STR(ht_mcs) },
   1638 #endif /* CONFIG_HT_OVERRIDES */
   1639 	{ INT(ap_max_inactivity) },
   1640 	{ INT(dtim_period) },
   1641 };
   1642 
   1643 #undef OFFSET
   1644 #undef _STR
   1645 #undef STR
   1646 #undef STR_KEY
   1647 #undef _STR_LEN
   1648 #undef STR_LEN
   1649 #undef STR_LEN_KEY
   1650 #undef _STR_RANGE
   1651 #undef STR_RANGE
   1652 #undef STR_RANGE_KEY
   1653 #undef _INT
   1654 #undef INT
   1655 #undef INT_RANGE
   1656 #undef _FUNC
   1657 #undef FUNC
   1658 #undef FUNC_KEY
   1659 #define NUM_SSID_FIELDS (sizeof(ssid_fields) / sizeof(ssid_fields[0]))
   1660 
   1661 
   1662 /**
   1663  * wpa_config_add_prio_network - Add a network to priority lists
   1664  * @config: Configuration data from wpa_config_read()
   1665  * @ssid: Pointer to the network configuration to be added to the list
   1666  * Returns: 0 on success, -1 on failure
   1667  *
   1668  * This function is used to add a network block to the priority list of
   1669  * networks. This must be called for each network when reading in the full
   1670  * configuration. In addition, this can be used indirectly when updating
   1671  * priorities by calling wpa_config_update_prio_list().
   1672  */
   1673 int wpa_config_add_prio_network(struct wpa_config *config,
   1674 				struct wpa_ssid *ssid)
   1675 {
   1676 	int prio;
   1677 	struct wpa_ssid *prev, **nlist;
   1678 
   1679 	/*
   1680 	 * Add to an existing priority list if one is available for the
   1681 	 * configured priority level for this network.
   1682 	 */
   1683 	for (prio = 0; prio < config->num_prio; prio++) {
   1684 		prev = config->pssid[prio];
   1685 		if (prev->priority == ssid->priority) {
   1686 			while (prev->pnext)
   1687 				prev = prev->pnext;
   1688 			prev->pnext = ssid;
   1689 			return 0;
   1690 		}
   1691 	}
   1692 
   1693 	/* First network for this priority - add a new priority list */
   1694 	nlist = os_realloc_array(config->pssid, config->num_prio + 1,
   1695 				 sizeof(struct wpa_ssid *));
   1696 	if (nlist == NULL)
   1697 		return -1;
   1698 
   1699 	for (prio = 0; prio < config->num_prio; prio++) {
   1700 		if (nlist[prio]->priority < ssid->priority) {
   1701 			os_memmove(&nlist[prio + 1], &nlist[prio],
   1702 				   (config->num_prio - prio) *
   1703 				   sizeof(struct wpa_ssid *));
   1704 			break;
   1705 		}
   1706 	}
   1707 
   1708 	nlist[prio] = ssid;
   1709 	config->num_prio++;
   1710 	config->pssid = nlist;
   1711 
   1712 	return 0;
   1713 }
   1714 
   1715 
   1716 /**
   1717  * wpa_config_update_prio_list - Update network priority list
   1718  * @config: Configuration data from wpa_config_read()
   1719  * Returns: 0 on success, -1 on failure
   1720  *
   1721  * This function is called to update the priority list of networks in the
   1722  * configuration when a network is being added or removed. This is also called
   1723  * if a priority for a network is changed.
   1724  */
   1725 int wpa_config_update_prio_list(struct wpa_config *config)
   1726 {
   1727 	struct wpa_ssid *ssid;
   1728 	int ret = 0;
   1729 
   1730 	os_free(config->pssid);
   1731 	config->pssid = NULL;
   1732 	config->num_prio = 0;
   1733 
   1734 	ssid = config->ssid;
   1735 	while (ssid) {
   1736 		ssid->pnext = NULL;
   1737 		if (wpa_config_add_prio_network(config, ssid) < 0)
   1738 			ret = -1;
   1739 		ssid = ssid->next;
   1740 	}
   1741 
   1742 	return ret;
   1743 }
   1744 
   1745 
   1746 #ifdef IEEE8021X_EAPOL
   1747 static void eap_peer_config_free(struct eap_peer_config *eap)
   1748 {
   1749 	os_free(eap->eap_methods);
   1750 	os_free(eap->identity);
   1751 	os_free(eap->anonymous_identity);
   1752 	os_free(eap->password);
   1753 	os_free(eap->ca_cert);
   1754 	os_free(eap->ca_path);
   1755 	os_free(eap->client_cert);
   1756 	os_free(eap->private_key);
   1757 	os_free(eap->private_key_passwd);
   1758 	os_free(eap->dh_file);
   1759 	os_free(eap->subject_match);
   1760 	os_free(eap->altsubject_match);
   1761 	os_free(eap->ca_cert2);
   1762 	os_free(eap->ca_path2);
   1763 	os_free(eap->client_cert2);
   1764 	os_free(eap->private_key2);
   1765 	os_free(eap->private_key2_passwd);
   1766 	os_free(eap->dh_file2);
   1767 	os_free(eap->subject_match2);
   1768 	os_free(eap->altsubject_match2);
   1769 	os_free(eap->phase1);
   1770 	os_free(eap->phase2);
   1771 	os_free(eap->pcsc);
   1772 	os_free(eap->pin);
   1773 	os_free(eap->engine_id);
   1774 	os_free(eap->key_id);
   1775 	os_free(eap->cert_id);
   1776 	os_free(eap->ca_cert_id);
   1777 	os_free(eap->key2_id);
   1778 	os_free(eap->cert2_id);
   1779 	os_free(eap->ca_cert2_id);
   1780 	os_free(eap->pin2);
   1781 	os_free(eap->engine2_id);
   1782 	os_free(eap->otp);
   1783 	os_free(eap->pending_req_otp);
   1784 	os_free(eap->pac_file);
   1785 	os_free(eap->new_password);
   1786 }
   1787 #endif /* IEEE8021X_EAPOL */
   1788 
   1789 
   1790 /**
   1791  * wpa_config_free_ssid - Free network/ssid configuration data
   1792  * @ssid: Configuration data for the network
   1793  *
   1794  * This function frees all resources allocated for the network configuration
   1795  * data.
   1796  */
   1797 void wpa_config_free_ssid(struct wpa_ssid *ssid)
   1798 {
   1799 	os_free(ssid->ssid);
   1800 	os_free(ssid->passphrase);
   1801 	os_free(ssid->ext_psk);
   1802 #ifdef IEEE8021X_EAPOL
   1803 	eap_peer_config_free(&ssid->eap);
   1804 #endif /* IEEE8021X_EAPOL */
   1805 	os_free(ssid->id_str);
   1806 	os_free(ssid->scan_freq);
   1807 	os_free(ssid->freq_list);
   1808 	os_free(ssid->bgscan);
   1809 	os_free(ssid->p2p_client_list);
   1810 #ifdef CONFIG_HT_OVERRIDES
   1811 	os_free(ssid->ht_mcs);
   1812 #endif /* CONFIG_HT_OVERRIDES */
   1813 	os_free(ssid);
   1814 }
   1815 
   1816 
   1817 void wpa_config_free_cred(struct wpa_cred *cred)
   1818 {
   1819 	os_free(cred->realm);
   1820 	os_free(cred->username);
   1821 	os_free(cred->password);
   1822 	os_free(cred->ca_cert);
   1823 	os_free(cred->client_cert);
   1824 	os_free(cred->private_key);
   1825 	os_free(cred->private_key_passwd);
   1826 	os_free(cred->imsi);
   1827 	os_free(cred->milenage);
   1828 	os_free(cred->domain);
   1829 	os_free(cred->eap_method);
   1830 	os_free(cred->phase1);
   1831 	os_free(cred->phase2);
   1832 	os_free(cred);
   1833 }
   1834 
   1835 
   1836 /**
   1837  * wpa_config_free - Free configuration data
   1838  * @config: Configuration data from wpa_config_read()
   1839  *
   1840  * This function frees all resources allocated for the configuration data by
   1841  * wpa_config_read().
   1842  */
   1843 void wpa_config_free(struct wpa_config *config)
   1844 {
   1845 #ifndef CONFIG_NO_CONFIG_BLOBS
   1846 	struct wpa_config_blob *blob, *prevblob;
   1847 #endif /* CONFIG_NO_CONFIG_BLOBS */
   1848 	struct wpa_ssid *ssid, *prev = NULL;
   1849 	struct wpa_cred *cred, *cprev;
   1850 
   1851 	ssid = config->ssid;
   1852 	while (ssid) {
   1853 		prev = ssid;
   1854 		ssid = ssid->next;
   1855 		wpa_config_free_ssid(prev);
   1856 	}
   1857 
   1858 	cred = config->cred;
   1859 	while (cred) {
   1860 		cprev = cred;
   1861 		cred = cred->next;
   1862 		wpa_config_free_cred(cprev);
   1863 	}
   1864 
   1865 #ifndef CONFIG_NO_CONFIG_BLOBS
   1866 	blob = config->blobs;
   1867 	prevblob = NULL;
   1868 	while (blob) {
   1869 		prevblob = blob;
   1870 		blob = blob->next;
   1871 		wpa_config_free_blob(prevblob);
   1872 	}
   1873 #endif /* CONFIG_NO_CONFIG_BLOBS */
   1874 
   1875 	wpabuf_free(config->wps_vendor_ext_m1);
   1876 	os_free(config->ctrl_interface);
   1877 	os_free(config->ctrl_interface_group);
   1878 	os_free(config->opensc_engine_path);
   1879 	os_free(config->pkcs11_engine_path);
   1880 	os_free(config->pkcs11_module_path);
   1881 	os_free(config->pcsc_reader);
   1882 	os_free(config->pcsc_pin);
   1883 	os_free(config->driver_param);
   1884 	os_free(config->device_name);
   1885 	os_free(config->manufacturer);
   1886 	os_free(config->model_name);
   1887 	os_free(config->model_number);
   1888 	os_free(config->serial_number);
   1889 	os_free(config->config_methods);
   1890 	os_free(config->p2p_ssid_postfix);
   1891 	os_free(config->pssid);
   1892 	os_free(config->p2p_pref_chan);
   1893 	os_free(config->autoscan);
   1894 	wpabuf_free(config->wps_nfc_dh_pubkey);
   1895 	wpabuf_free(config->wps_nfc_dh_privkey);
   1896 	wpabuf_free(config->wps_nfc_dev_pw);
   1897 	os_free(config->ext_password_backend);
   1898 	os_free(config);
   1899 }
   1900 
   1901 
   1902 /**
   1903  * wpa_config_foreach_network - Iterate over each configured network
   1904  * @config: Configuration data from wpa_config_read()
   1905  * @func: Callback function to process each network
   1906  * @arg: Opaque argument to pass to callback function
   1907  *
   1908  * Iterate over the set of configured networks calling the specified
   1909  * function for each item. We guard against callbacks removing the
   1910  * supplied network.
   1911  */
   1912 void wpa_config_foreach_network(struct wpa_config *config,
   1913 				void (*func)(void *, struct wpa_ssid *),
   1914 				void *arg)
   1915 {
   1916 	struct wpa_ssid *ssid, *next;
   1917 
   1918 	ssid = config->ssid;
   1919 	while (ssid) {
   1920 		next = ssid->next;
   1921 		func(arg, ssid);
   1922 		ssid = next;
   1923 	}
   1924 }
   1925 
   1926 
   1927 /**
   1928  * wpa_config_get_network - Get configured network based on id
   1929  * @config: Configuration data from wpa_config_read()
   1930  * @id: Unique network id to search for
   1931  * Returns: Network configuration or %NULL if not found
   1932  */
   1933 struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id)
   1934 {
   1935 	struct wpa_ssid *ssid;
   1936 
   1937 	ssid = config->ssid;
   1938 	while (ssid) {
   1939 		if (id == ssid->id)
   1940 			break;
   1941 		ssid = ssid->next;
   1942 	}
   1943 
   1944 	return ssid;
   1945 }
   1946 
   1947 
   1948 /**
   1949  * wpa_config_add_network - Add a new network with empty configuration
   1950  * @config: Configuration data from wpa_config_read()
   1951  * Returns: The new network configuration or %NULL if operation failed
   1952  */
   1953 struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
   1954 {
   1955 	int id;
   1956 	struct wpa_ssid *ssid, *last = NULL;
   1957 
   1958 	id = -1;
   1959 	ssid = config->ssid;
   1960 	while (ssid) {
   1961 		if (ssid->id > id)
   1962 			id = ssid->id;
   1963 		last = ssid;
   1964 		ssid = ssid->next;
   1965 	}
   1966 	id++;
   1967 
   1968 	ssid = os_zalloc(sizeof(*ssid));
   1969 	if (ssid == NULL)
   1970 		return NULL;
   1971 	ssid->id = id;
   1972 	if (last)
   1973 		last->next = ssid;
   1974 	else
   1975 		config->ssid = ssid;
   1976 
   1977 	wpa_config_update_prio_list(config);
   1978 
   1979 	return ssid;
   1980 }
   1981 
   1982 
   1983 /**
   1984  * wpa_config_remove_network - Remove a configured network based on id
   1985  * @config: Configuration data from wpa_config_read()
   1986  * @id: Unique network id to search for
   1987  * Returns: 0 on success, or -1 if the network was not found
   1988  */
   1989 int wpa_config_remove_network(struct wpa_config *config, int id)
   1990 {
   1991 	struct wpa_ssid *ssid, *prev = NULL;
   1992 
   1993 	ssid = config->ssid;
   1994 	while (ssid) {
   1995 		if (id == ssid->id)
   1996 			break;
   1997 		prev = ssid;
   1998 		ssid = ssid->next;
   1999 	}
   2000 
   2001 	if (ssid == NULL)
   2002 		return -1;
   2003 
   2004 	if (prev)
   2005 		prev->next = ssid->next;
   2006 	else
   2007 		config->ssid = ssid->next;
   2008 
   2009 	wpa_config_update_prio_list(config);
   2010 	wpa_config_free_ssid(ssid);
   2011 	return 0;
   2012 }
   2013 
   2014 
   2015 /**
   2016  * wpa_config_set_network_defaults - Set network default values
   2017  * @ssid: Pointer to network configuration data
   2018  */
   2019 void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
   2020 {
   2021 	ssid->proto = DEFAULT_PROTO;
   2022 	ssid->pairwise_cipher = DEFAULT_PAIRWISE;
   2023 	ssid->group_cipher = DEFAULT_GROUP;
   2024 	ssid->key_mgmt = DEFAULT_KEY_MGMT;
   2025 	ssid->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
   2026 #ifdef IEEE8021X_EAPOL
   2027 	ssid->eapol_flags = DEFAULT_EAPOL_FLAGS;
   2028 	ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
   2029 	ssid->eap.fragment_size = DEFAULT_FRAGMENT_SIZE;
   2030 #endif /* IEEE8021X_EAPOL */
   2031 #ifdef CONFIG_HT_OVERRIDES
   2032 	ssid->disable_ht = DEFAULT_DISABLE_HT;
   2033 	ssid->disable_ht40 = DEFAULT_DISABLE_HT40;
   2034 	ssid->disable_max_amsdu = DEFAULT_DISABLE_MAX_AMSDU;
   2035 	ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR;
   2036 	ssid->ampdu_density = DEFAULT_AMPDU_DENSITY;
   2037 #endif /* CONFIG_HT_OVERRIDES */
   2038 }
   2039 
   2040 
   2041 /**
   2042  * wpa_config_set - Set a variable in network configuration
   2043  * @ssid: Pointer to network configuration data
   2044  * @var: Variable name, e.g., "ssid"
   2045  * @value: Variable value
   2046  * @line: Line number in configuration file or 0 if not used
   2047  * Returns: 0 on success, -1 on failure
   2048  *
   2049  * This function can be used to set network configuration variables based on
   2050  * both the configuration file and management interface input. The value
   2051  * parameter must be in the same format as the text-based configuration file is
   2052  * using. For example, strings are using double quotation marks.
   2053  */
   2054 int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
   2055 		   int line)
   2056 {
   2057 	size_t i;
   2058 	int ret = 0;
   2059 
   2060 	if (ssid == NULL || var == NULL || value == NULL)
   2061 		return -1;
   2062 
   2063 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
   2064 		const struct parse_data *field = &ssid_fields[i];
   2065 		if (os_strcmp(var, field->name) != 0)
   2066 			continue;
   2067 
   2068 		if (field->parser(field, ssid, line, value)) {
   2069 			if (line) {
   2070 				wpa_printf(MSG_ERROR, "Line %d: failed to "
   2071 					   "parse %s '%s'.", line, var, value);
   2072 			}
   2073 			ret = -1;
   2074 		}
   2075 		break;
   2076 	}
   2077 	if (i == NUM_SSID_FIELDS) {
   2078 		if (line) {
   2079 			wpa_printf(MSG_ERROR, "Line %d: unknown network field "
   2080 				   "'%s'.", line, var);
   2081 		}
   2082 		ret = -1;
   2083 	}
   2084 
   2085 	return ret;
   2086 }
   2087 
   2088 
   2089 int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
   2090 			  const char *value)
   2091 {
   2092 	size_t len;
   2093 	char *buf;
   2094 	int ret;
   2095 
   2096 	len = os_strlen(value);
   2097 	buf = os_malloc(len + 3);
   2098 	if (buf == NULL)
   2099 		return -1;
   2100 	buf[0] = '"';
   2101 	os_memcpy(buf + 1, value, len);
   2102 	buf[len + 1] = '"';
   2103 	buf[len + 2] = '\0';
   2104 	ret = wpa_config_set(ssid, var, buf, 0);
   2105 	os_free(buf);
   2106 	return ret;
   2107 }
   2108 
   2109 
   2110 /**
   2111  * wpa_config_get_all - Get all options from network configuration
   2112  * @ssid: Pointer to network configuration data
   2113  * @get_keys: Determines if keys/passwords will be included in returned list
   2114  *	(if they may be exported)
   2115  * Returns: %NULL terminated list of all set keys and their values in the form
   2116  * of [key1, val1, key2, val2, ... , NULL]
   2117  *
   2118  * This function can be used to get list of all configured network properties.
   2119  * The caller is responsible for freeing the returned list and all its
   2120  * elements.
   2121  */
   2122 char ** wpa_config_get_all(struct wpa_ssid *ssid, int get_keys)
   2123 {
   2124 	const struct parse_data *field;
   2125 	char *key, *value;
   2126 	size_t i;
   2127 	char **props;
   2128 	int fields_num;
   2129 
   2130 	get_keys = get_keys && ssid->export_keys;
   2131 
   2132 	props = os_calloc(2 * NUM_SSID_FIELDS + 1, sizeof(char *));
   2133 	if (!props)
   2134 		return NULL;
   2135 
   2136 	fields_num = 0;
   2137 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
   2138 		field = &ssid_fields[i];
   2139 		if (field->key_data && !get_keys)
   2140 			continue;
   2141 		value = field->writer(field, ssid);
   2142 		if (value == NULL)
   2143 			continue;
   2144 		if (os_strlen(value) == 0) {
   2145 			os_free(value);
   2146 			continue;
   2147 		}
   2148 
   2149 		key = os_strdup(field->name);
   2150 		if (key == NULL) {
   2151 			os_free(value);
   2152 			goto err;
   2153 		}
   2154 
   2155 		props[fields_num * 2] = key;
   2156 		props[fields_num * 2 + 1] = value;
   2157 
   2158 		fields_num++;
   2159 	}
   2160 
   2161 	return props;
   2162 
   2163 err:
   2164 	value = *props;
   2165 	while (value)
   2166 		os_free(value++);
   2167 	os_free(props);
   2168 	return NULL;
   2169 }
   2170 
   2171 
   2172 #ifndef NO_CONFIG_WRITE
   2173 /**
   2174  * wpa_config_get - Get a variable in network configuration
   2175  * @ssid: Pointer to network configuration data
   2176  * @var: Variable name, e.g., "ssid"
   2177  * Returns: Value of the variable or %NULL on failure
   2178  *
   2179  * This function can be used to get network configuration variables. The
   2180  * returned value is a copy of the configuration variable in text format, i.e,.
   2181  * the same format that the text-based configuration file and wpa_config_set()
   2182  * are using for the value. The caller is responsible for freeing the returned
   2183  * value.
   2184  */
   2185 char * wpa_config_get(struct wpa_ssid *ssid, const char *var)
   2186 {
   2187 	size_t i;
   2188 
   2189 	if (ssid == NULL || var == NULL)
   2190 		return NULL;
   2191 
   2192 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
   2193 		const struct parse_data *field = &ssid_fields[i];
   2194 		if (os_strcmp(var, field->name) == 0)
   2195 			return field->writer(field, ssid);
   2196 	}
   2197 
   2198 	return NULL;
   2199 }
   2200 
   2201 
   2202 /**
   2203  * wpa_config_get_no_key - Get a variable in network configuration (no keys)
   2204  * @ssid: Pointer to network configuration data
   2205  * @var: Variable name, e.g., "ssid"
   2206  * Returns: Value of the variable or %NULL on failure
   2207  *
   2208  * This function can be used to get network configuration variable like
   2209  * wpa_config_get(). The only difference is that this functions does not expose
   2210  * key/password material from the configuration. In case a key/password field
   2211  * is requested, the returned value is an empty string or %NULL if the variable
   2212  * is not set or "*" if the variable is set (regardless of its value). The
   2213  * returned value is a copy of the configuration variable in text format, i.e,.
   2214  * the same format that the text-based configuration file and wpa_config_set()
   2215  * are using for the value. The caller is responsible for freeing the returned
   2216  * value.
   2217  */
   2218 char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var)
   2219 {
   2220 	size_t i;
   2221 
   2222 	if (ssid == NULL || var == NULL)
   2223 		return NULL;
   2224 
   2225 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
   2226 		const struct parse_data *field = &ssid_fields[i];
   2227 		if (os_strcmp(var, field->name) == 0) {
   2228 			char *res = field->writer(field, ssid);
   2229 			if (field->key_data) {
   2230 				if (res && res[0]) {
   2231 					wpa_printf(MSG_DEBUG, "Do not allow "
   2232 						   "key_data field to be "
   2233 						   "exposed");
   2234 					os_free(res);
   2235 					return os_strdup("*");
   2236 				}
   2237 
   2238 				os_free(res);
   2239 				return NULL;
   2240 			}
   2241 			return res;
   2242 		}
   2243 	}
   2244 
   2245 	return NULL;
   2246 }
   2247 #endif /* NO_CONFIG_WRITE */
   2248 
   2249 
   2250 /**
   2251  * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
   2252  * @ssid: Pointer to network configuration data
   2253  *
   2254  * This function must be called to update WPA PSK when either SSID or the
   2255  * passphrase has changed for the network configuration.
   2256  */
   2257 void wpa_config_update_psk(struct wpa_ssid *ssid)
   2258 {
   2259 #ifndef CONFIG_NO_PBKDF2
   2260 	pbkdf2_sha1(ssid->passphrase, ssid->ssid, ssid->ssid_len, 4096,
   2261 		    ssid->psk, PMK_LEN);
   2262 	wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
   2263 			ssid->psk, PMK_LEN);
   2264 	ssid->psk_set = 1;
   2265 #endif /* CONFIG_NO_PBKDF2 */
   2266 }
   2267 
   2268 
   2269 int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
   2270 			const char *value, int line)
   2271 {
   2272 	char *val;
   2273 	size_t len;
   2274 
   2275 	if (os_strcmp(var, "priority") == 0) {
   2276 		cred->priority = atoi(value);
   2277 		return 0;
   2278 	}
   2279 
   2280 	if (os_strcmp(var, "pcsc") == 0) {
   2281 		cred->pcsc = atoi(value);
   2282 		return 0;
   2283 	}
   2284 
   2285 	if (os_strcmp(var, "eap") == 0) {
   2286 		struct eap_method_type method;
   2287 		method.method = eap_peer_get_type(value, &method.vendor);
   2288 		if (method.vendor == EAP_VENDOR_IETF &&
   2289 		    method.method == EAP_TYPE_NONE) {
   2290 			wpa_printf(MSG_ERROR, "Line %d: unknown EAP type '%s' "
   2291 				   "for a credential", line, value);
   2292 			return -1;
   2293 		}
   2294 		os_free(cred->eap_method);
   2295 		cred->eap_method = os_malloc(sizeof(*cred->eap_method));
   2296 		if (cred->eap_method == NULL)
   2297 			return -1;
   2298 		os_memcpy(cred->eap_method, &method, sizeof(method));
   2299 		return 0;
   2300 	}
   2301 
   2302 	if (os_strcmp(var, "password") == 0 &&
   2303 	    os_strncmp(value, "ext:", 4) == 0) {
   2304 		os_free(cred->password);
   2305 		cred->password = os_strdup(value);
   2306 		cred->ext_password = 1;
   2307 		return 0;
   2308 	}
   2309 
   2310 	val = wpa_config_parse_string(value, &len);
   2311 	if (val == NULL) {
   2312 		wpa_printf(MSG_ERROR, "Line %d: invalid field '%s' string "
   2313 			   "value '%s'.", line, var, value);
   2314 		return -1;
   2315 	}
   2316 
   2317 	if (os_strcmp(var, "realm") == 0) {
   2318 		os_free(cred->realm);
   2319 		cred->realm = val;
   2320 		return 0;
   2321 	}
   2322 
   2323 	if (os_strcmp(var, "username") == 0) {
   2324 		os_free(cred->username);
   2325 		cred->username = val;
   2326 		return 0;
   2327 	}
   2328 
   2329 	if (os_strcmp(var, "password") == 0) {
   2330 		os_free(cred->password);
   2331 		cred->password = val;
   2332 		cred->ext_password = 0;
   2333 		return 0;
   2334 	}
   2335 
   2336 	if (os_strcmp(var, "ca_cert") == 0) {
   2337 		os_free(cred->ca_cert);
   2338 		cred->ca_cert = val;
   2339 		return 0;
   2340 	}
   2341 
   2342 	if (os_strcmp(var, "client_cert") == 0) {
   2343 		os_free(cred->client_cert);
   2344 		cred->client_cert = val;
   2345 		return 0;
   2346 	}
   2347 
   2348 	if (os_strcmp(var, "private_key") == 0) {
   2349 		os_free(cred->private_key);
   2350 		cred->private_key = val;
   2351 		return 0;
   2352 	}
   2353 
   2354 	if (os_strcmp(var, "private_key_passwd") == 0) {
   2355 		os_free(cred->private_key_passwd);
   2356 		cred->private_key_passwd = val;
   2357 		return 0;
   2358 	}
   2359 
   2360 	if (os_strcmp(var, "imsi") == 0) {
   2361 		os_free(cred->imsi);
   2362 		cred->imsi = val;
   2363 		return 0;
   2364 	}
   2365 
   2366 	if (os_strcmp(var, "milenage") == 0) {
   2367 		os_free(cred->milenage);
   2368 		cred->milenage = val;
   2369 		return 0;
   2370 	}
   2371 
   2372 	if (os_strcmp(var, "domain") == 0) {
   2373 		os_free(cred->domain);
   2374 		cred->domain = val;
   2375 		return 0;
   2376 	}
   2377 
   2378 	if (os_strcmp(var, "phase1") == 0) {
   2379 		os_free(cred->phase1);
   2380 		cred->phase1 = val;
   2381 		return 0;
   2382 	}
   2383 
   2384 	if (os_strcmp(var, "phase2") == 0) {
   2385 		os_free(cred->phase2);
   2386 		cred->phase2 = val;
   2387 		return 0;
   2388 	}
   2389 
   2390 	if (os_strcmp(var, "roaming_consortium") == 0) {
   2391 		if (len < 3 || len > sizeof(cred->roaming_consortium)) {
   2392 			wpa_printf(MSG_ERROR, "Line %d: invalid "
   2393 				   "roaming_consortium length %d (3..15 "
   2394 				   "expected)", line, (int) len);
   2395 			os_free(val);
   2396 			return -1;
   2397 		}
   2398 		os_memcpy(cred->roaming_consortium, val, len);
   2399 		cred->roaming_consortium_len = len;
   2400 		os_free(val);
   2401 		return 0;
   2402 	}
   2403 
   2404 	if (line) {
   2405 		wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
   2406 			   line, var);
   2407 	}
   2408 
   2409 	os_free(val);
   2410 
   2411 	return -1;
   2412 }
   2413 
   2414 
   2415 struct wpa_cred * wpa_config_get_cred(struct wpa_config *config, int id)
   2416 {
   2417 	struct wpa_cred *cred;
   2418 
   2419 	cred = config->cred;
   2420 	while (cred) {
   2421 		if (id == cred->id)
   2422 			break;
   2423 		cred = cred->next;
   2424 	}
   2425 
   2426 	return cred;
   2427 }
   2428 
   2429 
   2430 struct wpa_cred * wpa_config_add_cred(struct wpa_config *config)
   2431 {
   2432 	int id;
   2433 	struct wpa_cred *cred, *last = NULL;
   2434 
   2435 	id = -1;
   2436 	cred = config->cred;
   2437 	while (cred) {
   2438 		if (cred->id > id)
   2439 			id = cred->id;
   2440 		last = cred;
   2441 		cred = cred->next;
   2442 	}
   2443 	id++;
   2444 
   2445 	cred = os_zalloc(sizeof(*cred));
   2446 	if (cred == NULL)
   2447 		return NULL;
   2448 	cred->id = id;
   2449 	if (last)
   2450 		last->next = cred;
   2451 	else
   2452 		config->cred = cred;
   2453 
   2454 	return cred;
   2455 }
   2456 
   2457 
   2458 int wpa_config_remove_cred(struct wpa_config *config, int id)
   2459 {
   2460 	struct wpa_cred *cred, *prev = NULL;
   2461 
   2462 	cred = config->cred;
   2463 	while (cred) {
   2464 		if (id == cred->id)
   2465 			break;
   2466 		prev = cred;
   2467 		cred = cred->next;
   2468 	}
   2469 
   2470 	if (cred == NULL)
   2471 		return -1;
   2472 
   2473 	if (prev)
   2474 		prev->next = cred->next;
   2475 	else
   2476 		config->cred = cred->next;
   2477 
   2478 	wpa_config_free_cred(cred);
   2479 	return 0;
   2480 }
   2481 
   2482 
   2483 #ifndef CONFIG_NO_CONFIG_BLOBS
   2484 /**
   2485  * wpa_config_get_blob - Get a named configuration blob
   2486  * @config: Configuration data from wpa_config_read()
   2487  * @name: Name of the blob
   2488  * Returns: Pointer to blob data or %NULL if not found
   2489  */
   2490 const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
   2491 						   const char *name)
   2492 {
   2493 	struct wpa_config_blob *blob = config->blobs;
   2494 
   2495 	while (blob) {
   2496 		if (os_strcmp(blob->name, name) == 0)
   2497 			return blob;
   2498 		blob = blob->next;
   2499 	}
   2500 	return NULL;
   2501 }
   2502 
   2503 
   2504 /**
   2505  * wpa_config_set_blob - Set or add a named configuration blob
   2506  * @config: Configuration data from wpa_config_read()
   2507  * @blob: New value for the blob
   2508  *
   2509  * Adds a new configuration blob or replaces the current value of an existing
   2510  * blob.
   2511  */
   2512 void wpa_config_set_blob(struct wpa_config *config,
   2513 			 struct wpa_config_blob *blob)
   2514 {
   2515 	wpa_config_remove_blob(config, blob->name);
   2516 	blob->next = config->blobs;
   2517 	config->blobs = blob;
   2518 }
   2519 
   2520 
   2521 /**
   2522  * wpa_config_free_blob - Free blob data
   2523  * @blob: Pointer to blob to be freed
   2524  */
   2525 void wpa_config_free_blob(struct wpa_config_blob *blob)
   2526 {
   2527 	if (blob) {
   2528 		os_free(blob->name);
   2529 		os_free(blob->data);
   2530 		os_free(blob);
   2531 	}
   2532 }
   2533 
   2534 
   2535 /**
   2536  * wpa_config_remove_blob - Remove a named configuration blob
   2537  * @config: Configuration data from wpa_config_read()
   2538  * @name: Name of the blob to remove
   2539  * Returns: 0 if blob was removed or -1 if blob was not found
   2540  */
   2541 int wpa_config_remove_blob(struct wpa_config *config, const char *name)
   2542 {
   2543 	struct wpa_config_blob *pos = config->blobs, *prev = NULL;
   2544 
   2545 	while (pos) {
   2546 		if (os_strcmp(pos->name, name) == 0) {
   2547 			if (prev)
   2548 				prev->next = pos->next;
   2549 			else
   2550 				config->blobs = pos->next;
   2551 			wpa_config_free_blob(pos);
   2552 			return 0;
   2553 		}
   2554 		prev = pos;
   2555 		pos = pos->next;
   2556 	}
   2557 
   2558 	return -1;
   2559 }
   2560 #endif /* CONFIG_NO_CONFIG_BLOBS */
   2561 
   2562 
   2563 /**
   2564  * wpa_config_alloc_empty - Allocate an empty configuration
   2565  * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
   2566  * socket
   2567  * @driver_param: Driver parameters
   2568  * Returns: Pointer to allocated configuration data or %NULL on failure
   2569  */
   2570 struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
   2571 					   const char *driver_param)
   2572 {
   2573 	struct wpa_config *config;
   2574 	const int aCWmin = 4, aCWmax = 10;
   2575 	const struct hostapd_wmm_ac_params ac_bk =
   2576 		{ aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
   2577 	const struct hostapd_wmm_ac_params ac_be =
   2578 		{ aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
   2579 	const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
   2580 		{ aCWmin - 1, aCWmin, 2, 3000 / 32, 0 };
   2581 	const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
   2582 		{ aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 0 };
   2583 
   2584 	config = os_zalloc(sizeof(*config));
   2585 	if (config == NULL)
   2586 		return NULL;
   2587 	config->eapol_version = DEFAULT_EAPOL_VERSION;
   2588 	config->ap_scan = DEFAULT_AP_SCAN;
   2589 	config->fast_reauth = DEFAULT_FAST_REAUTH;
   2590 	config->p2p_go_intent = DEFAULT_P2P_GO_INTENT;
   2591 	config->p2p_intra_bss = DEFAULT_P2P_INTRA_BSS;
   2592 	config->p2p_go_max_inactivity = DEFAULT_P2P_GO_MAX_INACTIVITY;
   2593 	config->bss_max_count = DEFAULT_BSS_MAX_COUNT;
   2594 	config->bss_expiration_age = DEFAULT_BSS_EXPIRATION_AGE;
   2595 	config->bss_expiration_scan_count = DEFAULT_BSS_EXPIRATION_SCAN_COUNT;
   2596 	config->max_num_sta = DEFAULT_MAX_NUM_STA;
   2597 	config->access_network_type = DEFAULT_ACCESS_NETWORK_TYPE;
   2598 	config->wmm_ac_params[0] = ac_be;
   2599 	config->wmm_ac_params[1] = ac_bk;
   2600 	config->wmm_ac_params[2] = ac_vi;
   2601 	config->wmm_ac_params[3] = ac_vo;
   2602 
   2603 	if (ctrl_interface)
   2604 		config->ctrl_interface = os_strdup(ctrl_interface);
   2605 	if (driver_param)
   2606 		config->driver_param = os_strdup(driver_param);
   2607 
   2608 	return config;
   2609 }
   2610 
   2611 
   2612 #ifndef CONFIG_NO_STDOUT_DEBUG
   2613 /**
   2614  * wpa_config_debug_dump_networks - Debug dump of configured networks
   2615  * @config: Configuration data from wpa_config_read()
   2616  */
   2617 void wpa_config_debug_dump_networks(struct wpa_config *config)
   2618 {
   2619 	int prio;
   2620 	struct wpa_ssid *ssid;
   2621 
   2622 	for (prio = 0; prio < config->num_prio; prio++) {
   2623 		ssid = config->pssid[prio];
   2624 		wpa_printf(MSG_DEBUG, "Priority group %d",
   2625 			   ssid->priority);
   2626 		while (ssid) {
   2627 			wpa_printf(MSG_DEBUG, "   id=%d ssid='%s'",
   2628 				   ssid->id,
   2629 				   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
   2630 			ssid = ssid->pnext;
   2631 		}
   2632 	}
   2633 }
   2634 #endif /* CONFIG_NO_STDOUT_DEBUG */
   2635 
   2636 
   2637 struct global_parse_data {
   2638 	char *name;
   2639 	int (*parser)(const struct global_parse_data *data,
   2640 		      struct wpa_config *config, int line, const char *value);
   2641 	void *param1, *param2, *param3;
   2642 	unsigned int changed_flag;
   2643 };
   2644 
   2645 
   2646 static int wpa_global_config_parse_int(const struct global_parse_data *data,
   2647 				       struct wpa_config *config, int line,
   2648 				       const char *pos)
   2649 {
   2650 	int *dst;
   2651 	dst = (int *) (((u8 *) config) + (long) data->param1);
   2652 	*dst = atoi(pos);
   2653 	wpa_printf(MSG_DEBUG, "%s=%d", data->name, *dst);
   2654 
   2655 	if (data->param2 && *dst < (long) data->param2) {
   2656 		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
   2657 			   "min_value=%ld)", line, data->name, *dst,
   2658 			   (long) data->param2);
   2659 		*dst = (long) data->param2;
   2660 		return -1;
   2661 	}
   2662 
   2663 	if (data->param3 && *dst > (long) data->param3) {
   2664 		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
   2665 			   "max_value=%ld)", line, data->name, *dst,
   2666 			   (long) data->param3);
   2667 		*dst = (long) data->param3;
   2668 		return -1;
   2669 	}
   2670 
   2671 	return 0;
   2672 }
   2673 
   2674 
   2675 static int wpa_global_config_parse_str(const struct global_parse_data *data,
   2676 				       struct wpa_config *config, int line,
   2677 				       const char *pos)
   2678 {
   2679 	size_t len;
   2680 	char **dst, *tmp;
   2681 
   2682 	len = os_strlen(pos);
   2683 	if (data->param2 && len < (size_t) data->param2) {
   2684 		wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
   2685 			   "min_len=%ld)", line, data->name,
   2686 			   (unsigned long) len, (long) data->param2);
   2687 		return -1;
   2688 	}
   2689 
   2690 	if (data->param3 && len > (size_t) data->param3) {
   2691 		wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
   2692 			   "max_len=%ld)", line, data->name,
   2693 			   (unsigned long) len, (long) data->param3);
   2694 		return -1;
   2695 	}
   2696 
   2697 	tmp = os_strdup(pos);
   2698 	if (tmp == NULL)
   2699 		return -1;
   2700 
   2701 	dst = (char **) (((u8 *) config) + (long) data->param1);
   2702 	os_free(*dst);
   2703 	*dst = tmp;
   2704 	wpa_printf(MSG_DEBUG, "%s='%s'", data->name, *dst);
   2705 
   2706 	return 0;
   2707 }
   2708 
   2709 
   2710 static int wpa_global_config_parse_bin(const struct global_parse_data *data,
   2711 				       struct wpa_config *config, int line,
   2712 				       const char *pos)
   2713 {
   2714 	size_t len;
   2715 	struct wpabuf **dst, *tmp;
   2716 
   2717 	len = os_strlen(pos);
   2718 	if (len & 0x01)
   2719 		return -1;
   2720 
   2721 	tmp = wpabuf_alloc(len / 2);
   2722 	if (tmp == NULL)
   2723 		return -1;
   2724 
   2725 	if (hexstr2bin(pos, wpabuf_put(tmp, len / 2), len / 2)) {
   2726 		wpabuf_free(tmp);
   2727 		return -1;
   2728 	}
   2729 
   2730 	dst = (struct wpabuf **) (((u8 *) config) + (long) data->param1);
   2731 	wpabuf_free(*dst);
   2732 	*dst = tmp;
   2733 	wpa_printf(MSG_DEBUG, "%s", data->name);
   2734 
   2735 	return 0;
   2736 }
   2737 
   2738 
   2739 static int wpa_config_process_country(const struct global_parse_data *data,
   2740 				      struct wpa_config *config, int line,
   2741 				      const char *pos)
   2742 {
   2743 	if (!pos[0] || !pos[1]) {
   2744 		wpa_printf(MSG_DEBUG, "Invalid country set");
   2745 		return -1;
   2746 	}
   2747 	config->country[0] = pos[0];
   2748 	config->country[1] = pos[1];
   2749 	wpa_printf(MSG_DEBUG, "country='%c%c'",
   2750 		   config->country[0], config->country[1]);
   2751 	return 0;
   2752 }
   2753 
   2754 
   2755 static int wpa_config_process_load_dynamic_eap(
   2756 	const struct global_parse_data *data, struct wpa_config *config,
   2757 	int line, const char *so)
   2758 {
   2759 	int ret;
   2760 	wpa_printf(MSG_DEBUG, "load_dynamic_eap=%s", so);
   2761 	ret = eap_peer_method_load(so);
   2762 	if (ret == -2) {
   2763 		wpa_printf(MSG_DEBUG, "This EAP type was already loaded - not "
   2764 			   "reloading.");
   2765 	} else if (ret) {
   2766 		wpa_printf(MSG_ERROR, "Line %d: Failed to load dynamic EAP "
   2767 			   "method '%s'.", line, so);
   2768 		return -1;
   2769 	}
   2770 
   2771 	return 0;
   2772 }
   2773 
   2774 
   2775 #ifdef CONFIG_WPS
   2776 
   2777 static int wpa_config_process_uuid(const struct global_parse_data *data,
   2778 				   struct wpa_config *config, int line,
   2779 				   const char *pos)
   2780 {
   2781 	char buf[40];
   2782 	if (uuid_str2bin(pos, config->uuid)) {
   2783 		wpa_printf(MSG_ERROR, "Line %d: invalid UUID", line);
   2784 		return -1;
   2785 	}
   2786 	uuid_bin2str(config->uuid, buf, sizeof(buf));
   2787 	wpa_printf(MSG_DEBUG, "uuid=%s", buf);
   2788 	return 0;
   2789 }
   2790 
   2791 
   2792 static int wpa_config_process_device_type(
   2793 	const struct global_parse_data *data,
   2794 	struct wpa_config *config, int line, const char *pos)
   2795 {
   2796 	return wps_dev_type_str2bin(pos, config->device_type);
   2797 }
   2798 
   2799 
   2800 static int wpa_config_process_os_version(const struct global_parse_data *data,
   2801 					 struct wpa_config *config, int line,
   2802 					 const char *pos)
   2803 {
   2804 	if (hexstr2bin(pos, config->os_version, 4)) {
   2805 		wpa_printf(MSG_ERROR, "Line %d: invalid os_version", line);
   2806 		return -1;
   2807 	}
   2808 	wpa_printf(MSG_DEBUG, "os_version=%08x",
   2809 		   WPA_GET_BE32(config->os_version));
   2810 	return 0;
   2811 }
   2812 
   2813 
   2814 static int wpa_config_process_wps_vendor_ext_m1(
   2815 	const struct global_parse_data *data,
   2816 	struct wpa_config *config, int line, const char *pos)
   2817 {
   2818 	struct wpabuf *tmp;
   2819 	int len = os_strlen(pos) / 2;
   2820 	u8 *p;
   2821 
   2822 	if (!len) {
   2823 		wpa_printf(MSG_ERROR, "Line %d: "
   2824 			   "invalid wps_vendor_ext_m1", line);
   2825 		return -1;
   2826 	}
   2827 
   2828 	tmp = wpabuf_alloc(len);
   2829 	if (tmp) {
   2830 		p = wpabuf_put(tmp, len);
   2831 
   2832 		if (hexstr2bin(pos, p, len)) {
   2833 			wpa_printf(MSG_ERROR, "Line %d: "
   2834 				   "invalid wps_vendor_ext_m1", line);
   2835 			wpabuf_free(tmp);
   2836 			return -1;
   2837 		}
   2838 
   2839 		wpabuf_free(config->wps_vendor_ext_m1);
   2840 		config->wps_vendor_ext_m1 = tmp;
   2841 	} else {
   2842 		wpa_printf(MSG_ERROR, "Can not allocate "
   2843 			   "memory for wps_vendor_ext_m1");
   2844 		return -1;
   2845 	}
   2846 
   2847 	return 0;
   2848 }
   2849 
   2850 #endif /* CONFIG_WPS */
   2851 
   2852 #ifdef CONFIG_P2P
   2853 static int wpa_config_process_sec_device_type(
   2854 	const struct global_parse_data *data,
   2855 	struct wpa_config *config, int line, const char *pos)
   2856 {
   2857 	int idx;
   2858 
   2859 	if (config->num_sec_device_types >= MAX_SEC_DEVICE_TYPES) {
   2860 		wpa_printf(MSG_ERROR, "Line %d: too many sec_device_type "
   2861 			   "items", line);
   2862 		return -1;
   2863 	}
   2864 
   2865 	idx = config->num_sec_device_types;
   2866 
   2867 	if (wps_dev_type_str2bin(pos, config->sec_device_type[idx]))
   2868 		return -1;
   2869 
   2870 	config->num_sec_device_types++;
   2871 	return 0;
   2872 }
   2873 
   2874 
   2875 static int wpa_config_process_p2p_pref_chan(
   2876 	const struct global_parse_data *data,
   2877 	struct wpa_config *config, int line, const char *pos)
   2878 {
   2879 	struct p2p_channel *pref = NULL, *n;
   2880 	unsigned int num = 0;
   2881 	const char *pos2;
   2882 	u8 op_class, chan;
   2883 
   2884 	/* format: class:chan,class:chan,... */
   2885 
   2886 	while (*pos) {
   2887 		op_class = atoi(pos);
   2888 		pos2 = os_strchr(pos, ':');
   2889 		if (pos2 == NULL)
   2890 			goto fail;
   2891 		pos2++;
   2892 		chan = atoi(pos2);
   2893 
   2894 		n = os_realloc_array(pref, num + 1,
   2895 				     sizeof(struct p2p_channel));
   2896 		if (n == NULL)
   2897 			goto fail;
   2898 		pref = n;
   2899 		pref[num].op_class = op_class;
   2900 		pref[num].chan = chan;
   2901 		num++;
   2902 
   2903 		pos = os_strchr(pos2, ',');
   2904 		if (pos == NULL)
   2905 			break;
   2906 		pos++;
   2907 	}
   2908 
   2909 	os_free(config->p2p_pref_chan);
   2910 	config->p2p_pref_chan = pref;
   2911 	config->num_p2p_pref_chan = num;
   2912 	wpa_hexdump(MSG_DEBUG, "P2P: Preferred class/channel pairs",
   2913 		    (u8 *) config->p2p_pref_chan,
   2914 		    config->num_p2p_pref_chan * sizeof(struct p2p_channel));
   2915 
   2916 	return 0;
   2917 
   2918 fail:
   2919 	os_free(pref);
   2920 	wpa_printf(MSG_ERROR, "Line %d: Invalid p2p_pref_chan list", line);
   2921 	return -1;
   2922 }
   2923 #endif /* CONFIG_P2P */
   2924 
   2925 
   2926 static int wpa_config_process_hessid(
   2927 	const struct global_parse_data *data,
   2928 	struct wpa_config *config, int line, const char *pos)
   2929 {
   2930 	if (hwaddr_aton2(pos, config->hessid) < 0) {
   2931 		wpa_printf(MSG_ERROR, "Line %d: Invalid hessid '%s'",
   2932 			   line, pos);
   2933 		return -1;
   2934 	}
   2935 
   2936 	return 0;
   2937 }
   2938 
   2939 
   2940 #ifdef OFFSET
   2941 #undef OFFSET
   2942 #endif /* OFFSET */
   2943 /* OFFSET: Get offset of a variable within the wpa_config structure */
   2944 #define OFFSET(v) ((void *) &((struct wpa_config *) 0)->v)
   2945 
   2946 #define FUNC(f) #f, wpa_config_process_ ## f, OFFSET(f), NULL, NULL
   2947 #define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL
   2948 #define _INT(f) #f, wpa_global_config_parse_int, OFFSET(f)
   2949 #define INT(f) _INT(f), NULL, NULL
   2950 #define INT_RANGE(f, min, max) _INT(f), (void *) min, (void *) max
   2951 #define _STR(f) #f, wpa_global_config_parse_str, OFFSET(f)
   2952 #define STR(f) _STR(f), NULL, NULL
   2953 #define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
   2954 #define BIN(f) #f, wpa_global_config_parse_bin, OFFSET(f), NULL, NULL
   2955 
   2956 static const struct global_parse_data global_fields[] = {
   2957 #ifdef CONFIG_CTRL_IFACE
   2958 	{ STR(ctrl_interface), 0 },
   2959 	{ STR(ctrl_interface_group), 0 } /* deprecated */,
   2960 #endif /* CONFIG_CTRL_IFACE */
   2961 	{ INT_RANGE(eapol_version, 1, 2), 0 },
   2962 	{ INT(ap_scan), 0 },
   2963 	{ INT(disable_scan_offload), 0 },
   2964 	{ INT(fast_reauth), 0 },
   2965 	{ STR(opensc_engine_path), 0 },
   2966 	{ STR(pkcs11_engine_path), 0 },
   2967 	{ STR(pkcs11_module_path), 0 },
   2968 	{ STR(pcsc_reader), 0 },
   2969 	{ STR(pcsc_pin), 0 },
   2970 	{ STR(driver_param), 0 },
   2971 	{ INT(dot11RSNAConfigPMKLifetime), 0 },
   2972 	{ INT(dot11RSNAConfigPMKReauthThreshold), 0 },
   2973 	{ INT(dot11RSNAConfigSATimeout), 0 },
   2974 #ifndef CONFIG_NO_CONFIG_WRITE
   2975 	{ INT(update_config), 0 },
   2976 #endif /* CONFIG_NO_CONFIG_WRITE */
   2977 	{ FUNC_NO_VAR(load_dynamic_eap), 0 },
   2978 #ifdef CONFIG_WPS
   2979 	{ FUNC(uuid), CFG_CHANGED_UUID },
   2980 	{ STR_RANGE(device_name, 0, 32), CFG_CHANGED_DEVICE_NAME },
   2981 	{ STR_RANGE(manufacturer, 0, 64), CFG_CHANGED_WPS_STRING },
   2982 	{ STR_RANGE(model_name, 0, 32), CFG_CHANGED_WPS_STRING },
   2983 	{ STR_RANGE(model_number, 0, 32), CFG_CHANGED_WPS_STRING },
   2984 	{ STR_RANGE(serial_number, 0, 32), CFG_CHANGED_WPS_STRING },
   2985 	{ FUNC(device_type), CFG_CHANGED_DEVICE_TYPE },
   2986 	{ FUNC(os_version), CFG_CHANGED_OS_VERSION },
   2987 	{ STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
   2988 	{ INT_RANGE(wps_cred_processing, 0, 2), 0 },
   2989 	{ FUNC(wps_vendor_ext_m1), CFG_CHANGED_VENDOR_EXTENSION },
   2990 #endif /* CONFIG_WPS */
   2991 #ifdef CONFIG_P2P
   2992 	{ FUNC(sec_device_type), CFG_CHANGED_SEC_DEVICE_TYPE },
   2993 	{ INT(p2p_listen_reg_class), 0 },
   2994 	{ INT(p2p_listen_channel), 0 },
   2995 	{ INT(p2p_oper_reg_class), 0 },
   2996 	{ INT(p2p_oper_channel), 0 },
   2997 	{ INT_RANGE(p2p_go_intent, 0, 15), 0 },
   2998 	{ STR(p2p_ssid_postfix), CFG_CHANGED_P2P_SSID_POSTFIX },
   2999 	{ INT_RANGE(persistent_reconnect, 0, 1), 0 },
   3000 	{ INT_RANGE(p2p_intra_bss, 0, 1), CFG_CHANGED_P2P_INTRA_BSS },
   3001 	{ INT(p2p_group_idle), 0 },
   3002 	{ FUNC(p2p_pref_chan), CFG_CHANGED_P2P_PREF_CHAN },
   3003 #endif /* CONFIG_P2P */
   3004 	{ FUNC(country), CFG_CHANGED_COUNTRY },
   3005 	{ INT(bss_max_count), 0 },
   3006 	{ INT(bss_expiration_age), 0 },
   3007 	{ INT(bss_expiration_scan_count), 0 },
   3008 	{ INT_RANGE(filter_ssids, 0, 1), 0 },
   3009 	{ INT_RANGE(filter_rssi, -100, 0), 0 },
   3010 	{ INT(max_num_sta), 0 },
   3011 	{ INT_RANGE(disassoc_low_ack, 0, 1), 0 },
   3012 #ifdef CONFIG_HS20
   3013 	{ INT_RANGE(hs20, 0, 1), 0 },
   3014 #endif /* CONFIG_HS20 */
   3015 	{ INT_RANGE(interworking, 0, 1), 0 },
   3016 	{ FUNC(hessid), 0 },
   3017 	{ INT_RANGE(access_network_type, 0, 15), 0 },
   3018 	{ INT_RANGE(pbc_in_m1, 0, 1), 0 },
   3019 	{ STR(autoscan), 0 },
   3020 	{ INT_RANGE(wps_nfc_dev_pw_id, 0x10, 0xffff), 0 },
   3021 	{ BIN(wps_nfc_dh_pubkey), 0 },
   3022 	{ BIN(wps_nfc_dh_privkey), 0 },
   3023 	{ BIN(wps_nfc_dev_pw), 0 },
   3024 	{ STR(ext_password_backend), CFG_CHANGED_EXT_PW_BACKEND },
   3025 	{ INT(p2p_go_max_inactivity), 0 },
   3026 	{ INT_RANGE(auto_interworking, 0, 1), 0 },
   3027 };
   3028 
   3029 #undef FUNC
   3030 #undef _INT
   3031 #undef INT
   3032 #undef INT_RANGE
   3033 #undef _STR
   3034 #undef STR
   3035 #undef STR_RANGE
   3036 #undef BIN
   3037 #define NUM_GLOBAL_FIELDS (sizeof(global_fields) / sizeof(global_fields[0]))
   3038 
   3039 
   3040 int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
   3041 {
   3042 	size_t i;
   3043 	int ret = 0;
   3044 
   3045 	for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
   3046 		const struct global_parse_data *field = &global_fields[i];
   3047 		size_t flen = os_strlen(field->name);
   3048 		if (os_strncmp(pos, field->name, flen) != 0 ||
   3049 		    pos[flen] != '=')
   3050 			continue;
   3051 
   3052 		if (field->parser(field, config, line, pos + flen + 1)) {
   3053 			wpa_printf(MSG_ERROR, "Line %d: failed to "
   3054 				   "parse '%s'.", line, pos);
   3055 			ret = -1;
   3056 		}
   3057 		config->changed_parameters |= field->changed_flag;
   3058 		break;
   3059 	}
   3060 	if (i == NUM_GLOBAL_FIELDS) {
   3061 #ifdef CONFIG_AP
   3062 		if (os_strncmp(pos, "wmm_ac_", 7) == 0) {
   3063 			char *tmp = os_strchr(pos, '=');
   3064 			if (tmp == NULL) {
   3065 				if (line < 0)
   3066 					return -1;
   3067 				wpa_printf(MSG_ERROR, "Line %d: invalid line "
   3068 					   "'%s'", line, pos);
   3069 				return -1;
   3070 			}
   3071 			*tmp++ = '\0';
   3072 			if (hostapd_config_wmm_ac(config->wmm_ac_params, pos,
   3073 						  tmp)) {
   3074 				wpa_printf(MSG_ERROR, "Line %d: invalid WMM "
   3075 					   "AC item", line);
   3076 				return -1;
   3077 			}
   3078 		}
   3079 #endif /* CONFIG_AP */
   3080 		if (line < 0)
   3081 			return -1;
   3082 		wpa_printf(MSG_ERROR, "Line %d: unknown global field '%s'.",
   3083 			   line, pos);
   3084 		ret = -1;
   3085 	}
   3086 
   3087 	return ret;
   3088 }
   3089