]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa_supplicant/config.c
This commit was generated by cvs2svn to compensate for changes in r168515,
[FreeBSD/FreeBSD.git] / contrib / wpa_supplicant / config.c
1 /*
2  * WPA Supplicant / Configuration parser and common functions
3  * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
4  *
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.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18
19 #include "common.h"
20 #include "wpa.h"
21 #include "sha1.h"
22 #include "wpa_supplicant.h"
23 #include "eapol_sm.h"
24 #include "eap.h"
25 #include "l2_packet.h"
26 #include "config.h"
27
28
29 /*
30  * Structure for network configuration parsing. This data is used to implement
31  * a generic parser for each network block variable. The table of configuration
32  * variables is defined below in this file (ssid_fields[]).
33  */
34 struct parse_data {
35         /* Configuration variable name */
36         char *name;
37
38         /* Parser function for this variable */
39         int (*parser)(const struct parse_data *data, struct wpa_ssid *ssid,
40                       int line, const char *value);
41
42         /* Writer function (i.e., to get the variable in text format from
43          * internal presentation). */
44         char * (*writer)(const struct parse_data *data, struct wpa_ssid *ssid);
45
46         /* Variable specific parameters for the parser. */
47         void *param1, *param2, *param3, *param4;
48
49         /* 0 = this variable can be included in debug output
50          * 1 = this variable contains key/private data and it must not be
51          *     included in debug output unless explicitly requested
52          */
53         int key_data;
54 };
55
56
57 static char * wpa_config_parse_string(const char *value, size_t *len)
58 {
59         if (*value == '"') {
60                 char *pos;
61                 value++;
62                 pos = strchr(value, '"');
63                 if (pos == NULL || pos[1] != '\0')
64                         return NULL;
65                 *pos = '\0';
66                 *len = strlen(value);
67                 return strdup(value);
68         } else {
69                 u8 *str;
70                 size_t hlen = strlen(value);
71                 if (hlen % 1)
72                         return NULL;
73                 *len = hlen / 2;
74                 str = malloc(*len);
75                 if (str == NULL)
76                         return NULL;
77                 if (hexstr2bin(value, str, *len)) {
78                         free(str);
79                         return NULL;
80                 }
81                 return (char *) str;
82         }
83 }
84
85
86 static int wpa_config_parse_str(const struct parse_data *data,
87                                 struct wpa_ssid *ssid,
88                                 int line, const char *value)
89 {
90         size_t res_len, *dst_len;
91         char **dst;
92
93         dst = (char **) (((u8 *) ssid) + (long) data->param1);
94         dst_len = (size_t *) (((u8 *) ssid) + (long) data->param2);
95
96         free(*dst);
97         *dst = wpa_config_parse_string(value, &res_len);
98         if (*dst == NULL) {
99                 wpa_printf(MSG_ERROR, "Line %d: failed to parse %s '%s'.",
100                            line, data->name, value);
101                 return -1;
102         }
103         if (data->param2)
104                 *dst_len = res_len;
105
106         if (data->key_data) {
107                 wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
108                                       (u8 *) *dst, res_len);
109         } else {
110                 wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
111                                   (u8 *) *dst, res_len);
112         }
113
114         if (data->param3 && res_len < (size_t) data->param3) {
115                 wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
116                            "min_len=%ld)", line, data->name,
117                            (unsigned long) res_len, (long) data->param3);
118                 free(*dst);
119                 *dst = NULL;
120                 return -1;
121         }
122
123         if (data->param4 && res_len > (size_t) data->param4) {
124                 wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
125                            "max_len=%ld)", line, data->name,
126                            (unsigned long) res_len, (long) data->param4);
127                 free(*dst);
128                 *dst = NULL;
129                 return -1;
130         }
131
132         return 0;
133 }
134
135
136 static int is_hex(const u8 *data, size_t len)
137 {
138         int i;
139
140         for (i = 0; i < len; i++) {
141                 if (data[i] < 32 || data[i] >= 127)
142                         return 1;
143         }
144         return 0;
145 }
146
147
148 static char * wpa_config_write_string_ascii(const u8 *value, size_t len)
149 {
150         int i;
151         char *buf, *pos, *end;
152
153         pos = buf = malloc(len + 3);
154         if (buf == NULL)
155                 return NULL;
156         end = buf + len + 3;
157         pos += snprintf(pos, end - pos, "\"");
158         for (i = 0; i < len; i++)
159                 pos += snprintf(pos, end - pos, "%c", value[i]);
160         pos += snprintf(pos, end - pos, "\"");
161
162         return buf;
163 }
164
165
166 static char * wpa_config_write_string_hex(const u8 *value, size_t len)
167 {
168         int i;
169         char *buf, *pos, *end;
170
171         pos = buf = malloc(2 * len + 1);
172         if (buf == NULL)
173                 return NULL;
174         memset(buf, 0, 2 * len + 1);
175         end = buf + 2 * len + 1;
176         for (i = 0; i < len; i++)
177                 pos += snprintf(pos, end - pos, "%02x", value[i]);
178
179         return buf;
180 }
181
182
183 static char * wpa_config_write_string(const u8 *value, size_t len)
184 {
185         if (value == NULL)
186                 return NULL;
187
188         if (is_hex(value, len))
189                 return wpa_config_write_string_hex(value, len);
190         else
191                 return wpa_config_write_string_ascii(value, len);
192 }
193
194
195 static char * wpa_config_write_str(const struct parse_data *data,
196                                    struct wpa_ssid *ssid)
197 {
198         size_t len;
199         char **src;
200
201         src = (char **) (((u8 *) ssid) + (long) data->param1);
202         if (*src == NULL)
203                 return NULL;
204
205         if (data->param2)
206                 len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
207         else
208                 len = strlen(*src);
209
210         return wpa_config_write_string((const u8 *) *src, len);
211 }
212
213
214 static int wpa_config_parse_int(const struct parse_data *data,
215                                 struct wpa_ssid *ssid,
216                                 int line, const char *value)
217 {
218         int *dst;
219
220         dst = (int *) (((u8 *) ssid) + (long) data->param1);
221         *dst = atoi(value);
222         wpa_printf(MSG_MSGDUMP, "%s=%d (0x%x)", data->name, *dst, *dst);
223
224         if (data->param3 && *dst < (long) data->param3) {
225                 wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
226                            "min_value=%ld)", line, data->name, *dst,
227                            (long) data->param3);
228                 *dst = (long) data->param3;
229                 return -1;
230         }
231
232         if (data->param4 && *dst > (long) data->param4) {
233                 wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
234                            "max_value=%ld)", line, data->name, *dst,
235                            (long) data->param4);
236                 *dst = (long) data->param4;
237                 return -1;
238         }
239
240         return 0;
241 }
242
243
244 static char * wpa_config_write_int(const struct parse_data *data,
245                                    struct wpa_ssid *ssid)
246 {
247         int *src;
248         char *value;
249
250         src = (int *) (((u8 *) ssid) + (long) data->param1);
251
252         value = malloc(20);
253         if (value == NULL)
254                 return NULL;
255         snprintf(value, 20, "%d", *src);
256         return value;
257 }
258
259
260 static int wpa_config_parse_bssid(const struct parse_data *data,
261                                   struct wpa_ssid *ssid, int line,
262                                   const char *value)
263 {
264         if (hwaddr_aton(value, ssid->bssid)) {
265                 wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.",
266                            line, value);
267                 return -1;
268         }
269         ssid->bssid_set = 1;
270         wpa_hexdump(MSG_MSGDUMP, "BSSID", ssid->bssid, ETH_ALEN);
271         return 0;
272 }
273
274
275 static char * wpa_config_write_bssid(const struct parse_data *data,
276                                      struct wpa_ssid *ssid)
277 {
278         char *value;
279
280         if (!ssid->bssid_set)
281                 return NULL;
282
283         value = malloc(20);
284         if (value == NULL)
285                 return NULL;
286         snprintf(value, 20, MACSTR, MAC2STR(ssid->bssid));
287         return value;
288 }
289
290
291 static int wpa_config_parse_psk(const struct parse_data *data,
292                                 struct wpa_ssid *ssid, int line,
293                                 const char *value)
294 {
295         if (*value == '"') {
296                 char *pos;
297                 size_t len;
298
299                 value++;
300                 pos = strrchr(value, '"');
301                 if (pos)
302                         *pos = '\0';
303                 len = strlen(value);
304                 if (len < 8 || len > 63) {
305                         wpa_printf(MSG_ERROR, "Line %d: Invalid passphrase "
306                                    "length %lu (expected: 8..63) '%s'.",
307                                    line, (unsigned long) len, value);
308                         return -1;
309                 }
310                 wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)",
311                                       (u8 *) value, len);
312                 ssid->passphrase = strdup(value);
313                 return ssid->passphrase == NULL ? -1 : 0;
314         }
315
316         if (hexstr2bin(value, ssid->psk, PMK_LEN) ||
317             value[PMK_LEN * 2] != '\0') {
318                 wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
319                            line, value);
320                 return -1;
321         }
322         ssid->psk_set = 1;
323         wpa_hexdump_key(MSG_MSGDUMP, "PSK", ssid->psk, PMK_LEN);
324         return 0;
325 }
326
327
328 static char * wpa_config_write_psk(const struct parse_data *data,
329                                    struct wpa_ssid *ssid)
330 {
331         if (ssid->passphrase)
332                 return wpa_config_write_string_ascii(
333                         (const u8 *) ssid->passphrase,
334                         strlen(ssid->passphrase));
335
336         if (ssid->psk_set)
337                 return wpa_config_write_string_hex(ssid->psk, PMK_LEN);
338
339         return NULL;
340 }
341
342
343 static int wpa_config_parse_proto(const struct parse_data *data,
344                                   struct wpa_ssid *ssid, int line,
345                                   const char *value)
346 {
347         int val = 0, last, errors = 0;
348         char *start, *end, *buf;
349
350         buf = strdup(value);
351         if (buf == NULL)
352                 return -1;
353         start = buf;
354
355         while (*start != '\0') {
356                 while (*start == ' ' || *start == '\t')
357                         start++;
358                 if (*start == '\0')
359                         break;
360                 end = start;
361                 while (*end != ' ' && *end != '\t' && *end != '\0')
362                         end++;
363                 last = *end == '\0';
364                 *end = '\0';
365                 if (strcmp(start, "WPA") == 0)
366                         val |= WPA_PROTO_WPA;
367                 else if (strcmp(start, "RSN") == 0 ||
368                          strcmp(start, "WPA2") == 0)
369                         val |= WPA_PROTO_RSN;
370                 else {
371                         wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'",
372                                    line, start);
373                         errors++;
374                 }
375
376                 if (last)
377                         break;
378                 start = end + 1;
379         }
380         free(buf);
381
382         if (val == 0) {
383                 wpa_printf(MSG_ERROR,
384                            "Line %d: no proto values configured.", line);
385                 errors++;
386         }
387
388         wpa_printf(MSG_MSGDUMP, "proto: 0x%x", val);
389         ssid->proto = val;
390         return errors ? -1 : 0;
391 }
392
393
394 static char * wpa_config_write_proto(const struct parse_data *data,
395                                      struct wpa_ssid *ssid)
396 {
397         int first = 1;
398         char *buf, *pos, *end;
399
400         pos = buf = malloc(10);
401         if (buf == NULL)
402                 return NULL;
403         memset(buf, 0, 10);
404         end = buf + 10;
405
406         if (ssid->proto & WPA_PROTO_WPA) {
407                 pos += snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
408                 first = 0;
409         }
410
411         if (ssid->proto & WPA_PROTO_RSN) {
412                 pos += snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
413                 first = 0;
414         }
415
416         return buf;
417 }
418
419
420 static int wpa_config_parse_key_mgmt(const struct parse_data *data,
421                                      struct wpa_ssid *ssid, int line,
422                                      const char *value)
423 {
424         int val = 0, last, errors = 0;
425         char *start, *end, *buf;
426
427         buf = strdup(value);
428         if (buf == NULL)
429                 return -1;
430         start = buf;
431
432         while (*start != '\0') {
433                 while (*start == ' ' || *start == '\t')
434                         start++;
435                 if (*start == '\0')
436                         break;
437                 end = start;
438                 while (*end != ' ' && *end != '\t' && *end != '\0')
439                         end++;
440                 last = *end == '\0';
441                 *end = '\0';
442                 if (strcmp(start, "WPA-PSK") == 0)
443                         val |= WPA_KEY_MGMT_PSK;
444                 else if (strcmp(start, "WPA-EAP") == 0)
445                         val |= WPA_KEY_MGMT_IEEE8021X;
446                 else if (strcmp(start, "IEEE8021X") == 0)
447                         val |= WPA_KEY_MGMT_IEEE8021X_NO_WPA;
448                 else if (strcmp(start, "NONE") == 0)
449                         val |= WPA_KEY_MGMT_NONE;
450                 else if (strcmp(start, "WPA-NONE") == 0)
451                         val |= WPA_KEY_MGMT_WPA_NONE;
452                 else {
453                         wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
454                                    line, start);
455                         errors++;
456                 }
457
458                 if (last)
459                         break;
460                 start = end + 1;
461         }
462         free(buf);
463
464         if (val == 0) {
465                 wpa_printf(MSG_ERROR,
466                            "Line %d: no key_mgmt values configured.", line);
467                 errors++;
468         }
469
470         wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val);
471         ssid->key_mgmt = val;
472         return errors ? -1 : 0;
473 }
474
475
476 static char * wpa_config_write_key_mgmt(const struct parse_data *data,
477                                         struct wpa_ssid *ssid)
478 {
479         int first = 1;
480         char *buf, *pos, *end;
481
482         pos = buf = malloc(50);
483         if (buf == NULL)
484                 return NULL;
485         memset(buf, 0, 50);
486         end = buf + 50;
487
488         if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
489                 pos += snprintf(pos, end - pos, "%sWPA-PSK", first ? "" : " ");
490                 first = 0;
491         }
492
493         if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
494                 pos += snprintf(pos, end - pos, "%sWPA-EAP", first ? "" : " ");
495                 first = 0;
496         }
497
498         if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
499                 pos += snprintf(pos, end - pos, "%sIEEE8021X",
500                                 first ? "" : " ");
501                 first = 0;
502         }
503
504         if (ssid->key_mgmt & WPA_KEY_MGMT_NONE) {
505                 pos += snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
506                 first = 0;
507         }
508
509         if (ssid->key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
510                 pos += snprintf(pos, end - pos, "%sWPA-NONE",
511                                 first ? "" : " ");
512                 first = 0;
513         }
514
515         return buf;
516 }
517
518
519 static int wpa_config_parse_cipher(int line, const char *value)
520 {
521         int val = 0, last;
522         char *start, *end, *buf;
523
524         buf = strdup(value);
525         if (buf == NULL)
526                 return -1;
527         start = buf;
528
529         while (*start != '\0') {
530                 while (*start == ' ' || *start == '\t')
531                         start++;
532                 if (*start == '\0')
533                         break;
534                 end = start;
535                 while (*end != ' ' && *end != '\t' && *end != '\0')
536                         end++;
537                 last = *end == '\0';
538                 *end = '\0';
539                 if (strcmp(start, "CCMP") == 0)
540                         val |= WPA_CIPHER_CCMP;
541                 else if (strcmp(start, "TKIP") == 0)
542                         val |= WPA_CIPHER_TKIP;
543                 else if (strcmp(start, "WEP104") == 0)
544                         val |= WPA_CIPHER_WEP104;
545                 else if (strcmp(start, "WEP40") == 0)
546                         val |= WPA_CIPHER_WEP40;
547                 else if (strcmp(start, "NONE") == 0)
548                         val |= WPA_CIPHER_NONE;
549                 else {
550                         wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
551                                    line, start);
552                         free(buf);
553                         return -1;
554                 }
555
556                 if (last)
557                         break;
558                 start = end + 1;
559         }
560         free(buf);
561
562         if (val == 0) {
563                 wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
564                            line);
565                 return -1;
566         }
567         return val;
568 }
569
570
571 static char * wpa_config_write_cipher(int cipher)
572 {
573         int first = 1;
574         char *buf, *pos, *end;
575
576         pos = buf = malloc(50);
577         if (buf == NULL)
578                 return NULL;
579         memset(buf, 0, 50);
580         end = buf + 50;
581
582         if (cipher & WPA_CIPHER_CCMP) {
583                 pos += snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
584                 first = 0;
585         }
586
587         if (cipher & WPA_CIPHER_TKIP) {
588                 pos += snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
589                 first = 0;
590         }
591
592         if (cipher & WPA_CIPHER_WEP104) {
593                 pos += snprintf(pos, end - pos, "%sWEP104", first ? "" : " ");
594                 first = 0;
595         }
596
597         if (cipher & WPA_CIPHER_WEP40) {
598                 pos += snprintf(pos, end - pos, "%sWEP40", first ? "" : " ");
599                 first = 0;
600         }
601
602         if (cipher & WPA_CIPHER_NONE) {
603                 pos += snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
604                 first = 0;
605         }
606
607         return buf;
608 }
609
610
611 static int wpa_config_parse_pairwise(const struct parse_data *data,
612                                      struct wpa_ssid *ssid, int line,
613                                      const char *value)
614 {
615         int val;
616         val = wpa_config_parse_cipher(line, value);
617         if (val == -1)
618                 return -1;
619         if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_NONE)) {
620                 wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
621                            "(0x%x).", line, val);
622                 return -1;
623         }
624
625         wpa_printf(MSG_MSGDUMP, "pairwise: 0x%x", val);
626         ssid->pairwise_cipher = val;
627         return 0;
628 }
629
630
631 static char * wpa_config_write_pairwise(const struct parse_data *data,
632                                         struct wpa_ssid *ssid)
633 {
634         return wpa_config_write_cipher(ssid->pairwise_cipher);
635 }
636
637
638 static int wpa_config_parse_group(const struct parse_data *data,
639                                   struct wpa_ssid *ssid, int line,
640                                   const char *value)
641 {
642         int val;
643         val = wpa_config_parse_cipher(line, value);
644         if (val == -1)
645                 return -1;
646         if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 |
647                     WPA_CIPHER_WEP40)) {
648                 wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
649                            "(0x%x).", line, val);
650                 return -1;
651         }
652
653         wpa_printf(MSG_MSGDUMP, "group: 0x%x", val);
654         ssid->group_cipher = val;
655         return 0;
656 }
657
658
659 static char * wpa_config_write_group(const struct parse_data *data,
660                                      struct wpa_ssid *ssid)
661 {
662         return wpa_config_write_cipher(ssid->group_cipher);
663 }
664
665
666 static int wpa_config_parse_auth_alg(const struct parse_data *data,
667                                      struct wpa_ssid *ssid, int line,
668                                      const char *value)
669 {
670         int val = 0, last, errors = 0;
671         char *start, *end, *buf;
672
673         buf = strdup(value);
674         if (buf == NULL)
675                 return -1;
676         start = buf;
677
678         while (*start != '\0') {
679                 while (*start == ' ' || *start == '\t')
680                         start++;
681                 if (*start == '\0')
682                         break;
683                 end = start;
684                 while (*end != ' ' && *end != '\t' && *end != '\0')
685                         end++;
686                 last = *end == '\0';
687                 *end = '\0';
688                 if (strcmp(start, "OPEN") == 0)
689                         val |= WPA_AUTH_ALG_OPEN;
690                 else if (strcmp(start, "SHARED") == 0)
691                         val |= WPA_AUTH_ALG_SHARED;
692                 else if (strcmp(start, "LEAP") == 0)
693                         val |= WPA_AUTH_ALG_LEAP;
694                 else {
695                         wpa_printf(MSG_ERROR, "Line %d: invalid auth_alg '%s'",
696                                    line, start);
697                         errors++;
698                 }
699
700                 if (last)
701                         break;
702                 start = end + 1;
703         }
704         free(buf);
705
706         if (val == 0) {
707                 wpa_printf(MSG_ERROR,
708                            "Line %d: no auth_alg values configured.", line);
709                 errors++;
710         }
711
712         wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", val);
713         ssid->auth_alg = val;
714         return errors ? -1 : 0;
715 }
716
717
718 static char * wpa_config_write_auth_alg(const struct parse_data *data,
719                                         struct wpa_ssid *ssid)
720 {
721         int first = 1;
722         char *buf, *pos, *end;
723
724         pos = buf = malloc(30);
725         if (buf == NULL)
726                 return NULL;
727         memset(buf, 0, 30);
728         end = buf + 30;
729
730         if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) {
731                 pos += snprintf(pos, end - pos, "%sOPEN", first ? "" : " ");
732                 first = 0;
733         }
734
735         if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) {
736                 pos += snprintf(pos, end - pos, "%sSHARED", first ? "" : " ");
737                 first = 0;
738         }
739
740         if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) {
741                 pos += snprintf(pos, end - pos, "%sLEAP", first ? "" : " ");
742                 first = 0;
743         }
744
745         return buf;
746 }
747
748
749 static int wpa_config_parse_eap(const struct parse_data *data,
750                                 struct wpa_ssid *ssid, int line,
751                                 const char *value)
752 {
753         int last, errors = 0;
754         char *start, *end, *buf;
755         u8 *methods = NULL, *tmp;
756         size_t num_methods = 0;
757
758         buf = strdup(value);
759         if (buf == NULL)
760                 return -1;
761         start = buf;
762
763         while (*start != '\0') {
764                 while (*start == ' ' || *start == '\t')
765                         start++;
766                 if (*start == '\0')
767                         break;
768                 end = start;
769                 while (*end != ' ' && *end != '\t' && *end != '\0')
770                         end++;
771                 last = *end == '\0';
772                 *end = '\0';
773                 tmp = methods;
774                 methods = realloc(methods, num_methods + 1);
775                 if (methods == NULL) {
776                         free(tmp);
777                         return -1;
778                 }
779                 methods[num_methods] = eap_get_type(start);
780                 if (methods[num_methods] == EAP_TYPE_NONE) {
781                         wpa_printf(MSG_ERROR, "Line %d: unknown EAP method "
782                                    "'%s'", line, start);
783                         wpa_printf(MSG_ERROR, "You may need to add support for"
784                                    " this EAP method during wpa_supplicant\n"
785                                    "build time configuration.\n"
786                                    "See README for more information.");
787                         errors++;
788                 } else if (methods[num_methods] == EAP_TYPE_LEAP)
789                         ssid->leap++;
790                 else
791                         ssid->non_leap++;
792                 num_methods++;
793                 if (last)
794                         break;
795                 start = end + 1;
796         }
797         free(buf);
798
799         tmp = methods;
800         methods = realloc(methods, num_methods + 1);
801         if (methods == NULL) {
802                 free(tmp);
803                 return -1;
804         }
805         methods[num_methods] = EAP_TYPE_NONE;
806         num_methods++;
807
808         wpa_hexdump(MSG_MSGDUMP, "eap methods", methods, num_methods);
809         ssid->eap_methods = methods;
810         return errors ? -1 : 0;
811 }
812
813
814 static char * wpa_config_write_eap(const struct parse_data *data,
815                                    struct wpa_ssid *ssid)
816 {
817         int first = 1;
818         char *buf, *pos, *end;
819         const u8 *eap_methods = ssid->eap_methods;
820         const char *name;
821
822         if (eap_methods == NULL)
823                 return NULL;
824
825         pos = buf = malloc(100);
826         if (buf == NULL)
827                 return NULL;
828         memset(buf, 0, 100);
829         end = buf + 100;
830
831         while (*eap_methods != EAP_TYPE_NONE) {
832                 name = eap_get_name(*eap_methods);
833                 if (name)
834                         pos += snprintf(pos, end - pos, "%s%s",
835                                         first ? "" : " ", name);
836                 first = 0;
837                 eap_methods++;
838         }
839
840         return buf;
841 }
842
843
844 static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line,
845                                     const char *value, int idx)
846 {
847         char *buf, title[20];
848
849         buf = wpa_config_parse_string(value, len);
850         if (buf == NULL) {
851                 wpa_printf(MSG_ERROR, "Line %d: Invalid WEP key %d '%s'.",
852                            line, idx, value);
853                 return -1;
854         }
855         if (*len > MAX_WEP_KEY_LEN) {
856                 wpa_printf(MSG_ERROR, "Line %d: Too long WEP key %d '%s'.",
857                            line, idx, value);
858                 free(buf);
859                 return -1;
860         }
861         memcpy(key, buf, *len);
862         free(buf);
863         snprintf(title, sizeof(title), "wep_key%d", idx);
864         wpa_hexdump_key(MSG_MSGDUMP, title, key, *len);
865         return 0;
866 }
867
868
869 static int wpa_config_parse_wep_key0(const struct parse_data *data,
870                                      struct wpa_ssid *ssid, int line,
871                                      const char *value)
872 {
873         return wpa_config_parse_wep_key(ssid->wep_key[0],
874                                         &ssid->wep_key_len[0], line,
875                                         value, 0);
876 }
877
878
879 static int wpa_config_parse_wep_key1(const struct parse_data *data,
880                                      struct wpa_ssid *ssid, int line,
881                                      const char *value)
882 {
883         return wpa_config_parse_wep_key(ssid->wep_key[1],
884                                         &ssid->wep_key_len[1], line,
885                                         value, 1);
886 }
887
888
889 static int wpa_config_parse_wep_key2(const struct parse_data *data,
890                                      struct wpa_ssid *ssid, int line,
891                                      const char *value)
892 {
893         return wpa_config_parse_wep_key(ssid->wep_key[2],
894                                         &ssid->wep_key_len[2], line,
895                                         value, 2);
896 }
897
898
899 static int wpa_config_parse_wep_key3(const struct parse_data *data,
900                                      struct wpa_ssid *ssid, int line,
901                                      const char *value)
902 {
903         return wpa_config_parse_wep_key(ssid->wep_key[3],
904                                         &ssid->wep_key_len[3], line,
905                                         value, 3);
906 }
907
908
909 static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx)
910 {
911         if (ssid->wep_key_len[idx] == 0)
912                 return NULL;
913         return wpa_config_write_string(ssid->wep_key[idx],
914                                        ssid->wep_key_len[idx]);
915 }
916
917
918 static char * wpa_config_write_wep_key0(const struct parse_data *data,
919                                         struct wpa_ssid *ssid)
920 {
921         return wpa_config_write_wep_key(ssid, 0);
922 }
923
924
925 static char * wpa_config_write_wep_key1(const struct parse_data *data,
926                                         struct wpa_ssid *ssid)
927 {
928         return wpa_config_write_wep_key(ssid, 1);
929 }
930
931
932 static char * wpa_config_write_wep_key2(const struct parse_data *data,
933                                         struct wpa_ssid *ssid)
934 {
935         return wpa_config_write_wep_key(ssid, 2);
936 }
937
938
939 static char * wpa_config_write_wep_key3(const struct parse_data *data,
940                                         struct wpa_ssid *ssid)
941 {
942         return wpa_config_write_wep_key(ssid, 3);
943 }
944
945
946 /* Helper macros for network block parser */
947
948 /* OFFSET: Get offset of a variable within the wpa_ssid structure */
949 #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
950
951 /* STR: Define a string variable for an ASCII string; f = field name */
952 #define STR(f) .name = #f, .parser = wpa_config_parse_str, \
953         .writer = wpa_config_write_str, .param1 = OFFSET(f)
954
955 /* STR_LEN: Define a string variable with a separate variable for storing the
956  * data length. Unlike STR(), this can be used to store arbitrary binary data
957  * (i.e., even nul termination character). */
958 #define STR_LEN(f) STR(f), .param2 = OFFSET(f ## _len)
959
960 /* STR_RANGE: Like STR_LEN(), but with minimum and maximum allowed length
961  * explicitly specified. */
962 #define STR_RANGE(f, min, max) STR_LEN(f), .param3 = (void *) (min), \
963         .param4 = (void *) (max)
964
965
966 /* INT: Define an integer variable */
967 #define INT(f) .name = #f, .parser = wpa_config_parse_int, \
968         .writer = wpa_config_write_int, \
969         .param1 = OFFSET(f), .param2 = (void *) 0
970
971 /* INT: Define an integer variable with allowed value range */
972 #define INT_RANGE(f, min, max) INT(f), .param3 = (void *) (min), \
973         .param4 = (void *) (max)
974
975 /* FUNC: Define a configuration variable that uses a custom function for
976  * parsing and writing the value. */
977 #define FUNC(f) .name = #f, .parser = wpa_config_parse_ ## f, \
978                 .writer = wpa_config_write_ ## f
979
980 /*
981  * Table of network configuration variables. This table is used to parse each
982  * network configuration variable, e.g., each line in wpa_supplicant.conf file
983  * that is insider a network block.
984  *
985  * This table is generated using the helper macros defined above and with
986  * generous help from the C pre-processor. The field name is stored as a string
987  * into .name and for STR and INT types, the offset of the target buffer within
988  * struct wpa_ssid is stored in .param1. .param2 (if not NULL) is similar
989  * offset to the field containing the length of the configuration variable.
990  * .param3 and .param4 can be used to mark the allowed range (length for STR
991  * and value for INT).
992  *
993  * For each configuration line in wpa_supplicant.conf, the parser goes through
994  * this table and select the entry that matches with the field name. The parser
995  * function (.parser) is then called to parse the actual value of the field.
996  *
997  * This kind of mechanism makes it easy to add new configuration parameters,
998  * since only one line needs to be added into this table and in struct wpa_ssid
999  * definitions if the new variable is either a string or integer. More complex
1000  * types will need to use their own parser and writer functions.
1001  */
1002 static const struct parse_data ssid_fields[] = {
1003         { STR_RANGE(ssid, 0, MAX_SSID_LEN) },
1004         { INT_RANGE(scan_ssid, 0, 1) },
1005         { FUNC(bssid) },
1006         { FUNC(psk), .key_data = 1 },
1007         { FUNC(proto) },
1008         { FUNC(key_mgmt) },
1009         { FUNC(pairwise) },
1010         { FUNC(group) },
1011         { FUNC(auth_alg) },
1012         { FUNC(eap) },
1013         { STR_LEN(identity) },
1014         { STR_LEN(anonymous_identity) },
1015         { STR_RANGE(eappsk, EAP_PSK_LEN, EAP_PSK_LEN), .key_data = 1 },
1016         { STR_LEN(nai) },
1017         { STR_LEN(password), .key_data = 1 },
1018         { STR(ca_cert) },
1019         { STR(ca_path) },
1020         { STR(client_cert) },
1021         { STR(private_key) },
1022         { STR(private_key_passwd), .key_data = 1 },
1023         { STR(dh_file) },
1024         { STR(subject_match) },
1025         { STR(altsubject_match) },
1026         { STR(ca_cert2) },
1027         { STR(ca_path2) },
1028         { STR(client_cert2) },
1029         { STR(private_key2) },
1030         { STR(private_key2_passwd), .key_data = 1 },
1031         { STR(dh_file2) },
1032         { STR(subject_match2) },
1033         { STR(altsubject_match2) },
1034         { STR(phase1) },
1035         { STR(phase2) },
1036         { STR(pcsc) },
1037         { STR(pin), .key_data = 1 },
1038         { STR(engine_id) },
1039         { STR(key_id) },
1040         { INT(engine) },
1041         { INT(eapol_flags) },
1042         { FUNC(wep_key0), .key_data = 1 },
1043         { FUNC(wep_key1), .key_data = 1 },
1044         { FUNC(wep_key2), .key_data = 1 },
1045         { FUNC(wep_key3), .key_data = 1 },
1046         { INT(wep_tx_keyidx) },
1047         { INT(priority) },
1048         { INT(eap_workaround) },
1049         { STR(pac_file) },
1050         { INT_RANGE(mode, 0, 1) },
1051         { INT_RANGE(proactive_key_caching, 0, 1) },
1052         { INT_RANGE(disabled, 0, 1) },
1053 };
1054
1055 #undef OFFSET
1056 #undef STR
1057 #undef STR_LEN
1058 #undef STR_RANGE
1059 #undef INT
1060 #undef INT_RANGE
1061 #undef FUNC
1062 #define NUM_SSID_FIELDS (sizeof(ssid_fields) / sizeof(ssid_fields[0]))
1063
1064
1065 /**
1066  * wpa_config_add_prio_network - Add a network to priority lists
1067  * @config: Configuration data from wpa_config_read()
1068  * Returns: 0 on success, -1 on failure
1069  *
1070  * This function is used to add a network block to the priority list of
1071  * networks. This must be called for each network when reading in the full
1072  * configuration. In addition, this can be used indirectly when updating
1073  * priorities by calling wpa_config_update_prio_list().
1074  */
1075 int wpa_config_add_prio_network(struct wpa_config *config,
1076                                 struct wpa_ssid *ssid)
1077 {
1078         int prio;
1079         struct wpa_ssid *prev, **nlist;
1080
1081         for (prio = 0; prio < config->num_prio; prio++) {
1082                 prev = config->pssid[prio];
1083                 if (prev->priority == ssid->priority) {
1084                         while (prev->pnext)
1085                                 prev = prev->pnext;
1086                         prev->pnext = ssid;
1087                         return 0;
1088                 }
1089         }
1090
1091         /* First network for this priority - add new priority list */
1092         nlist = realloc(config->pssid,
1093                         (config->num_prio + 1) * sizeof(struct wpa_ssid *));
1094         if (nlist == NULL)
1095                 return -1;
1096
1097         for (prio = 0; prio < config->num_prio; prio++) {
1098                 if (nlist[prio]->priority < ssid->priority)
1099                         break;
1100         }
1101
1102         memmove(&nlist[prio + 1], &nlist[prio],
1103                 (config->num_prio - prio) * sizeof(struct wpa_ssid *));
1104
1105         nlist[prio] = ssid;
1106         config->num_prio++;
1107         config->pssid = nlist;
1108
1109         return 0;
1110 }
1111
1112
1113 /**
1114  * wpa_config_update_prio_list - Update network priority list
1115  * @config: Configuration data from wpa_config_read()
1116  * Returns: 0 on success, -1 on failure
1117  *
1118  * This function is called to update the priority list of networks in the
1119  * configuration when a network is being added or removed. This is also called
1120  * if a priority for a network is changed.
1121  */
1122 static int wpa_config_update_prio_list(struct wpa_config *config)
1123 {
1124         struct wpa_ssid *ssid;
1125         int ret = 0;
1126
1127         free(config->pssid);
1128         config->pssid = NULL;
1129         config->num_prio = 0;
1130
1131         ssid = config->ssid;
1132         while (ssid) {
1133                 ssid->pnext = NULL;
1134                 if (wpa_config_add_prio_network(config, ssid) < 0)
1135                         ret = -1;
1136                 ssid = ssid->next;
1137         }
1138
1139         return ret;
1140 }
1141
1142
1143 /**
1144  * wpa_config_free_ssid - Free network/ssid configuration data
1145  * @ssid: Configuration data for the network
1146  *
1147  * This function frees all resources allocated for the netowkr configuration
1148  * data.
1149  */
1150 void wpa_config_free_ssid(struct wpa_ssid *ssid)
1151 {
1152         free(ssid->ssid);
1153         free(ssid->passphrase);
1154         free(ssid->eap_methods);
1155         free(ssid->identity);
1156         free(ssid->anonymous_identity);
1157         free(ssid->eappsk);
1158         free(ssid->nai);
1159         free(ssid->password);
1160         free(ssid->ca_cert);
1161         free(ssid->ca_path);
1162         free(ssid->client_cert);
1163         free(ssid->private_key);
1164         free(ssid->private_key_passwd);
1165         free(ssid->dh_file);
1166         free(ssid->subject_match);
1167         free(ssid->altsubject_match);
1168         free(ssid->ca_cert2);
1169         free(ssid->ca_path2);
1170         free(ssid->client_cert2);
1171         free(ssid->private_key2);
1172         free(ssid->private_key2_passwd);
1173         free(ssid->dh_file2);
1174         free(ssid->subject_match2);
1175         free(ssid->altsubject_match2);
1176         free(ssid->phase1);
1177         free(ssid->phase2);
1178         free(ssid->pcsc);
1179         free(ssid->pin);
1180         free(ssid->engine_id);
1181         free(ssid->key_id);
1182         free(ssid->otp);
1183         free(ssid->pending_req_otp);
1184         free(ssid->pac_file);
1185         free(ssid->new_password);
1186         free(ssid);
1187 }
1188
1189
1190 /**
1191  * wpa_config_free - Free configuration data
1192  * @config: Configuration data from wpa_config_read()
1193  *
1194  * This function frees all resources allocated for the configuration data by
1195  * wpa_config_read().
1196  */
1197 void wpa_config_free(struct wpa_config *config)
1198 {
1199         struct wpa_config_blob *blob, *prevblob;
1200         struct wpa_ssid *ssid, *prev = NULL;
1201         ssid = config->ssid;
1202         while (ssid) {
1203                 prev = ssid;
1204                 ssid = ssid->next;
1205                 wpa_config_free_ssid(prev);
1206         }
1207
1208         blob = config->blobs;
1209         prevblob = NULL;
1210         while (blob) {
1211                 prevblob = blob;
1212                 blob = blob->next;
1213                 wpa_config_free_blob(prevblob);
1214         }
1215
1216         free(config->ctrl_interface);
1217         free(config->opensc_engine_path);
1218         free(config->pkcs11_engine_path);
1219         free(config->pkcs11_module_path);
1220         free(config->driver_param);
1221         free(config->pssid);
1222         free(config);
1223 }
1224
1225
1226 /**
1227  * wpa_config_allowed_eap_method - Check whether EAP method is allowed
1228  * @ssid: Pointer to a configuration data
1229  * @method: EAP type
1230  * Returns: 1 = allowed EAP method, 0 = not allowed
1231  */
1232 int wpa_config_allowed_eap_method(struct wpa_ssid *ssid, int method)
1233 {
1234         u8 *pos;
1235
1236         if (ssid == NULL || ssid->eap_methods == NULL)
1237                 return 1;
1238
1239         pos = ssid->eap_methods;
1240         while (*pos != EAP_TYPE_NONE) {
1241                 if (*pos == method)
1242                         return 1;
1243                 pos++;
1244         }
1245         return 0;
1246 }
1247
1248
1249 /**
1250  * wpa_config_get_network - Get configured network based on id
1251  * @config: Configuration data from wpa_config_read()
1252  * @id: Unique network id to search for
1253  * Returns: Network configuration or %NULL if not found
1254  */
1255 struct wpa_ssid * wpa_config_get_network(struct wpa_config *config, int id)
1256 {
1257         struct wpa_ssid *ssid;
1258
1259         ssid = config->ssid;
1260         while (ssid) {
1261                 if (id == ssid->id)
1262                         break;
1263                 ssid = ssid->next;
1264         }
1265
1266         return ssid;
1267 }
1268
1269
1270 /**
1271  * wpa_config_add_network - Add a new network with empty configuration
1272  * @config: Configuration data from wpa_config_read()
1273  * Returns: The new network configuration or %NULL if operation failed
1274  */
1275 struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
1276 {
1277         int id;
1278         struct wpa_ssid *ssid, *last = NULL;
1279
1280         id = -1;
1281         ssid = config->ssid;
1282         while (ssid) {
1283                 if (ssid->id > id)
1284                         id = ssid->id;
1285                 last = ssid;
1286                 ssid = ssid->next;
1287         }
1288         id++;
1289
1290         ssid = malloc(sizeof(*ssid));
1291         if (ssid == NULL)
1292                 return NULL;
1293         memset(ssid, 0, sizeof(*ssid));
1294         ssid->id = id;
1295         if (last)
1296                 last->next = ssid;
1297         else
1298                 config->ssid = ssid;
1299
1300         wpa_config_update_prio_list(config);
1301
1302         return ssid;
1303 }
1304
1305
1306 /**
1307  * wpa_config_remove_network - Remove a configured network based on id
1308  * @config: Configuration data from wpa_config_read()
1309  * @id: Unique network id to search for
1310  * Returns: 0 on success, or -1 if the network was not found
1311  */
1312 int wpa_config_remove_network(struct wpa_config *config, int id)
1313 {
1314         struct wpa_ssid *ssid, *prev = NULL;
1315
1316         ssid = config->ssid;
1317         while (ssid) {
1318                 if (id == ssid->id)
1319                         break;
1320                 prev = ssid;
1321                 ssid = ssid->next;
1322         }
1323
1324         if (ssid == NULL)
1325                 return -1;
1326
1327         if (prev)
1328                 prev->next = ssid->next;
1329         else
1330                 config->ssid = ssid->next;
1331
1332         wpa_config_update_prio_list(config);
1333         wpa_config_free_ssid(ssid);
1334         return 0;
1335 }
1336
1337
1338 /**
1339  * wpa_config_set_network_defaults - Set network default values
1340  * @ssid: Pointer to a network configuration data
1341  */
1342 void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
1343 {
1344         ssid->proto = DEFAULT_PROTO;
1345         ssid->pairwise_cipher = DEFAULT_PAIRWISE;
1346         ssid->group_cipher = DEFAULT_GROUP;
1347         ssid->key_mgmt = DEFAULT_KEY_MGMT;
1348         ssid->eapol_flags = DEFAULT_EAPOL_FLAGS;
1349         ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
1350 }
1351
1352
1353 /**
1354  * wpa_config_set - Set a variable in network configuration
1355  * @ssid: Pointer to a network configuration data
1356  * @var: Variable name, e.g., "ssid"
1357  * @value: Variable value
1358  * @line: Line number in configuration file or 0 if not used
1359  * Returns: 0 on success, -1 on failure
1360  *
1361  * This function can be used to set network configuration variables based on
1362  * both the configuration file and management interface input. The value
1363  * parameter must be in the same format as the text-based configuration file is
1364  * using. For example, strings are using double quotation marks.
1365  */
1366 int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value,
1367                    int line)
1368 {
1369         int i, ret = 0;
1370
1371         if (ssid == NULL || var == NULL || value == NULL)
1372                 return -1;
1373
1374         for (i = 0; i < NUM_SSID_FIELDS; i++) {
1375                 const struct parse_data *field = &ssid_fields[i];
1376                 if (strcmp(var, field->name) != 0)
1377                         continue;
1378
1379                 if (field->parser(field, ssid, line, value)) {
1380                         if (line) {
1381                                 wpa_printf(MSG_ERROR, "Line %d: failed to "
1382                                            "parse %s '%s'.", line, var, value);
1383                         }
1384                         ret = -1;
1385                 }
1386                 break;
1387         }
1388         if (i == NUM_SSID_FIELDS) {
1389                 if (line) {
1390                         wpa_printf(MSG_ERROR, "Line %d: unknown network field "
1391                                    "'%s'.", line, var);
1392                 }
1393                 ret = -1;
1394         }
1395
1396         return ret;
1397 }
1398
1399
1400 /**
1401  * wpa_config_get - Get a variable in network configuration
1402  * @ssid: Pointer to a network configuration data
1403  * @var: Variable name, e.g., "ssid"
1404  * Returns: Value of the variable or %NULL on failure
1405  *
1406  * This function can be used to get network configuration variables. The
1407  * returned value is a copy of the configuration variable in text format, i.e,.
1408  * the same format that the text-based configuration file and wpa_config_set()
1409  * are using for the value. The caller is responsible for freeing the returned
1410  * value.
1411  */
1412 char * wpa_config_get(struct wpa_ssid *ssid, const char *var)
1413 {
1414         int i;
1415
1416         if (ssid == NULL || var == NULL)
1417                 return NULL;
1418
1419         for (i = 0; i < NUM_SSID_FIELDS; i++) {
1420                 const struct parse_data *field = &ssid_fields[i];
1421                 if (strcmp(var, field->name) == 0)
1422                         return field->writer(field, ssid);
1423         }
1424
1425         return NULL;
1426 }
1427
1428
1429 /**
1430  * wpa_config_update_psk - Update WPA PSK based on passphrase and SSID
1431  * @ssid: Pointer to a network configuration data
1432  *
1433  * This function must be called to update WPA PSK when either SSID or the
1434  * passphrase has changed for the network configuration.
1435  */
1436 void wpa_config_update_psk(struct wpa_ssid *ssid)
1437 {
1438         pbkdf2_sha1(ssid->passphrase,
1439                     (char *) ssid->ssid, ssid->ssid_len, 4096,
1440                     ssid->psk, PMK_LEN);
1441         wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1442                         ssid->psk, PMK_LEN);
1443         ssid->psk_set = 1;
1444 }
1445
1446
1447 /**
1448  * wpa_config_get_blob - Get a named configuration blob
1449  * @config: Configuration data from wpa_config_read()
1450  * @name: Name of the blob
1451  * Returns: Pointer to blob data or %NULL if not found
1452  */
1453 const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
1454                                                    const char *name)
1455 {
1456         struct wpa_config_blob *blob = config->blobs;
1457
1458         while (blob) {
1459                 if (strcmp(blob->name, name) == 0)
1460                         return blob;
1461                 blob = blob->next;
1462         }
1463         return NULL;
1464 }
1465
1466
1467 /**
1468  * wpa_config_set_blob - Set or add a named configuration blob
1469  * @config: Configuration data from wpa_config_read()
1470  * @blob: New value for the blob
1471  *
1472  * Adds a new configuration blob or replaces the current value of an existing
1473  * blob.
1474  */
1475 void wpa_config_set_blob(struct wpa_config *config,
1476                          struct wpa_config_blob *blob)
1477 {
1478         wpa_config_remove_blob(config, blob->name);
1479         blob->next = config->blobs;
1480         config->blobs = blob;
1481 }
1482
1483
1484 /**
1485  * wpa_config_free_blob - Free blob data
1486  * @blob: Pointer to blob to be freed
1487  */
1488 void wpa_config_free_blob(struct wpa_config_blob *blob)
1489 {
1490         if (blob) {
1491                 free(blob->name);
1492                 free(blob->data);
1493                 free(blob);
1494         }
1495 }
1496
1497
1498 /**
1499  * wpa_config_remove_blob - Remove a named configuration blob
1500  * @config: Configuration data from wpa_config_read()
1501  * @name: Name of the blob to remove
1502  * Returns: 0 if blob was removed or -1 if blob was not found
1503  */
1504 int wpa_config_remove_blob(struct wpa_config *config, const char *name)
1505 {
1506         struct wpa_config_blob *pos = config->blobs, *prev = NULL;
1507
1508         while (pos) {
1509                 if (strcmp(pos->name, name) == 0) {
1510                         if (prev)
1511                                 prev->next = pos->next;
1512                         else
1513                                 config->blobs = pos->next;
1514                         wpa_config_free_blob(pos);
1515                         return 0;
1516                 }
1517                 prev = pos;
1518                 pos = pos->next;
1519         }
1520
1521         return -1;
1522 }
1523
1524
1525 /**
1526  * wpa_config_alloc_empty - Allocate an empty configuration
1527  * @ctrl_interface: Control interface parameters, e.g., path to UNIX domain
1528  * socket
1529  * @driver_param: Driver parameters
1530  * Returns: Pointer to allocated configuration data or %NULL on failure
1531  */
1532 struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
1533                                            const char *driver_param)
1534 {
1535         struct wpa_config *config;
1536
1537         config = malloc(sizeof(*config));
1538         if (config == NULL)
1539                 return NULL;
1540         memset(config, 0, sizeof(*config));
1541         config->eapol_version = DEFAULT_EAPOL_VERSION;
1542         config->ap_scan = DEFAULT_AP_SCAN;
1543         config->fast_reauth = DEFAULT_FAST_REAUTH;
1544
1545         if (ctrl_interface)
1546                 config->ctrl_interface = strdup(ctrl_interface);
1547         if (driver_param)
1548                 config->driver_param = strdup(driver_param);
1549
1550         return config;
1551 }