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