MFC: An off-by-one malloc size was corrupting the installer's memory,
[dragonfly.git] / contrib / wpa_supplicant-0.5.8 / config.c
blob171970dc210f8335cbdbe85879ecfc5b731d0cee
1 /*
2 * WPA Supplicant / Configuration parser and common functions
3 * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
12 * See README and COPYING for more details.
15 #include "includes.h"
17 #include "common.h"
18 #include "wpa.h"
19 #include "sha1.h"
20 #include "eapol_sm.h"
21 #include "eap.h"
22 #include "l2_packet.h"
23 #include "config.h"
27 * Structure for network configuration parsing. This data is used to implement
28 * a generic parser for each network block variable. The table of configuration
29 * variables is defined below in this file (ssid_fields[]).
31 struct parse_data {
32 /* Configuration variable name */
33 char *name;
35 /* Parser function for this variable */
36 int (*parser)(const struct parse_data *data, struct wpa_ssid *ssid,
37 int line, const char *value);
39 /* Writer function (i.e., to get the variable in text format from
40 * internal presentation). */
41 char * (*writer)(const struct parse_data *data, struct wpa_ssid *ssid);
43 /* Variable specific parameters for the parser. */
44 void *param1, *param2, *param3, *param4;
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.
52 int key_data;
56 static char * wpa_config_parse_string(const char *value, size_t *len)
58 if (*value == '"') {
59 char *pos;
60 value++;
61 pos = os_strrchr(value, '"');
62 if (pos == NULL || pos[1] != '\0')
63 return NULL;
64 *pos = '\0';
65 *len = os_strlen(value);
66 return os_strdup(value);
67 } else {
68 u8 *str;
69 size_t hlen = os_strlen(value);
70 if (hlen & 1)
71 return NULL;
72 *len = hlen / 2;
73 str = os_malloc(*len);
74 if (str == NULL)
75 return NULL;
76 if (hexstr2bin(value, str, *len)) {
77 os_free(str);
78 return NULL;
80 return (char *) str;
85 static int wpa_config_parse_str(const struct parse_data *data,
86 struct wpa_ssid *ssid,
87 int line, const char *value)
89 size_t res_len, *dst_len;
90 char **dst, *tmp;
92 tmp = wpa_config_parse_string(value, &res_len);
93 if (tmp == NULL) {
94 wpa_printf(MSG_ERROR, "Line %d: failed to parse %s '%s'.",
95 line, data->name,
96 data->key_data ? "[KEY DATA REMOVED]" : value);
97 return -1;
100 if (data->key_data) {
101 wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
102 (u8 *) tmp, res_len);
103 } else {
104 wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
105 (u8 *) tmp, res_len);
108 if (data->param3 && res_len < (size_t) data->param3) {
109 wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
110 "min_len=%ld)", line, data->name,
111 (unsigned long) res_len, (long) data->param3);
112 os_free(tmp);
113 return -1;
116 if (data->param4 && res_len > (size_t) data->param4) {
117 wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
118 "max_len=%ld)", line, data->name,
119 (unsigned long) res_len, (long) data->param4);
120 os_free(tmp);
121 return -1;
124 dst = (char **) (((u8 *) ssid) + (long) data->param1);
125 dst_len = (size_t *) (((u8 *) ssid) + (long) data->param2);
126 os_free(*dst);
127 *dst = tmp;
128 if (data->param2)
129 *dst_len = res_len;
131 return 0;
135 static int is_hex(const u8 *data, size_t len)
137 size_t i;
139 for (i = 0; i < len; i++) {
140 if (data[i] < 32 || data[i] >= 127)
141 return 1;
143 return 0;
147 static char * wpa_config_write_string_ascii(const u8 *value, size_t len)
149 char *buf;
151 buf = os_malloc(len + 3);
152 if (buf == NULL)
153 return NULL;
154 buf[0] = '"';
155 os_memcpy(buf + 1, value, len);
156 buf[len + 1] = '"';
157 buf[len + 2] = '\0';
159 return buf;
163 static char * wpa_config_write_string_hex(const u8 *value, size_t len)
165 char *buf;
167 buf = os_zalloc(2 * len + 1);
168 if (buf == NULL)
169 return NULL;
170 wpa_snprintf_hex(buf, 2 * len + 1, value, len);
172 return buf;
176 static char * wpa_config_write_string(const u8 *value, size_t len)
178 if (value == NULL)
179 return NULL;
181 if (is_hex(value, len))
182 return wpa_config_write_string_hex(value, len);
183 else
184 return wpa_config_write_string_ascii(value, len);
188 static char * wpa_config_write_str(const struct parse_data *data,
189 struct wpa_ssid *ssid)
191 size_t len;
192 char **src;
194 src = (char **) (((u8 *) ssid) + (long) data->param1);
195 if (*src == NULL)
196 return NULL;
198 if (data->param2)
199 len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
200 else
201 len = os_strlen(*src);
203 return wpa_config_write_string((const u8 *) *src, len);
207 static int wpa_config_parse_int(const struct parse_data *data,
208 struct wpa_ssid *ssid,
209 int line, const char *value)
211 int *dst;
213 dst = (int *) (((u8 *) ssid) + (long) data->param1);
214 *dst = atoi(value);
215 wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst);
217 if (data->param3 && *dst < (long) data->param3) {
218 wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
219 "min_value=%ld)", line, data->name, *dst,
220 (long) data->param3);
221 *dst = (long) data->param3;
222 return -1;
225 if (data->param4 && *dst > (long) data->param4) {
226 wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
227 "max_value=%ld)", line, data->name, *dst,
228 (long) data->param4);
229 *dst = (long) data->param4;
230 return -1;
233 return 0;
237 static char * wpa_config_write_int(const struct parse_data *data,
238 struct wpa_ssid *ssid)
240 int *src;
241 char *value;
243 src = (int *) (((u8 *) ssid) + (long) data->param1);
245 value = os_malloc(20);
246 if (value == NULL)
247 return NULL;
248 os_snprintf(value, 20, "%d", *src);
249 value[20 - 1] = '\0';
250 return value;
254 static int wpa_config_parse_bssid(const struct parse_data *data,
255 struct wpa_ssid *ssid, int line,
256 const char *value)
258 if (hwaddr_aton(value, ssid->bssid)) {
259 wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.",
260 line, value);
261 return -1;
263 ssid->bssid_set = 1;
264 wpa_hexdump(MSG_MSGDUMP, "BSSID", ssid->bssid, ETH_ALEN);
265 return 0;
269 static char * wpa_config_write_bssid(const struct parse_data *data,
270 struct wpa_ssid *ssid)
272 char *value;
274 if (!ssid->bssid_set)
275 return NULL;
277 value = os_malloc(20);
278 if (value == NULL)
279 return NULL;
280 os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid));
281 value[20 - 1] = '\0';
282 return value;
286 static int wpa_config_parse_psk(const struct parse_data *data,
287 struct wpa_ssid *ssid, int line,
288 const char *value)
290 if (*value == '"') {
291 const char *pos;
292 size_t len;
294 value++;
295 pos = os_strrchr(value, '"');
296 if (pos)
297 len = pos - value;
298 else
299 len = os_strlen(value);
300 if (len < 8 || len > 63) {
301 wpa_printf(MSG_ERROR, "Line %d: Invalid passphrase "
302 "length %lu (expected: 8..63) '%s'.",
303 line, (unsigned long) len, value);
304 return -1;
306 wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)",
307 (u8 *) value, len);
308 if (ssid->passphrase && os_strlen(ssid->passphrase) == len &&
309 os_memcmp(ssid->passphrase, value, len) == 0)
310 return 0;
311 ssid->psk_set = 0;
312 os_free(ssid->passphrase);
313 ssid->passphrase = os_malloc(len + 1);
314 if (ssid->passphrase == NULL)
315 return -1;
316 os_memcpy(ssid->passphrase, value, len);
317 ssid->passphrase[len] = '\0';
318 return 0;
321 if (hexstr2bin(value, ssid->psk, PMK_LEN) ||
322 value[PMK_LEN * 2] != '\0') {
323 wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
324 line, value);
325 return -1;
328 os_free(ssid->passphrase);
329 ssid->passphrase = NULL;
331 ssid->psk_set = 1;
332 wpa_hexdump_key(MSG_MSGDUMP, "PSK", ssid->psk, PMK_LEN);
333 return 0;
337 static char * wpa_config_write_psk(const struct parse_data *data,
338 struct wpa_ssid *ssid)
340 if (ssid->passphrase)
341 return wpa_config_write_string_ascii(
342 (const u8 *) ssid->passphrase,
343 os_strlen(ssid->passphrase));
345 if (ssid->psk_set)
346 return wpa_config_write_string_hex(ssid->psk, PMK_LEN);
348 return NULL;
352 static int wpa_config_parse_proto(const struct parse_data *data,
353 struct wpa_ssid *ssid, int line,
354 const char *value)
356 int val = 0, last, errors = 0;
357 char *start, *end, *buf;
359 buf = os_strdup(value);
360 if (buf == NULL)
361 return -1;
362 start = buf;
364 while (*start != '\0') {
365 while (*start == ' ' || *start == '\t')
366 start++;
367 if (*start == '\0')
368 break;
369 end = start;
370 while (*end != ' ' && *end != '\t' && *end != '\0')
371 end++;
372 last = *end == '\0';
373 *end = '\0';
374 if (os_strcmp(start, "WPA") == 0)
375 val |= WPA_PROTO_WPA;
376 else if (os_strcmp(start, "RSN") == 0 ||
377 os_strcmp(start, "WPA2") == 0)
378 val |= WPA_PROTO_RSN;
379 else {
380 wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'",
381 line, start);
382 errors++;
385 if (last)
386 break;
387 start = end + 1;
389 os_free(buf);
391 if (val == 0) {
392 wpa_printf(MSG_ERROR,
393 "Line %d: no proto values configured.", line);
394 errors++;
397 wpa_printf(MSG_MSGDUMP, "proto: 0x%x", val);
398 ssid->proto = val;
399 return errors ? -1 : 0;
403 static char * wpa_config_write_proto(const struct parse_data *data,
404 struct wpa_ssid *ssid)
406 int first = 1, ret;
407 char *buf, *pos, *end;
409 pos = buf = os_zalloc(10);
410 if (buf == NULL)
411 return NULL;
412 end = buf + 10;
414 if (ssid->proto & WPA_PROTO_WPA) {
415 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
416 if (ret < 0 || ret >= end - pos)
417 return buf;
418 pos += ret;
419 first = 0;
422 if (ssid->proto & WPA_PROTO_RSN) {
423 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
424 if (ret < 0 || ret >= end - pos)
425 return buf;
426 pos += ret;
427 first = 0;
430 return buf;
434 static int wpa_config_parse_key_mgmt(const struct parse_data *data,
435 struct wpa_ssid *ssid, int line,
436 const char *value)
438 int val = 0, last, errors = 0;
439 char *start, *end, *buf;
441 buf = os_strdup(value);
442 if (buf == NULL)
443 return -1;
444 start = buf;
446 while (*start != '\0') {
447 while (*start == ' ' || *start == '\t')
448 start++;
449 if (*start == '\0')
450 break;
451 end = start;
452 while (*end != ' ' && *end != '\t' && *end != '\0')
453 end++;
454 last = *end == '\0';
455 *end = '\0';
456 if (os_strcmp(start, "WPA-PSK") == 0)
457 val |= WPA_KEY_MGMT_PSK;
458 else if (os_strcmp(start, "WPA-EAP") == 0)
459 val |= WPA_KEY_MGMT_IEEE8021X;
460 else if (os_strcmp(start, "IEEE8021X") == 0)
461 val |= WPA_KEY_MGMT_IEEE8021X_NO_WPA;
462 else if (os_strcmp(start, "NONE") == 0)
463 val |= WPA_KEY_MGMT_NONE;
464 else if (os_strcmp(start, "WPA-NONE") == 0)
465 val |= WPA_KEY_MGMT_WPA_NONE;
466 else {
467 wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
468 line, start);
469 errors++;
472 if (last)
473 break;
474 start = end + 1;
476 os_free(buf);
478 if (val == 0) {
479 wpa_printf(MSG_ERROR,
480 "Line %d: no key_mgmt values configured.", line);
481 errors++;
484 wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val);
485 ssid->key_mgmt = val;
486 return errors ? -1 : 0;
490 static char * wpa_config_write_key_mgmt(const struct parse_data *data,
491 struct wpa_ssid *ssid)
493 char *buf, *pos, *end;
494 int ret;
496 pos = buf = os_zalloc(50);
497 if (buf == NULL)
498 return NULL;
499 end = buf + 50;
501 if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
502 ret = os_snprintf(pos, end - pos, "%sWPA-PSK",
503 pos == buf ? "" : " ");
504 if (ret < 0 || ret >= end - pos) {
505 end[-1] = '\0';
506 return buf;
508 pos += ret;
511 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
512 ret = os_snprintf(pos, end - pos, "%sWPA-EAP",
513 pos == buf ? "" : " ");
514 if (ret < 0 || ret >= end - pos) {
515 end[-1] = '\0';
516 return buf;
518 pos += ret;
521 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
522 ret = os_snprintf(pos, end - pos, "%sIEEE8021X",
523 pos == buf ? "" : " ");
524 if (ret < 0 || ret >= end - pos) {
525 end[-1] = '\0';
526 return buf;
528 pos += ret;
531 if (ssid->key_mgmt & WPA_KEY_MGMT_NONE) {
532 ret = os_snprintf(pos, end - pos, "%sNONE",
533 pos == buf ? "" : " ");
534 if (ret < 0 || ret >= end - pos) {
535 end[-1] = '\0';
536 return buf;
538 pos += ret;
541 if (ssid->key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
542 ret = os_snprintf(pos, end - pos, "%sWPA-NONE",
543 pos == buf ? "" : " ");
544 if (ret < 0 || ret >= end - pos) {
545 end[-1] = '\0';
546 return buf;
548 pos += ret;
551 return buf;
555 static int wpa_config_parse_cipher(int line, const char *value)
557 int val = 0, last;
558 char *start, *end, *buf;
560 buf = os_strdup(value);
561 if (buf == NULL)
562 return -1;
563 start = buf;
565 while (*start != '\0') {
566 while (*start == ' ' || *start == '\t')
567 start++;
568 if (*start == '\0')
569 break;
570 end = start;
571 while (*end != ' ' && *end != '\t' && *end != '\0')
572 end++;
573 last = *end == '\0';
574 *end = '\0';
575 if (os_strcmp(start, "CCMP") == 0)
576 val |= WPA_CIPHER_CCMP;
577 else if (os_strcmp(start, "TKIP") == 0)
578 val |= WPA_CIPHER_TKIP;
579 else if (os_strcmp(start, "WEP104") == 0)
580 val |= WPA_CIPHER_WEP104;
581 else if (os_strcmp(start, "WEP40") == 0)
582 val |= WPA_CIPHER_WEP40;
583 else if (os_strcmp(start, "NONE") == 0)
584 val |= WPA_CIPHER_NONE;
585 else {
586 wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
587 line, start);
588 os_free(buf);
589 return -1;
592 if (last)
593 break;
594 start = end + 1;
596 os_free(buf);
598 if (val == 0) {
599 wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
600 line);
601 return -1;
603 return val;
607 static char * wpa_config_write_cipher(int cipher)
609 char *buf, *pos, *end;
610 int ret;
612 pos = buf = os_zalloc(50);
613 if (buf == NULL)
614 return NULL;
615 end = buf + 50;
617 if (cipher & WPA_CIPHER_CCMP) {
618 ret = os_snprintf(pos, end - pos, "%sCCMP",
619 pos == buf ? "" : " ");
620 if (ret < 0 || ret >= end - pos) {
621 end[-1] = '\0';
622 return buf;
624 pos += ret;
627 if (cipher & WPA_CIPHER_TKIP) {
628 ret = os_snprintf(pos, end - pos, "%sTKIP",
629 pos == buf ? "" : " ");
630 if (ret < 0 || ret >= end - pos) {
631 end[-1] = '\0';
632 return buf;
634 pos += ret;
637 if (cipher & WPA_CIPHER_WEP104) {
638 ret = os_snprintf(pos, end - pos, "%sWEP104",
639 pos == buf ? "" : " ");
640 if (ret < 0 || ret >= end - pos) {
641 end[-1] = '\0';
642 return buf;
644 pos += ret;
647 if (cipher & WPA_CIPHER_WEP40) {
648 ret = os_snprintf(pos, end - pos, "%sWEP40",
649 pos == buf ? "" : " ");
650 if (ret < 0 || ret >= end - pos) {
651 end[-1] = '\0';
652 return buf;
654 pos += ret;
657 if (cipher & WPA_CIPHER_NONE) {
658 ret = os_snprintf(pos, end - pos, "%sNONE",
659 pos == buf ? "" : " ");
660 if (ret < 0 || ret >= end - pos) {
661 end[-1] = '\0';
662 return buf;
664 pos += ret;
667 return buf;
671 static int wpa_config_parse_pairwise(const struct parse_data *data,
672 struct wpa_ssid *ssid, int line,
673 const char *value)
675 int val;
676 val = wpa_config_parse_cipher(line, value);
677 if (val == -1)
678 return -1;
679 if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_NONE)) {
680 wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
681 "(0x%x).", line, val);
682 return -1;
685 wpa_printf(MSG_MSGDUMP, "pairwise: 0x%x", val);
686 ssid->pairwise_cipher = val;
687 return 0;
691 static char * wpa_config_write_pairwise(const struct parse_data *data,
692 struct wpa_ssid *ssid)
694 return wpa_config_write_cipher(ssid->pairwise_cipher);
698 static int wpa_config_parse_group(const struct parse_data *data,
699 struct wpa_ssid *ssid, int line,
700 const char *value)
702 int val;
703 val = wpa_config_parse_cipher(line, value);
704 if (val == -1)
705 return -1;
706 if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 |
707 WPA_CIPHER_WEP40)) {
708 wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
709 "(0x%x).", line, val);
710 return -1;
713 wpa_printf(MSG_MSGDUMP, "group: 0x%x", val);
714 ssid->group_cipher = val;
715 return 0;
719 static char * wpa_config_write_group(const struct parse_data *data,
720 struct wpa_ssid *ssid)
722 return wpa_config_write_cipher(ssid->group_cipher);
726 static int wpa_config_parse_auth_alg(const struct parse_data *data,
727 struct wpa_ssid *ssid, int line,
728 const char *value)
730 int val = 0, last, errors = 0;
731 char *start, *end, *buf;
733 buf = os_strdup(value);
734 if (buf == NULL)
735 return -1;
736 start = buf;
738 while (*start != '\0') {
739 while (*start == ' ' || *start == '\t')
740 start++;
741 if (*start == '\0')
742 break;
743 end = start;
744 while (*end != ' ' && *end != '\t' && *end != '\0')
745 end++;
746 last = *end == '\0';
747 *end = '\0';
748 if (os_strcmp(start, "OPEN") == 0)
749 val |= WPA_AUTH_ALG_OPEN;
750 else if (os_strcmp(start, "SHARED") == 0)
751 val |= WPA_AUTH_ALG_SHARED;
752 else if (os_strcmp(start, "LEAP") == 0)
753 val |= WPA_AUTH_ALG_LEAP;
754 else {
755 wpa_printf(MSG_ERROR, "Line %d: invalid auth_alg '%s'",
756 line, start);
757 errors++;
760 if (last)
761 break;
762 start = end + 1;
764 os_free(buf);
766 if (val == 0) {
767 wpa_printf(MSG_ERROR,
768 "Line %d: no auth_alg values configured.", line);
769 errors++;
772 wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", val);
773 ssid->auth_alg = val;
774 return errors ? -1 : 0;
778 static char * wpa_config_write_auth_alg(const struct parse_data *data,
779 struct wpa_ssid *ssid)
781 char *buf, *pos, *end;
782 int ret;
784 pos = buf = os_zalloc(30);
785 if (buf == NULL)
786 return NULL;
787 end = buf + 30;
789 if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) {
790 ret = os_snprintf(pos, end - pos, "%sOPEN",
791 pos == buf ? "" : " ");
792 if (ret < 0 || ret >= end - pos) {
793 end[-1] = '\0';
794 return buf;
796 pos += ret;
799 if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) {
800 ret = os_snprintf(pos, end - pos, "%sSHARED",
801 pos == buf ? "" : " ");
802 if (ret < 0 || ret >= end - pos) {
803 end[-1] = '\0';
804 return buf;
806 pos += ret;
809 if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) {
810 ret = os_snprintf(pos, end - pos, "%sLEAP",
811 pos == buf ? "" : " ");
812 if (ret < 0 || ret >= end - pos) {
813 end[-1] = '\0';
814 return buf;
816 pos += ret;
819 return buf;
823 #ifdef IEEE8021X_EAPOL
824 static int wpa_config_parse_eap(const struct parse_data *data,
825 struct wpa_ssid *ssid, int line,
826 const char *value)
828 int last, errors = 0;
829 char *start, *end, *buf;
830 struct eap_method_type *methods = NULL, *tmp;
831 size_t num_methods = 0;
833 buf = os_strdup(value);
834 if (buf == NULL)
835 return -1;
836 start = buf;
838 while (*start != '\0') {
839 while (*start == ' ' || *start == '\t')
840 start++;
841 if (*start == '\0')
842 break;
843 end = start;
844 while (*end != ' ' && *end != '\t' && *end != '\0')
845 end++;
846 last = *end == '\0';
847 *end = '\0';
848 tmp = methods;
849 methods = os_realloc(methods,
850 (num_methods + 1) * sizeof(*methods));
851 if (methods == NULL) {
852 os_free(tmp);
853 os_free(buf);
854 return -1;
856 methods[num_methods].method = eap_get_type(
857 start, &methods[num_methods].vendor);
858 if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
859 methods[num_methods].method == EAP_TYPE_NONE) {
860 wpa_printf(MSG_ERROR, "Line %d: unknown EAP method "
861 "'%s'", line, start);
862 wpa_printf(MSG_ERROR, "You may need to add support for"
863 " this EAP method during wpa_supplicant\n"
864 "build time configuration.\n"
865 "See README for more information.");
866 errors++;
867 } else if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
868 methods[num_methods].method == EAP_TYPE_LEAP)
869 ssid->leap++;
870 else
871 ssid->non_leap++;
872 num_methods++;
873 if (last)
874 break;
875 start = end + 1;
877 os_free(buf);
879 tmp = methods;
880 methods = os_realloc(methods, (num_methods + 1) * sizeof(*methods));
881 if (methods == NULL) {
882 os_free(tmp);
883 return -1;
885 methods[num_methods].vendor = EAP_VENDOR_IETF;
886 methods[num_methods].method = EAP_TYPE_NONE;
887 num_methods++;
889 wpa_hexdump(MSG_MSGDUMP, "eap methods",
890 (u8 *) methods, num_methods * sizeof(*methods));
891 ssid->eap_methods = methods;
892 return errors ? -1 : 0;
896 static char * wpa_config_write_eap(const struct parse_data *data,
897 struct wpa_ssid *ssid)
899 int i, ret;
900 char *buf, *pos, *end;
901 const struct eap_method_type *eap_methods = ssid->eap_methods;
902 const char *name;
904 if (eap_methods == NULL)
905 return NULL;
907 pos = buf = os_zalloc(100);
908 if (buf == NULL)
909 return NULL;
910 end = buf + 100;
912 for (i = 0; eap_methods[i].vendor != EAP_VENDOR_IETF ||
913 eap_methods[i].method != EAP_TYPE_NONE; i++) {
914 name = eap_get_name(eap_methods[i].vendor,
915 eap_methods[i].method);
916 if (name) {
917 ret = os_snprintf(pos, end - pos, "%s%s",
918 pos == buf ? "" : " ", name);
919 if (ret < 0 || ret >= end - pos)
920 break;
921 pos += ret;
925 end[-1] = '\0';
927 return buf;
929 #endif /* IEEE8021X_EAPOL */
932 static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line,
933 const char *value, int idx)
935 char *buf, title[20];
937 buf = wpa_config_parse_string(value, len);
938 if (buf == NULL) {
939 wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key %d '%s'.",
940 line, idx, value);
941 return -1;
943 if (*len > MAX_WEP_KEY_LEN) {
944 wpa_printf(MSG_ERROR, "Line %d: Too long WEP key %d '%s'.",
945 line, idx, value);
946 os_free(buf);
947 return -1;
949 os_memcpy(key, buf, *len);
950 os_free(buf);
951 os_snprintf(title, sizeof(title), "wep_key%d", idx);
952 wpa_hexdump_key(MSG_MSGDUMP, title, key, *len);
953 return 0;
957 static int wpa_config_parse_wep_key0(const struct parse_data *data,
958 struct wpa_ssid *ssid, int line,
959 const char *value)
961 return wpa_config_parse_wep_key(ssid->wep_key[0],
962 &ssid->wep_key_len[0], line,
963 value, 0);
967 static int wpa_config_parse_wep_key1(const struct parse_data *data,
968 struct wpa_ssid *ssid, int line,
969 const char *value)
971 return wpa_config_parse_wep_key(ssid->wep_key[1],
972 &ssid->wep_key_len[1], line,
973 value, 1);
977 static int wpa_config_parse_wep_key2(const struct parse_data *data,
978 struct wpa_ssid *ssid, int line,
979 const char *value)
981 return wpa_config_parse_wep_key(ssid->wep_key[2],
982 &ssid->wep_key_len[2], line,
983 value, 2);
987 static int wpa_config_parse_wep_key3(const struct parse_data *data,
988 struct wpa_ssid *ssid, int line,
989 const char *value)
991 return wpa_config_parse_wep_key(ssid->wep_key[3],
992 &ssid->wep_key_len[3], line,
993 value, 3);
997 static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx)
999 if (ssid->wep_key_len[idx] == 0)
1000 return NULL;
1001 return wpa_config_write_string(ssid->wep_key[idx],
1002 ssid->wep_key_len[idx]);
1006 static char * wpa_config_write_wep_key0(const struct parse_data *data,
1007 struct wpa_ssid *ssid)
1009 return wpa_config_write_wep_key(ssid, 0);
1013 static char * wpa_config_write_wep_key1(const struct parse_data *data,
1014 struct wpa_ssid *ssid)
1016 return wpa_config_write_wep_key(ssid, 1);
1020 static char * wpa_config_write_wep_key2(const struct parse_data *data,
1021 struct wpa_ssid *ssid)
1023 return wpa_config_write_wep_key(ssid, 2);
1027 static char * wpa_config_write_wep_key3(const struct parse_data *data,
1028 struct wpa_ssid *ssid)
1030 return wpa_config_write_wep_key(ssid, 3);
1034 /* Helper macros for network block parser */
1036 #ifdef OFFSET
1037 #undef OFFSET
1038 #endif /* OFFSET */
1039 /* OFFSET: Get offset of a variable within the wpa_ssid structure */
1040 #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
1042 /* STR: Define a string variable for an ASCII string; f = field name */
1043 #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
1044 #define STR(f) _STR(f), NULL, NULL, NULL, 0
1045 #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
1047 /* STR_LEN: Define a string variable with a separate variable for storing the
1048 * data length. Unlike STR(), this can be used to store arbitrary binary data
1049 * (i.e., even nul termination character). */
1050 #define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
1051 #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
1052 #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
1054 /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
1055 * explicitly specified. */
1056 #define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max)
1057 #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
1058 #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
1060 #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
1061 OFFSET(f), (void *) 0
1063 /* INT: Define an integer variable */
1064 #define INT(f) _INT(f), NULL, NULL, 0
1066 /* INT_RANGE: Define an integer variable with allowed value range */
1067 #define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
1069 /* FUNC: Define a configuration variable that uses a custom function for
1070 * parsing and writing the value. */
1071 #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
1072 NULL, NULL, NULL, NULL
1073 #define FUNC(f) _FUNC(f), 0
1074 #define FUNC_KEY(f) _FUNC(f), 1
1077 * Table of network configuration variables. This table is used to parse each
1078 * network configuration variable, e.g., each line in wpa_supplicant.conf file
1079 * that is inside a network block.
1081 * This table is generated using the helper macros defined above and with
1082 * generous help from the C pre-processor. The field name is stored as a string
1083 * into .name and for STR and INT types, the offset of the target buffer within
1084 * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
1085 * offset to the field containing the length of the configuration variable.
1086 * .param3 and .param4 can be used to mark the allowed range (length for STR
1087 * and value for INT).
1089 * For each configuration line in wpa_supplicant.conf, the parser goes through
1090 * this table and select the entry that matches with the field name. The parser
1091 * function (.parser) is then called to parse the actual value of the field.
1093 * This kind of mechanism makes it easy to add new configuration parameters,
1094 * since only one line needs to be added into this table and into the
1095 * struct wpa_ssid definition if the new variable is either a string or
1096 * integer. More complex types will need to use their own parser and writer
1097 * functions.
1099 static const struct parse_data ssid_fields[] = {
1100 { STR_RANGE(ssid, 0, MAX_SSID_LEN) },
1101 { INT_RANGE(scan_ssid, 0, 1) },
1102 { FUNC(bssid) },
1103 { FUNC_KEY(psk) },
1104 { FUNC(proto) },
1105 { FUNC(key_mgmt) },
1106 { FUNC(pairwise) },
1107 { FUNC(group) },
1108 { FUNC(auth_alg) },
1109 #ifdef IEEE8021X_EAPOL
1110 { FUNC(eap) },
1111 { STR_LEN(identity) },
1112 { STR_LEN(anonymous_identity) },
1113 { STR_RANGE_KEY(eappsk, EAP_PSK_LEN_MIN, EAP_PSK_LEN_MAX) },
1114 { STR_LEN(nai) },
1115 { STR_LEN_KEY(password) },
1116 { STR(ca_cert) },
1117 { STR(ca_path) },
1118 { STR(client_cert) },
1119 { STR(private_key) },
1120 { STR_KEY(private_key_passwd) },
1121 { STR(dh_file) },
1122 { STR(subject_match) },
1123 { STR(altsubject_match) },
1124 { STR(ca_cert2) },
1125 { STR(ca_path2) },
1126 { STR(client_cert2) },
1127 { STR(private_key2) },
1128 { STR_KEY(private_key2_passwd) },
1129 { STR(dh_file2) },
1130 { STR(subject_match2) },
1131 { STR(altsubject_match2) },
1132 { STR(phase1) },
1133 { STR(phase2) },
1134 { STR(pcsc) },
1135 { STR_KEY(pin) },
1136 { STR(engine_id) },
1137 { STR(key_id) },
1138 { INT(engine) },
1139 { INT(eapol_flags) },
1140 #endif /* IEEE8021X_EAPOL */
1141 { FUNC_KEY(wep_key0) },
1142 { FUNC_KEY(wep_key1) },
1143 { FUNC_KEY(wep_key2) },
1144 { FUNC_KEY(wep_key3) },
1145 { INT(wep_tx_keyidx) },
1146 { INT(priority) },
1147 #ifdef IEEE8021X_EAPOL
1148 { INT(eap_workaround) },
1149 { STR(pac_file) },
1150 { INT(fragment_size) },
1151 #endif /* IEEE8021X_EAPOL */
1152 { INT_RANGE(mode, 0, 1) },
1153 { INT_RANGE(proactive_key_caching, 0, 1) },
1154 { INT_RANGE(disabled, 0, 1) },
1155 { STR(id_str) },
1156 #ifdef CONFIG_IEEE80211W
1157 { INT_RANGE(ieee80211w, 0, 2) },
1158 #endif /* CONFIG_IEEE80211W */
1159 { INT_RANGE(peerkey, 0, 1) },
1160 { INT_RANGE(mixed_cell, 0, 1) }
1163 #undef OFFSET
1164 #undef _STR
1165 #undef STR
1166 #undef STR_KEY
1167 #undef _STR_LEN
1168 #undef STR_LEN
1169 #undef STR_LEN_KEY
1170 #undef _STR_RANGE
1171 #undef STR_RANGE
1172 #undef STR_RANGE_KEY
1173 #undef _INT
1174 #undef INT
1175 #undef INT_RANGE
1176 #undef _FUNC
1177 #undef FUNC
1178 #undef FUNC_KEY
1179 #define NUM_SSID_FIELDS (sizeof(ssid_fields) / sizeof(ssid_fields[0]))
1183 * wpa_config_add_prio_network - Add a network to priority lists
1184 * @config: Configuration data from wpa_config_read()
1185 * @ssid: Pointer to the network configuration to be added to the list
1186 * Returns: 0 on success, -1 on failure
1188 * This function is used to add a network block to the priority list of
1189 * networks. This must be called for each network when reading in the full
1190 * configuration. In addition, this can be used indirectly when updating
1191 * priorities by calling wpa_config_update_prio_list().
1193 int wpa_config_add_prio_network(struct wpa_config *config,
1194 struct wpa_ssid *ssid)
1196 int prio;
1197 struct wpa_ssid *prev, **nlist;
1200 * Add to an existing priority list if one is available for the
1201 * configured priority level for this network.
1203 for (prio = 0; prio < config->num_prio; prio++) {
1204 prev = config->pssid[prio];
1205 if (prev->priority == ssid->priority) {
1206 while (prev->pnext)
1207 prev = prev->pnext;
1208 prev->pnext = ssid;
1209 return 0;
1213 /* First network for this priority - add a new priority list */
1214 nlist = os_realloc(config->pssid,
1215 (config->num_prio + 1) * sizeof(struct wpa_ssid *));
1216 if (nlist == NULL)
1217 return -1;
1219 for (prio = 0; prio < config->num_prio; prio++) {
1220 if (nlist[prio]->priority < ssid->priority)
1221 break;
1224 os_memmove(&nlist[prio + 1], &nlist[prio],
1225 (config->num_prio - prio) * sizeof(struct wpa_ssid *));
1227 nlist[prio] = ssid;
1228 config->num_prio++;
1229 config->pssid = nlist;
1231 return 0;
1236 * wpa_config_update_prio_list - Update network priority list
1237 * @config: Configuration data from wpa_config_read()
1238 * Returns: 0 on success, -1 on failure
1240 * This function is called to update the priority list of networks in the
1241 * configuration when a network is being added or removed. This is also called
1242 * if a priority for a network is changed.
1244 static int wpa_config_update_prio_list(struct wpa_config *config)
1246 struct wpa_ssid *ssid;
1247 int ret = 0;
1249 os_free(config->pssid);
1250 config->pssid = NULL;
1251 config->num_prio = 0;
1253 ssid = config->ssid;
1254 while (ssid) {
1255 ssid->pnext = NULL;
1256 if (wpa_config_add_prio_network(config, ssid) < 0)
1257 ret = -1;
1258 ssid = ssid->next;
1261 return ret;
1266 * wpa_config_free_ssid - Free network/ssid configuration data
1267 * @ssid: Configuration data for the network
1269 * This function frees all resources allocated for the network configuration
1270 * data.
1272 void wpa_config_free_ssid(struct wpa_ssid *ssid)
1274 os_free(ssid->ssid);
1275 os_free(ssid->passphrase);
1276 #ifdef IEEE8021X_EAPOL
1277 os_free(ssid->eap_methods);
1278 os_free(ssid->identity);
1279 os_free(ssid->anonymous_identity);
1280 os_free(ssid->eappsk);
1281 os_free(ssid->nai);
1282 os_free(ssid->password);
1283 os_free(ssid->ca_cert);
1284 os_free(ssid->ca_path);
1285 os_free(ssid->client_cert);
1286 os_free(ssid->private_key);
1287 os_free(ssid->private_key_passwd);
1288 os_free(ssid->dh_file);
1289 os_free(ssid->subject_match);
1290 os_free(ssid->altsubject_match);
1291 os_free(ssid->ca_cert2);
1292 os_free(ssid->ca_path2);
1293 os_free(ssid->client_cert2);
1294 os_free(ssid->private_key2);
1295 os_free(ssid->private_key2_passwd);
1296 os_free(ssid->dh_file2);
1297 os_free(ssid->subject_match2);
1298 os_free(ssid->altsubject_match2);
1299 os_free(ssid->phase1);
1300 os_free(ssid->phase2);
1301 os_free(ssid->pcsc);
1302 os_free(ssid->pin);
1303 os_free(ssid->engine_id);
1304 os_free(ssid->key_id);
1305 os_free(ssid->otp);
1306 os_free(ssid->pending_req_otp);
1307 os_free(ssid->pac_file);
1308 os_free(ssid->new_password);
1309 #endif /* IEEE8021X_EAPOL */
1310 os_free(ssid->id_str);
1311 os_free(ssid);
1316 * wpa_config_free - Free configuration data
1317 * @config: Configuration data from wpa_config_read()
1319 * This function frees all resources allocated for the configuration data by
1320 * wpa_config_read().
1322 void wpa_config_free(struct wpa_config *config)
1324 struct wpa_config_blob *blob, *prevblob;
1325 struct wpa_ssid *ssid, *prev = NULL;
1326 ssid = config->ssid;
1327 while (ssid) {
1328 prev = ssid;
1329 ssid = ssid->next;
1330 wpa_config_free_ssid(prev);
1333 blob = config->blobs;
1334 prevblob = NULL;
1335 while (blob) {
1336 prevblob = blob;
1337 blob = blob->next;
1338 wpa_config_free_blob(prevblob);
1341 os_free(config->ctrl_interface);
1342 os_free(config->ctrl_interface_group);
1343 os_free(config->opensc_engine_path);
1344 os_free(config->pkcs11_engine_path);
1345 os_free(config->pkcs11_module_path);
1346 os_free(config->driver_param);
1347 os_free(config->pssid);
1348 os_free(config);
1352 #ifdef IEEE8021X_EAPOL
1354 * wpa_config_allowed_eap_method - Check whether EAP method is allowed
1355 * @ssid: Pointer to configuration data
1356 * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types
1357 * @method: EAP type
1358 * Returns: 1 = allowed EAP method, 0 = not allowed
1360 int wpa_config_allowed_eap_method(struct wpa_ssid *ssid, int vendor,
1361 u32 method)
1363 int i;
1364 struct eap_method_type *m;
1366 if (ssid == NULL || ssid->eap_methods == NULL)
1367 return 1;
1369 m = ssid->eap_methods;
1370 for (i = 0; m[i].vendor != EAP_VENDOR_IETF ||
1371 m[i].method != EAP_TYPE_NONE; i++) {
1372 if (m[i].vendor == vendor && m[i].method == method)
1373 return 1;
1375 return 0;
1377 #endif /* IEEE8021X_EAPOL */
1381 * wpa_config_get_network - Get configured network based on id
1382 * @config: Configuration data from wpa_config_read()
1383 * @id: Unique network id to search for
1384 * Returns: Network configuration or %NULL if not found
1386 struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id)
1388 struct wpa_ssid *ssid;
1390 ssid = config->ssid;
1391 while (ssid) {
1392 if (id == ssid->id)
1393 break;
1394 ssid = ssid->next;
1397 return ssid;
1402 * wpa_config_add_network - Add a new network with empty configuration
1403 * @config: Configuration data from wpa_config_read()
1404 * Returns: The new network configuration or %NULL if operation failed
1406 struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
1408 int id;
1409 struct wpa_ssid *ssid, *last = NULL;
1411 id = -1;
1412 ssid = config->ssid;
1413 while (ssid) {
1414 if (ssid->id > id)
1415 id = ssid->id;
1416 last = ssid;
1417 ssid = ssid->next;
1419 id++;
1421 ssid = os_zalloc(sizeof(*ssid));
1422 if (ssid == NULL)
1423 return NULL;
1424 ssid->id = id;
1425 if (last)
1426 last->next = ssid;
1427 else
1428 config->ssid = ssid;
1430 wpa_config_update_prio_list(config);
1432 return ssid;
1437 * wpa_config_remove_network - Remove a configured network based on id
1438 * @config: Configuration data from wpa_config_read()
1439 * @id: Unique network id to search for
1440 * Returns: 0 on success, or -1 if the network was not found
1442 int wpa_config_remove_network(struct wpa_config *config, int id)
1444 struct wpa_ssid *ssid, *prev = NULL;
1446 ssid = config->ssid;
1447 while (ssid) {
1448 if (id == ssid->id)
1449 break;
1450 prev = ssid;
1451 ssid = ssid->next;
1454 if (ssid == NULL)
1455 return -1;
1457 if (prev)
1458 prev->next = ssid->next;
1459 else
1460 config->ssid = ssid->next;
1462 wpa_config_update_prio_list(config);
1463 wpa_config_free_ssid(ssid);
1464 return 0;
1469 * wpa_config_set_network_defaults - Set network default values
1470 * @ssid: Pointer to network configuration data
1472 void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
1474 ssid->proto = DEFAULT_PROTO;
1475 ssid->pairwise_cipher = DEFAULT_PAIRWISE;
1476 ssid->group_cipher = DEFAULT_GROUP;
1477 ssid->key_mgmt = DEFAULT_KEY_MGMT;
1478 #ifdef IEEE8021X_EAPOL
1479 ssid->eapol_flags = DEFAULT_EAPOL_FLAGS;
1480 ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
1481 ssid->fragment_size = DEFAULT_FRAGMENT_SIZE;
1482 #endif /* IEEE8021X_EAPOL */
1487 * wpa_config_set - Set a variable in network configuration
1488 * @ssid: Pointer to network configuration data
1489 * @var: Variable name, e.g., "ssid"
1490 * @value: Variable value
1491 * @line: Line number in configuration file or 0 if not used
1492 * Returns: 0 on success, -1 on failure
1494 * This function can be used to set network configuration variables based on
1495 * both the configuration file and management interface input. The value
1496 * parameter must be in the same format as the text-based configuration file is
1497 * using. For example, strings are using double quotation marks.
1499 int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
1500 int line)
1502 size_t i;
1503 int ret = 0;
1505 if (ssid == NULL || var == NULL || value == NULL)
1506 return -1;
1508 for (i = 0; i < NUM_SSID_FIELDS; i++) {
1509 const struct parse_data *field = &ssid_fields[i];
1510 if (os_strcmp(var, field->name) != 0)
1511 continue;
1513 if (field->parser(field, ssid, line, value)) {
1514 if (line) {
1515 wpa_printf(MSG_ERROR, "Line %d: failed to "
1516 "parse %s '%s'.", line, var, value);
1518 ret = -1;
1520 break;
1522 if (i == NUM_SSID_FIELDS) {
1523 if (line) {
1524 wpa_printf(MSG_ERROR, "Line %d: unknown network field "
1525 "'%s'.", line, var);
1527 ret = -1;
1530 return ret;
1535 * wpa_config_get - Get a variable in network configuration
1536 * @ssid: Pointer to network configuration data
1537 * @var: Variable name, e.g., "ssid"
1538 * Returns: Value of the variable or %NULL on failure
1540 * This function can be used to get network configuration variables. The
1541 * returned value is a copy of the configuration variable in text format, i.e,.
1542 * the same format that the text-based configuration file and wpa_config_set()
1543 * are using for the value. The caller is responsible for freeing the returned
1544 * value.
1546 char * wpa_config_get(struct wpa_ssid *ssid, const char *var)
1548 size_t i;
1550 if (ssid == NULL || var == NULL)
1551 return NULL;
1553 for (i = 0; i < NUM_SSID_FIELDS; i++) {
1554 const struct parse_data *field = &ssid_fields[i];
1555 if (os_strcmp(var, field->name) == 0)
1556 return field->writer(field, ssid);
1559 return NULL;
1564 * wpa_config_get_no_key - Get a variable in network configuration (no keys)
1565 * @ssid: Pointer to network configuration data
1566 * @var: Variable name, e.g., "ssid"
1567 * Returns: Value of the variable or %NULL on failure
1569 * This function can be used to get network configuration variable like
1570 * wpa_config_get(). The only difference is that this functions does not expose
1571 * key/password material from the configuration. In case a key/password field
1572 * is requested, the returned value is an empty string or %NULL if the variable
1573 * is not set or "*" if the variable is set (regardless of its value). The
1574 * returned value is a copy of the configuration variable in text format, i.e,.
1575 * the same format that the text-based configuration file and wpa_config_set()
1576 * are using for the value. The caller is responsible for freeing the returned
1577 * value.
1579 char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var)
1581 size_t i;
1583 if (ssid == NULL || var == NULL)
1584 return NULL;
1586 for (i = 0; i < NUM_SSID_FIELDS; i++) {
1587 const struct parse_data *field = &ssid_fields[i];
1588 if (os_strcmp(var, field->name) == 0) {
1589 char *res = field->writer(field, ssid);
1590 if (field->key_data) {
1591 if (res && res[0]) {
1592 wpa_printf(MSG_DEBUG, "Do not allow "
1593 "key_data field to be "
1594 "exposed");
1595 os_free(res);
1596 return os_strdup("*");
1599 os_free(res);
1600 return NULL;
1602 return res;
1606 return NULL;
1611 * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
1612 * @ssid: Pointer to network configuration data
1614 * This function must be called to update WPA PSK when either SSID or the
1615 * passphrase has changed for the network configuration.
1617 void wpa_config_update_psk(struct wpa_ssid *ssid)
1619 pbkdf2_sha1(ssid->passphrase,
1620 (char *) ssid->ssid, ssid->ssid_len, 4096,
1621 ssid->psk, PMK_LEN);
1622 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1623 ssid->psk, PMK_LEN);
1624 ssid->psk_set = 1;
1629 * wpa_config_get_blob - Get a named configuration blob
1630 * @config: Configuration data from wpa_config_read()
1631 * @name: Name of the blob
1632 * Returns: Pointer to blob data or %NULL if not found
1634 const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
1635 const char *name)
1637 struct wpa_config_blob *blob = config->blobs;
1639 while (blob) {
1640 if (os_strcmp(blob->name, name) == 0)
1641 return blob;
1642 blob = blob->next;
1644 return NULL;
1649 * wpa_config_set_blob - Set or add a named configuration blob
1650 * @config: Configuration data from wpa_config_read()
1651 * @blob: New value for the blob
1653 * Adds a new configuration blob or replaces the current value of an existing
1654 * blob.
1656 void wpa_config_set_blob(struct wpa_config *config,
1657 struct wpa_config_blob *blob)
1659 wpa_config_remove_blob(config, blob->name);
1660 blob->next = config->blobs;
1661 config->blobs = blob;
1666 * wpa_config_free_blob - Free blob data
1667 * @blob: Pointer to blob to be freed
1669 void wpa_config_free_blob(struct wpa_config_blob *blob)
1671 if (blob) {
1672 os_free(blob->name);
1673 os_free(blob->data);
1674 os_free(blob);
1680 * wpa_config_remove_blob - Remove a named configuration blob
1681 * @config: Configuration data from wpa_config_read()
1682 * @name: Name of the blob to remove
1683 * Returns: 0 if blob was removed or -1 if blob was not found
1685 int wpa_config_remove_blob(struct wpa_config *config, const char *name)
1687 struct wpa_config_blob *pos = config->blobs, *prev = NULL;
1689 while (pos) {
1690 if (os_strcmp(pos->name, name) == 0) {
1691 if (prev)
1692 prev->next = pos->next;
1693 else
1694 config->blobs = pos->next;
1695 wpa_config_free_blob(pos);
1696 return 0;
1698 prev = pos;
1699 pos = pos->next;
1702 return -1;
1707 * wpa_config_alloc_empty - Allocate an empty configuration
1708 * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
1709 * socket
1710 * @driver_param: Driver parameters
1711 * Returns: Pointer to allocated configuration data or %NULL on failure
1713 struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
1714 const char *driver_param)
1716 struct wpa_config *config;
1718 config = os_zalloc(sizeof(*config));
1719 if (config == NULL)
1720 return NULL;
1721 config->eapol_version = DEFAULT_EAPOL_VERSION;
1722 config->ap_scan = DEFAULT_AP_SCAN;
1723 config->fast_reauth = DEFAULT_FAST_REAUTH;
1725 if (ctrl_interface)
1726 config->ctrl_interface = os_strdup(ctrl_interface);
1727 if (driver_param)
1728 config->driver_param = os_strdup(driver_param);
1730 return config;
1734 #ifndef CONFIG_NO_STDOUT_DEBUG
1736 * wpa_config_debug_dump_networks - Debug dump of configured networks
1737 * @config: Configuration data from wpa_config_read()
1739 void wpa_config_debug_dump_networks(struct wpa_config *config)
1741 int prio;
1742 struct wpa_ssid *ssid;
1744 for (prio = 0; prio < config->num_prio; prio++) {
1745 ssid = config->pssid[prio];
1746 wpa_printf(MSG_DEBUG, "Priority group %d",
1747 ssid->priority);
1748 while (ssid) {
1749 wpa_printf(MSG_DEBUG, " id=%d ssid='%s'",
1750 ssid->id,
1751 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1752 ssid = ssid->pnext;
1756 #endif /* CONFIG_NO_STDOUT_DEBUG */