2 * WPA Supplicant / Configuration parser and common functions
3 * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "utils/uuid.h"
13 #include "crypto/sha1.h"
14 #include "rsn_supp/wpa.h"
15 #include "eap_peer/eap.h"
20 #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE)
21 #define NO_CONFIG_WRITE
25 * Structure for network configuration parsing. This data is used to implement
26 * a generic parser for each network block variable. The table of configuration
27 * variables is defined below in this file (ssid_fields[]).
30 /* Configuration variable name */
33 /* Parser function for this variable */
34 int (*parser
)(const struct parse_data
*data
, struct wpa_ssid
*ssid
,
35 int line
, const char *value
);
37 #ifndef NO_CONFIG_WRITE
38 /* Writer function (i.e., to get the variable in text format from
39 * internal presentation). */
40 char * (*writer
)(const struct parse_data
*data
, struct wpa_ssid
*ssid
);
41 #endif /* NO_CONFIG_WRITE */
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
)
62 pos
= os_strrchr(value
, '"');
63 if (pos
== NULL
|| pos
[1] != '\0')
66 str
= os_malloc(*len
+ 1);
69 os_memcpy(str
, value
, *len
);
74 size_t tlen
, hlen
= os_strlen(value
);
78 str
= os_malloc(tlen
+ 1);
81 if (hexstr2bin(value
, str
, tlen
)) {
92 static int wpa_config_parse_str(const struct parse_data
*data
,
93 struct wpa_ssid
*ssid
,
94 int line
, const char *value
)
96 size_t res_len
, *dst_len
;
99 if (os_strcmp(value
, "NULL") == 0) {
100 wpa_printf(MSG_DEBUG
, "Unset configuration string '%s'",
107 tmp
= wpa_config_parse_string(value
, &res_len
);
109 wpa_printf(MSG_ERROR
, "Line %d: failed to parse %s '%s'.",
111 data
->key_data
? "[KEY DATA REMOVED]" : value
);
115 if (data
->key_data
) {
116 wpa_hexdump_ascii_key(MSG_MSGDUMP
, data
->name
,
117 (u8
*) tmp
, res_len
);
119 wpa_hexdump_ascii(MSG_MSGDUMP
, data
->name
,
120 (u8
*) tmp
, res_len
);
123 if (data
->param3
&& res_len
< (size_t) data
->param3
) {
124 wpa_printf(MSG_ERROR
, "Line %d: too short %s (len=%lu "
125 "min_len=%ld)", line
, data
->name
,
126 (unsigned long) res_len
, (long) data
->param3
);
131 if (data
->param4
&& res_len
> (size_t) data
->param4
) {
132 wpa_printf(MSG_ERROR
, "Line %d: too long %s (len=%lu "
133 "max_len=%ld)", line
, data
->name
,
134 (unsigned long) res_len
, (long) data
->param4
);
140 dst
= (char **) (((u8
*) ssid
) + (long) data
->param1
);
141 dst_len
= (size_t *) (((u8
*) ssid
) + (long) data
->param2
);
151 #ifndef NO_CONFIG_WRITE
152 static int is_hex(const u8
*data
, size_t len
)
156 for (i
= 0; i
< len
; i
++) {
157 if (data
[i
] < 32 || data
[i
] >= 127)
164 static char * wpa_config_write_string_ascii(const u8
*value
, size_t len
)
168 buf
= os_malloc(len
+ 3);
172 os_memcpy(buf
+ 1, value
, len
);
180 static char * wpa_config_write_string_hex(const u8
*value
, size_t len
)
184 buf
= os_zalloc(2 * len
+ 1);
187 wpa_snprintf_hex(buf
, 2 * len
+ 1, value
, len
);
193 static char * wpa_config_write_string(const u8
*value
, size_t len
)
198 if (is_hex(value
, len
))
199 return wpa_config_write_string_hex(value
, len
);
201 return wpa_config_write_string_ascii(value
, len
);
205 static char * wpa_config_write_str(const struct parse_data
*data
,
206 struct wpa_ssid
*ssid
)
211 src
= (char **) (((u8
*) ssid
) + (long) data
->param1
);
216 len
= *((size_t *) (((u8
*) ssid
) + (long) data
->param2
));
218 len
= os_strlen(*src
);
220 return wpa_config_write_string((const u8
*) *src
, len
);
222 #endif /* NO_CONFIG_WRITE */
225 static int wpa_config_parse_int(const struct parse_data
*data
,
226 struct wpa_ssid
*ssid
,
227 int line
, const char *value
)
231 dst
= (int *) (((u8
*) ssid
) + (long) data
->param1
);
233 wpa_printf(MSG_MSGDUMP
, "%s=%d (0x%x)", data
->name
, *dst
, *dst
);
235 if (data
->param3
&& *dst
< (long) data
->param3
) {
236 wpa_printf(MSG_ERROR
, "Line %d: too small %s (value=%d "
237 "min_value=%ld)", line
, data
->name
, *dst
,
238 (long) data
->param3
);
239 *dst
= (long) data
->param3
;
243 if (data
->param4
&& *dst
> (long) data
->param4
) {
244 wpa_printf(MSG_ERROR
, "Line %d: too large %s (value=%d "
245 "max_value=%ld)", line
, data
->name
, *dst
,
246 (long) data
->param4
);
247 *dst
= (long) data
->param4
;
255 #ifndef NO_CONFIG_WRITE
256 static char * wpa_config_write_int(const struct parse_data
*data
,
257 struct wpa_ssid
*ssid
)
262 src
= (int *) (((u8
*) ssid
) + (long) data
->param1
);
264 value
= os_malloc(20);
267 res
= os_snprintf(value
, 20, "%d", *src
);
268 if (res
< 0 || res
>= 20) {
272 value
[20 - 1] = '\0';
275 #endif /* NO_CONFIG_WRITE */
278 static int wpa_config_parse_bssid(const struct parse_data
*data
,
279 struct wpa_ssid
*ssid
, int line
,
282 if (value
[0] == '\0' || os_strcmp(value
, "\"\"") == 0 ||
283 os_strcmp(value
, "any") == 0) {
285 wpa_printf(MSG_MSGDUMP
, "BSSID any");
288 if (hwaddr_aton(value
, ssid
->bssid
)) {
289 wpa_printf(MSG_ERROR
, "Line %d: Invalid BSSID '%s'.",
294 wpa_hexdump(MSG_MSGDUMP
, "BSSID", ssid
->bssid
, ETH_ALEN
);
299 #ifndef NO_CONFIG_WRITE
300 static char * wpa_config_write_bssid(const struct parse_data
*data
,
301 struct wpa_ssid
*ssid
)
306 if (!ssid
->bssid_set
)
309 value
= os_malloc(20);
312 res
= os_snprintf(value
, 20, MACSTR
, MAC2STR(ssid
->bssid
));
313 if (res
< 0 || res
>= 20) {
317 value
[20 - 1] = '\0';
320 #endif /* NO_CONFIG_WRITE */
323 static int wpa_config_parse_psk(const struct parse_data
*data
,
324 struct wpa_ssid
*ssid
, int line
,
327 #ifdef CONFIG_EXT_PASSWORD
328 if (os_strncmp(value
, "ext:", 4) == 0) {
329 os_free(ssid
->passphrase
);
330 ssid
->passphrase
= NULL
;
332 os_free(ssid
->ext_psk
);
333 ssid
->ext_psk
= os_strdup(value
+ 4);
334 if (ssid
->ext_psk
== NULL
)
336 wpa_printf(MSG_DEBUG
, "PSK: External password '%s'",
340 #endif /* CONFIG_EXT_PASSWORD */
343 #ifndef CONFIG_NO_PBKDF2
348 pos
= os_strrchr(value
, '"');
352 len
= os_strlen(value
);
353 if (len
< 8 || len
> 63) {
354 wpa_printf(MSG_ERROR
, "Line %d: Invalid passphrase "
355 "length %lu (expected: 8..63) '%s'.",
356 line
, (unsigned long) len
, value
);
359 wpa_hexdump_ascii_key(MSG_MSGDUMP
, "PSK (ASCII passphrase)",
361 if (ssid
->passphrase
&& os_strlen(ssid
->passphrase
) == len
&&
362 os_memcmp(ssid
->passphrase
, value
, len
) == 0)
365 os_free(ssid
->passphrase
);
366 ssid
->passphrase
= os_malloc(len
+ 1);
367 if (ssid
->passphrase
== NULL
)
369 os_memcpy(ssid
->passphrase
, value
, len
);
370 ssid
->passphrase
[len
] = '\0';
372 #else /* CONFIG_NO_PBKDF2 */
373 wpa_printf(MSG_ERROR
, "Line %d: ASCII passphrase not "
376 #endif /* CONFIG_NO_PBKDF2 */
379 if (hexstr2bin(value
, ssid
->psk
, PMK_LEN
) ||
380 value
[PMK_LEN
* 2] != '\0') {
381 wpa_printf(MSG_ERROR
, "Line %d: Invalid PSK '%s'.",
386 os_free(ssid
->passphrase
);
387 ssid
->passphrase
= NULL
;
390 wpa_hexdump_key(MSG_MSGDUMP
, "PSK", ssid
->psk
, PMK_LEN
);
395 #ifndef NO_CONFIG_WRITE
396 static char * wpa_config_write_psk(const struct parse_data
*data
,
397 struct wpa_ssid
*ssid
)
399 #ifdef CONFIG_EXT_PASSWORD
401 size_t len
= 4 + os_strlen(ssid
->ext_psk
) + 1;
402 char *buf
= os_malloc(len
);
405 os_snprintf(buf
, len
, "ext:%s", ssid
->ext_psk
);
408 #endif /* CONFIG_EXT_PASSWORD */
410 if (ssid
->passphrase
)
411 return wpa_config_write_string_ascii(
412 (const u8
*) ssid
->passphrase
,
413 os_strlen(ssid
->passphrase
));
416 return wpa_config_write_string_hex(ssid
->psk
, PMK_LEN
);
420 #endif /* NO_CONFIG_WRITE */
423 static int wpa_config_parse_proto(const struct parse_data
*data
,
424 struct wpa_ssid
*ssid
, int line
,
427 int val
= 0, last
, errors
= 0;
428 char *start
, *end
, *buf
;
430 buf
= os_strdup(value
);
435 while (*start
!= '\0') {
436 while (*start
== ' ' || *start
== '\t')
441 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
445 if (os_strcmp(start
, "WPA") == 0)
446 val
|= WPA_PROTO_WPA
;
447 else if (os_strcmp(start
, "RSN") == 0 ||
448 os_strcmp(start
, "WPA2") == 0)
449 val
|= WPA_PROTO_RSN
;
451 wpa_printf(MSG_ERROR
, "Line %d: invalid proto '%s'",
463 wpa_printf(MSG_ERROR
,
464 "Line %d: no proto values configured.", line
);
468 wpa_printf(MSG_MSGDUMP
, "proto: 0x%x", val
);
470 return errors
? -1 : 0;
474 #ifndef NO_CONFIG_WRITE
475 static char * wpa_config_write_proto(const struct parse_data
*data
,
476 struct wpa_ssid
*ssid
)
479 char *buf
, *pos
, *end
;
481 pos
= buf
= os_zalloc(10);
486 if (ssid
->proto
& WPA_PROTO_WPA
) {
487 ret
= os_snprintf(pos
, end
- pos
, "%sWPA", first
? "" : " ");
488 if (ret
< 0 || ret
>= end
- pos
)
494 if (ssid
->proto
& WPA_PROTO_RSN
) {
495 ret
= os_snprintf(pos
, end
- pos
, "%sRSN", first
? "" : " ");
496 if (ret
< 0 || ret
>= end
- pos
)
504 #endif /* NO_CONFIG_WRITE */
507 static int wpa_config_parse_key_mgmt(const struct parse_data
*data
,
508 struct wpa_ssid
*ssid
, int line
,
511 int val
= 0, last
, errors
= 0;
512 char *start
, *end
, *buf
;
514 buf
= os_strdup(value
);
519 while (*start
!= '\0') {
520 while (*start
== ' ' || *start
== '\t')
525 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
529 if (os_strcmp(start
, "WPA-PSK") == 0)
530 val
|= WPA_KEY_MGMT_PSK
;
531 else if (os_strcmp(start
, "WPA-EAP") == 0)
532 val
|= WPA_KEY_MGMT_IEEE8021X
;
533 else if (os_strcmp(start
, "IEEE8021X") == 0)
534 val
|= WPA_KEY_MGMT_IEEE8021X_NO_WPA
;
535 else if (os_strcmp(start
, "NONE") == 0)
536 val
|= WPA_KEY_MGMT_NONE
;
537 else if (os_strcmp(start
, "WPA-NONE") == 0)
538 val
|= WPA_KEY_MGMT_WPA_NONE
;
539 #ifdef CONFIG_IEEE80211R
540 else if (os_strcmp(start
, "FT-PSK") == 0)
541 val
|= WPA_KEY_MGMT_FT_PSK
;
542 else if (os_strcmp(start
, "FT-EAP") == 0)
543 val
|= WPA_KEY_MGMT_FT_IEEE8021X
;
544 #endif /* CONFIG_IEEE80211R */
545 #ifdef CONFIG_IEEE80211W
546 else if (os_strcmp(start
, "WPA-PSK-SHA256") == 0)
547 val
|= WPA_KEY_MGMT_PSK_SHA256
;
548 else if (os_strcmp(start
, "WPA-EAP-SHA256") == 0)
549 val
|= WPA_KEY_MGMT_IEEE8021X_SHA256
;
550 #endif /* CONFIG_IEEE80211W */
552 else if (os_strcmp(start
, "WPS") == 0)
553 val
|= WPA_KEY_MGMT_WPS
;
554 #endif /* CONFIG_WPS */
556 wpa_printf(MSG_ERROR
, "Line %d: invalid key_mgmt '%s'",
568 wpa_printf(MSG_ERROR
,
569 "Line %d: no key_mgmt values configured.", line
);
573 wpa_printf(MSG_MSGDUMP
, "key_mgmt: 0x%x", val
);
574 ssid
->key_mgmt
= val
;
575 return errors
? -1 : 0;
579 #ifndef NO_CONFIG_WRITE
580 static char * wpa_config_write_key_mgmt(const struct parse_data
*data
,
581 struct wpa_ssid
*ssid
)
583 char *buf
, *pos
, *end
;
586 pos
= buf
= os_zalloc(50);
591 if (ssid
->key_mgmt
& WPA_KEY_MGMT_PSK
) {
592 ret
= os_snprintf(pos
, end
- pos
, "%sWPA-PSK",
593 pos
== buf
? "" : " ");
594 if (ret
< 0 || ret
>= end
- pos
) {
601 if (ssid
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X
) {
602 ret
= os_snprintf(pos
, end
- pos
, "%sWPA-EAP",
603 pos
== buf
? "" : " ");
604 if (ret
< 0 || ret
>= end
- pos
) {
611 if (ssid
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
612 ret
= os_snprintf(pos
, end
- pos
, "%sIEEE8021X",
613 pos
== buf
? "" : " ");
614 if (ret
< 0 || ret
>= end
- pos
) {
621 if (ssid
->key_mgmt
& WPA_KEY_MGMT_NONE
) {
622 ret
= os_snprintf(pos
, end
- pos
, "%sNONE",
623 pos
== buf
? "" : " ");
624 if (ret
< 0 || ret
>= end
- pos
) {
631 if (ssid
->key_mgmt
& WPA_KEY_MGMT_WPA_NONE
) {
632 ret
= os_snprintf(pos
, end
- pos
, "%sWPA-NONE",
633 pos
== buf
? "" : " ");
634 if (ret
< 0 || ret
>= end
- pos
) {
641 #ifdef CONFIG_IEEE80211R
642 if (ssid
->key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
643 pos
+= os_snprintf(pos
, end
- pos
, "%sFT-PSK",
644 pos
== buf
? "" : " ");
646 if (ssid
->key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
647 pos
+= os_snprintf(pos
, end
- pos
, "%sFT-EAP",
648 pos
== buf
? "" : " ");
649 #endif /* CONFIG_IEEE80211R */
651 #ifdef CONFIG_IEEE80211W
652 if (ssid
->key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
653 pos
+= os_snprintf(pos
, end
- pos
, "%sWPA-PSK-SHA256",
654 pos
== buf
? "" : " ");
656 if (ssid
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
657 pos
+= os_snprintf(pos
, end
- pos
, "%sWPA-EAP-SHA256",
658 pos
== buf
? "" : " ");
659 #endif /* CONFIG_IEEE80211W */
662 if (ssid
->key_mgmt
& WPA_KEY_MGMT_WPS
)
663 pos
+= os_snprintf(pos
, end
- pos
, "%sWPS",
664 pos
== buf
? "" : " ");
665 #endif /* CONFIG_WPS */
669 #endif /* NO_CONFIG_WRITE */
672 static int wpa_config_parse_cipher(int line
, const char *value
)
675 char *start
, *end
, *buf
;
677 buf
= os_strdup(value
);
682 while (*start
!= '\0') {
683 while (*start
== ' ' || *start
== '\t')
688 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
692 if (os_strcmp(start
, "CCMP") == 0)
693 val
|= WPA_CIPHER_CCMP
;
694 else if (os_strcmp(start
, "TKIP") == 0)
695 val
|= WPA_CIPHER_TKIP
;
696 else if (os_strcmp(start
, "WEP104") == 0)
697 val
|= WPA_CIPHER_WEP104
;
698 else if (os_strcmp(start
, "WEP40") == 0)
699 val
|= WPA_CIPHER_WEP40
;
700 else if (os_strcmp(start
, "NONE") == 0)
701 val
|= WPA_CIPHER_NONE
;
703 wpa_printf(MSG_ERROR
, "Line %d: invalid cipher '%s'.",
716 wpa_printf(MSG_ERROR
, "Line %d: no cipher values configured.",
724 #ifndef NO_CONFIG_WRITE
725 static char * wpa_config_write_cipher(int cipher
)
727 char *buf
, *pos
, *end
;
730 pos
= buf
= os_zalloc(50);
735 if (cipher
& WPA_CIPHER_CCMP
) {
736 ret
= os_snprintf(pos
, end
- pos
, "%sCCMP",
737 pos
== buf
? "" : " ");
738 if (ret
< 0 || ret
>= end
- pos
) {
745 if (cipher
& WPA_CIPHER_TKIP
) {
746 ret
= os_snprintf(pos
, end
- pos
, "%sTKIP",
747 pos
== buf
? "" : " ");
748 if (ret
< 0 || ret
>= end
- pos
) {
755 if (cipher
& WPA_CIPHER_WEP104
) {
756 ret
= os_snprintf(pos
, end
- pos
, "%sWEP104",
757 pos
== buf
? "" : " ");
758 if (ret
< 0 || ret
>= end
- pos
) {
765 if (cipher
& WPA_CIPHER_WEP40
) {
766 ret
= os_snprintf(pos
, end
- pos
, "%sWEP40",
767 pos
== buf
? "" : " ");
768 if (ret
< 0 || ret
>= end
- pos
) {
775 if (cipher
& WPA_CIPHER_NONE
) {
776 ret
= os_snprintf(pos
, end
- pos
, "%sNONE",
777 pos
== buf
? "" : " ");
778 if (ret
< 0 || ret
>= end
- pos
) {
787 #endif /* NO_CONFIG_WRITE */
790 static int wpa_config_parse_pairwise(const struct parse_data
*data
,
791 struct wpa_ssid
*ssid
, int line
,
795 val
= wpa_config_parse_cipher(line
, value
);
798 if (val
& ~(WPA_CIPHER_CCMP
| WPA_CIPHER_TKIP
| WPA_CIPHER_NONE
)) {
799 wpa_printf(MSG_ERROR
, "Line %d: not allowed pairwise cipher "
800 "(0x%x).", line
, val
);
804 wpa_printf(MSG_MSGDUMP
, "pairwise: 0x%x", val
);
805 ssid
->pairwise_cipher
= val
;
810 #ifndef NO_CONFIG_WRITE
811 static char * wpa_config_write_pairwise(const struct parse_data
*data
,
812 struct wpa_ssid
*ssid
)
814 return wpa_config_write_cipher(ssid
->pairwise_cipher
);
816 #endif /* NO_CONFIG_WRITE */
819 static int wpa_config_parse_group(const struct parse_data
*data
,
820 struct wpa_ssid
*ssid
, int line
,
824 val
= wpa_config_parse_cipher(line
, value
);
827 if (val
& ~(WPA_CIPHER_CCMP
| WPA_CIPHER_TKIP
| WPA_CIPHER_WEP104
|
829 wpa_printf(MSG_ERROR
, "Line %d: not allowed group cipher "
830 "(0x%x).", line
, val
);
834 wpa_printf(MSG_MSGDUMP
, "group: 0x%x", val
);
835 ssid
->group_cipher
= val
;
840 #ifndef NO_CONFIG_WRITE
841 static char * wpa_config_write_group(const struct parse_data
*data
,
842 struct wpa_ssid
*ssid
)
844 return wpa_config_write_cipher(ssid
->group_cipher
);
846 #endif /* NO_CONFIG_WRITE */
849 static int wpa_config_parse_auth_alg(const struct parse_data
*data
,
850 struct wpa_ssid
*ssid
, int line
,
853 int val
= 0, last
, errors
= 0;
854 char *start
, *end
, *buf
;
856 buf
= os_strdup(value
);
861 while (*start
!= '\0') {
862 while (*start
== ' ' || *start
== '\t')
867 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
871 if (os_strcmp(start
, "OPEN") == 0)
872 val
|= WPA_AUTH_ALG_OPEN
;
873 else if (os_strcmp(start
, "SHARED") == 0)
874 val
|= WPA_AUTH_ALG_SHARED
;
875 else if (os_strcmp(start
, "LEAP") == 0)
876 val
|= WPA_AUTH_ALG_LEAP
;
878 wpa_printf(MSG_ERROR
, "Line %d: invalid auth_alg '%s'",
890 wpa_printf(MSG_ERROR
,
891 "Line %d: no auth_alg values configured.", line
);
895 wpa_printf(MSG_MSGDUMP
, "auth_alg: 0x%x", val
);
896 ssid
->auth_alg
= val
;
897 return errors
? -1 : 0;
901 #ifndef NO_CONFIG_WRITE
902 static char * wpa_config_write_auth_alg(const struct parse_data
*data
,
903 struct wpa_ssid
*ssid
)
905 char *buf
, *pos
, *end
;
908 pos
= buf
= os_zalloc(30);
913 if (ssid
->auth_alg
& WPA_AUTH_ALG_OPEN
) {
914 ret
= os_snprintf(pos
, end
- pos
, "%sOPEN",
915 pos
== buf
? "" : " ");
916 if (ret
< 0 || ret
>= end
- pos
) {
923 if (ssid
->auth_alg
& WPA_AUTH_ALG_SHARED
) {
924 ret
= os_snprintf(pos
, end
- pos
, "%sSHARED",
925 pos
== buf
? "" : " ");
926 if (ret
< 0 || ret
>= end
- pos
) {
933 if (ssid
->auth_alg
& WPA_AUTH_ALG_LEAP
) {
934 ret
= os_snprintf(pos
, end
- pos
, "%sLEAP",
935 pos
== buf
? "" : " ");
936 if (ret
< 0 || ret
>= end
- pos
) {
945 #endif /* NO_CONFIG_WRITE */
948 static int * wpa_config_parse_freqs(const struct parse_data
*data
,
949 struct wpa_ssid
*ssid
, int line
,
958 freqs
= os_zalloc((len
+ 1) * sizeof(int));
969 n
= os_realloc(freqs
, (len
* 2 + 1) * sizeof(int));
974 for (i
= len
; i
<= len
* 2; i
++)
980 freqs
[used
] = atoi(pos
);
981 if (freqs
[used
] == 0)
984 pos
= os_strchr(pos
+ 1, ' ');
991 static int wpa_config_parse_scan_freq(const struct parse_data
*data
,
992 struct wpa_ssid
*ssid
, int line
,
997 freqs
= wpa_config_parse_freqs(data
, ssid
, line
, value
);
1000 os_free(ssid
->scan_freq
);
1001 ssid
->scan_freq
= freqs
;
1007 static int wpa_config_parse_freq_list(const struct parse_data
*data
,
1008 struct wpa_ssid
*ssid
, int line
,
1013 freqs
= wpa_config_parse_freqs(data
, ssid
, line
, value
);
1016 os_free(ssid
->freq_list
);
1017 ssid
->freq_list
= freqs
;
1023 #ifndef NO_CONFIG_WRITE
1024 static char * wpa_config_write_freqs(const struct parse_data
*data
,
1027 char *buf
, *pos
, *end
;
1035 for (i
= 0; freqs
[i
]; i
++)
1038 pos
= buf
= os_zalloc(10 * count
+ 1);
1041 end
= buf
+ 10 * count
+ 1;
1043 for (i
= 0; freqs
[i
]; i
++) {
1044 ret
= os_snprintf(pos
, end
- pos
, "%s%u",
1045 i
== 0 ? "" : " ", freqs
[i
]);
1046 if (ret
< 0 || ret
>= end
- pos
) {
1057 static char * wpa_config_write_scan_freq(const struct parse_data
*data
,
1058 struct wpa_ssid
*ssid
)
1060 return wpa_config_write_freqs(data
, ssid
->scan_freq
);
1064 static char * wpa_config_write_freq_list(const struct parse_data
*data
,
1065 struct wpa_ssid
*ssid
)
1067 return wpa_config_write_freqs(data
, ssid
->freq_list
);
1069 #endif /* NO_CONFIG_WRITE */
1072 #ifdef IEEE8021X_EAPOL
1073 static int wpa_config_parse_eap(const struct parse_data
*data
,
1074 struct wpa_ssid
*ssid
, int line
,
1077 int last
, errors
= 0;
1078 char *start
, *end
, *buf
;
1079 struct eap_method_type
*methods
= NULL
, *tmp
;
1080 size_t num_methods
= 0;
1082 buf
= os_strdup(value
);
1087 while (*start
!= '\0') {
1088 while (*start
== ' ' || *start
== '\t')
1093 while (*end
!= ' ' && *end
!= '\t' && *end
!= '\0')
1095 last
= *end
== '\0';
1098 methods
= os_realloc(methods
,
1099 (num_methods
+ 1) * sizeof(*methods
));
1100 if (methods
== NULL
) {
1105 methods
[num_methods
].method
= eap_peer_get_type(
1106 start
, &methods
[num_methods
].vendor
);
1107 if (methods
[num_methods
].vendor
== EAP_VENDOR_IETF
&&
1108 methods
[num_methods
].method
== EAP_TYPE_NONE
) {
1109 wpa_printf(MSG_ERROR
, "Line %d: unknown EAP method "
1110 "'%s'", line
, start
);
1111 wpa_printf(MSG_ERROR
, "You may need to add support for"
1112 " this EAP method during wpa_supplicant\n"
1113 "build time configuration.\n"
1114 "See README for more information.");
1116 } else if (methods
[num_methods
].vendor
== EAP_VENDOR_IETF
&&
1117 methods
[num_methods
].method
== EAP_TYPE_LEAP
)
1129 methods
= os_realloc(methods
, (num_methods
+ 1) * sizeof(*methods
));
1130 if (methods
== NULL
) {
1134 methods
[num_methods
].vendor
= EAP_VENDOR_IETF
;
1135 methods
[num_methods
].method
= EAP_TYPE_NONE
;
1138 wpa_hexdump(MSG_MSGDUMP
, "eap methods",
1139 (u8
*) methods
, num_methods
* sizeof(*methods
));
1140 os_free(ssid
->eap
.eap_methods
);
1141 ssid
->eap
.eap_methods
= methods
;
1142 return errors
? -1 : 0;
1146 static char * wpa_config_write_eap(const struct parse_data
*data
,
1147 struct wpa_ssid
*ssid
)
1150 char *buf
, *pos
, *end
;
1151 const struct eap_method_type
*eap_methods
= ssid
->eap
.eap_methods
;
1154 if (eap_methods
== NULL
)
1157 pos
= buf
= os_zalloc(100);
1162 for (i
= 0; eap_methods
[i
].vendor
!= EAP_VENDOR_IETF
||
1163 eap_methods
[i
].method
!= EAP_TYPE_NONE
; i
++) {
1164 name
= eap_get_name(eap_methods
[i
].vendor
,
1165 eap_methods
[i
].method
);
1167 ret
= os_snprintf(pos
, end
- pos
, "%s%s",
1168 pos
== buf
? "" : " ", name
);
1169 if (ret
< 0 || ret
>= end
- pos
)
1181 static int wpa_config_parse_password(const struct parse_data
*data
,
1182 struct wpa_ssid
*ssid
, int line
,
1187 if (os_strcmp(value
, "NULL") == 0) {
1188 wpa_printf(MSG_DEBUG
, "Unset configuration string 'password'");
1189 os_free(ssid
->eap
.password
);
1190 ssid
->eap
.password
= NULL
;
1191 ssid
->eap
.password_len
= 0;
1195 if (os_strncmp(value
, "hash:", 5) != 0) {
1199 tmp
= wpa_config_parse_string(value
, &res_len
);
1201 wpa_printf(MSG_ERROR
, "Line %d: failed to parse "
1205 wpa_hexdump_ascii_key(MSG_MSGDUMP
, data
->name
,
1206 (u8
*) tmp
, res_len
);
1208 os_free(ssid
->eap
.password
);
1209 ssid
->eap
.password
= (u8
*) tmp
;
1210 ssid
->eap
.password_len
= res_len
;
1211 ssid
->eap
.flags
&= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH
;
1217 /* NtPasswordHash: hash:<32 hex digits> */
1218 if (os_strlen(value
+ 5) != 2 * 16) {
1219 wpa_printf(MSG_ERROR
, "Line %d: Invalid password hash length "
1220 "(expected 32 hex digits)", line
);
1224 hash
= os_malloc(16);
1228 if (hexstr2bin(value
+ 5, hash
, 16)) {
1230 wpa_printf(MSG_ERROR
, "Line %d: Invalid password hash", line
);
1234 wpa_hexdump_key(MSG_MSGDUMP
, data
->name
, hash
, 16);
1236 os_free(ssid
->eap
.password
);
1237 ssid
->eap
.password
= hash
;
1238 ssid
->eap
.password_len
= 16;
1239 ssid
->eap
.flags
|= EAP_CONFIG_FLAGS_PASSWORD_NTHASH
;
1245 static char * wpa_config_write_password(const struct parse_data
*data
,
1246 struct wpa_ssid
*ssid
)
1250 if (ssid
->eap
.password
== NULL
)
1253 if (!(ssid
->eap
.flags
& EAP_CONFIG_FLAGS_PASSWORD_NTHASH
)) {
1254 return wpa_config_write_string(
1255 ssid
->eap
.password
, ssid
->eap
.password_len
);
1258 buf
= os_malloc(5 + 32 + 1);
1262 os_memcpy(buf
, "hash:", 5);
1263 wpa_snprintf_hex(buf
+ 5, 32 + 1, ssid
->eap
.password
, 16);
1267 #endif /* IEEE8021X_EAPOL */
1270 static int wpa_config_parse_wep_key(u8
*key
, size_t *len
, int line
,
1271 const char *value
, int idx
)
1273 char *buf
, title
[20];
1276 buf
= wpa_config_parse_string(value
, len
);
1278 wpa_printf(MSG_ERROR
, "Line %d: Invalid WEP key %d '%s'.",
1282 if (*len
> MAX_WEP_KEY_LEN
) {
1283 wpa_printf(MSG_ERROR
, "Line %d: Too long WEP key %d '%s'.",
1288 if (*len
&& *len
!= 5 && *len
!= 13 && *len
!= 16) {
1289 wpa_printf(MSG_ERROR
, "Line %d: Invalid WEP key length %u - "
1290 "this network block will be ignored",
1291 line
, (unsigned int) *len
);
1293 os_memcpy(key
, buf
, *len
);
1295 res
= os_snprintf(title
, sizeof(title
), "wep_key%d", idx
);
1296 if (res
>= 0 && (size_t) res
< sizeof(title
))
1297 wpa_hexdump_key(MSG_MSGDUMP
, title
, key
, *len
);
1302 static int wpa_config_parse_wep_key0(const struct parse_data
*data
,
1303 struct wpa_ssid
*ssid
, int line
,
1306 return wpa_config_parse_wep_key(ssid
->wep_key
[0],
1307 &ssid
->wep_key_len
[0], line
,
1312 static int wpa_config_parse_wep_key1(const struct parse_data
*data
,
1313 struct wpa_ssid
*ssid
, int line
,
1316 return wpa_config_parse_wep_key(ssid
->wep_key
[1],
1317 &ssid
->wep_key_len
[1], line
,
1322 static int wpa_config_parse_wep_key2(const struct parse_data
*data
,
1323 struct wpa_ssid
*ssid
, int line
,
1326 return wpa_config_parse_wep_key(ssid
->wep_key
[2],
1327 &ssid
->wep_key_len
[2], line
,
1332 static int wpa_config_parse_wep_key3(const struct parse_data
*data
,
1333 struct wpa_ssid
*ssid
, int line
,
1336 return wpa_config_parse_wep_key(ssid
->wep_key
[3],
1337 &ssid
->wep_key_len
[3], line
,
1342 #ifndef NO_CONFIG_WRITE
1343 static char * wpa_config_write_wep_key(struct wpa_ssid
*ssid
, int idx
)
1345 if (ssid
->wep_key_len
[idx
] == 0)
1347 return wpa_config_write_string(ssid
->wep_key
[idx
],
1348 ssid
->wep_key_len
[idx
]);
1352 static char * wpa_config_write_wep_key0(const struct parse_data
*data
,
1353 struct wpa_ssid
*ssid
)
1355 return wpa_config_write_wep_key(ssid
, 0);
1359 static char * wpa_config_write_wep_key1(const struct parse_data
*data
,
1360 struct wpa_ssid
*ssid
)
1362 return wpa_config_write_wep_key(ssid
, 1);
1366 static char * wpa_config_write_wep_key2(const struct parse_data
*data
,
1367 struct wpa_ssid
*ssid
)
1369 return wpa_config_write_wep_key(ssid
, 2);
1373 static char * wpa_config_write_wep_key3(const struct parse_data
*data
,
1374 struct wpa_ssid
*ssid
)
1376 return wpa_config_write_wep_key(ssid
, 3);
1378 #endif /* NO_CONFIG_WRITE */
1383 static int wpa_config_parse_p2p_client_list(const struct parse_data
*data
,
1384 struct wpa_ssid
*ssid
, int line
,
1388 u8
*buf
, *n
, addr
[ETH_ALEN
];
1395 while (pos
&& *pos
) {
1399 if (hwaddr_aton(pos
, addr
)) {
1400 wpa_printf(MSG_ERROR
, "Line %d: Invalid "
1401 "p2p_client_list address '%s'.",
1403 /* continue anyway */
1405 n
= os_realloc(buf
, (count
+ 1) * ETH_ALEN
);
1411 os_memcpy(buf
+ count
* ETH_ALEN
, addr
, ETH_ALEN
);
1413 wpa_hexdump(MSG_MSGDUMP
, "p2p_client_list",
1417 pos
= os_strchr(pos
, ' ');
1420 os_free(ssid
->p2p_client_list
);
1421 ssid
->p2p_client_list
= buf
;
1422 ssid
->num_p2p_clients
= count
;
1428 #ifndef NO_CONFIG_WRITE
1429 static char * wpa_config_write_p2p_client_list(const struct parse_data
*data
,
1430 struct wpa_ssid
*ssid
)
1432 char *value
, *end
, *pos
;
1436 if (ssid
->p2p_client_list
== NULL
|| ssid
->num_p2p_clients
== 0)
1439 value
= os_malloc(20 * ssid
->num_p2p_clients
);
1443 end
= value
+ 20 * ssid
->num_p2p_clients
;
1445 for (i
= 0; i
< ssid
->num_p2p_clients
; i
++) {
1446 res
= os_snprintf(pos
, end
- pos
, MACSTR
" ",
1447 MAC2STR(ssid
->p2p_client_list
+
1449 if (res
< 0 || res
>= end
- pos
) {
1461 #endif /* NO_CONFIG_WRITE */
1463 #endif /* CONFIG_P2P */
1465 /* Helper macros for network block parser */
1470 /* OFFSET: Get offset of a variable within the wpa_ssid structure */
1471 #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
1473 /* STR: Define a string variable for an ASCII string; f = field name */
1474 #ifdef NO_CONFIG_WRITE
1475 #define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
1476 #define _STRe(f) #f, wpa_config_parse_str, OFFSET(eap.f)
1477 #else /* NO_CONFIG_WRITE */
1478 #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
1479 #define _STRe(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(eap.f)
1480 #endif /* NO_CONFIG_WRITE */
1481 #define STR(f) _STR(f), NULL, NULL, NULL, 0
1482 #define STRe(f) _STRe(f), NULL, NULL, NULL, 0
1483 #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
1484 #define STR_KEYe(f) _STRe(f), NULL, NULL, NULL, 1
1486 /* STR_LEN: Define a string variable with a separate variable for storing the
1487 * data length. Unlike STR(), this can be used to store arbitrary binary data
1488 * (i.e., even nul termination character). */
1489 #define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
1490 #define _STR_LENe(f) _STRe(f), OFFSET(eap.f ## _len)
1491 #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
1492 #define STR_LENe(f) _STR_LENe(f), NULL, NULL, 0
1493 #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
1495 /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
1496 * explicitly specified. */
1497 #define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max)
1498 #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
1499 #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
1501 #ifdef NO_CONFIG_WRITE
1502 #define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
1503 #define _INTe(f) #f, wpa_config_parse_int, OFFSET(eap.f), (void *) 0
1504 #else /* NO_CONFIG_WRITE */
1505 #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
1506 OFFSET(f), (void *) 0
1507 #define _INTe(f) #f, wpa_config_parse_int, wpa_config_write_int, \
1508 OFFSET(eap.f), (void *) 0
1509 #endif /* NO_CONFIG_WRITE */
1511 /* INT: Define an integer variable */
1512 #define INT(f) _INT(f), NULL, NULL, 0
1513 #define INTe(f) _INTe(f), NULL, NULL, 0
1515 /* INT_RANGE: Define an integer variable with allowed value range */
1516 #define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
1518 /* FUNC: Define a configuration variable that uses a custom function for
1519 * parsing and writing the value. */
1520 #ifdef NO_CONFIG_WRITE
1521 #define _FUNC(f) #f, wpa_config_parse_ ## f, NULL, NULL, NULL, NULL
1522 #else /* NO_CONFIG_WRITE */
1523 #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
1524 NULL, NULL, NULL, NULL
1525 #endif /* NO_CONFIG_WRITE */
1526 #define FUNC(f) _FUNC(f), 0
1527 #define FUNC_KEY(f) _FUNC(f), 1
1530 * Table of network configuration variables. This table is used to parse each
1531 * network configuration variable, e.g., each line in wpa_supplicant.conf file
1532 * that is inside a network block.
1534 * This table is generated using the helper macros defined above and with
1535 * generous help from the C pre-processor. The field name is stored as a string
1536 * into .name and for STR and INT types, the offset of the target buffer within
1537 * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
1538 * offset to the field containing the length of the configuration variable.
1539 * .param3 and .param4 can be used to mark the allowed range (length for STR
1540 * and value for INT).
1542 * For each configuration line in wpa_supplicant.conf, the parser goes through
1543 * this table and select the entry that matches with the field name. The parser
1544 * function (.parser) is then called to parse the actual value of the field.
1546 * This kind of mechanism makes it easy to add new configuration parameters,
1547 * since only one line needs to be added into this table and into the
1548 * struct wpa_ssid definition if the new variable is either a string or
1549 * integer. More complex types will need to use their own parser and writer
1552 static const struct parse_data ssid_fields
[] = {
1553 { STR_RANGE(ssid
, 0, MAX_SSID_LEN
) },
1554 { INT_RANGE(scan_ssid
, 0, 1) },
1559 { INT(bg_scan_period
) },
1563 { FUNC(scan_freq
) },
1564 { FUNC(freq_list
) },
1565 #ifdef IEEE8021X_EAPOL
1567 { STR_LENe(identity
) },
1568 { STR_LENe(anonymous_identity
) },
1569 { FUNC_KEY(password
) },
1572 { STRe(client_cert
) },
1573 { STRe(private_key
) },
1574 { STR_KEYe(private_key_passwd
) },
1576 { STRe(subject_match
) },
1577 { STRe(altsubject_match
) },
1580 { STRe(client_cert2
) },
1581 { STRe(private_key2
) },
1582 { STR_KEYe(private_key2_passwd
) },
1584 { STRe(subject_match2
) },
1585 { STRe(altsubject_match2
) },
1590 { STRe(engine_id
) },
1593 { STRe(ca_cert_id
) },
1595 { STRe(engine2_id
) },
1598 { STRe(ca_cert2_id
) },
1601 { INT(eapol_flags
) },
1602 #endif /* IEEE8021X_EAPOL */
1603 { FUNC_KEY(wep_key0
) },
1604 { FUNC_KEY(wep_key1
) },
1605 { FUNC_KEY(wep_key2
) },
1606 { FUNC_KEY(wep_key3
) },
1607 { INT(wep_tx_keyidx
) },
1609 #ifdef IEEE8021X_EAPOL
1610 { INT(eap_workaround
) },
1612 { INTe(fragment_size
) },
1613 #endif /* IEEE8021X_EAPOL */
1614 { INT_RANGE(mode
, 0, 4) },
1615 { INT_RANGE(proactive_key_caching
, 0, 1) },
1616 { INT_RANGE(disabled
, 0, 2) },
1618 #ifdef CONFIG_IEEE80211W
1619 { INT_RANGE(ieee80211w
, 0, 2) },
1620 #endif /* CONFIG_IEEE80211W */
1621 { INT_RANGE(peerkey
, 0, 1) },
1622 { INT_RANGE(mixed_cell
, 0, 1) },
1623 { INT_RANGE(frequency
, 0, 10000) },
1624 { INT(wpa_ptk_rekey
) },
1626 { INT_RANGE(ignore_broadcast_ssid
, 0, 2) },
1628 { FUNC(p2p_client_list
) },
1629 #endif /* CONFIG_P2P */
1630 #ifdef CONFIG_HT_OVERRIDES
1631 { INT_RANGE(disable_ht
, 0, 1) },
1632 { INT_RANGE(disable_ht40
, -1, 1) },
1633 { INT_RANGE(disable_max_amsdu
, -1, 1) },
1634 { INT_RANGE(ampdu_factor
, -1, 3) },
1635 { INT_RANGE(ampdu_density
, -1, 7) },
1637 #endif /* CONFIG_HT_OVERRIDES */
1638 { INT(ap_max_inactivity
) },
1639 { INT(dtim_period
) },
1651 #undef STR_RANGE_KEY
1658 #define NUM_SSID_FIELDS (sizeof(ssid_fields) / sizeof(ssid_fields[0]))
1662 * wpa_config_add_prio_network - Add a network to priority lists
1663 * @config: Configuration data from wpa_config_read()
1664 * @ssid: Pointer to the network configuration to be added to the list
1665 * Returns: 0 on success, -1 on failure
1667 * This function is used to add a network block to the priority list of
1668 * networks. This must be called for each network when reading in the full
1669 * configuration. In addition, this can be used indirectly when updating
1670 * priorities by calling wpa_config_update_prio_list().
1672 int wpa_config_add_prio_network(struct wpa_config
*config
,
1673 struct wpa_ssid
*ssid
)
1676 struct wpa_ssid
*prev
, **nlist
;
1679 * Add to an existing priority list if one is available for the
1680 * configured priority level for this network.
1682 for (prio
= 0; prio
< config
->num_prio
; prio
++) {
1683 prev
= config
->pssid
[prio
];
1684 if (prev
->priority
== ssid
->priority
) {
1692 /* First network for this priority - add a new priority list */
1693 nlist
= os_realloc(config
->pssid
,
1694 (config
->num_prio
+ 1) * sizeof(struct wpa_ssid
*));
1698 for (prio
= 0; prio
< config
->num_prio
; prio
++) {
1699 if (nlist
[prio
]->priority
< ssid
->priority
) {
1700 os_memmove(&nlist
[prio
+ 1], &nlist
[prio
],
1701 (config
->num_prio
- prio
) *
1702 sizeof(struct wpa_ssid
*));
1709 config
->pssid
= nlist
;
1716 * wpa_config_update_prio_list - Update network priority list
1717 * @config: Configuration data from wpa_config_read()
1718 * Returns: 0 on success, -1 on failure
1720 * This function is called to update the priority list of networks in the
1721 * configuration when a network is being added or removed. This is also called
1722 * if a priority for a network is changed.
1724 int wpa_config_update_prio_list(struct wpa_config
*config
)
1726 struct wpa_ssid
*ssid
;
1729 os_free(config
->pssid
);
1730 config
->pssid
= NULL
;
1731 config
->num_prio
= 0;
1733 ssid
= config
->ssid
;
1736 if (wpa_config_add_prio_network(config
, ssid
) < 0)
1745 #ifdef IEEE8021X_EAPOL
1746 static void eap_peer_config_free(struct eap_peer_config
*eap
)
1748 os_free(eap
->eap_methods
);
1749 os_free(eap
->identity
);
1750 os_free(eap
->anonymous_identity
);
1751 os_free(eap
->password
);
1752 os_free(eap
->ca_cert
);
1753 os_free(eap
->ca_path
);
1754 os_free(eap
->client_cert
);
1755 os_free(eap
->private_key
);
1756 os_free(eap
->private_key_passwd
);
1757 os_free(eap
->dh_file
);
1758 os_free(eap
->subject_match
);
1759 os_free(eap
->altsubject_match
);
1760 os_free(eap
->ca_cert2
);
1761 os_free(eap
->ca_path2
);
1762 os_free(eap
->client_cert2
);
1763 os_free(eap
->private_key2
);
1764 os_free(eap
->private_key2_passwd
);
1765 os_free(eap
->dh_file2
);
1766 os_free(eap
->subject_match2
);
1767 os_free(eap
->altsubject_match2
);
1768 os_free(eap
->phase1
);
1769 os_free(eap
->phase2
);
1772 os_free(eap
->engine_id
);
1773 os_free(eap
->key_id
);
1774 os_free(eap
->cert_id
);
1775 os_free(eap
->ca_cert_id
);
1776 os_free(eap
->key2_id
);
1777 os_free(eap
->cert2_id
);
1778 os_free(eap
->ca_cert2_id
);
1780 os_free(eap
->engine2_id
);
1782 os_free(eap
->pending_req_otp
);
1783 os_free(eap
->pac_file
);
1784 os_free(eap
->new_password
);
1786 #endif /* IEEE8021X_EAPOL */
1790 * wpa_config_free_ssid - Free network/ssid configuration data
1791 * @ssid: Configuration data for the network
1793 * This function frees all resources allocated for the network configuration
1796 void wpa_config_free_ssid(struct wpa_ssid
*ssid
)
1798 os_free(ssid
->ssid
);
1799 os_free(ssid
->passphrase
);
1800 os_free(ssid
->ext_psk
);
1801 #ifdef IEEE8021X_EAPOL
1802 eap_peer_config_free(&ssid
->eap
);
1803 #endif /* IEEE8021X_EAPOL */
1804 os_free(ssid
->id_str
);
1805 os_free(ssid
->scan_freq
);
1806 os_free(ssid
->freq_list
);
1807 os_free(ssid
->bgscan
);
1808 os_free(ssid
->p2p_client_list
);
1809 #ifdef CONFIG_HT_OVERRIDES
1810 os_free(ssid
->ht_mcs
);
1811 #endif /* CONFIG_HT_OVERRIDES */
1816 void wpa_config_free_cred(struct wpa_cred
*cred
)
1818 os_free(cred
->realm
);
1819 os_free(cred
->username
);
1820 os_free(cred
->password
);
1821 os_free(cred
->ca_cert
);
1822 os_free(cred
->client_cert
);
1823 os_free(cred
->private_key
);
1824 os_free(cred
->private_key_passwd
);
1825 os_free(cred
->imsi
);
1826 os_free(cred
->milenage
);
1827 os_free(cred
->domain
);
1828 os_free(cred
->eap_method
);
1829 os_free(cred
->phase1
);
1830 os_free(cred
->phase2
);
1836 * wpa_config_free - Free configuration data
1837 * @config: Configuration data from wpa_config_read()
1839 * This function frees all resources allocated for the configuration data by
1840 * wpa_config_read().
1842 void wpa_config_free(struct wpa_config
*config
)
1844 #ifndef CONFIG_NO_CONFIG_BLOBS
1845 struct wpa_config_blob
*blob
, *prevblob
;
1846 #endif /* CONFIG_NO_CONFIG_BLOBS */
1847 struct wpa_ssid
*ssid
, *prev
= NULL
;
1848 struct wpa_cred
*cred
, *cprev
;
1850 ssid
= config
->ssid
;
1854 wpa_config_free_ssid(prev
);
1857 cred
= config
->cred
;
1861 wpa_config_free_cred(cprev
);
1864 #ifndef CONFIG_NO_CONFIG_BLOBS
1865 blob
= config
->blobs
;
1870 wpa_config_free_blob(prevblob
);
1872 #endif /* CONFIG_NO_CONFIG_BLOBS */
1874 wpabuf_free(config
->wps_vendor_ext_m1
);
1875 os_free(config
->ctrl_interface
);
1876 os_free(config
->ctrl_interface_group
);
1877 os_free(config
->opensc_engine_path
);
1878 os_free(config
->pkcs11_engine_path
);
1879 os_free(config
->pkcs11_module_path
);
1880 os_free(config
->pcsc_reader
);
1881 os_free(config
->pcsc_pin
);
1882 os_free(config
->driver_param
);
1883 os_free(config
->device_name
);
1884 os_free(config
->manufacturer
);
1885 os_free(config
->model_name
);
1886 os_free(config
->model_number
);
1887 os_free(config
->serial_number
);
1888 os_free(config
->config_methods
);
1889 os_free(config
->p2p_ssid_postfix
);
1890 os_free(config
->pssid
);
1891 os_free(config
->p2p_pref_chan
);
1892 os_free(config
->autoscan
);
1893 wpabuf_free(config
->wps_nfc_dh_pubkey
);
1894 wpabuf_free(config
->wps_nfc_dh_privkey
);
1895 wpabuf_free(config
->wps_nfc_dev_pw
);
1896 os_free(config
->ext_password_backend
);
1902 * wpa_config_foreach_network - Iterate over each configured network
1903 * @config: Configuration data from wpa_config_read()
1904 * @func: Callback function to process each network
1905 * @arg: Opaque argument to pass to callback function
1907 * Iterate over the set of configured networks calling the specified
1908 * function for each item. We guard against callbacks removing the
1911 void wpa_config_foreach_network(struct wpa_config
*config
,
1912 void (*func
)(void *, struct wpa_ssid
*),
1915 struct wpa_ssid
*ssid
, *next
;
1917 ssid
= config
->ssid
;
1927 * wpa_config_get_network - Get configured network based on id
1928 * @config: Configuration data from wpa_config_read()
1929 * @id: Unique network id to search for
1930 * Returns: Network configuration or %NULL if not found
1932 struct wpa_ssid
* wpa_config_get_network(struct wpa_config
*config
, int id
)
1934 struct wpa_ssid
*ssid
;
1936 ssid
= config
->ssid
;
1948 * wpa_config_add_network - Add a new network with empty configuration
1949 * @config: Configuration data from wpa_config_read()
1950 * Returns: The new network configuration or %NULL if operation failed
1952 struct wpa_ssid
* wpa_config_add_network(struct wpa_config
*config
)
1955 struct wpa_ssid
*ssid
, *last
= NULL
;
1958 ssid
= config
->ssid
;
1967 ssid
= os_zalloc(sizeof(*ssid
));
1974 config
->ssid
= ssid
;
1976 wpa_config_update_prio_list(config
);
1983 * wpa_config_remove_network - Remove a configured network based on id
1984 * @config: Configuration data from wpa_config_read()
1985 * @id: Unique network id to search for
1986 * Returns: 0 on success, or -1 if the network was not found
1988 int wpa_config_remove_network(struct wpa_config
*config
, int id
)
1990 struct wpa_ssid
*ssid
, *prev
= NULL
;
1992 ssid
= config
->ssid
;
2004 prev
->next
= ssid
->next
;
2006 config
->ssid
= ssid
->next
;
2008 wpa_config_update_prio_list(config
);
2009 wpa_config_free_ssid(ssid
);
2015 * wpa_config_set_network_defaults - Set network default values
2016 * @ssid: Pointer to network configuration data
2018 void wpa_config_set_network_defaults(struct wpa_ssid
*ssid
)
2020 ssid
->proto
= DEFAULT_PROTO
;
2021 ssid
->pairwise_cipher
= DEFAULT_PAIRWISE
;
2022 ssid
->group_cipher
= DEFAULT_GROUP
;
2023 ssid
->key_mgmt
= DEFAULT_KEY_MGMT
;
2024 ssid
->bg_scan_period
= DEFAULT_BG_SCAN_PERIOD
;
2025 #ifdef IEEE8021X_EAPOL
2026 ssid
->eapol_flags
= DEFAULT_EAPOL_FLAGS
;
2027 ssid
->eap_workaround
= DEFAULT_EAP_WORKAROUND
;
2028 ssid
->eap
.fragment_size
= DEFAULT_FRAGMENT_SIZE
;
2029 #endif /* IEEE8021X_EAPOL */
2030 #ifdef CONFIG_HT_OVERRIDES
2031 ssid
->disable_ht
= DEFAULT_DISABLE_HT
;
2032 ssid
->disable_ht40
= DEFAULT_DISABLE_HT40
;
2033 ssid
->disable_max_amsdu
= DEFAULT_DISABLE_MAX_AMSDU
;
2034 ssid
->ampdu_factor
= DEFAULT_AMPDU_FACTOR
;
2035 ssid
->ampdu_density
= DEFAULT_AMPDU_DENSITY
;
2036 #endif /* CONFIG_HT_OVERRIDES */
2041 * wpa_config_set - Set a variable in network configuration
2042 * @ssid: Pointer to network configuration data
2043 * @var: Variable name, e.g., "ssid"
2044 * @value: Variable value
2045 * @line: Line number in configuration file or 0 if not used
2046 * Returns: 0 on success, -1 on failure
2048 * This function can be used to set network configuration variables based on
2049 * both the configuration file and management interface input. The value
2050 * parameter must be in the same format as the text-based configuration file is
2051 * using. For example, strings are using double quotation marks.
2053 int wpa_config_set(struct wpa_ssid
*ssid
, const char *var
, const char *value
,
2059 if (ssid
== NULL
|| var
== NULL
|| value
== NULL
)
2062 for (i
= 0; i
< NUM_SSID_FIELDS
; i
++) {
2063 const struct parse_data
*field
= &ssid_fields
[i
];
2064 if (os_strcmp(var
, field
->name
) != 0)
2067 if (field
->parser(field
, ssid
, line
, value
)) {
2069 wpa_printf(MSG_ERROR
, "Line %d: failed to "
2070 "parse %s '%s'.", line
, var
, value
);
2076 if (i
== NUM_SSID_FIELDS
) {
2078 wpa_printf(MSG_ERROR
, "Line %d: unknown network field "
2079 "'%s'.", line
, var
);
2088 int wpa_config_set_quoted(struct wpa_ssid
*ssid
, const char *var
,
2095 len
= os_strlen(value
);
2096 buf
= os_malloc(len
+ 3);
2100 os_memcpy(buf
+ 1, value
, len
);
2102 buf
[len
+ 2] = '\0';
2103 ret
= wpa_config_set(ssid
, var
, buf
, 0);
2110 * wpa_config_get_all - Get all options from network configuration
2111 * @ssid: Pointer to network configuration data
2112 * @get_keys: Determines if keys/passwords will be included in returned list
2113 * (if they may be exported)
2114 * Returns: %NULL terminated list of all set keys and their values in the form
2115 * of [key1, val1, key2, val2, ... , NULL]
2117 * This function can be used to get list of all configured network properties.
2118 * The caller is responsible for freeing the returned list and all its
2121 char ** wpa_config_get_all(struct wpa_ssid
*ssid
, int get_keys
)
2123 const struct parse_data
*field
;
2129 get_keys
= get_keys
&& ssid
->export_keys
;
2131 props
= os_zalloc(sizeof(char *) * ((2 * NUM_SSID_FIELDS
) + 1));
2136 for (i
= 0; i
< NUM_SSID_FIELDS
; i
++) {
2137 field
= &ssid_fields
[i
];
2138 if (field
->key_data
&& !get_keys
)
2140 value
= field
->writer(field
, ssid
);
2143 if (os_strlen(value
) == 0) {
2148 key
= os_strdup(field
->name
);
2154 props
[fields_num
* 2] = key
;
2155 props
[fields_num
* 2 + 1] = value
;
2171 #ifndef NO_CONFIG_WRITE
2173 * wpa_config_get - Get a variable in network configuration
2174 * @ssid: Pointer to network configuration data
2175 * @var: Variable name, e.g., "ssid"
2176 * Returns: Value of the variable or %NULL on failure
2178 * This function can be used to get network configuration variables. The
2179 * returned value is a copy of the configuration variable in text format, i.e,.
2180 * the same format that the text-based configuration file and wpa_config_set()
2181 * are using for the value. The caller is responsible for freeing the returned
2184 char * wpa_config_get(struct wpa_ssid
*ssid
, const char *var
)
2188 if (ssid
== NULL
|| var
== NULL
)
2191 for (i
= 0; i
< NUM_SSID_FIELDS
; i
++) {
2192 const struct parse_data
*field
= &ssid_fields
[i
];
2193 if (os_strcmp(var
, field
->name
) == 0)
2194 return field
->writer(field
, ssid
);
2202 * wpa_config_get_no_key - Get a variable in network configuration (no keys)
2203 * @ssid: Pointer to network configuration data
2204 * @var: Variable name, e.g., "ssid"
2205 * Returns: Value of the variable or %NULL on failure
2207 * This function can be used to get network configuration variable like
2208 * wpa_config_get(). The only difference is that this functions does not expose
2209 * key/password material from the configuration. In case a key/password field
2210 * is requested, the returned value is an empty string or %NULL if the variable
2211 * is not set or "*" if the variable is set (regardless of its value). The
2212 * returned value is a copy of the configuration variable in text format, i.e,.
2213 * the same format that the text-based configuration file and wpa_config_set()
2214 * are using for the value. The caller is responsible for freeing the returned
2217 char * wpa_config_get_no_key(struct wpa_ssid
*ssid
, const char *var
)
2221 if (ssid
== NULL
|| var
== NULL
)
2224 for (i
= 0; i
< NUM_SSID_FIELDS
; i
++) {
2225 const struct parse_data
*field
= &ssid_fields
[i
];
2226 if (os_strcmp(var
, field
->name
) == 0) {
2227 char *res
= field
->writer(field
, ssid
);
2228 if (field
->key_data
) {
2229 if (res
&& res
[0]) {
2230 wpa_printf(MSG_DEBUG
, "Do not allow "
2231 "key_data field to be "
2234 return os_strdup("*");
2246 #endif /* NO_CONFIG_WRITE */
2250 * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
2251 * @ssid: Pointer to network configuration data
2253 * This function must be called to update WPA PSK when either SSID or the
2254 * passphrase has changed for the network configuration.
2256 void wpa_config_update_psk(struct wpa_ssid
*ssid
)
2258 #ifndef CONFIG_NO_PBKDF2
2259 pbkdf2_sha1(ssid
->passphrase
,
2260 (char *) ssid
->ssid
, ssid
->ssid_len
, 4096,
2261 ssid
->psk
, PMK_LEN
);
2262 wpa_hexdump_key(MSG_MSGDUMP
, "PSK (from passphrase)",
2263 ssid
->psk
, PMK_LEN
);
2265 #endif /* CONFIG_NO_PBKDF2 */
2269 int wpa_config_set_cred(struct wpa_cred
*cred
, const char *var
,
2270 const char *value
, int line
)
2275 if (os_strcmp(var
, "priority") == 0) {
2276 cred
->priority
= atoi(value
);
2280 if (os_strcmp(var
, "pcsc") == 0) {
2281 cred
->pcsc
= atoi(value
);
2285 if (os_strcmp(var
, "eap") == 0) {
2286 struct eap_method_type method
;
2287 method
.method
= eap_peer_get_type(value
, &method
.vendor
);
2288 if (method
.vendor
== EAP_VENDOR_IETF
&&
2289 method
.method
== EAP_TYPE_NONE
) {
2290 wpa_printf(MSG_ERROR
, "Line %d: unknown EAP type '%s' "
2291 "for a credential", line
, value
);
2294 os_free(cred
->eap_method
);
2295 cred
->eap_method
= os_malloc(sizeof(*cred
->eap_method
));
2296 if (cred
->eap_method
== NULL
)
2298 os_memcpy(cred
->eap_method
, &method
, sizeof(method
));
2302 val
= wpa_config_parse_string(value
, &len
);
2304 wpa_printf(MSG_ERROR
, "Line %d: invalid field '%s' string "
2305 "value '%s'.", line
, var
, value
);
2309 if (os_strcmp(var
, "realm") == 0) {
2310 os_free(cred
->realm
);
2315 if (os_strcmp(var
, "username") == 0) {
2316 os_free(cred
->username
);
2317 cred
->username
= val
;
2321 if (os_strcmp(var
, "password") == 0) {
2322 os_free(cred
->password
);
2323 cred
->password
= val
;
2327 if (os_strcmp(var
, "ca_cert") == 0) {
2328 os_free(cred
->ca_cert
);
2329 cred
->ca_cert
= val
;
2333 if (os_strcmp(var
, "client_cert") == 0) {
2334 os_free(cred
->client_cert
);
2335 cred
->client_cert
= val
;
2339 if (os_strcmp(var
, "private_key") == 0) {
2340 os_free(cred
->private_key
);
2341 cred
->private_key
= val
;
2345 if (os_strcmp(var
, "private_key_passwd") == 0) {
2346 os_free(cred
->private_key_passwd
);
2347 cred
->private_key_passwd
= val
;
2351 if (os_strcmp(var
, "imsi") == 0) {
2352 os_free(cred
->imsi
);
2357 if (os_strcmp(var
, "milenage") == 0) {
2358 os_free(cred
->milenage
);
2359 cred
->milenage
= val
;
2363 if (os_strcmp(var
, "domain") == 0) {
2364 os_free(cred
->domain
);
2369 if (os_strcmp(var
, "phase1") == 0) {
2370 os_free(cred
->phase1
);
2375 if (os_strcmp(var
, "phase2") == 0) {
2376 os_free(cred
->phase2
);
2381 if (os_strcmp(var
, "roaming_consortium") == 0) {
2382 if (len
< 3 || len
> sizeof(cred
->roaming_consortium
)) {
2383 wpa_printf(MSG_ERROR
, "Line %d: invalid "
2384 "roaming_consortium length %d (3..15 "
2385 "expected)", line
, (int) len
);
2389 os_memcpy(cred
->roaming_consortium
, val
, len
);
2390 cred
->roaming_consortium_len
= len
;
2396 wpa_printf(MSG_ERROR
, "Line %d: unknown cred field '%s'.",
2406 struct wpa_cred
* wpa_config_get_cred(struct wpa_config
*config
, int id
)
2408 struct wpa_cred
*cred
;
2410 cred
= config
->cred
;
2421 struct wpa_cred
* wpa_config_add_cred(struct wpa_config
*config
)
2424 struct wpa_cred
*cred
, *last
= NULL
;
2427 cred
= config
->cred
;
2436 cred
= os_zalloc(sizeof(*cred
));
2443 config
->cred
= cred
;
2449 int wpa_config_remove_cred(struct wpa_config
*config
, int id
)
2451 struct wpa_cred
*cred
, *prev
= NULL
;
2453 cred
= config
->cred
;
2465 prev
->next
= cred
->next
;
2467 config
->cred
= cred
->next
;
2469 wpa_config_free_cred(cred
);
2474 #ifndef CONFIG_NO_CONFIG_BLOBS
2476 * wpa_config_get_blob - Get a named configuration blob
2477 * @config: Configuration data from wpa_config_read()
2478 * @name: Name of the blob
2479 * Returns: Pointer to blob data or %NULL if not found
2481 const struct wpa_config_blob
* wpa_config_get_blob(struct wpa_config
*config
,
2484 struct wpa_config_blob
*blob
= config
->blobs
;
2487 if (os_strcmp(blob
->name
, name
) == 0)
2496 * wpa_config_set_blob - Set or add a named configuration blob
2497 * @config: Configuration data from wpa_config_read()
2498 * @blob: New value for the blob
2500 * Adds a new configuration blob or replaces the current value of an existing
2503 void wpa_config_set_blob(struct wpa_config
*config
,
2504 struct wpa_config_blob
*blob
)
2506 wpa_config_remove_blob(config
, blob
->name
);
2507 blob
->next
= config
->blobs
;
2508 config
->blobs
= blob
;
2513 * wpa_config_free_blob - Free blob data
2514 * @blob: Pointer to blob to be freed
2516 void wpa_config_free_blob(struct wpa_config_blob
*blob
)
2519 os_free(blob
->name
);
2520 os_free(blob
->data
);
2527 * wpa_config_remove_blob - Remove a named configuration blob
2528 * @config: Configuration data from wpa_config_read()
2529 * @name: Name of the blob to remove
2530 * Returns: 0 if blob was removed or -1 if blob was not found
2532 int wpa_config_remove_blob(struct wpa_config
*config
, const char *name
)
2534 struct wpa_config_blob
*pos
= config
->blobs
, *prev
= NULL
;
2537 if (os_strcmp(pos
->name
, name
) == 0) {
2539 prev
->next
= pos
->next
;
2541 config
->blobs
= pos
->next
;
2542 wpa_config_free_blob(pos
);
2551 #endif /* CONFIG_NO_CONFIG_BLOBS */
2555 * wpa_config_alloc_empty - Allocate an empty configuration
2556 * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
2558 * @driver_param: Driver parameters
2559 * Returns: Pointer to allocated configuration data or %NULL on failure
2561 struct wpa_config
* wpa_config_alloc_empty(const char *ctrl_interface
,
2562 const char *driver_param
)
2564 struct wpa_config
*config
;
2566 config
= os_zalloc(sizeof(*config
));
2569 config
->eapol_version
= DEFAULT_EAPOL_VERSION
;
2570 config
->ap_scan
= DEFAULT_AP_SCAN
;
2571 config
->fast_reauth
= DEFAULT_FAST_REAUTH
;
2572 config
->p2p_go_intent
= DEFAULT_P2P_GO_INTENT
;
2573 config
->p2p_intra_bss
= DEFAULT_P2P_INTRA_BSS
;
2574 config
->bss_max_count
= DEFAULT_BSS_MAX_COUNT
;
2575 config
->bss_expiration_age
= DEFAULT_BSS_EXPIRATION_AGE
;
2576 config
->bss_expiration_scan_count
= DEFAULT_BSS_EXPIRATION_SCAN_COUNT
;
2577 config
->max_num_sta
= DEFAULT_MAX_NUM_STA
;
2578 config
->access_network_type
= DEFAULT_ACCESS_NETWORK_TYPE
;
2581 config
->ctrl_interface
= os_strdup(ctrl_interface
);
2583 config
->driver_param
= os_strdup(driver_param
);
2589 #ifndef CONFIG_NO_STDOUT_DEBUG
2591 * wpa_config_debug_dump_networks - Debug dump of configured networks
2592 * @config: Configuration data from wpa_config_read()
2594 void wpa_config_debug_dump_networks(struct wpa_config
*config
)
2597 struct wpa_ssid
*ssid
;
2599 for (prio
= 0; prio
< config
->num_prio
; prio
++) {
2600 ssid
= config
->pssid
[prio
];
2601 wpa_printf(MSG_DEBUG
, "Priority group %d",
2604 wpa_printf(MSG_DEBUG
, " id=%d ssid='%s'",
2606 wpa_ssid_txt(ssid
->ssid
, ssid
->ssid_len
));
2611 #endif /* CONFIG_NO_STDOUT_DEBUG */
2614 struct global_parse_data
{
2616 int (*parser
)(const struct global_parse_data
*data
,
2617 struct wpa_config
*config
, int line
, const char *value
);
2618 void *param1
, *param2
, *param3
;
2619 unsigned int changed_flag
;
2623 static int wpa_global_config_parse_int(const struct global_parse_data
*data
,
2624 struct wpa_config
*config
, int line
,
2628 dst
= (int *) (((u8
*) config
) + (long) data
->param1
);
2630 wpa_printf(MSG_DEBUG
, "%s=%d", data
->name
, *dst
);
2632 if (data
->param2
&& *dst
< (long) data
->param2
) {
2633 wpa_printf(MSG_ERROR
, "Line %d: too small %s (value=%d "
2634 "min_value=%ld)", line
, data
->name
, *dst
,
2635 (long) data
->param2
);
2636 *dst
= (long) data
->param2
;
2640 if (data
->param3
&& *dst
> (long) data
->param3
) {
2641 wpa_printf(MSG_ERROR
, "Line %d: too large %s (value=%d "
2642 "max_value=%ld)", line
, data
->name
, *dst
,
2643 (long) data
->param3
);
2644 *dst
= (long) data
->param3
;
2652 static int wpa_global_config_parse_str(const struct global_parse_data
*data
,
2653 struct wpa_config
*config
, int line
,
2659 len
= os_strlen(pos
);
2660 if (data
->param2
&& len
< (size_t) data
->param2
) {
2661 wpa_printf(MSG_ERROR
, "Line %d: too short %s (len=%lu "
2662 "min_len=%ld)", line
, data
->name
,
2663 (unsigned long) len
, (long) data
->param2
);
2667 if (data
->param3
&& len
> (size_t) data
->param3
) {
2668 wpa_printf(MSG_ERROR
, "Line %d: too long %s (len=%lu "
2669 "max_len=%ld)", line
, data
->name
,
2670 (unsigned long) len
, (long) data
->param3
);
2674 tmp
= os_strdup(pos
);
2678 dst
= (char **) (((u8
*) config
) + (long) data
->param1
);
2681 wpa_printf(MSG_DEBUG
, "%s='%s'", data
->name
, *dst
);
2687 static int wpa_global_config_parse_bin(const struct global_parse_data
*data
,
2688 struct wpa_config
*config
, int line
,
2692 struct wpabuf
**dst
, *tmp
;
2694 len
= os_strlen(pos
);
2698 tmp
= wpabuf_alloc(len
/ 2);
2702 if (hexstr2bin(pos
, wpabuf_put(tmp
, len
/ 2), len
/ 2)) {
2707 dst
= (struct wpabuf
**) (((u8
*) config
) + (long) data
->param1
);
2710 wpa_printf(MSG_DEBUG
, "%s", data
->name
);
2716 static int wpa_config_process_country(const struct global_parse_data
*data
,
2717 struct wpa_config
*config
, int line
,
2720 if (!pos
[0] || !pos
[1]) {
2721 wpa_printf(MSG_DEBUG
, "Invalid country set");
2724 config
->country
[0] = pos
[0];
2725 config
->country
[1] = pos
[1];
2726 wpa_printf(MSG_DEBUG
, "country='%c%c'",
2727 config
->country
[0], config
->country
[1]);
2732 static int wpa_config_process_load_dynamic_eap(
2733 const struct global_parse_data
*data
, struct wpa_config
*config
,
2734 int line
, const char *so
)
2737 wpa_printf(MSG_DEBUG
, "load_dynamic_eap=%s", so
);
2738 ret
= eap_peer_method_load(so
);
2740 wpa_printf(MSG_DEBUG
, "This EAP type was already loaded - not "
2743 wpa_printf(MSG_ERROR
, "Line %d: Failed to load dynamic EAP "
2744 "method '%s'.", line
, so
);
2754 static int wpa_config_process_uuid(const struct global_parse_data
*data
,
2755 struct wpa_config
*config
, int line
,
2759 if (uuid_str2bin(pos
, config
->uuid
)) {
2760 wpa_printf(MSG_ERROR
, "Line %d: invalid UUID", line
);
2763 uuid_bin2str(config
->uuid
, buf
, sizeof(buf
));
2764 wpa_printf(MSG_DEBUG
, "uuid=%s", buf
);
2769 static int wpa_config_process_device_type(
2770 const struct global_parse_data
*data
,
2771 struct wpa_config
*config
, int line
, const char *pos
)
2773 return wps_dev_type_str2bin(pos
, config
->device_type
);
2777 static int wpa_config_process_os_version(const struct global_parse_data
*data
,
2778 struct wpa_config
*config
, int line
,
2781 if (hexstr2bin(pos
, config
->os_version
, 4)) {
2782 wpa_printf(MSG_ERROR
, "Line %d: invalid os_version", line
);
2785 wpa_printf(MSG_DEBUG
, "os_version=%08x",
2786 WPA_GET_BE32(config
->os_version
));
2791 static int wpa_config_process_wps_vendor_ext_m1(
2792 const struct global_parse_data
*data
,
2793 struct wpa_config
*config
, int line
, const char *pos
)
2796 int len
= os_strlen(pos
) / 2;
2800 wpa_printf(MSG_ERROR
, "Line %d: "
2801 "invalid wps_vendor_ext_m1", line
);
2805 tmp
= wpabuf_alloc(len
);
2807 p
= wpabuf_put(tmp
, len
);
2809 if (hexstr2bin(pos
, p
, len
)) {
2810 wpa_printf(MSG_ERROR
, "Line %d: "
2811 "invalid wps_vendor_ext_m1", line
);
2816 wpabuf_free(config
->wps_vendor_ext_m1
);
2817 config
->wps_vendor_ext_m1
= tmp
;
2819 wpa_printf(MSG_ERROR
, "Can not allocate "
2820 "memory for wps_vendor_ext_m1");
2827 #endif /* CONFIG_WPS */
2830 static int wpa_config_process_sec_device_type(
2831 const struct global_parse_data
*data
,
2832 struct wpa_config
*config
, int line
, const char *pos
)
2836 if (config
->num_sec_device_types
>= MAX_SEC_DEVICE_TYPES
) {
2837 wpa_printf(MSG_ERROR
, "Line %d: too many sec_device_type "
2842 idx
= config
->num_sec_device_types
;
2844 if (wps_dev_type_str2bin(pos
, config
->sec_device_type
[idx
]))
2847 config
->num_sec_device_types
++;
2852 static int wpa_config_process_p2p_pref_chan(
2853 const struct global_parse_data
*data
,
2854 struct wpa_config
*config
, int line
, const char *pos
)
2856 struct p2p_channel
*pref
= NULL
, *n
;
2857 unsigned int num
= 0;
2861 /* format: class:chan,class:chan,... */
2864 op_class
= atoi(pos
);
2865 pos2
= os_strchr(pos
, ':');
2871 n
= os_realloc(pref
, (num
+ 1) * sizeof(struct p2p_channel
));
2875 pref
[num
].op_class
= op_class
;
2876 pref
[num
].chan
= chan
;
2879 pos
= os_strchr(pos2
, ',');
2885 os_free(config
->p2p_pref_chan
);
2886 config
->p2p_pref_chan
= pref
;
2887 config
->num_p2p_pref_chan
= num
;
2888 wpa_hexdump(MSG_DEBUG
, "P2P: Preferred class/channel pairs",
2889 (u8
*) config
->p2p_pref_chan
,
2890 config
->num_p2p_pref_chan
* sizeof(struct p2p_channel
));
2896 wpa_printf(MSG_ERROR
, "Line %d: Invalid p2p_pref_chan list", line
);
2899 #endif /* CONFIG_P2P */
2902 static int wpa_config_process_hessid(
2903 const struct global_parse_data
*data
,
2904 struct wpa_config
*config
, int line
, const char *pos
)
2906 if (hwaddr_aton2(pos
, config
->hessid
) < 0) {
2907 wpa_printf(MSG_ERROR
, "Line %d: Invalid hessid '%s'",
2919 /* OFFSET: Get offset of a variable within the wpa_config structure */
2920 #define OFFSET(v) ((void *) &((struct wpa_config *) 0)->v)
2922 #define FUNC(f) #f, wpa_config_process_ ## f, OFFSET(f), NULL, NULL
2923 #define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL
2924 #define _INT(f) #f, wpa_global_config_parse_int, OFFSET(f)
2925 #define INT(f) _INT(f), NULL, NULL
2926 #define INT_RANGE(f, min, max) _INT(f), (void *) min, (void *) max
2927 #define _STR(f) #f, wpa_global_config_parse_str, OFFSET(f)
2928 #define STR(f) _STR(f), NULL, NULL
2929 #define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
2930 #define BIN(f) #f, wpa_global_config_parse_bin, OFFSET(f), NULL, NULL
2932 static const struct global_parse_data global_fields
[] = {
2933 #ifdef CONFIG_CTRL_IFACE
2934 { STR(ctrl_interface
), 0 },
2935 { STR(ctrl_interface_group
), 0 } /* deprecated */,
2936 #endif /* CONFIG_CTRL_IFACE */
2937 { INT_RANGE(eapol_version
, 1, 2), 0 },
2938 { INT(ap_scan
), 0 },
2939 { INT(disable_scan_offload
), 0 },
2940 { INT(fast_reauth
), 0 },
2941 { STR(opensc_engine_path
), 0 },
2942 { STR(pkcs11_engine_path
), 0 },
2943 { STR(pkcs11_module_path
), 0 },
2944 { STR(pcsc_reader
), 0 },
2945 { STR(pcsc_pin
), 0 },
2946 { STR(driver_param
), 0 },
2947 { INT(dot11RSNAConfigPMKLifetime
), 0 },
2948 { INT(dot11RSNAConfigPMKReauthThreshold
), 0 },
2949 { INT(dot11RSNAConfigSATimeout
), 0 },
2950 #ifndef CONFIG_NO_CONFIG_WRITE
2951 { INT(update_config
), 0 },
2952 #endif /* CONFIG_NO_CONFIG_WRITE */
2953 { FUNC_NO_VAR(load_dynamic_eap
), 0 },
2955 { FUNC(uuid
), CFG_CHANGED_UUID
},
2956 { STR_RANGE(device_name
, 0, 32), CFG_CHANGED_DEVICE_NAME
},
2957 { STR_RANGE(manufacturer
, 0, 64), CFG_CHANGED_WPS_STRING
},
2958 { STR_RANGE(model_name
, 0, 32), CFG_CHANGED_WPS_STRING
},
2959 { STR_RANGE(model_number
, 0, 32), CFG_CHANGED_WPS_STRING
},
2960 { STR_RANGE(serial_number
, 0, 32), CFG_CHANGED_WPS_STRING
},
2961 { FUNC(device_type
), CFG_CHANGED_DEVICE_TYPE
},
2962 { FUNC(os_version
), CFG_CHANGED_OS_VERSION
},
2963 { STR(config_methods
), CFG_CHANGED_CONFIG_METHODS
},
2964 { INT_RANGE(wps_cred_processing
, 0, 2), 0 },
2965 { FUNC(wps_vendor_ext_m1
), CFG_CHANGED_VENDOR_EXTENSION
},
2966 #endif /* CONFIG_WPS */
2968 { FUNC(sec_device_type
), CFG_CHANGED_SEC_DEVICE_TYPE
},
2969 { INT(p2p_listen_reg_class
), 0 },
2970 { INT(p2p_listen_channel
), 0 },
2971 { INT(p2p_oper_reg_class
), 0 },
2972 { INT(p2p_oper_channel
), 0 },
2973 { INT_RANGE(p2p_go_intent
, 0, 15), 0 },
2974 { STR(p2p_ssid_postfix
), CFG_CHANGED_P2P_SSID_POSTFIX
},
2975 { INT_RANGE(persistent_reconnect
, 0, 1), 0 },
2976 { INT_RANGE(p2p_intra_bss
, 0, 1), CFG_CHANGED_P2P_INTRA_BSS
},
2977 { INT(p2p_group_idle
), 0 },
2978 { FUNC(p2p_pref_chan
), CFG_CHANGED_P2P_PREF_CHAN
},
2979 #endif /* CONFIG_P2P */
2980 { FUNC(country
), CFG_CHANGED_COUNTRY
},
2981 { INT(bss_max_count
), 0 },
2982 { INT(bss_expiration_age
), 0 },
2983 { INT(bss_expiration_scan_count
), 0 },
2984 { INT_RANGE(filter_ssids
, 0, 1), 0 },
2985 { INT_RANGE(filter_rssi
, -100, 0), 0 },
2986 { INT(max_num_sta
), 0 },
2987 { INT_RANGE(disassoc_low_ack
, 0, 1), 0 },
2989 { INT_RANGE(hs20
, 0, 1), 0 },
2990 #endif /* CONFIG_HS20 */
2991 { INT_RANGE(interworking
, 0, 1), 0 },
2992 { FUNC(hessid
), 0 },
2993 { INT_RANGE(access_network_type
, 0, 15), 0 },
2994 { INT_RANGE(pbc_in_m1
, 0, 1), 0 },
2995 { STR(autoscan
), 0 },
2996 { INT_RANGE(wps_nfc_dev_pw_id
, 0x10, 0xffff), 0 },
2997 { BIN(wps_nfc_dh_pubkey
), 0 },
2998 { BIN(wps_nfc_dh_privkey
), 0 },
2999 { BIN(wps_nfc_dev_pw
), 0 },
3000 { STR(ext_password_backend
), CFG_CHANGED_EXT_PW_BACKEND
}
3011 #define NUM_GLOBAL_FIELDS (sizeof(global_fields) / sizeof(global_fields[0]))
3014 int wpa_config_process_global(struct wpa_config
*config
, char *pos
, int line
)
3019 for (i
= 0; i
< NUM_GLOBAL_FIELDS
; i
++) {
3020 const struct global_parse_data
*field
= &global_fields
[i
];
3021 size_t flen
= os_strlen(field
->name
);
3022 if (os_strncmp(pos
, field
->name
, flen
) != 0 ||
3026 if (field
->parser(field
, config
, line
, pos
+ flen
+ 1)) {
3027 wpa_printf(MSG_ERROR
, "Line %d: failed to "
3028 "parse '%s'.", line
, pos
);
3031 config
->changed_parameters
|= field
->changed_flag
;
3034 if (i
== NUM_GLOBAL_FIELDS
) {
3037 wpa_printf(MSG_ERROR
, "Line %d: unknown global field '%s'.",