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