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