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
12 * See README and COPYING for more details.
22 #include "l2_packet.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[]).
32 /* Configuration variable 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
56 static char * wpa_config_parse_string(const char *value
, size_t *len
)
61 pos
= os_strrchr(value
, '"');
62 if (pos
== NULL
|| pos
[1] != '\0')
65 *len
= os_strlen(value
);
66 return os_strdup(value
);
69 size_t hlen
= os_strlen(value
);
73 str
= os_malloc(*len
);
76 if (hexstr2bin(value
, str
, *len
)) {
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
;
92 tmp
= wpa_config_parse_string(value
, &res_len
);
94 wpa_printf(MSG_ERROR
, "Line %d: failed to parse %s '%s'.",
96 data
->key_data
? "[KEY DATA REMOVED]" : value
);
100 if (data
->key_data
) {
101 wpa_hexdump_ascii_key(MSG_MSGDUMP
, data
->name
,
102 (u8
*) tmp
, res_len
);
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
);
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
);
124 dst
= (char **) (((u8
*) ssid
) + (long) data
->param1
);
125 dst_len
= (size_t *) (((u8
*) ssid
) + (long) data
->param2
);
135 static int is_hex(const u8
*data
, size_t len
)
139 for (i
= 0; i
< len
; i
++) {
140 if (data
[i
] < 32 || data
[i
] >= 127)
147 static char * wpa_config_write_string_ascii(const u8
*value
, size_t len
)
151 buf
= os_malloc(len
+ 3);
155 os_memcpy(buf
+ 1, value
, len
);
163 static char * wpa_config_write_string_hex(const u8
*value
, size_t len
)
167 buf
= os_zalloc(2 * len
+ 1);
170 wpa_snprintf_hex(buf
, 2 * len
+ 1, value
, len
);
176 static char * wpa_config_write_string(const u8
*value
, size_t len
)
181 if (is_hex(value
, len
))
182 return wpa_config_write_string_hex(value
, len
);
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
)
194 src
= (char **) (((u8
*) ssid
) + (long) data
->param1
);
199 len
= *((size_t *) (((u8
*) ssid
) + (long) data
->param2
));
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
)
213 dst
= (int *) (((u8
*) ssid
) + (long) data
->param1
);
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
;
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
;
237 static char * wpa_config_write_int(const struct parse_data
*data
,
238 struct wpa_ssid
*ssid
)
243 src
= (int *) (((u8
*) ssid
) + (long) data
->param1
);
245 value
= os_malloc(20);
248 os_snprintf(value
, 20, "%d", *src
);
249 value
[20 - 1] = '\0';
254 static int wpa_config_parse_bssid(const struct parse_data
*data
,
255 struct wpa_ssid
*ssid
, int line
,
258 if (hwaddr_aton(value
, ssid
->bssid
)) {
259 wpa_printf(MSG_ERROR
, "Line %d: Invalid BSSID '%s'.",
264 wpa_hexdump(MSG_MSGDUMP
, "BSSID", ssid
->bssid
, ETH_ALEN
);
269 static char * wpa_config_write_bssid(const struct parse_data
*data
,
270 struct wpa_ssid
*ssid
)
274 if (!ssid
->bssid_set
)
277 value
= os_malloc(20);
280 os_snprintf(value
, 20, MACSTR
, MAC2STR(ssid
->bssid
));
281 value
[20 - 1] = '\0';
286 static int wpa_config_parse_psk(const struct parse_data
*data
,
287 struct wpa_ssid
*ssid
, int line
,
295 pos
= os_strrchr(value
, '"');
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
);
306 wpa_hexdump_ascii_key(MSG_MSGDUMP
, "PSK (ASCII passphrase)",
308 if (ssid
->passphrase
&& os_strlen(ssid
->passphrase
) == len
&&
309 os_memcmp(ssid
->passphrase
, value
, len
) == 0)
312 os_free(ssid
->passphrase
);
313 ssid
->passphrase
= os_malloc(len
+ 1);
314 if (ssid
->passphrase
== NULL
)
316 os_memcpy(ssid
->passphrase
, value
, len
);
317 ssid
->passphrase
[len
] = '\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'.",
328 os_free(ssid
->passphrase
);
329 ssid
->passphrase
= NULL
;
332 wpa_hexdump_key(MSG_MSGDUMP
, "PSK", ssid
->psk
, PMK_LEN
);
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
));
346 return wpa_config_write_string_hex(ssid
->psk
, PMK_LEN
);
352 static int wpa_config_parse_proto(const struct parse_data
*data
,
353 struct wpa_ssid
*ssid
, int line
,
356 int val
= 0, last
, errors
= 0;
357 char *start
, *end
, *buf
;
359 buf
= os_strdup(value
);
364 while (*start
!= '\0') {
365 while (*start
== ' ' || *start
== '\t')
370 while (*end
!= ' ' && *end
!= '\t' && *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
;
380 wpa_printf(MSG_ERROR
, "Line %d: invalid proto '%s'",
392 wpa_printf(MSG_ERROR
,
393 "Line %d: no proto values configured.", line
);
397 wpa_printf(MSG_MSGDUMP
, "proto: 0x%x", val
);
399 return errors
? -1 : 0;
403 static char * wpa_config_write_proto(const struct parse_data
*data
,
404 struct wpa_ssid
*ssid
)
407 char *buf
, *pos
, *end
;
409 pos
= buf
= os_zalloc(10);
414 if (ssid
->proto
& WPA_PROTO_WPA
) {
415 ret
= os_snprintf(pos
, end
- pos
, "%sWPA", first
? "" : " ");
416 if (ret
< 0 || ret
>= end
- pos
)
422 if (ssid
->proto
& WPA_PROTO_RSN
) {
423 ret
= os_snprintf(pos
, end
- pos
, "%sRSN", first
? "" : " ");
424 if (ret
< 0 || ret
>= end
- pos
)
434 static int wpa_config_parse_key_mgmt(const struct parse_data
*data
,
435 struct wpa_ssid
*ssid
, int line
,
438 int val
= 0, last
, errors
= 0;
439 char *start
, *end
, *buf
;
441 buf
= os_strdup(value
);
446 while (*start
!= '\0') {
447 while (*start
== ' ' || *start
== '\t')
452 while (*end
!= ' ' && *end
!= '\t' && *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
;
467 wpa_printf(MSG_ERROR
, "Line %d: invalid key_mgmt '%s'",
479 wpa_printf(MSG_ERROR
,
480 "Line %d: no key_mgmt values configured.", line
);
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
;
496 pos
= buf
= os_zalloc(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
) {
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
) {
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
) {
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
) {
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
) {
555 static int wpa_config_parse_cipher(int line
, const char *value
)
558 char *start
, *end
, *buf
;
560 buf
= os_strdup(value
);
565 while (*start
!= '\0') {
566 while (*start
== ' ' || *start
== '\t')
571 while (*end
!= ' ' && *end
!= '\t' && *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
;
586 wpa_printf(MSG_ERROR
, "Line %d: invalid cipher '%s'.",
599 wpa_printf(MSG_ERROR
, "Line %d: no cipher values configured.",
607 static char * wpa_config_write_cipher(int cipher
)
609 char *buf
, *pos
, *end
;
612 pos
= buf
= os_zalloc(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
) {
627 if (cipher
& WPA_CIPHER_TKIP
) {
628 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP",
629 pos
== buf
? "" : " ");
630 if (ret
< 0 || ret
>= end
- pos
) {
637 if (cipher
& WPA_CIPHER_WEP104
) {
638 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
639 pos
== buf
? "" : " ");
640 if (ret
< 0 || ret
>= end
- pos
) {
647 if (cipher
& WPA_CIPHER_WEP40
) {
648 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40",
649 pos
== buf
? "" : " ");
650 if (ret
< 0 || ret
>= end
- pos
) {
657 if (cipher
& WPA_CIPHER_NONE
) {
658 ret
= os_snprintf(pos
, end
- pos
, "%sNONE",
659 pos
== buf
? "" : " ");
660 if (ret
< 0 || ret
>= end
- pos
) {
671 static int wpa_config_parse_pairwise(const struct parse_data
*data
,
672 struct wpa_ssid
*ssid
, int line
,
676 val
= wpa_config_parse_cipher(line
, value
);
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
);
685 wpa_printf(MSG_MSGDUMP
, "pairwise: 0x%x", val
);
686 ssid
->pairwise_cipher
= val
;
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
,
703 val
= wpa_config_parse_cipher(line
, value
);
706 if (val
& ~(WPA_CIPHER_CCMP
| WPA_CIPHER_TKIP
| WPA_CIPHER_WEP104
|
708 wpa_printf(MSG_ERROR
, "Line %d: not allowed group cipher "
709 "(0x%x).", line
, val
);
713 wpa_printf(MSG_MSGDUMP
, "group: 0x%x", val
);
714 ssid
->group_cipher
= val
;
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
,
730 int val
= 0, last
, errors
= 0;
731 char *start
, *end
, *buf
;
733 buf
= os_strdup(value
);
738 while (*start
!= '\0') {
739 while (*start
== ' ' || *start
== '\t')
744 while (*end
!= ' ' && *end
!= '\t' && *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
;
755 wpa_printf(MSG_ERROR
, "Line %d: invalid auth_alg '%s'",
767 wpa_printf(MSG_ERROR
,
768 "Line %d: no auth_alg values configured.", line
);
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
;
784 pos
= buf
= os_zalloc(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
) {
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
) {
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
) {
823 #ifdef IEEE8021X_EAPOL
824 static int wpa_config_parse_eap(const struct parse_data
*data
,
825 struct wpa_ssid
*ssid
, int line
,
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
);
838 while (*start
!= '\0') {
839 while (*start
== ' ' || *start
== '\t')
844 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
849 methods
= os_realloc(methods
,
850 (num_methods
+ 1) * sizeof(*methods
));
851 if (methods
== NULL
) {
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.");
867 } else if (methods
[num_methods
].vendor
== EAP_VENDOR_IETF
&&
868 methods
[num_methods
].method
== EAP_TYPE_LEAP
)
880 methods
= os_realloc(methods
, (num_methods
+ 1) * sizeof(*methods
));
881 if (methods
== NULL
) {
885 methods
[num_methods
].vendor
= EAP_VENDOR_IETF
;
886 methods
[num_methods
].method
= EAP_TYPE_NONE
;
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
)
900 char *buf
, *pos
, *end
;
901 const struct eap_method_type
*eap_methods
= ssid
->eap_methods
;
904 if (eap_methods
== NULL
)
907 pos
= buf
= os_zalloc(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
);
917 ret
= os_snprintf(pos
, end
- pos
, "%s%s",
918 pos
== buf
? "" : " ", name
);
919 if (ret
< 0 || ret
>= end
- pos
)
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
);
939 wpa_printf(MSG_ERROR
, "Line %d: Invalid WEP key %d '%s'.",
943 if (*len
> MAX_WEP_KEY_LEN
) {
944 wpa_printf(MSG_ERROR
, "Line %d: Too long WEP key %d '%s'.",
949 os_memcpy(key
, buf
, *len
);
951 os_snprintf(title
, sizeof(title
), "wep_key%d", idx
);
952 wpa_hexdump_key(MSG_MSGDUMP
, title
, key
, *len
);
957 static int wpa_config_parse_wep_key0(const struct parse_data
*data
,
958 struct wpa_ssid
*ssid
, int line
,
961 return wpa_config_parse_wep_key(ssid
->wep_key
[0],
962 &ssid
->wep_key_len
[0], line
,
967 static int wpa_config_parse_wep_key1(const struct parse_data
*data
,
968 struct wpa_ssid
*ssid
, int line
,
971 return wpa_config_parse_wep_key(ssid
->wep_key
[1],
972 &ssid
->wep_key_len
[1], line
,
977 static int wpa_config_parse_wep_key2(const struct parse_data
*data
,
978 struct wpa_ssid
*ssid
, int line
,
981 return wpa_config_parse_wep_key(ssid
->wep_key
[2],
982 &ssid
->wep_key_len
[2], line
,
987 static int wpa_config_parse_wep_key3(const struct parse_data
*data
,
988 struct wpa_ssid
*ssid
, int line
,
991 return wpa_config_parse_wep_key(ssid
->wep_key
[3],
992 &ssid
->wep_key_len
[3], line
,
997 static char * wpa_config_write_wep_key(struct wpa_ssid
*ssid
, int idx
)
999 if (ssid
->wep_key_len
[idx
] == 0)
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 */
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
1099 static const struct parse_data ssid_fields
[] = {
1100 { STR_RANGE(ssid
, 0, MAX_SSID_LEN
) },
1101 { INT_RANGE(scan_ssid
, 0, 1) },
1109 #ifdef IEEE8021X_EAPOL
1111 { STR_LEN(identity
) },
1112 { STR_LEN(anonymous_identity
) },
1113 { STR_RANGE_KEY(eappsk
, EAP_PSK_LEN_MIN
, EAP_PSK_LEN_MAX
) },
1115 { STR_LEN_KEY(password
) },
1118 { STR(client_cert
) },
1119 { STR(private_key
) },
1120 { STR_KEY(private_key_passwd
) },
1122 { STR(subject_match
) },
1123 { STR(altsubject_match
) },
1126 { STR(client_cert2
) },
1127 { STR(private_key2
) },
1128 { STR_KEY(private_key2_passwd
) },
1130 { STR(subject_match2
) },
1131 { STR(altsubject_match2
) },
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
) },
1147 #ifdef IEEE8021X_EAPOL
1148 { INT(eap_workaround
) },
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) },
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) }
1172 #undef STR_RANGE_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
)
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
) {
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
*));
1219 for (prio
= 0; prio
< config
->num_prio
; prio
++) {
1220 if (nlist
[prio
]->priority
< ssid
->priority
)
1224 os_memmove(&nlist
[prio
+ 1], &nlist
[prio
],
1225 (config
->num_prio
- prio
) * sizeof(struct wpa_ssid
*));
1229 config
->pssid
= nlist
;
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
;
1249 os_free(config
->pssid
);
1250 config
->pssid
= NULL
;
1251 config
->num_prio
= 0;
1253 ssid
= config
->ssid
;
1256 if (wpa_config_add_prio_network(config
, ssid
) < 0)
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
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
);
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
);
1303 os_free(ssid
->engine_id
);
1304 os_free(ssid
->key_id
);
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
);
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
;
1330 wpa_config_free_ssid(prev
);
1333 blob
= config
->blobs
;
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
);
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
1358 * Returns: 1 = allowed EAP method, 0 = not allowed
1360 int wpa_config_allowed_eap_method(struct wpa_ssid
*ssid
, int vendor
,
1364 struct eap_method_type
*m
;
1366 if (ssid
== NULL
|| ssid
->eap_methods
== NULL
)
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
)
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
;
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
)
1409 struct wpa_ssid
*ssid
, *last
= NULL
;
1412 ssid
= config
->ssid
;
1421 ssid
= os_zalloc(sizeof(*ssid
));
1428 config
->ssid
= ssid
;
1430 wpa_config_update_prio_list(config
);
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
;
1458 prev
->next
= ssid
->next
;
1460 config
->ssid
= ssid
->next
;
1462 wpa_config_update_prio_list(config
);
1463 wpa_config_free_ssid(ssid
);
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
,
1505 if (ssid
== NULL
|| var
== NULL
|| value
== NULL
)
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)
1513 if (field
->parser(field
, ssid
, line
, value
)) {
1515 wpa_printf(MSG_ERROR
, "Line %d: failed to "
1516 "parse %s '%s'.", line
, var
, value
);
1522 if (i
== NUM_SSID_FIELDS
) {
1524 wpa_printf(MSG_ERROR
, "Line %d: unknown network field "
1525 "'%s'.", line
, var
);
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
1546 char * wpa_config_get(struct wpa_ssid
*ssid
, const char *var
)
1550 if (ssid
== NULL
|| var
== 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
);
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
1579 char * wpa_config_get_no_key(struct wpa_ssid
*ssid
, const char *var
)
1583 if (ssid
== NULL
|| var
== 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 "
1596 return os_strdup("*");
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
);
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
,
1637 struct wpa_config_blob
*blob
= config
->blobs
;
1640 if (os_strcmp(blob
->name
, name
) == 0)
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
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
)
1672 os_free(blob
->name
);
1673 os_free(blob
->data
);
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
;
1690 if (os_strcmp(pos
->name
, name
) == 0) {
1692 prev
->next
= pos
->next
;
1694 config
->blobs
= pos
->next
;
1695 wpa_config_free_blob(pos
);
1707 * wpa_config_alloc_empty - Allocate an empty configuration
1708 * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
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
));
1721 config
->eapol_version
= DEFAULT_EAPOL_VERSION
;
1722 config
->ap_scan
= DEFAULT_AP_SCAN
;
1723 config
->fast_reauth
= DEFAULT_FAST_REAUTH
;
1726 config
->ctrl_interface
= os_strdup(ctrl_interface
);
1728 config
->driver_param
= os_strdup(driver_param
);
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
)
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",
1749 wpa_printf(MSG_DEBUG
, " id=%d ssid='%s'",
1751 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
1756 #endif /* CONFIG_NO_STDOUT_DEBUG */