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 tlen, hlen = os_strlen(value);
73 str = os_malloc(tlen + 1);
76 if (hexstr2bin(value, str, tlen)) {
87 static int wpa_config_parse_str(const struct parse_data *data,
88 struct wpa_ssid *ssid,
89 int line, const char *value)
91 size_t res_len, *dst_len;
94 tmp = wpa_config_parse_string(value, &res_len);
96 wpa_printf(MSG_ERROR, "Line %d: failed to parse %s '%s'.",
98 data->key_data ? "[KEY DATA REMOVED]" : value);
102 if (data->key_data) {
103 wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
104 (u8 *) tmp, res_len);
106 wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
107 (u8 *) tmp, res_len);
110 if (data->param3 && res_len < (size_t) data->param3) {
111 wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
112 "min_len=%ld)", line, data->name,
113 (unsigned long) res_len, (long) data->param3);
118 if (data->param4 && res_len > (size_t) data->param4) {
119 wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
120 "max_len=%ld)", line, data->name,
121 (unsigned long) res_len, (long) data->param4);
126 dst = (char **) (((u8 *) ssid) + (long) data->param1);
127 dst_len = (size_t *) (((u8 *) ssid) + (long) data->param2);
137 static int is_hex(const u8 *data, size_t len)
141 for (i = 0; i < len; i++) {
142 if (data[i] < 32 || data[i] >= 127)
149 static char * wpa_config_write_string_ascii(const u8 *value, size_t len)
153 buf = os_malloc(len + 3);
157 os_memcpy(buf + 1, value, len);
165 static char * wpa_config_write_string_hex(const u8 *value, size_t len)
169 buf = os_zalloc(2 * len + 1);
172 wpa_snprintf_hex(buf, 2 * len + 1, value, len);
178 static char * wpa_config_write_string(const u8 *value, size_t len)
183 if (is_hex(value, len))
184 return wpa_config_write_string_hex(value, len);
186 return wpa_config_write_string_ascii(value, len);
190 static char * wpa_config_write_str(const struct parse_data *data,
191 struct wpa_ssid *ssid)
196 src = (char **) (((u8 *) ssid) + (long) data->param1);
201 len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
203 len = os_strlen(*src);
205 return wpa_config_write_string((const u8 *) *src, len);
209 static int wpa_config_parse_int(const struct parse_data *data,
210 struct wpa_ssid *ssid,
211 int line, const char *value)
215 dst = (int *) (((u8 *) ssid) + (long) data->param1);
217 wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst);
219 if (data->param3 && *dst < (long) data->param3) {
220 wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
221 "min_value=%ld)", line, data->name, *dst,
222 (long) data->param3);
223 *dst = (long) data->param3;
227 if (data->param4 && *dst > (long) data->param4) {
228 wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
229 "max_value=%ld)", line, data->name, *dst,
230 (long) data->param4);
231 *dst = (long) data->param4;
239 static char * wpa_config_write_int(const struct parse_data *data,
240 struct wpa_ssid *ssid)
245 src = (int *) (((u8 *) ssid) + (long) data->param1);
247 value = os_malloc(20);
250 os_snprintf(value, 20, "%d", *src);
251 value[20 - 1] = '\0';
256 static int wpa_config_parse_bssid(const struct parse_data *data,
257 struct wpa_ssid *ssid, int line,
260 if (hwaddr_aton(value, ssid->bssid)) {
261 wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.",
266 wpa_hexdump(MSG_MSGDUMP, "BSSID", ssid->bssid, ETH_ALEN);
271 static char * wpa_config_write_bssid(const struct parse_data *data,
272 struct wpa_ssid *ssid)
276 if (!ssid->bssid_set)
279 value = os_malloc(20);
282 os_snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid));
283 value[20 - 1] = '\0';
288 static int wpa_config_parse_psk(const struct parse_data *data,
289 struct wpa_ssid *ssid, int line,
297 pos = os_strrchr(value, '"');
301 len = os_strlen(value);
302 if (len < 8 || len > 63) {
303 wpa_printf(MSG_ERROR, "Line %d: Invalid passphrase "
304 "length %lu (expected: 8..63) '%s'.",
305 line, (unsigned long) len, value);
308 wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)",
310 if (ssid->passphrase && os_strlen(ssid->passphrase) == len &&
311 os_memcmp(ssid->passphrase, value, len) == 0)
314 os_free(ssid->passphrase);
315 ssid->passphrase = os_malloc(len + 1);
316 if (ssid->passphrase == NULL)
318 os_memcpy(ssid->passphrase, value, len);
319 ssid->passphrase[len] = '\0';
323 if (hexstr2bin(value, ssid->psk, PMK_LEN) ||
324 value[PMK_LEN * 2] != '\0') {
325 wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
330 os_free(ssid->passphrase);
331 ssid->passphrase = NULL;
334 wpa_hexdump_key(MSG_MSGDUMP, "PSK", ssid->psk, PMK_LEN);
339 static char * wpa_config_write_psk(const struct parse_data *data,
340 struct wpa_ssid *ssid)
342 if (ssid->passphrase)
343 return wpa_config_write_string_ascii(
344 (const u8 *) ssid->passphrase,
345 os_strlen(ssid->passphrase));
348 return wpa_config_write_string_hex(ssid->psk, PMK_LEN);
354 static int wpa_config_parse_proto(const struct parse_data *data,
355 struct wpa_ssid *ssid, int line,
358 int val = 0, last, errors = 0;
359 char *start, *end, *buf;
361 buf = os_strdup(value);
366 while (*start != '\0') {
367 while (*start == ' ' || *start == '\t')
372 while (*end != ' ' && *end != '\t' && *end != '\0')
376 if (os_strcmp(start, "WPA") == 0)
377 val |= WPA_PROTO_WPA;
378 else if (os_strcmp(start, "RSN") == 0 ||
379 os_strcmp(start, "WPA2") == 0)
380 val |= WPA_PROTO_RSN;
382 wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'",
394 wpa_printf(MSG_ERROR,
395 "Line %d: no proto values configured.", line);
399 wpa_printf(MSG_MSGDUMP, "proto: 0x%x", val);
401 return errors ? -1 : 0;
405 static char * wpa_config_write_proto(const struct parse_data *data,
406 struct wpa_ssid *ssid)
409 char *buf, *pos, *end;
411 pos = buf = os_zalloc(10);
416 if (ssid->proto & WPA_PROTO_WPA) {
417 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
418 if (ret < 0 || ret >= end - pos)
424 if (ssid->proto & WPA_PROTO_RSN) {
425 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
426 if (ret < 0 || ret >= end - pos)
436 static int wpa_config_parse_key_mgmt(const struct parse_data *data,
437 struct wpa_ssid *ssid, int line,
440 int val = 0, last, errors = 0;
441 char *start, *end, *buf;
443 buf = os_strdup(value);
448 while (*start != '\0') {
449 while (*start == ' ' || *start == '\t')
454 while (*end != ' ' && *end != '\t' && *end != '\0')
458 if (os_strcmp(start, "WPA-PSK") == 0)
459 val |= WPA_KEY_MGMT_PSK;
460 else if (os_strcmp(start, "WPA-EAP") == 0)
461 val |= WPA_KEY_MGMT_IEEE8021X;
462 else if (os_strcmp(start, "IEEE8021X") == 0)
463 val |= WPA_KEY_MGMT_IEEE8021X_NO_WPA;
464 else if (os_strcmp(start, "NONE") == 0)
465 val |= WPA_KEY_MGMT_NONE;
466 else if (os_strcmp(start, "WPA-NONE") == 0)
467 val |= WPA_KEY_MGMT_WPA_NONE;
469 wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
481 wpa_printf(MSG_ERROR,
482 "Line %d: no key_mgmt values configured.", line);
486 wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val);
487 ssid->key_mgmt = val;
488 return errors ? -1 : 0;
492 static char * wpa_config_write_key_mgmt(const struct parse_data *data,
493 struct wpa_ssid *ssid)
495 char *buf, *pos, *end;
498 pos = buf = os_zalloc(50);
503 if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
504 ret = os_snprintf(pos, end - pos, "%sWPA-PSK",
505 pos == buf ? "" : " ");
506 if (ret < 0 || ret >= end - pos) {
513 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
514 ret = os_snprintf(pos, end - pos, "%sWPA-EAP",
515 pos == buf ? "" : " ");
516 if (ret < 0 || ret >= end - pos) {
523 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
524 ret = os_snprintf(pos, end - pos, "%sIEEE8021X",
525 pos == buf ? "" : " ");
526 if (ret < 0 || ret >= end - pos) {
533 if (ssid->key_mgmt & WPA_KEY_MGMT_NONE) {
534 ret = os_snprintf(pos, end - pos, "%sNONE",
535 pos == buf ? "" : " ");
536 if (ret < 0 || ret >= end - pos) {
543 if (ssid->key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
544 ret = os_snprintf(pos, end - pos, "%sWPA-NONE",
545 pos == buf ? "" : " ");
546 if (ret < 0 || ret >= end - pos) {
557 static int wpa_config_parse_cipher(int line, const char *value)
560 char *start, *end, *buf;
562 buf = os_strdup(value);
567 while (*start != '\0') {
568 while (*start == ' ' || *start == '\t')
573 while (*end != ' ' && *end != '\t' && *end != '\0')
577 if (os_strcmp(start, "CCMP") == 0)
578 val |= WPA_CIPHER_CCMP;
579 else if (os_strcmp(start, "TKIP") == 0)
580 val |= WPA_CIPHER_TKIP;
581 else if (os_strcmp(start, "WEP104") == 0)
582 val |= WPA_CIPHER_WEP104;
583 else if (os_strcmp(start, "WEP40") == 0)
584 val |= WPA_CIPHER_WEP40;
585 else if (os_strcmp(start, "NONE") == 0)
586 val |= WPA_CIPHER_NONE;
588 wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
601 wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
609 static char * wpa_config_write_cipher(int cipher)
611 char *buf, *pos, *end;
614 pos = buf = os_zalloc(50);
619 if (cipher & WPA_CIPHER_CCMP) {
620 ret = os_snprintf(pos, end - pos, "%sCCMP",
621 pos == buf ? "" : " ");
622 if (ret < 0 || ret >= end - pos) {
629 if (cipher & WPA_CIPHER_TKIP) {
630 ret = os_snprintf(pos, end - pos, "%sTKIP",
631 pos == buf ? "" : " ");
632 if (ret < 0 || ret >= end - pos) {
639 if (cipher & WPA_CIPHER_WEP104) {
640 ret = os_snprintf(pos, end - pos, "%sWEP104",
641 pos == buf ? "" : " ");
642 if (ret < 0 || ret >= end - pos) {
649 if (cipher & WPA_CIPHER_WEP40) {
650 ret = os_snprintf(pos, end - pos, "%sWEP40",
651 pos == buf ? "" : " ");
652 if (ret < 0 || ret >= end - pos) {
659 if (cipher & WPA_CIPHER_NONE) {
660 ret = os_snprintf(pos, end - pos, "%sNONE",
661 pos == buf ? "" : " ");
662 if (ret < 0 || ret >= end - pos) {
673 static int wpa_config_parse_pairwise(const struct parse_data *data,
674 struct wpa_ssid *ssid, int line,
678 val = wpa_config_parse_cipher(line, value);
681 if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_NONE)) {
682 wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
683 "(0x%x).", line, val);
687 wpa_printf(MSG_MSGDUMP, "pairwise: 0x%x", val);
688 ssid->pairwise_cipher = val;
693 static char * wpa_config_write_pairwise(const struct parse_data *data,
694 struct wpa_ssid *ssid)
696 return wpa_config_write_cipher(ssid->pairwise_cipher);
700 static int wpa_config_parse_group(const struct parse_data *data,
701 struct wpa_ssid *ssid, int line,
705 val = wpa_config_parse_cipher(line, value);
708 if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 |
710 wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
711 "(0x%x).", line, val);
715 wpa_printf(MSG_MSGDUMP, "group: 0x%x", val);
716 ssid->group_cipher = val;
721 static char * wpa_config_write_group(const struct parse_data *data,
722 struct wpa_ssid *ssid)
724 return wpa_config_write_cipher(ssid->group_cipher);
728 static int wpa_config_parse_auth_alg(const struct parse_data *data,
729 struct wpa_ssid *ssid, int line,
732 int val = 0, last, errors = 0;
733 char *start, *end, *buf;
735 buf = os_strdup(value);
740 while (*start != '\0') {
741 while (*start == ' ' || *start == '\t')
746 while (*end != ' ' && *end != '\t' && *end != '\0')
750 if (os_strcmp(start, "OPEN") == 0)
751 val |= WPA_AUTH_ALG_OPEN;
752 else if (os_strcmp(start, "SHARED") == 0)
753 val |= WPA_AUTH_ALG_SHARED;
754 else if (os_strcmp(start, "LEAP") == 0)
755 val |= WPA_AUTH_ALG_LEAP;
757 wpa_printf(MSG_ERROR, "Line %d: invalid auth_alg '%s'",
769 wpa_printf(MSG_ERROR,
770 "Line %d: no auth_alg values configured.", line);
774 wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", val);
775 ssid->auth_alg = val;
776 return errors ? -1 : 0;
780 static char * wpa_config_write_auth_alg(const struct parse_data *data,
781 struct wpa_ssid *ssid)
783 char *buf, *pos, *end;
786 pos = buf = os_zalloc(30);
791 if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) {
792 ret = os_snprintf(pos, end - pos, "%sOPEN",
793 pos == buf ? "" : " ");
794 if (ret < 0 || ret >= end - pos) {
801 if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) {
802 ret = os_snprintf(pos, end - pos, "%sSHARED",
803 pos == buf ? "" : " ");
804 if (ret < 0 || ret >= end - pos) {
811 if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) {
812 ret = os_snprintf(pos, end - pos, "%sLEAP",
813 pos == buf ? "" : " ");
814 if (ret < 0 || ret >= end - pos) {
825 #ifdef IEEE8021X_EAPOL
826 static int wpa_config_parse_eap(const struct parse_data *data,
827 struct wpa_ssid *ssid, int line,
830 int last, errors = 0;
831 char *start, *end, *buf;
832 struct eap_method_type *methods = NULL, *tmp;
833 size_t num_methods = 0;
835 buf = os_strdup(value);
840 while (*start != '\0') {
841 while (*start == ' ' || *start == '\t')
846 while (*end != ' ' && *end != '\t' && *end != '\0')
851 methods = os_realloc(methods,
852 (num_methods + 1) * sizeof(*methods));
853 if (methods == NULL) {
858 methods[num_methods].method = eap_get_type(
859 start, &methods[num_methods].vendor);
860 if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
861 methods[num_methods].method == EAP_TYPE_NONE) {
862 wpa_printf(MSG_ERROR, "Line %d: unknown EAP method "
863 "'%s'", line, start);
864 wpa_printf(MSG_ERROR, "You may need to add support for"
865 " this EAP method during wpa_supplicant\n"
866 "build time configuration.\n"
867 "See README for more information.");
869 } else if (methods[num_methods].vendor == EAP_VENDOR_IETF &&
870 methods[num_methods].method == EAP_TYPE_LEAP)
882 methods = os_realloc(methods, (num_methods + 1) * sizeof(*methods));
883 if (methods == NULL) {
887 methods[num_methods].vendor = EAP_VENDOR_IETF;
888 methods[num_methods].method = EAP_TYPE_NONE;
891 wpa_hexdump(MSG_MSGDUMP, "eap methods",
892 (u8 *) methods, num_methods * sizeof(*methods));
893 ssid->eap_methods = methods;
894 return errors ? -1 : 0;
898 static char * wpa_config_write_eap(const struct parse_data *data,
899 struct wpa_ssid *ssid)
902 char *buf, *pos, *end;
903 const struct eap_method_type *eap_methods = ssid->eap_methods;
906 if (eap_methods == NULL)
909 pos = buf = os_zalloc(100);
914 for (i = 0; eap_methods[i].vendor != EAP_VENDOR_IETF ||
915 eap_methods[i].method != EAP_TYPE_NONE; i++) {
916 name = eap_get_name(eap_methods[i].vendor,
917 eap_methods[i].method);
919 ret = os_snprintf(pos, end - pos, "%s%s",
920 pos == buf ? "" : " ", name);
921 if (ret < 0 || ret >= end - pos)
931 #endif /* IEEE8021X_EAPOL */
934 static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line,
935 const char *value, int idx)
937 char *buf, title[20];
939 buf = wpa_config_parse_string(value, len);
941 wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key %d '%s'.",
945 if (*len > MAX_WEP_KEY_LEN) {
946 wpa_printf(MSG_ERROR, "Line %d: Too long WEP key %d '%s'.",
951 os_memcpy(key, buf, *len);
953 os_snprintf(title, sizeof(title), "wep_key%d", idx);
954 wpa_hexdump_key(MSG_MSGDUMP, title, key, *len);
959 static int wpa_config_parse_wep_key0(const struct parse_data *data,
960 struct wpa_ssid *ssid, int line,
963 return wpa_config_parse_wep_key(ssid->wep_key[0],
964 &ssid->wep_key_len[0], line,
969 static int wpa_config_parse_wep_key1(const struct parse_data *data,
970 struct wpa_ssid *ssid, int line,
973 return wpa_config_parse_wep_key(ssid->wep_key[1],
974 &ssid->wep_key_len[1], line,
979 static int wpa_config_parse_wep_key2(const struct parse_data *data,
980 struct wpa_ssid *ssid, int line,
983 return wpa_config_parse_wep_key(ssid->wep_key[2],
984 &ssid->wep_key_len[2], line,
989 static int wpa_config_parse_wep_key3(const struct parse_data *data,
990 struct wpa_ssid *ssid, int line,
993 return wpa_config_parse_wep_key(ssid->wep_key[3],
994 &ssid->wep_key_len[3], line,
999 static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx)
1001 if (ssid->wep_key_len[idx] == 0)
1003 return wpa_config_write_string(ssid->wep_key[idx],
1004 ssid->wep_key_len[idx]);
1008 static char * wpa_config_write_wep_key0(const struct parse_data *data,
1009 struct wpa_ssid *ssid)
1011 return wpa_config_write_wep_key(ssid, 0);
1015 static char * wpa_config_write_wep_key1(const struct parse_data *data,
1016 struct wpa_ssid *ssid)
1018 return wpa_config_write_wep_key(ssid, 1);
1022 static char * wpa_config_write_wep_key2(const struct parse_data *data,
1023 struct wpa_ssid *ssid)
1025 return wpa_config_write_wep_key(ssid, 2);
1029 static char * wpa_config_write_wep_key3(const struct parse_data *data,
1030 struct wpa_ssid *ssid)
1032 return wpa_config_write_wep_key(ssid, 3);
1036 /* Helper macros for network block parser */
1041 /* OFFSET: Get offset of a variable within the wpa_ssid structure */
1042 #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
1044 /* STR: Define a string variable for an ASCII string; f = field name */
1045 #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
1046 #define STR(f) _STR(f), NULL, NULL, NULL, 0
1047 #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
1049 /* STR_LEN: Define a string variable with a separate variable for storing the
1050 * data length. Unlike STR(), this can be used to store arbitrary binary data
1051 * (i.e., even nul termination character). */
1052 #define _STR_LEN(f) _STR(f), OFFSET(f ## _len)
1053 #define STR_LEN(f) _STR_LEN(f), NULL, NULL, 0
1054 #define STR_LEN_KEY(f) _STR_LEN(f), NULL, NULL, 1
1056 /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
1057 * explicitly specified. */
1058 #define _STR_RANGE(f, min, max) _STR_LEN(f), (void *) (min), (void *) (max)
1059 #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
1060 #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
1062 #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
1063 OFFSET(f), (void *) 0
1065 /* INT: Define an integer variable */
1066 #define INT(f) _INT(f), NULL, NULL, 0
1068 /* INT_RANGE: Define an integer variable with allowed value range */
1069 #define INT_RANGE(f, min, max) _INT(f), (void *) (min), (void *) (max), 0
1071 /* FUNC: Define a configuration variable that uses a custom function for
1072 * parsing and writing the value. */
1073 #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
1074 NULL, NULL, NULL, NULL
1075 #define FUNC(f) _FUNC(f), 0
1076 #define FUNC_KEY(f) _FUNC(f), 1
1079 * Table of network configuration variables. This table is used to parse each
1080 * network configuration variable, e.g., each line in wpa_supplicant.conf file
1081 * that is inside a network block.
1083 * This table is generated using the helper macros defined above and with
1084 * generous help from the C pre-processor. The field name is stored as a string
1085 * into .name and for STR and INT types, the offset of the target buffer within
1086 * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
1087 * offset to the field containing the length of the configuration variable.
1088 * .param3 and .param4 can be used to mark the allowed range (length for STR
1089 * and value for INT).
1091 * For each configuration line in wpa_supplicant.conf, the parser goes through
1092 * this table and select the entry that matches with the field name. The parser
1093 * function (.parser) is then called to parse the actual value of the field.
1095 * This kind of mechanism makes it easy to add new configuration parameters,
1096 * since only one line needs to be added into this table and into the
1097 * struct wpa_ssid definition if the new variable is either a string or
1098 * integer. More complex types will need to use their own parser and writer
1101 static const struct parse_data ssid_fields[] = {
1102 { STR_RANGE(ssid, 0, MAX_SSID_LEN) },
1103 { INT_RANGE(scan_ssid, 0, 1) },
1111 #ifdef IEEE8021X_EAPOL
1113 { STR_LEN(identity) },
1114 { STR_LEN(anonymous_identity) },
1115 { STR_RANGE_KEY(eappsk, EAP_PSK_LEN_MIN, EAP_PSK_LEN_MAX) },
1117 { STR_LEN_KEY(password) },
1120 { STR(client_cert) },
1121 { STR(private_key) },
1122 { STR_KEY(private_key_passwd) },
1124 { STR(subject_match) },
1125 { STR(altsubject_match) },
1128 { STR(client_cert2) },
1129 { STR(private_key2) },
1130 { STR_KEY(private_key2_passwd) },
1132 { STR(subject_match2) },
1133 { STR(altsubject_match2) },
1141 { INT(eapol_flags) },
1142 #endif /* IEEE8021X_EAPOL */
1143 { FUNC_KEY(wep_key0) },
1144 { FUNC_KEY(wep_key1) },
1145 { FUNC_KEY(wep_key2) },
1146 { FUNC_KEY(wep_key3) },
1147 { INT(wep_tx_keyidx) },
1149 #ifdef IEEE8021X_EAPOL
1150 { INT(eap_workaround) },
1152 { INT(fragment_size) },
1153 #endif /* IEEE8021X_EAPOL */
1154 { INT_RANGE(mode, 0, 1) },
1155 { INT_RANGE(proactive_key_caching, 0, 1) },
1156 { INT_RANGE(disabled, 0, 1) },
1158 #ifdef CONFIG_IEEE80211W
1159 { INT_RANGE(ieee80211w, 0, 2) },
1160 #endif /* CONFIG_IEEE80211W */
1161 { INT_RANGE(peerkey, 0, 1) },
1162 { INT_RANGE(mixed_cell, 0, 1) },
1163 { INT_RANGE(frequency, 0, 10000) }
1175 #undef STR_RANGE_KEY
1182 #define NUM_SSID_FIELDS (sizeof(ssid_fields) / sizeof(ssid_fields[0]))
1186 * wpa_config_add_prio_network - Add a network to priority lists
1187 * @config: Configuration data from wpa_config_read()
1188 * @ssid: Pointer to the network configuration to be added to the list
1189 * Returns: 0 on success, -1 on failure
1191 * This function is used to add a network block to the priority list of
1192 * networks. This must be called for each network when reading in the full
1193 * configuration. In addition, this can be used indirectly when updating
1194 * priorities by calling wpa_config_update_prio_list().
1196 int wpa_config_add_prio_network(struct wpa_config *config,
1197 struct wpa_ssid *ssid)
1200 struct wpa_ssid *prev, **nlist;
1203 * Add to an existing priority list if one is available for the
1204 * configured priority level for this network.
1206 for (prio = 0; prio < config->num_prio; prio++) {
1207 prev = config->pssid[prio];
1208 if (prev->priority == ssid->priority) {
1216 /* First network for this priority - add a new priority list */
1217 nlist = os_realloc(config->pssid,
1218 (config->num_prio + 1) * sizeof(struct wpa_ssid *));
1222 for (prio = 0; prio < config->num_prio; prio++) {
1223 if (nlist[prio]->priority < ssid->priority)
1227 os_memmove(&nlist[prio + 1], &nlist[prio],
1228 (config->num_prio - prio) * sizeof(struct wpa_ssid *));
1232 config->pssid = nlist;
1239 * wpa_config_update_prio_list - Update network priority list
1240 * @config: Configuration data from wpa_config_read()
1241 * Returns: 0 on success, -1 on failure
1243 * This function is called to update the priority list of networks in the
1244 * configuration when a network is being added or removed. This is also called
1245 * if a priority for a network is changed.
1247 static int wpa_config_update_prio_list(struct wpa_config *config)
1249 struct wpa_ssid *ssid;
1252 os_free(config->pssid);
1253 config->pssid = NULL;
1254 config->num_prio = 0;
1256 ssid = config->ssid;
1259 if (wpa_config_add_prio_network(config, ssid) < 0)
1269 * wpa_config_free_ssid - Free network/ssid configuration data
1270 * @ssid: Configuration data for the network
1272 * This function frees all resources allocated for the network configuration
1275 void wpa_config_free_ssid(struct wpa_ssid *ssid)
1277 os_free(ssid->ssid);
1278 os_free(ssid->passphrase);
1279 #ifdef IEEE8021X_EAPOL
1280 os_free(ssid->eap_methods);
1281 os_free(ssid->identity);
1282 os_free(ssid->anonymous_identity);
1283 os_free(ssid->eappsk);
1285 os_free(ssid->password);
1286 os_free(ssid->ca_cert);
1287 os_free(ssid->ca_path);
1288 os_free(ssid->client_cert);
1289 os_free(ssid->private_key);
1290 os_free(ssid->private_key_passwd);
1291 os_free(ssid->dh_file);
1292 os_free(ssid->subject_match);
1293 os_free(ssid->altsubject_match);
1294 os_free(ssid->ca_cert2);
1295 os_free(ssid->ca_path2);
1296 os_free(ssid->client_cert2);
1297 os_free(ssid->private_key2);
1298 os_free(ssid->private_key2_passwd);
1299 os_free(ssid->dh_file2);
1300 os_free(ssid->subject_match2);
1301 os_free(ssid->altsubject_match2);
1302 os_free(ssid->phase1);
1303 os_free(ssid->phase2);
1304 os_free(ssid->pcsc);
1306 os_free(ssid->engine_id);
1307 os_free(ssid->key_id);
1309 os_free(ssid->pending_req_otp);
1310 os_free(ssid->pac_file);
1311 os_free(ssid->new_password);
1312 #endif /* IEEE8021X_EAPOL */
1313 os_free(ssid->id_str);
1319 * wpa_config_free - Free configuration data
1320 * @config: Configuration data from wpa_config_read()
1322 * This function frees all resources allocated for the configuration data by
1323 * wpa_config_read().
1325 void wpa_config_free(struct wpa_config *config)
1327 struct wpa_config_blob *blob, *prevblob;
1328 struct wpa_ssid *ssid, *prev = NULL;
1329 ssid = config->ssid;
1333 wpa_config_free_ssid(prev);
1336 blob = config->blobs;
1341 wpa_config_free_blob(prevblob);
1344 os_free(config->ctrl_interface);
1345 os_free(config->ctrl_interface_group);
1346 os_free(config->opensc_engine_path);
1347 os_free(config->pkcs11_engine_path);
1348 os_free(config->pkcs11_module_path);
1349 os_free(config->driver_param);
1350 os_free(config->pssid);
1355 #ifdef IEEE8021X_EAPOL
1357 * wpa_config_allowed_eap_method - Check whether EAP method is allowed
1358 * @ssid: Pointer to configuration data
1359 * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types
1361 * Returns: 1 = allowed EAP method, 0 = not allowed
1363 int wpa_config_allowed_eap_method(struct wpa_ssid *ssid, int vendor,
1367 struct eap_method_type *m;
1369 if (ssid == NULL || ssid->eap_methods == NULL)
1372 m = ssid->eap_methods;
1373 for (i = 0; m[i].vendor != EAP_VENDOR_IETF ||
1374 m[i].method != EAP_TYPE_NONE; i++) {
1375 if (m[i].vendor == vendor && m[i].method == method)
1380 #endif /* IEEE8021X_EAPOL */
1384 * wpa_config_get_network - Get configured network based on id
1385 * @config: Configuration data from wpa_config_read()
1386 * @id: Unique network id to search for
1387 * Returns: Network configuration or %NULL if not found
1389 struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id)
1391 struct wpa_ssid *ssid;
1393 ssid = config->ssid;
1405 * wpa_config_add_network - Add a new network with empty configuration
1406 * @config: Configuration data from wpa_config_read()
1407 * Returns: The new network configuration or %NULL if operation failed
1409 struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
1412 struct wpa_ssid *ssid, *last = NULL;
1415 ssid = config->ssid;
1424 ssid = os_zalloc(sizeof(*ssid));
1431 config->ssid = ssid;
1433 wpa_config_update_prio_list(config);
1440 * wpa_config_remove_network - Remove a configured network based on id
1441 * @config: Configuration data from wpa_config_read()
1442 * @id: Unique network id to search for
1443 * Returns: 0 on success, or -1 if the network was not found
1445 int wpa_config_remove_network(struct wpa_config *config, int id)
1447 struct wpa_ssid *ssid, *prev = NULL;
1449 ssid = config->ssid;
1461 prev->next = ssid->next;
1463 config->ssid = ssid->next;
1465 wpa_config_update_prio_list(config);
1466 wpa_config_free_ssid(ssid);
1472 * wpa_config_set_network_defaults - Set network default values
1473 * @ssid: Pointer to network configuration data
1475 void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
1477 ssid->proto = DEFAULT_PROTO;
1478 ssid->pairwise_cipher = DEFAULT_PAIRWISE;
1479 ssid->group_cipher = DEFAULT_GROUP;
1480 ssid->key_mgmt = DEFAULT_KEY_MGMT;
1481 #ifdef IEEE8021X_EAPOL
1482 ssid->eapol_flags = DEFAULT_EAPOL_FLAGS;
1483 ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
1484 ssid->fragment_size = DEFAULT_FRAGMENT_SIZE;
1485 #endif /* IEEE8021X_EAPOL */
1490 * wpa_config_set - Set a variable in network configuration
1491 * @ssid: Pointer to network configuration data
1492 * @var: Variable name, e.g., "ssid"
1493 * @value: Variable value
1494 * @line: Line number in configuration file or 0 if not used
1495 * Returns: 0 on success, -1 on failure
1497 * This function can be used to set network configuration variables based on
1498 * both the configuration file and management interface input. The value
1499 * parameter must be in the same format as the text-based configuration file is
1500 * using. For example, strings are using double quotation marks.
1502 int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
1508 if (ssid == NULL || var == NULL || value == NULL)
1511 for (i = 0; i < NUM_SSID_FIELDS; i++) {
1512 const struct parse_data *field = &ssid_fields[i];
1513 if (os_strcmp(var, field->name) != 0)
1516 if (field->parser(field, ssid, line, value)) {
1518 wpa_printf(MSG_ERROR, "Line %d: failed to "
1519 "parse %s '%s'.", line, var, value);
1525 if (i == NUM_SSID_FIELDS) {
1527 wpa_printf(MSG_ERROR, "Line %d: unknown network field "
1528 "'%s'.", line, var);
1538 * wpa_config_get - Get a variable in network configuration
1539 * @ssid: Pointer to network configuration data
1540 * @var: Variable name, e.g., "ssid"
1541 * Returns: Value of the variable or %NULL on failure
1543 * This function can be used to get network configuration variables. The
1544 * returned value is a copy of the configuration variable in text format, i.e,.
1545 * the same format that the text-based configuration file and wpa_config_set()
1546 * are using for the value. The caller is responsible for freeing the returned
1549 char * wpa_config_get(struct wpa_ssid *ssid, const char *var)
1553 if (ssid == NULL || var == NULL)
1556 for (i = 0; i < NUM_SSID_FIELDS; i++) {
1557 const struct parse_data *field = &ssid_fields[i];
1558 if (os_strcmp(var, field->name) == 0)
1559 return field->writer(field, ssid);
1567 * wpa_config_get_no_key - Get a variable in network configuration (no keys)
1568 * @ssid: Pointer to network configuration data
1569 * @var: Variable name, e.g., "ssid"
1570 * Returns: Value of the variable or %NULL on failure
1572 * This function can be used to get network configuration variable like
1573 * wpa_config_get(). The only difference is that this functions does not expose
1574 * key/password material from the configuration. In case a key/password field
1575 * is requested, the returned value is an empty string or %NULL if the variable
1576 * is not set or "*" if the variable is set (regardless of its value). The
1577 * returned value is a copy of the configuration variable in text format, i.e,.
1578 * the same format that the text-based configuration file and wpa_config_set()
1579 * are using for the value. The caller is responsible for freeing the returned
1582 char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var)
1586 if (ssid == NULL || var == NULL)
1589 for (i = 0; i < NUM_SSID_FIELDS; i++) {
1590 const struct parse_data *field = &ssid_fields[i];
1591 if (os_strcmp(var, field->name) == 0) {
1592 char *res = field->writer(field, ssid);
1593 if (field->key_data) {
1594 if (res && res[0]) {
1595 wpa_printf(MSG_DEBUG, "Do not allow "
1596 "key_data field to be "
1599 return os_strdup("*");
1614 * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
1615 * @ssid: Pointer to network configuration data
1617 * This function must be called to update WPA PSK when either SSID or the
1618 * passphrase has changed for the network configuration.
1620 void wpa_config_update_psk(struct wpa_ssid *ssid)
1622 pbkdf2_sha1(ssid->passphrase,
1623 (char *) ssid->ssid, ssid->ssid_len, 4096,
1624 ssid->psk, PMK_LEN);
1625 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1626 ssid->psk, PMK_LEN);
1632 * wpa_config_get_blob - Get a named configuration blob
1633 * @config: Configuration data from wpa_config_read()
1634 * @name: Name of the blob
1635 * Returns: Pointer to blob data or %NULL if not found
1637 const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
1640 struct wpa_config_blob *blob = config->blobs;
1643 if (os_strcmp(blob->name, name) == 0)
1652 * wpa_config_set_blob - Set or add a named configuration blob
1653 * @config: Configuration data from wpa_config_read()
1654 * @blob: New value for the blob
1656 * Adds a new configuration blob or replaces the current value of an existing
1659 void wpa_config_set_blob(struct wpa_config *config,
1660 struct wpa_config_blob *blob)
1662 wpa_config_remove_blob(config, blob->name);
1663 blob->next = config->blobs;
1664 config->blobs = blob;
1669 * wpa_config_free_blob - Free blob data
1670 * @blob: Pointer to blob to be freed
1672 void wpa_config_free_blob(struct wpa_config_blob *blob)
1675 os_free(blob->name);
1676 os_free(blob->data);
1683 * wpa_config_remove_blob - Remove a named configuration blob
1684 * @config: Configuration data from wpa_config_read()
1685 * @name: Name of the blob to remove
1686 * Returns: 0 if blob was removed or -1 if blob was not found
1688 int wpa_config_remove_blob(struct wpa_config *config, const char *name)
1690 struct wpa_config_blob *pos = config->blobs, *prev = NULL;
1693 if (os_strcmp(pos->name, name) == 0) {
1695 prev->next = pos->next;
1697 config->blobs = pos->next;
1698 wpa_config_free_blob(pos);
1710 * wpa_config_alloc_empty - Allocate an empty configuration
1711 * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
1713 * @driver_param: Driver parameters
1714 * Returns: Pointer to allocated configuration data or %NULL on failure
1716 struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
1717 const char *driver_param)
1719 struct wpa_config *config;
1721 config = os_zalloc(sizeof(*config));
1724 config->eapol_version = DEFAULT_EAPOL_VERSION;
1725 config->ap_scan = DEFAULT_AP_SCAN;
1726 config->fast_reauth = DEFAULT_FAST_REAUTH;
1729 config->ctrl_interface = os_strdup(ctrl_interface);
1731 config->driver_param = os_strdup(driver_param);
1737 #ifndef CONFIG_NO_STDOUT_DEBUG
1739 * wpa_config_debug_dump_networks - Debug dump of configured networks
1740 * @config: Configuration data from wpa_config_read()
1742 void wpa_config_debug_dump_networks(struct wpa_config *config)
1745 struct wpa_ssid *ssid;
1747 for (prio = 0; prio < config->num_prio; prio++) {
1748 ssid = config->pssid[prio];
1749 wpa_printf(MSG_DEBUG, "Priority group %d",
1752 wpa_printf(MSG_DEBUG, " id=%d ssid='%s'",
1754 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1759 #endif /* CONFIG_NO_STDOUT_DEBUG */