2 * WPA Supplicant / Configuration parser and common functions
3 * Copyright (c) 2003-2008, 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
12 * See README and COPYING for more details.
20 #include "eap_peer/eap.h"
24 #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE)
25 #define NO_CONFIG_WRITE
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[]).
34 /* Configuration variable name */
37 /* Parser function for this variable */
38 int (*parser
)(const struct parse_data
*data
, struct wpa_ssid
*ssid
,
39 int line
, const char *value
);
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 */
47 /* Variable specific parameters for the parser. */
48 void *param1
, *param2
, *param3
, *param4
;
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
60 static char * wpa_config_parse_string(const char *value
, size_t *len
)
65 pos
= os_strrchr(value
, '"');
66 if (pos
== NULL
|| pos
[1] != '\0')
69 *len
= os_strlen(value
);
70 return os_strdup(value
);
73 size_t tlen
, hlen
= os_strlen(value
);
77 str
= os_malloc(tlen
+ 1);
80 if (hexstr2bin(value
, str
, tlen
)) {
91 static int wpa_config_parse_str(const struct parse_data
*data
,
92 struct wpa_ssid
*ssid
,
93 int line
, const char *value
)
95 size_t res_len
, *dst_len
;
98 if (os_strcmp(value
, "NULL") == 0) {
99 wpa_printf(MSG_DEBUG
, "Unset configuration string '%s'",
106 tmp
= wpa_config_parse_string(value
, &res_len
);
108 wpa_printf(MSG_ERROR
, "Line %d: failed to parse %s '%s'.",
110 data
->key_data
? "[KEY DATA REMOVED]" : value
);
114 if (data
->key_data
) {
115 wpa_hexdump_ascii_key(MSG_MSGDUMP
, data
->name
,
116 (u8
*) tmp
, res_len
);
118 wpa_hexdump_ascii(MSG_MSGDUMP
, data
->name
,
119 (u8
*) tmp
, res_len
);
122 if (data
->param3
&& res_len
< (size_t) data
->param3
) {
123 wpa_printf(MSG_ERROR
, "Line %d: too short %s (len=%lu "
124 "min_len=%ld)", line
, data
->name
,
125 (unsigned long) res_len
, (long) data
->param3
);
130 if (data
->param4
&& res_len
> (size_t) data
->param4
) {
131 wpa_printf(MSG_ERROR
, "Line %d: too long %s (len=%lu "
132 "max_len=%ld)", line
, data
->name
,
133 (unsigned long) res_len
, (long) data
->param4
);
139 dst
= (char **) (((u8
*) ssid
) + (long) data
->param1
);
140 dst_len
= (size_t *) (((u8
*) ssid
) + (long) data
->param2
);
150 #ifndef NO_CONFIG_WRITE
151 static int is_hex(const u8
*data
, size_t len
)
155 for (i
= 0; i
< len
; i
++) {
156 if (data
[i
] < 32 || data
[i
] >= 127)
163 static char * wpa_config_write_string_ascii(const u8
*value
, size_t len
)
167 buf
= os_malloc(len
+ 3);
171 os_memcpy(buf
+ 1, value
, len
);
179 static char * wpa_config_write_string_hex(const u8
*value
, size_t len
)
183 buf
= os_zalloc(2 * len
+ 1);
186 wpa_snprintf_hex(buf
, 2 * len
+ 1, value
, len
);
192 static char * wpa_config_write_string(const u8
*value
, size_t len
)
197 if (is_hex(value
, len
))
198 return wpa_config_write_string_hex(value
, len
);
200 return wpa_config_write_string_ascii(value
, len
);
204 static char * wpa_config_write_str(const struct parse_data
*data
,
205 struct wpa_ssid
*ssid
)
210 src
= (char **) (((u8
*) ssid
) + (long) data
->param1
);
215 len
= *((size_t *) (((u8
*) ssid
) + (long) data
->param2
));
217 len
= os_strlen(*src
);
219 return wpa_config_write_string((const u8
*) *src
, len
);
221 #endif /* NO_CONFIG_WRITE */
224 static int wpa_config_parse_int(const struct parse_data
*data
,
225 struct wpa_ssid
*ssid
,
226 int line
, const char *value
)
230 dst
= (int *) (((u8
*) ssid
) + (long) data
->param1
);
232 wpa_printf(MSG_MSGDUMP
, "%s=%d (0x%x)", data
->name
, *dst
, *dst
);
234 if (data
->param3
&& *dst
< (long) data
->param3
) {
235 wpa_printf(MSG_ERROR
, "Line %d: too small %s (value=%d "
236 "min_value=%ld)", line
, data
->name
, *dst
,
237 (long) data
->param3
);
238 *dst
= (long) data
->param3
;
242 if (data
->param4
&& *dst
> (long) data
->param4
) {
243 wpa_printf(MSG_ERROR
, "Line %d: too large %s (value=%d "
244 "max_value=%ld)", line
, data
->name
, *dst
,
245 (long) data
->param4
);
246 *dst
= (long) data
->param4
;
254 #ifndef NO_CONFIG_WRITE
255 static char * wpa_config_write_int(const struct parse_data
*data
,
256 struct wpa_ssid
*ssid
)
261 src
= (int *) (((u8
*) ssid
) + (long) data
->param1
);
263 value
= os_malloc(20);
266 res
= os_snprintf(value
, 20, "%d", *src
);
267 if (res
< 0 || res
>= 20) {
271 value
[20 - 1] = '\0';
274 #endif /* NO_CONFIG_WRITE */
277 static int wpa_config_parse_bssid(const struct parse_data
*data
,
278 struct wpa_ssid
*ssid
, int line
,
281 if (hwaddr_aton(value
, ssid
->bssid
)) {
282 wpa_printf(MSG_ERROR
, "Line %d: Invalid BSSID '%s'.",
287 wpa_hexdump(MSG_MSGDUMP
, "BSSID", ssid
->bssid
, ETH_ALEN
);
292 #ifndef NO_CONFIG_WRITE
293 static char * wpa_config_write_bssid(const struct parse_data
*data
,
294 struct wpa_ssid
*ssid
)
299 if (!ssid
->bssid_set
)
302 value
= os_malloc(20);
305 res
= os_snprintf(value
, 20, MACSTR
, MAC2STR(ssid
->bssid
));
306 if (res
< 0 || res
>= 20) {
310 value
[20 - 1] = '\0';
313 #endif /* NO_CONFIG_WRITE */
316 static int wpa_config_parse_psk(const struct parse_data
*data
,
317 struct wpa_ssid
*ssid
, int line
,
321 #ifndef CONFIG_NO_PBKDF2
326 pos
= os_strrchr(value
, '"');
330 len
= os_strlen(value
);
331 if (len
< 8 || len
> 63) {
332 wpa_printf(MSG_ERROR
, "Line %d: Invalid passphrase "
333 "length %lu (expected: 8..63) '%s'.",
334 line
, (unsigned long) len
, value
);
337 wpa_hexdump_ascii_key(MSG_MSGDUMP
, "PSK (ASCII passphrase)",
339 if (ssid
->passphrase
&& os_strlen(ssid
->passphrase
) == len
&&
340 os_memcmp(ssid
->passphrase
, value
, len
) == 0)
343 os_free(ssid
->passphrase
);
344 ssid
->passphrase
= os_malloc(len
+ 1);
345 if (ssid
->passphrase
== NULL
)
347 os_memcpy(ssid
->passphrase
, value
, len
);
348 ssid
->passphrase
[len
] = '\0';
350 #else /* CONFIG_NO_PBKDF2 */
351 wpa_printf(MSG_ERROR
, "Line %d: ASCII passphrase not "
354 #endif /* CONFIG_NO_PBKDF2 */
357 if (hexstr2bin(value
, ssid
->psk
, PMK_LEN
) ||
358 value
[PMK_LEN
* 2] != '\0') {
359 wpa_printf(MSG_ERROR
, "Line %d: Invalid PSK '%s'.",
364 os_free(ssid
->passphrase
);
365 ssid
->passphrase
= NULL
;
368 wpa_hexdump_key(MSG_MSGDUMP
, "PSK", ssid
->psk
, PMK_LEN
);
373 #ifndef NO_CONFIG_WRITE
374 static char * wpa_config_write_psk(const struct parse_data
*data
,
375 struct wpa_ssid
*ssid
)
377 if (ssid
->passphrase
)
378 return wpa_config_write_string_ascii(
379 (const u8
*) ssid
->passphrase
,
380 os_strlen(ssid
->passphrase
));
383 return wpa_config_write_string_hex(ssid
->psk
, PMK_LEN
);
387 #endif /* NO_CONFIG_WRITE */
390 static int wpa_config_parse_proto(const struct parse_data
*data
,
391 struct wpa_ssid
*ssid
, int line
,
394 int val
= 0, last
, errors
= 0;
395 char *start
, *end
, *buf
;
397 buf
= os_strdup(value
);
402 while (*start
!= '\0') {
403 while (*start
== ' ' || *start
== '\t')
408 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
412 if (os_strcmp(start
, "WPA") == 0)
413 val
|= WPA_PROTO_WPA
;
414 else if (os_strcmp(start
, "RSN") == 0 ||
415 os_strcmp(start
, "WPA2") == 0)
416 val
|= WPA_PROTO_RSN
;
418 wpa_printf(MSG_ERROR
, "Line %d: invalid proto '%s'",
430 wpa_printf(MSG_ERROR
,
431 "Line %d: no proto values configured.", line
);
435 wpa_printf(MSG_MSGDUMP
, "proto: 0x%x", val
);
437 return errors
? -1 : 0;
441 #ifndef NO_CONFIG_WRITE
442 static char * wpa_config_write_proto(const struct parse_data
*data
,
443 struct wpa_ssid
*ssid
)
446 char *buf
, *pos
, *end
;
448 pos
= buf
= os_zalloc(10);
453 if (ssid
->proto
& WPA_PROTO_WPA
) {
454 ret
= os_snprintf(pos
, end
- pos
, "%sWPA", first
? "" : " ");
455 if (ret
< 0 || ret
>= end
- pos
)
461 if (ssid
->proto
& WPA_PROTO_RSN
) {
462 ret
= os_snprintf(pos
, end
- pos
, "%sRSN", first
? "" : " ");
463 if (ret
< 0 || ret
>= end
- pos
)
471 #endif /* NO_CONFIG_WRITE */
474 static int wpa_config_parse_key_mgmt(const struct parse_data
*data
,
475 struct wpa_ssid
*ssid
, int line
,
478 int val
= 0, last
, errors
= 0;
479 char *start
, *end
, *buf
;
481 buf
= os_strdup(value
);
486 while (*start
!= '\0') {
487 while (*start
== ' ' || *start
== '\t')
492 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
496 if (os_strcmp(start
, "WPA-PSK") == 0)
497 val
|= WPA_KEY_MGMT_PSK
;
498 else if (os_strcmp(start
, "WPA-EAP") == 0)
499 val
|= WPA_KEY_MGMT_IEEE8021X
;
500 else if (os_strcmp(start
, "IEEE8021X") == 0)
501 val
|= WPA_KEY_MGMT_IEEE8021X_NO_WPA
;
502 else if (os_strcmp(start
, "NONE") == 0)
503 val
|= WPA_KEY_MGMT_NONE
;
504 else if (os_strcmp(start
, "WPA-NONE") == 0)
505 val
|= WPA_KEY_MGMT_WPA_NONE
;
506 #ifdef CONFIG_IEEE80211R
507 else if (os_strcmp(start
, "FT-PSK") == 0)
508 val
|= WPA_KEY_MGMT_FT_PSK
;
509 else if (os_strcmp(start
, "FT-EAP") == 0)
510 val
|= WPA_KEY_MGMT_FT_IEEE8021X
;
511 #endif /* CONFIG_IEEE80211R */
512 #ifdef CONFIG_IEEE80211W
513 else if (os_strcmp(start
, "WPA-PSK-SHA256") == 0)
514 val
|= WPA_KEY_MGMT_PSK_SHA256
;
515 else if (os_strcmp(start
, "WPA-EAP-SHA256") == 0)
516 val
|= WPA_KEY_MGMT_IEEE8021X_SHA256
;
517 #endif /* CONFIG_IEEE80211W */
519 wpa_printf(MSG_ERROR
, "Line %d: invalid key_mgmt '%s'",
531 wpa_printf(MSG_ERROR
,
532 "Line %d: no key_mgmt values configured.", line
);
536 wpa_printf(MSG_MSGDUMP
, "key_mgmt: 0x%x", val
);
537 ssid
->key_mgmt
= val
;
538 return errors
? -1 : 0;
542 #ifndef NO_CONFIG_WRITE
543 static char * wpa_config_write_key_mgmt(const struct parse_data
*data
,
544 struct wpa_ssid
*ssid
)
546 char *buf
, *pos
, *end
;
549 pos
= buf
= os_zalloc(50);
554 if (ssid
->key_mgmt
& WPA_KEY_MGMT_PSK
) {
555 ret
= os_snprintf(pos
, end
- pos
, "%sWPA-PSK",
556 pos
== buf
? "" : " ");
557 if (ret
< 0 || ret
>= end
- pos
) {
564 if (ssid
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
565 ret
= os_snprintf(pos
, end
- pos
, "%sWPA-EAP",
566 pos
== buf
? "" : " ");
567 if (ret
< 0 || ret
>= end
- pos
) {
574 if (ssid
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
575 ret
= os_snprintf(pos
, end
- pos
, "%sIEEE8021X",
576 pos
== buf
? "" : " ");
577 if (ret
< 0 || ret
>= end
- pos
) {
584 if (ssid
->key_mgmt
& WPA_KEY_MGMT_NONE
) {
585 ret
= os_snprintf(pos
, end
- pos
, "%sNONE",
586 pos
== buf
? "" : " ");
587 if (ret
< 0 || ret
>= end
- pos
) {
594 if (ssid
->key_mgmt
& WPA_KEY_MGMT_WPA_NONE
) {
595 ret
= os_snprintf(pos
, end
- pos
, "%sWPA-NONE",
596 pos
== buf
? "" : " ");
597 if (ret
< 0 || ret
>= end
- pos
) {
604 #ifdef CONFIG_IEEE80211R
605 if (ssid
->key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
606 pos
+= os_snprintf(pos
, end
- pos
, "%sFT-PSK",
607 pos
== buf
? "" : " ");
609 if (ssid
->key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
610 pos
+= os_snprintf(pos
, end
- pos
, "%sFT-EAP",
611 pos
== buf
? "" : " ");
612 #endif /* CONFIG_IEEE80211R */
614 #ifdef CONFIG_IEEE80211W
615 if (ssid
->key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
616 pos
+= os_snprintf(pos
, end
- pos
, "%sWPA-PSK-SHA256",
617 pos
== buf
? "" : " ");
619 if (ssid
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
620 pos
+= os_snprintf(pos
, end
- pos
, "%sWPA-EAP-SHA256",
621 pos
== buf
? "" : " ");
622 #endif /* CONFIG_IEEE80211W */
626 #endif /* NO_CONFIG_WRITE */
629 static int wpa_config_parse_cipher(int line
, const char *value
)
632 char *start
, *end
, *buf
;
634 buf
= os_strdup(value
);
639 while (*start
!= '\0') {
640 while (*start
== ' ' || *start
== '\t')
645 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
649 if (os_strcmp(start
, "CCMP") == 0)
650 val
|= WPA_CIPHER_CCMP
;
651 else if (os_strcmp(start
, "TKIP") == 0)
652 val
|= WPA_CIPHER_TKIP
;
653 else if (os_strcmp(start
, "WEP104") == 0)
654 val
|= WPA_CIPHER_WEP104
;
655 else if (os_strcmp(start
, "WEP40") == 0)
656 val
|= WPA_CIPHER_WEP40
;
657 else if (os_strcmp(start
, "NONE") == 0)
658 val
|= WPA_CIPHER_NONE
;
660 wpa_printf(MSG_ERROR
, "Line %d: invalid cipher '%s'.",
673 wpa_printf(MSG_ERROR
, "Line %d: no cipher values configured.",
681 #ifndef NO_CONFIG_WRITE
682 static char * wpa_config_write_cipher(int cipher
)
684 char *buf
, *pos
, *end
;
687 pos
= buf
= os_zalloc(50);
692 if (cipher
& WPA_CIPHER_CCMP
) {
693 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP",
694 pos
== buf
? "" : " ");
695 if (ret
< 0 || ret
>= end
- pos
) {
702 if (cipher
& WPA_CIPHER_TKIP
) {
703 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP",
704 pos
== buf
? "" : " ");
705 if (ret
< 0 || ret
>= end
- pos
) {
712 if (cipher
& WPA_CIPHER_WEP104
) {
713 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
714 pos
== buf
? "" : " ");
715 if (ret
< 0 || ret
>= end
- pos
) {
722 if (cipher
& WPA_CIPHER_WEP40
) {
723 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40",
724 pos
== buf
? "" : " ");
725 if (ret
< 0 || ret
>= end
- pos
) {
732 if (cipher
& WPA_CIPHER_NONE
) {
733 ret
= os_snprintf(pos
, end
- pos
, "%sNONE",
734 pos
== buf
? "" : " ");
735 if (ret
< 0 || ret
>= end
- pos
) {
744 #endif /* NO_CONFIG_WRITE */
747 static int wpa_config_parse_pairwise(const struct parse_data
*data
,
748 struct wpa_ssid
*ssid
, int line
,
752 val
= wpa_config_parse_cipher(line
, value
);
755 if (val
& ~(WPA_CIPHER_CCMP
| WPA_CIPHER_TKIP
| WPA_CIPHER_NONE
)) {
756 wpa_printf(MSG_ERROR
, "Line %d: not allowed pairwise cipher "
757 "(0x%x).", line
, val
);
761 wpa_printf(MSG_MSGDUMP
, "pairwise: 0x%x", val
);
762 ssid
->pairwise_cipher
= val
;
767 #ifndef NO_CONFIG_WRITE
768 static char * wpa_config_write_pairwise(const struct parse_data
*data
,
769 struct wpa_ssid
*ssid
)
771 return wpa_config_write_cipher(ssid
->pairwise_cipher
);
773 #endif /* NO_CONFIG_WRITE */
776 static int wpa_config_parse_group(const struct parse_data
*data
,
777 struct wpa_ssid
*ssid
, int line
,
781 val
= wpa_config_parse_cipher(line
, value
);
784 if (val
& ~(WPA_CIPHER_CCMP
| WPA_CIPHER_TKIP
| WPA_CIPHER_WEP104
|
786 wpa_printf(MSG_ERROR
, "Line %d: not allowed group cipher "
787 "(0x%x).", line
, val
);
791 wpa_printf(MSG_MSGDUMP
, "group: 0x%x", val
);
792 ssid
->group_cipher
= val
;
797 #ifndef NO_CONFIG_WRITE
798 static char * wpa_config_write_group(const struct parse_data
*data
,
799 struct wpa_ssid
*ssid
)
801 return wpa_config_write_cipher(ssid
->group_cipher
);
803 #endif /* NO_CONFIG_WRITE */
806 static int wpa_config_parse_auth_alg(const struct parse_data
*data
,
807 struct wpa_ssid
*ssid
, int line
,
810 int val
= 0, last
, errors
= 0;
811 char *start
, *end
, *buf
;
813 buf
= os_strdup(value
);
818 while (*start
!= '\0') {
819 while (*start
== ' ' || *start
== '\t')
824 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
828 if (os_strcmp(start
, "OPEN") == 0)
829 val
|= WPA_AUTH_ALG_OPEN
;
830 else if (os_strcmp(start
, "SHARED") == 0)
831 val
|= WPA_AUTH_ALG_SHARED
;
832 else if (os_strcmp(start
, "LEAP") == 0)
833 val
|= WPA_AUTH_ALG_LEAP
;
835 wpa_printf(MSG_ERROR
, "Line %d: invalid auth_alg '%s'",
847 wpa_printf(MSG_ERROR
,
848 "Line %d: no auth_alg values configured.", line
);
852 wpa_printf(MSG_MSGDUMP
, "auth_alg: 0x%x", val
);
853 ssid
->auth_alg
= val
;
854 return errors
? -1 : 0;
858 #ifndef NO_CONFIG_WRITE
859 static char * wpa_config_write_auth_alg(const struct parse_data
*data
,
860 struct wpa_ssid
*ssid
)
862 char *buf
, *pos
, *end
;
865 pos
= buf
= os_zalloc(30);
870 if (ssid
->auth_alg
& WPA_AUTH_ALG_OPEN
) {
871 ret
= os_snprintf(pos
, end
- pos
, "%sOPEN",
872 pos
== buf
? "" : " ");
873 if (ret
< 0 || ret
>= end
- pos
) {
880 if (ssid
->auth_alg
& WPA_AUTH_ALG_SHARED
) {
881 ret
= os_snprintf(pos
, end
- pos
, "%sSHARED",
882 pos
== buf
? "" : " ");
883 if (ret
< 0 || ret
>= end
- pos
) {
890 if (ssid
->auth_alg
& WPA_AUTH_ALG_LEAP
) {
891 ret
= os_snprintf(pos
, end
- pos
, "%sLEAP",
892 pos
== buf
? "" : " ");
893 if (ret
< 0 || ret
>= end
- pos
) {
902 #endif /* NO_CONFIG_WRITE */
905 #ifdef IEEE8021X_EAPOL
906 static int wpa_config_parse_eap(const struct parse_data
*data
,
907 struct wpa_ssid
*ssid
, int line
,
910 int last
, errors
= 0;
911 char *start
, *end
, *buf
;
912 struct eap_method_type
*methods
= NULL
, *tmp
;
913 size_t num_methods
= 0;
915 buf
= os_strdup(value
);
920 while (*start
!= '\0') {
921 while (*start
== ' ' || *start
== '\t')
926 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
931 methods
= os_realloc(methods
,
932 (num_methods
+ 1) * sizeof(*methods
));
933 if (methods
== NULL
) {
938 methods
[num_methods
].method
= eap_peer_get_type(
939 start
, &methods
[num_methods
].vendor
);
940 if (methods
[num_methods
].vendor
== EAP_VENDOR_IETF
&&
941 methods
[num_methods
].method
== EAP_TYPE_NONE
) {
942 wpa_printf(MSG_ERROR
, "Line %d: unknown EAP method "
943 "'%s'", line
, start
);
944 wpa_printf(MSG_ERROR
, "You may need to add support for"
945 " this EAP method during wpa_supplicant\n"
946 "build time configuration.\n"
947 "See README for more information.");
949 } else if (methods
[num_methods
].vendor
== EAP_VENDOR_IETF
&&
950 methods
[num_methods
].method
== EAP_TYPE_LEAP
)
962 methods
= os_realloc(methods
, (num_methods
+ 1) * sizeof(*methods
));
963 if (methods
== NULL
) {
967 methods
[num_methods
].vendor
= EAP_VENDOR_IETF
;
968 methods
[num_methods
].method
= EAP_TYPE_NONE
;
971 wpa_hexdump(MSG_MSGDUMP
, "eap methods",
972 (u8
*) methods
, num_methods
* sizeof(*methods
));
973 ssid
->eap
.eap_methods
= methods
;
974 return errors
? -1 : 0;
978 static char * wpa_config_write_eap(const struct parse_data
*data
,
979 struct wpa_ssid
*ssid
)
982 char *buf
, *pos
, *end
;
983 const struct eap_method_type
*eap_methods
= ssid
->eap
.eap_methods
;
986 if (eap_methods
== NULL
)
989 pos
= buf
= os_zalloc(100);
994 for (i
= 0; eap_methods
[i
].vendor
!= EAP_VENDOR_IETF
||
995 eap_methods
[i
].method
!= EAP_TYPE_NONE
; i
++) {
996 name
= eap_get_name(eap_methods
[i
].vendor
,
997 eap_methods
[i
].method
);
999 ret
= os_snprintf(pos
, end
- pos
, "%s%s",
1000 pos
== buf
? "" : " ", name
);
1001 if (ret
< 0 || ret
>= end
- pos
)
1013 static int wpa_config_parse_password(const struct parse_data
*data
,
1014 struct wpa_ssid
*ssid
, int line
,
1019 if (os_strcmp(value
, "NULL") == 0) {
1020 wpa_printf(MSG_DEBUG
, "Unset configuration string 'password'");
1021 os_free(ssid
->eap
.password
);
1022 ssid
->eap
.password
= NULL
;
1023 ssid
->eap
.password_len
= 0;
1027 if (os_strncmp(value
, "hash:", 5) != 0) {
1031 tmp
= wpa_config_parse_string(value
, &res_len
);
1033 wpa_printf(MSG_ERROR
, "Line %d: failed to parse "
1037 wpa_hexdump_ascii(MSG_MSGDUMP
, data
->name
,
1038 (u8
*) tmp
, res_len
);
1040 os_free(ssid
->eap
.password
);
1041 ssid
->eap
.password
= (u8
*) tmp
;
1042 ssid
->eap
.password_len
= res_len
;
1043 ssid
->eap
.flags
&= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH
;
1049 /* NtPasswordHash: hash:<32 hex digits> */
1050 if (os_strlen(value
+ 5) != 2 * 16) {
1051 wpa_printf(MSG_ERROR
, "Line %d: Invalid password hash length "
1052 "(expected 32 hex digits)", line
);
1056 hash
= os_malloc(16);
1060 if (hexstr2bin(value
+ 5, hash
, 16)) {
1062 wpa_printf(MSG_ERROR
, "Line %d: Invalid password hash", line
);
1066 wpa_hexdump_key(MSG_MSGDUMP
, data
->name
, hash
, 16);
1068 os_free(ssid
->eap
.password
);
1069 ssid
->eap
.password
= hash
;
1070 ssid
->eap
.password_len
= 16;
1071 ssid
->eap
.flags
|= EAP_CONFIG_FLAGS_PASSWORD_NTHASH
;
1077 static char * wpa_config_write_password(const struct parse_data
*data
,
1078 struct wpa_ssid
*ssid
)
1082 if (ssid
->eap
.password
== NULL
)
1085 if (!(ssid
->eap
.flags
& EAP_CONFIG_FLAGS_PASSWORD_NTHASH
)) {
1086 return wpa_config_write_string(
1087 ssid
->eap
.password
, ssid
->eap
.password_len
);
1090 buf
= os_malloc(5 + 32 + 1);
1094 os_memcpy(buf
, "hash:", 5);
1095 wpa_snprintf_hex(buf
+ 5, 32 + 1, ssid
->eap
.password
, 16);
1099 #endif /* IEEE8021X_EAPOL */
1102 static int wpa_config_parse_wep_key(u8
*key
, size_t *len
, int line
,
1103 const char *value
, int idx
)
1105 char *buf
, title
[20];
1108 buf
= wpa_config_parse_string(value
, len
);
1110 wpa_printf(MSG_ERROR
, "Line %d: Invalid WEP key %d '%s'.",
1114 if (*len
> MAX_WEP_KEY_LEN
) {
1115 wpa_printf(MSG_ERROR
, "Line %d: Too long WEP key %d '%s'.",
1120 os_memcpy(key
, buf
, *len
);
1122 res
= os_snprintf(title
, sizeof(title
), "wep_key%d", idx
);
1123 if (res
>= 0 && (size_t) res
< sizeof(title
))
1124 wpa_hexdump_key(MSG_MSGDUMP
, title
, key
, *len
);
1129 static int wpa_config_parse_wep_key0(const struct parse_data
*data
,
1130 struct wpa_ssid
*ssid
, int line
,
1133 return wpa_config_parse_wep_key(ssid
->wep_key
[0],
1134 &ssid
->wep_key_len
[0], line
,
1139 static int wpa_config_parse_wep_key1(const struct parse_data
*data
,
1140 struct wpa_ssid
*ssid
, int line
,
1143 return wpa_config_parse_wep_key(ssid
->wep_key
[1],
1144 &ssid
->wep_key_len
[1], line
,
1149 static int wpa_config_parse_wep_key2(const struct parse_data
*data
,
1150 struct wpa_ssid
*ssid
, int line
,
1153 return wpa_config_parse_wep_key(ssid
->wep_key
[2],
1154 &ssid
->wep_key_len
[2], line
,
1159 static int wpa_config_parse_wep_key3(const struct parse_data
*data
,
1160 struct wpa_ssid
*ssid
, int line
,
1163 return wpa_config_parse_wep_key(ssid
->wep_key
[3],
1164 &ssid
->wep_key_len
[3], line
,
1169 #ifndef NO_CONFIG_WRITE
1170 static char * wpa_config_write_wep_key(struct wpa_ssid
*ssid
, int idx
)
1172 if (ssid
->wep_key_len
[idx
] == 0)
1174 return wpa_config_write_string(ssid
->wep_key
[idx
],
1175 ssid
->wep_key_len
[idx
]);
1179 static char * wpa_config_write_wep_key0(const struct parse_data
*data
,
1180 struct wpa_ssid
*ssid
)
1182 return wpa_config_write_wep_key(ssid
, 0);
1186 static char * wpa_config_write_wep_key1(const struct parse_data
*data
,
1187 struct wpa_ssid
*ssid
)
1189 return wpa_config_write_wep_key(ssid
, 1);
1193 static char * wpa_config_write_wep_key2(const struct parse_data
*data
,
1194 struct wpa_ssid
*ssid
)
1196 return wpa_config_write_wep_key(ssid
, 2);
1200 static char * wpa_config_write_wep_key3(const struct parse_data
*data
,
1201 struct wpa_ssid
*ssid
)
1203 return wpa_config_write_wep_key(ssid
, 3);
1205 #endif /* NO_CONFIG_WRITE */
1208 /* Helper macros for network block parser */
1213 /* OFFSET: Get offset of a variable within the wpa_ssid structure */
1214 #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
1216 /* STR: Define a string variable for an ASCII string; f = field name */
1217 #ifdef NO_CONFIG_WRITE
1218 #define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
1219 #define _STRe(f) #f, wpa_config_parse_str, OFFSET(eap.f)
1220 #else /* NO_CONFIG_WRITE */
1221 #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
1222 #define _STRe(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(eap.f)
1223 #endif /* NO_CONFIG_WRITE */
1224 #define STR(f) _STR(f), NULL, NULL, NULL, 0
1225 #define STRe(f) _STRe(f), NULL, NULL, NULL, 0
1226 #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
1227 #define STR_KEYe(f) _STRe(f), NULL, NULL, NULL, 1
1229 /* STR_LEN: Define a string variable with a separate variable for storing the
1230 * data length. Unlike STR(), this can be used to store arbitrary binary data
1231 * (i.e., even nul termination character). */
1232 #define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
1233 #define _STR_LENe(f) _STRe(f), OFFSET(eap.f ## _len)
1234 #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
1235 #define STR_LENe(f) _STR_LENe(f), NULL, NULL, 0
1236 #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
1238 /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
1239 * explicitly specified. */
1240 #define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max)
1241 #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
1242 #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
1244 #ifdef NO_CONFIG_WRITE
1245 #define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
1246 #define _INTe(f) #f, wpa_config_parse_int, OFFSET(eap.f), (void *) 0
1247 #else /* NO_CONFIG_WRITE */
1248 #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
1249 OFFSET(f), (void *) 0
1250 #define _INTe(f) #f, wpa_config_parse_int, wpa_config_write_int, \
1251 OFFSET(eap.f), (void *) 0
1252 #endif /* NO_CONFIG_WRITE */
1254 /* INT: Define an integer variable */
1255 #define INT(f) _INT(f), NULL, NULL, 0
1256 #define INTe(f) _INTe(f), NULL, NULL, 0
1258 /* INT_RANGE: Define an integer variable with allowed value range */
1259 #define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
1261 /* FUNC: Define a configuration variable that uses a custom function for
1262 * parsing and writing the value. */
1263 #ifdef NO_CONFIG_WRITE
1264 #define _FUNC(f) #f, wpa_config_parse_ ## f, NULL, NULL, NULL, NULL
1265 #else /* NO_CONFIG_WRITE */
1266 #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
1267 NULL, NULL, NULL, NULL
1268 #endif /* NO_CONFIG_WRITE */
1269 #define FUNC(f) _FUNC(f), 0
1270 #define FUNC_KEY(f) _FUNC(f), 1
1273 * Table of network configuration variables. This table is used to parse each
1274 * network configuration variable, e.g., each line in wpa_supplicant.conf file
1275 * that is inside a network block.
1277 * This table is generated using the helper macros defined above and with
1278 * generous help from the C pre-processor. The field name is stored as a string
1279 * into .name and for STR and INT types, the offset of the target buffer within
1280 * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
1281 * offset to the field containing the length of the configuration variable.
1282 * .param3 and .param4 can be used to mark the allowed range (length for STR
1283 * and value for INT).
1285 * For each configuration line in wpa_supplicant.conf, the parser goes through
1286 * this table and select the entry that matches with the field name. The parser
1287 * function (.parser) is then called to parse the actual value of the field.
1289 * This kind of mechanism makes it easy to add new configuration parameters,
1290 * since only one line needs to be added into this table and into the
1291 * struct wpa_ssid definition if the new variable is either a string or
1292 * integer. More complex types will need to use their own parser and writer
1295 static const struct parse_data ssid_fields
[] = {
1296 { STR_RANGE(ssid
, 0, MAX_SSID_LEN
) },
1297 { INT_RANGE(scan_ssid
, 0, 1) },
1305 #ifdef IEEE8021X_EAPOL
1307 { STR_LENe(identity
) },
1308 { STR_LENe(anonymous_identity
) },
1312 { STRe(client_cert
) },
1313 { STRe(private_key
) },
1314 { STR_KEYe(private_key_passwd
) },
1316 { STRe(subject_match
) },
1317 { STRe(altsubject_match
) },
1320 { STRe(client_cert2
) },
1321 { STRe(private_key2
) },
1322 { STR_KEYe(private_key2_passwd
) },
1324 { STRe(subject_match2
) },
1325 { STRe(altsubject_match2
) },
1330 { STRe(engine_id
) },
1333 { STRe(ca_cert_id
) },
1336 { STRe(ca_cert2_id
) },
1338 { INT(eapol_flags
) },
1339 #endif /* IEEE8021X_EAPOL */
1340 { FUNC_KEY(wep_key0
) },
1341 { FUNC_KEY(wep_key1
) },
1342 { FUNC_KEY(wep_key2
) },
1343 { FUNC_KEY(wep_key3
) },
1344 { INT(wep_tx_keyidx
) },
1346 #ifdef IEEE8021X_EAPOL
1347 { INT(eap_workaround
) },
1349 { INTe(fragment_size
) },
1350 #endif /* IEEE8021X_EAPOL */
1351 { INT_RANGE(mode
, 0, 1) },
1352 { INT_RANGE(proactive_key_caching
, 0, 1) },
1353 { INT_RANGE(disabled
, 0, 1) },
1355 #ifdef CONFIG_IEEE80211W
1356 { INT_RANGE(ieee80211w
, 0, 2) },
1357 #endif /* CONFIG_IEEE80211W */
1358 { INT_RANGE(peerkey
, 0, 1) },
1359 { INT_RANGE(mixed_cell
, 0, 1) },
1360 { INT_RANGE(frequency
, 0, 10000) },
1361 { INT(wpa_ptk_rekey
) }
1373 #undef STR_RANGE_KEY
1380 #define NUM_SSID_FIELDS (sizeof(ssid_fields) / sizeof(ssid_fields[0]))
1384 * wpa_config_add_prio_network - Add a network to priority lists
1385 * @config: Configuration data from wpa_config_read()
1386 * @ssid: Pointer to the network configuration to be added to the list
1387 * Returns: 0 on success, -1 on failure
1389 * This function is used to add a network block to the priority list of
1390 * networks. This must be called for each network when reading in the full
1391 * configuration. In addition, this can be used indirectly when updating
1392 * priorities by calling wpa_config_update_prio_list().
1394 int wpa_config_add_prio_network(struct wpa_config
*config
,
1395 struct wpa_ssid
*ssid
)
1398 struct wpa_ssid
*prev
, **nlist
;
1401 * Add to an existing priority list if one is available for the
1402 * configured priority level for this network.
1404 for (prio
= 0; prio
< config
->num_prio
; prio
++) {
1405 prev
= config
->pssid
[prio
];
1406 if (prev
->priority
== ssid
->priority
) {
1414 /* First network for this priority - add a new priority list */
1415 nlist
= os_realloc(config
->pssid
,
1416 (config
->num_prio
+ 1) * sizeof(struct wpa_ssid
*));
1420 for (prio
= 0; prio
< config
->num_prio
; prio
++) {
1421 if (nlist
[prio
]->priority
< ssid
->priority
)
1425 os_memmove(&nlist
[prio
+ 1], &nlist
[prio
],
1426 (config
->num_prio
- prio
) * sizeof(struct wpa_ssid
*));
1430 config
->pssid
= nlist
;
1437 * wpa_config_update_prio_list - Update network priority list
1438 * @config: Configuration data from wpa_config_read()
1439 * Returns: 0 on success, -1 on failure
1441 * This function is called to update the priority list of networks in the
1442 * configuration when a network is being added or removed. This is also called
1443 * if a priority for a network is changed.
1445 static int wpa_config_update_prio_list(struct wpa_config
*config
)
1447 struct wpa_ssid
*ssid
;
1450 os_free(config
->pssid
);
1451 config
->pssid
= NULL
;
1452 config
->num_prio
= 0;
1454 ssid
= config
->ssid
;
1457 if (wpa_config_add_prio_network(config
, ssid
) < 0)
1466 #ifdef IEEE8021X_EAPOL
1467 static void eap_peer_config_free(struct eap_peer_config
*eap
)
1469 os_free(eap
->eap_methods
);
1470 os_free(eap
->identity
);
1471 os_free(eap
->anonymous_identity
);
1472 os_free(eap
->password
);
1473 os_free(eap
->ca_cert
);
1474 os_free(eap
->ca_path
);
1475 os_free(eap
->client_cert
);
1476 os_free(eap
->private_key
);
1477 os_free(eap
->private_key_passwd
);
1478 os_free(eap
->dh_file
);
1479 os_free(eap
->subject_match
);
1480 os_free(eap
->altsubject_match
);
1481 os_free(eap
->ca_cert2
);
1482 os_free(eap
->ca_path2
);
1483 os_free(eap
->client_cert2
);
1484 os_free(eap
->private_key2
);
1485 os_free(eap
->private_key2_passwd
);
1486 os_free(eap
->dh_file2
);
1487 os_free(eap
->subject_match2
);
1488 os_free(eap
->altsubject_match2
);
1489 os_free(eap
->phase1
);
1490 os_free(eap
->phase2
);
1493 os_free(eap
->engine_id
);
1494 os_free(eap
->key_id
);
1495 os_free(eap
->cert_id
);
1496 os_free(eap
->ca_cert_id
);
1497 os_free(eap
->key2_id
);
1498 os_free(eap
->cert2_id
);
1499 os_free(eap
->ca_cert2_id
);
1501 os_free(eap
->pending_req_otp
);
1502 os_free(eap
->pac_file
);
1503 os_free(eap
->new_password
);
1505 #endif /* IEEE8021X_EAPOL */
1509 * wpa_config_free_ssid - Free network/ssid configuration data
1510 * @ssid: Configuration data for the network
1512 * This function frees all resources allocated for the network configuration
1515 void wpa_config_free_ssid(struct wpa_ssid
*ssid
)
1517 os_free(ssid
->ssid
);
1518 os_free(ssid
->passphrase
);
1519 #ifdef IEEE8021X_EAPOL
1520 eap_peer_config_free(&ssid
->eap
);
1521 #endif /* IEEE8021X_EAPOL */
1522 os_free(ssid
->id_str
);
1528 * wpa_config_free - Free configuration data
1529 * @config: Configuration data from wpa_config_read()
1531 * This function frees all resources allocated for the configuration data by
1532 * wpa_config_read().
1534 void wpa_config_free(struct wpa_config
*config
)
1536 #ifndef CONFIG_NO_CONFIG_BLOBS
1537 struct wpa_config_blob
*blob
, *prevblob
;
1538 #endif /* CONFIG_NO_CONFIG_BLOBS */
1539 struct wpa_ssid
*ssid
, *prev
= NULL
;
1540 ssid
= config
->ssid
;
1544 wpa_config_free_ssid(prev
);
1547 #ifndef CONFIG_NO_CONFIG_BLOBS
1548 blob
= config
->blobs
;
1553 wpa_config_free_blob(prevblob
);
1555 #endif /* CONFIG_NO_CONFIG_BLOBS */
1557 os_free(config
->ctrl_interface
);
1558 os_free(config
->ctrl_interface_group
);
1559 #ifdef EAP_TLS_OPENSSL
1560 os_free(config
->opensc_engine_path
);
1561 os_free(config
->pkcs11_engine_path
);
1562 os_free(config
->pkcs11_module_path
);
1563 #endif /* EAP_TLS_OPENSSL */
1564 os_free(config
->driver_param
);
1565 os_free(config
->pssid
);
1571 * wpa_config_get_network - Get configured network based on id
1572 * @config: Configuration data from wpa_config_read()
1573 * @id: Unique network id to search for
1574 * Returns: Network configuration or %NULL if not found
1576 struct wpa_ssid
* wpa_config_get_network(struct wpa_config
*config
, int id
)
1578 struct wpa_ssid
*ssid
;
1580 ssid
= config
->ssid
;
1592 * wpa_config_add_network - Add a new network with empty configuration
1593 * @config: Configuration data from wpa_config_read()
1594 * Returns: The new network configuration or %NULL if operation failed
1596 struct wpa_ssid
* wpa_config_add_network(struct wpa_config
*config
)
1599 struct wpa_ssid
*ssid
, *last
= NULL
;
1602 ssid
= config
->ssid
;
1611 ssid
= os_zalloc(sizeof(*ssid
));
1618 config
->ssid
= ssid
;
1620 wpa_config_update_prio_list(config
);
1627 * wpa_config_remove_network - Remove a configured network based on id
1628 * @config: Configuration data from wpa_config_read()
1629 * @id: Unique network id to search for
1630 * Returns: 0 on success, or -1 if the network was not found
1632 int wpa_config_remove_network(struct wpa_config
*config
, int id
)
1634 struct wpa_ssid
*ssid
, *prev
= NULL
;
1636 ssid
= config
->ssid
;
1648 prev
->next
= ssid
->next
;
1650 config
->ssid
= ssid
->next
;
1652 wpa_config_update_prio_list(config
);
1653 wpa_config_free_ssid(ssid
);
1659 * wpa_config_set_network_defaults - Set network default values
1660 * @ssid: Pointer to network configuration data
1662 void wpa_config_set_network_defaults(struct wpa_ssid
*ssid
)
1664 ssid
->proto
= DEFAULT_PROTO
;
1665 ssid
->pairwise_cipher
= DEFAULT_PAIRWISE
;
1666 ssid
->group_cipher
= DEFAULT_GROUP
;
1667 ssid
->key_mgmt
= DEFAULT_KEY_MGMT
;
1668 #ifdef IEEE8021X_EAPOL
1669 ssid
->eapol_flags
= DEFAULT_EAPOL_FLAGS
;
1670 ssid
->eap_workaround
= DEFAULT_EAP_WORKAROUND
;
1671 ssid
->eap
.fragment_size
= DEFAULT_FRAGMENT_SIZE
;
1672 #endif /* IEEE8021X_EAPOL */
1677 * wpa_config_set - Set a variable in network configuration
1678 * @ssid: Pointer to network configuration data
1679 * @var: Variable name, e.g., "ssid"
1680 * @value: Variable value
1681 * @line: Line number in configuration file or 0 if not used
1682 * Returns: 0 on success, -1 on failure
1684 * This function can be used to set network configuration variables based on
1685 * both the configuration file and management interface input. The value
1686 * parameter must be in the same format as the text-based configuration file is
1687 * using. For example, strings are using double quotation marks.
1689 int wpa_config_set(struct wpa_ssid
*ssid
, const char *var
, const char *value
,
1695 if (ssid
== NULL
|| var
== NULL
|| value
== NULL
)
1698 for (i
= 0; i
< NUM_SSID_FIELDS
; i
++) {
1699 const struct parse_data
*field
= &ssid_fields
[i
];
1700 if (os_strcmp(var
, field
->name
) != 0)
1703 if (field
->parser(field
, ssid
, line
, value
)) {
1705 wpa_printf(MSG_ERROR
, "Line %d: failed to "
1706 "parse %s '%s'.", line
, var
, value
);
1712 if (i
== NUM_SSID_FIELDS
) {
1714 wpa_printf(MSG_ERROR
, "Line %d: unknown network field "
1715 "'%s'.", line
, var
);
1724 #ifndef NO_CONFIG_WRITE
1726 * wpa_config_get - Get a variable in network configuration
1727 * @ssid: Pointer to network configuration data
1728 * @var: Variable name, e.g., "ssid"
1729 * Returns: Value of the variable or %NULL on failure
1731 * This function can be used to get network configuration variables. The
1732 * returned value is a copy of the configuration variable in text format, i.e,.
1733 * the same format that the text-based configuration file and wpa_config_set()
1734 * are using for the value. The caller is responsible for freeing the returned
1737 char * wpa_config_get(struct wpa_ssid
*ssid
, const char *var
)
1741 if (ssid
== NULL
|| var
== NULL
)
1744 for (i
= 0; i
< NUM_SSID_FIELDS
; i
++) {
1745 const struct parse_data
*field
= &ssid_fields
[i
];
1746 if (os_strcmp(var
, field
->name
) == 0)
1747 return field
->writer(field
, ssid
);
1755 * wpa_config_get_no_key - Get a variable in network configuration (no keys)
1756 * @ssid: Pointer to network configuration data
1757 * @var: Variable name, e.g., "ssid"
1758 * Returns: Value of the variable or %NULL on failure
1760 * This function can be used to get network configuration variable like
1761 * wpa_config_get(). The only difference is that this functions does not expose
1762 * key/password material from the configuration. In case a key/password field
1763 * is requested, the returned value is an empty string or %NULL if the variable
1764 * is not set or "*" if the variable is set (regardless of its value). The
1765 * returned value is a copy of the configuration variable in text format, i.e,.
1766 * the same format that the text-based configuration file and wpa_config_set()
1767 * are using for the value. The caller is responsible for freeing the returned
1770 char * wpa_config_get_no_key(struct wpa_ssid
*ssid
, const char *var
)
1774 if (ssid
== NULL
|| var
== NULL
)
1777 for (i
= 0; i
< NUM_SSID_FIELDS
; i
++) {
1778 const struct parse_data
*field
= &ssid_fields
[i
];
1779 if (os_strcmp(var
, field
->name
) == 0) {
1780 char *res
= field
->writer(field
, ssid
);
1781 if (field
->key_data
) {
1782 if (res
&& res
[0]) {
1783 wpa_printf(MSG_DEBUG
, "Do not allow "
1784 "key_data field to be "
1787 return os_strdup("*");
1799 #endif /* NO_CONFIG_WRITE */
1803 * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
1804 * @ssid: Pointer to network configuration data
1806 * This function must be called to update WPA PSK when either SSID or the
1807 * passphrase has changed for the network configuration.
1809 void wpa_config_update_psk(struct wpa_ssid
*ssid
)
1811 #ifndef CONFIG_NO_PBKDF2
1812 pbkdf2_sha1(ssid
->passphrase
,
1813 (char *) ssid
->ssid
, ssid
->ssid_len
, 4096,
1814 ssid
->psk
, PMK_LEN
);
1815 wpa_hexdump_key(MSG_MSGDUMP
, "PSK (from passphrase)",
1816 ssid
->psk
, PMK_LEN
);
1818 #endif /* CONFIG_NO_PBKDF2 */
1822 #ifndef CONFIG_NO_CONFIG_BLOBS
1824 * wpa_config_get_blob - Get a named configuration blob
1825 * @config: Configuration data from wpa_config_read()
1826 * @name: Name of the blob
1827 * Returns: Pointer to blob data or %NULL if not found
1829 const struct wpa_config_blob
* wpa_config_get_blob(struct wpa_config
*config
,
1832 struct wpa_config_blob
*blob
= config
->blobs
;
1835 if (os_strcmp(blob
->name
, name
) == 0)
1844 * wpa_config_set_blob - Set or add a named configuration blob
1845 * @config: Configuration data from wpa_config_read()
1846 * @blob: New value for the blob
1848 * Adds a new configuration blob or replaces the current value of an existing
1851 void wpa_config_set_blob(struct wpa_config
*config
,
1852 struct wpa_config_blob
*blob
)
1854 wpa_config_remove_blob(config
, blob
->name
);
1855 blob
->next
= config
->blobs
;
1856 config
->blobs
= blob
;
1861 * wpa_config_free_blob - Free blob data
1862 * @blob: Pointer to blob to be freed
1864 void wpa_config_free_blob(struct wpa_config_blob
*blob
)
1867 os_free(blob
->name
);
1868 os_free(blob
->data
);
1875 * wpa_config_remove_blob - Remove a named configuration blob
1876 * @config: Configuration data from wpa_config_read()
1877 * @name: Name of the blob to remove
1878 * Returns: 0 if blob was removed or -1 if blob was not found
1880 int wpa_config_remove_blob(struct wpa_config
*config
, const char *name
)
1882 struct wpa_config_blob
*pos
= config
->blobs
, *prev
= NULL
;
1885 if (os_strcmp(pos
->name
, name
) == 0) {
1887 prev
->next
= pos
->next
;
1889 config
->blobs
= pos
->next
;
1890 wpa_config_free_blob(pos
);
1899 #endif /* CONFIG_NO_CONFIG_BLOBS */
1903 * wpa_config_alloc_empty - Allocate an empty configuration
1904 * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
1906 * @driver_param: Driver parameters
1907 * Returns: Pointer to allocated configuration data or %NULL on failure
1909 struct wpa_config
* wpa_config_alloc_empty(const char *ctrl_interface
,
1910 const char *driver_param
)
1912 struct wpa_config
*config
;
1914 config
= os_zalloc(sizeof(*config
));
1917 config
->eapol_version
= DEFAULT_EAPOL_VERSION
;
1918 config
->ap_scan
= DEFAULT_AP_SCAN
;
1919 config
->fast_reauth
= DEFAULT_FAST_REAUTH
;
1922 config
->ctrl_interface
= os_strdup(ctrl_interface
);
1924 config
->driver_param
= os_strdup(driver_param
);
1930 #ifndef CONFIG_NO_STDOUT_DEBUG
1932 * wpa_config_debug_dump_networks - Debug dump of configured networks
1933 * @config: Configuration data from wpa_config_read()
1935 void wpa_config_debug_dump_networks(struct wpa_config
*config
)
1938 struct wpa_ssid
*ssid
;
1940 for (prio
= 0; prio
< config
->num_prio
; prio
++) {
1941 ssid
= config
->pssid
[prio
];
1942 wpa_printf(MSG_DEBUG
, "Priority group %d",
1945 wpa_printf(MSG_DEBUG
, " id=%d ssid='%s'",
1947 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
1952 #endif /* CONFIG_NO_STDOUT_DEBUG */