Conver hostapd specific files to include common.h
[libeap.git] / hostapd / config.c
1 /*
2  * hostapd / Configuration file
3  * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
4  * Copyright (c) 2007-2008, Intel Corporation
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Alternatively, this software may be distributed under the terms of BSD
11  * license.
12  *
13  * See README and COPYING for more details.
14  */
15
16 #include "includes.h"
17 #ifndef CONFIG_NATIVE_WINDOWS
18 #include <grp.h>
19 #endif /* CONFIG_NATIVE_WINDOWS */
20
21 #include "common.h"
22 #include "hostapd.h"
23 #include "drivers/driver.h"
24 #include "sha1.h"
25 #include "eap_server/eap.h"
26 #include "radius/radius_client.h"
27 #include "common/wpa_common.h"
28 #include "wpa.h"
29 #include "uuid.h"
30 #include "eap_common/eap_wsc_common.h"
31 #include "sta_info.h"
32 #include "config.h"
33
34
35 #define MAX_STA_COUNT 2007
36
37 extern struct wpa_driver_ops *wpa_drivers[];
38
39
40 #ifndef CONFIG_NO_VLAN
41 static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
42                                          const char *fname)
43 {
44         FILE *f;
45         char buf[128], *pos, *pos2;
46         int line = 0, vlan_id;
47         struct hostapd_vlan *vlan;
48
49         f = fopen(fname, "r");
50         if (!f) {
51                 wpa_printf(MSG_ERROR, "VLAN file '%s' not readable.", fname);
52                 return -1;
53         }
54
55         while (fgets(buf, sizeof(buf), f)) {
56                 line++;
57
58                 if (buf[0] == '#')
59                         continue;
60                 pos = buf;
61                 while (*pos != '\0') {
62                         if (*pos == '\n') {
63                                 *pos = '\0';
64                                 break;
65                         }
66                         pos++;
67                 }
68                 if (buf[0] == '\0')
69                         continue;
70
71                 if (buf[0] == '*') {
72                         vlan_id = VLAN_ID_WILDCARD;
73                         pos = buf + 1;
74                 } else {
75                         vlan_id = strtol(buf, &pos, 10);
76                         if (buf == pos || vlan_id < 1 ||
77                             vlan_id > MAX_VLAN_ID) {
78                                 wpa_printf(MSG_ERROR, "Invalid VLAN ID at "
79                                            "line %d in '%s'", line, fname);
80                                 fclose(f);
81                                 return -1;
82                         }
83                 }
84
85                 while (*pos == ' ' || *pos == '\t')
86                         pos++;
87                 pos2 = pos;
88                 while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0')
89                         pos2++;
90                 *pos2 = '\0';
91                 if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) {
92                         wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d "
93                                    "in '%s'", line, fname);
94                         fclose(f);
95                         return -1;
96                 }
97
98                 vlan = os_malloc(sizeof(*vlan));
99                 if (vlan == NULL) {
100                         wpa_printf(MSG_ERROR, "Out of memory while reading "
101                                    "VLAN interfaces from '%s'", fname);
102                         fclose(f);
103                         return -1;
104                 }
105
106                 os_memset(vlan, 0, sizeof(*vlan));
107                 vlan->vlan_id = vlan_id;
108                 os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname));
109                 if (bss->vlan_tail)
110                         bss->vlan_tail->next = vlan;
111                 else
112                         bss->vlan = vlan;
113                 bss->vlan_tail = vlan;
114         }
115
116         fclose(f);
117
118         return 0;
119 }
120 #endif /* CONFIG_NO_VLAN */
121
122
123 static void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
124 {
125         struct hostapd_vlan *vlan, *prev;
126
127         vlan = bss->vlan;
128         prev = NULL;
129         while (vlan) {
130                 prev = vlan;
131                 vlan = vlan->next;
132                 os_free(prev);
133         }
134
135         bss->vlan = NULL;
136 }
137
138
139 /* convert floats with one decimal place to value*10 int, i.e.,
140  * "1.5" will return 15 */
141 static int hostapd_config_read_int10(const char *value)
142 {
143         int i, d;
144         char *pos;
145
146         i = atoi(value);
147         pos = os_strchr(value, '.');
148         d = 0;
149         if (pos) {
150                 pos++;
151                 if (*pos >= '0' && *pos <= '9')
152                         d = *pos - '0';
153         }
154
155         return i * 10 + d;
156 }
157
158
159 static void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
160 {
161         bss->logger_syslog_level = HOSTAPD_LEVEL_INFO;
162         bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
163         bss->logger_syslog = (unsigned int) -1;
164         bss->logger_stdout = (unsigned int) -1;
165
166         bss->auth_algs = WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED;
167
168         bss->wep_rekeying_period = 300;
169         /* use key0 in individual key and key1 in broadcast key */
170         bss->broadcast_key_idx_min = 1;
171         bss->broadcast_key_idx_max = 2;
172         bss->eap_reauth_period = 3600;
173
174         bss->wpa_group_rekey = 600;
175         bss->wpa_gmk_rekey = 86400;
176         bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
177         bss->wpa_pairwise = WPA_CIPHER_TKIP;
178         bss->wpa_group = WPA_CIPHER_TKIP;
179         bss->rsn_pairwise = 0;
180
181         bss->max_num_sta = MAX_STA_COUNT;
182
183         bss->dtim_period = 2;
184
185         bss->radius_server_auth_port = 1812;
186         bss->ap_max_inactivity = AP_MAX_INACTIVITY;
187         bss->eapol_version = EAPOL_VERSION;
188
189         bss->max_listen_interval = 65535;
190
191 #ifdef CONFIG_IEEE80211W
192         bss->assoc_sa_query_max_timeout = 1000;
193         bss->assoc_sa_query_retry_timeout = 201;
194 #endif /* CONFIG_IEEE80211W */
195 #ifdef EAP_SERVER_FAST
196          /* both anonymous and authenticated provisioning */
197         bss->eap_fast_prov = 3;
198         bss->pac_key_lifetime = 7 * 24 * 60 * 60;
199         bss->pac_key_refresh_time = 1 * 24 * 60 * 60;
200 #endif /* EAP_SERVER_FAST */
201 }
202
203
204 struct hostapd_config * hostapd_config_defaults(void)
205 {
206         struct hostapd_config *conf;
207         struct hostapd_bss_config *bss;
208         int i;
209         const int aCWmin = 15, aCWmax = 1024;
210         const struct hostapd_wmm_ac_params ac_bk =
211                 { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
212         const struct hostapd_wmm_ac_params ac_be =
213                 { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
214         const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
215                 { aCWmin >> 1, aCWmin, 2, 3000 / 32, 1 };
216         const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
217                 { aCWmin >> 2, aCWmin >> 1, 2, 1500 / 32, 1 };
218
219         conf = os_zalloc(sizeof(*conf));
220         bss = os_zalloc(sizeof(*bss));
221         if (conf == NULL || bss == NULL) {
222                 wpa_printf(MSG_ERROR, "Failed to allocate memory for "
223                            "configuration data.");
224                 os_free(conf);
225                 os_free(bss);
226                 return NULL;
227         }
228
229         /* set default driver based on configuration */
230         conf->driver = wpa_drivers[0];
231         if (conf->driver == NULL) {
232                 wpa_printf(MSG_ERROR, "No driver wrappers registered!");
233                 os_free(conf);
234                 os_free(bss);
235                 return NULL;
236         }
237
238         bss->radius = os_zalloc(sizeof(*bss->radius));
239         if (bss->radius == NULL) {
240                 os_free(conf);
241                 os_free(bss);
242                 return NULL;
243         }
244
245         hostapd_config_defaults_bss(bss);
246
247         conf->num_bss = 1;
248         conf->bss = bss;
249
250         conf->beacon_int = 100;
251         conf->rts_threshold = -1; /* use driver default: 2347 */
252         conf->fragm_threshold = -1; /* user driver default: 2346 */
253         conf->send_probe_response = 1;
254         conf->bridge_packets = INTERNAL_BRIDGE_DO_NOT_CONTROL;
255
256         for (i = 0; i < NUM_TX_QUEUES; i++)
257                 conf->tx_queue[i].aifs = -1; /* use hw default */
258
259         conf->wmm_ac_params[0] = ac_be;
260         conf->wmm_ac_params[1] = ac_bk;
261         conf->wmm_ac_params[2] = ac_vi;
262         conf->wmm_ac_params[3] = ac_vo;
263
264 #ifdef CONFIG_IEEE80211N
265         conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED;
266 #endif /* CONFIG_IEEE80211N */
267
268         return conf;
269 }
270
271
272 int hostapd_mac_comp(const void *a, const void *b)
273 {
274         return os_memcmp(a, b, sizeof(macaddr));
275 }
276
277
278 int hostapd_mac_comp_empty(const void *a)
279 {
280         macaddr empty = { 0 };
281         return os_memcmp(a, empty, sizeof(macaddr));
282 }
283
284
285 static int hostapd_acl_comp(const void *a, const void *b)
286 {
287         const struct mac_acl_entry *aa = a;
288         const struct mac_acl_entry *bb = b;
289         return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));
290 }
291
292
293 static int hostapd_config_read_maclist(const char *fname,
294                                        struct mac_acl_entry **acl, int *num)
295 {
296         FILE *f;
297         char buf[128], *pos;
298         int line = 0;
299         u8 addr[ETH_ALEN];
300         struct mac_acl_entry *newacl;
301         int vlan_id;
302
303         if (!fname)
304                 return 0;
305
306         f = fopen(fname, "r");
307         if (!f) {
308                 wpa_printf(MSG_ERROR, "MAC list file '%s' not found.", fname);
309                 return -1;
310         }
311
312         while (fgets(buf, sizeof(buf), f)) {
313                 line++;
314
315                 if (buf[0] == '#')
316                         continue;
317                 pos = buf;
318                 while (*pos != '\0') {
319                         if (*pos == '\n') {
320                                 *pos = '\0';
321                                 break;
322                         }
323                         pos++;
324                 }
325                 if (buf[0] == '\0')
326                         continue;
327
328                 if (hwaddr_aton(buf, addr)) {
329                         wpa_printf(MSG_ERROR, "Invalid MAC address '%s' at "
330                                    "line %d in '%s'", buf, line, fname);
331                         fclose(f);
332                         return -1;
333                 }
334
335                 vlan_id = 0;
336                 pos = buf;
337                 while (*pos != '\0' && *pos != ' ' && *pos != '\t')
338                         pos++;
339                 while (*pos == ' ' || *pos == '\t')
340                         pos++;
341                 if (*pos != '\0')
342                         vlan_id = atoi(pos);
343
344                 newacl = os_realloc(*acl, (*num + 1) * sizeof(**acl));
345                 if (newacl == NULL) {
346                         wpa_printf(MSG_ERROR, "MAC list reallocation failed");
347                         fclose(f);
348                         return -1;
349                 }
350
351                 *acl = newacl;
352                 os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
353                 (*acl)[*num].vlan_id = vlan_id;
354                 (*num)++;
355         }
356
357         fclose(f);
358
359         qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
360
361         return 0;
362 }
363
364
365 static int hostapd_config_read_wpa_psk(const char *fname,
366                                        struct hostapd_ssid *ssid)
367 {
368         FILE *f;
369         char buf[128], *pos;
370         int line = 0, ret = 0, len, ok;
371         u8 addr[ETH_ALEN];
372         struct hostapd_wpa_psk *psk;
373
374         if (!fname)
375                 return 0;
376
377         f = fopen(fname, "r");
378         if (!f) {
379                 wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname);
380                 return -1;
381         }
382
383         while (fgets(buf, sizeof(buf), f)) {
384                 line++;
385
386                 if (buf[0] == '#')
387                         continue;
388                 pos = buf;
389                 while (*pos != '\0') {
390                         if (*pos == '\n') {
391                                 *pos = '\0';
392                                 break;
393                         }
394                         pos++;
395                 }
396                 if (buf[0] == '\0')
397                         continue;
398
399                 if (hwaddr_aton(buf, addr)) {
400                         wpa_printf(MSG_ERROR, "Invalid MAC address '%s' on "
401                                    "line %d in '%s'", buf, line, fname);
402                         ret = -1;
403                         break;
404                 }
405
406                 psk = os_zalloc(sizeof(*psk));
407                 if (psk == NULL) {
408                         wpa_printf(MSG_ERROR, "WPA PSK allocation failed");
409                         ret = -1;
410                         break;
411                 }
412                 if (is_zero_ether_addr(addr))
413                         psk->group = 1;
414                 else
415                         os_memcpy(psk->addr, addr, ETH_ALEN);
416
417                 pos = buf + 17;
418                 if (*pos == '\0') {
419                         wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'",
420                                    line, fname);
421                         os_free(psk);
422                         ret = -1;
423                         break;
424                 }
425                 pos++;
426
427                 ok = 0;
428                 len = os_strlen(pos);
429                 if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
430                         ok = 1;
431                 else if (len >= 8 && len < 64) {
432                         pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
433                                     4096, psk->psk, PMK_LEN);
434                         ok = 1;
435                 }
436                 if (!ok) {
437                         wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in "
438                                    "'%s'", pos, line, fname);
439                         os_free(psk);
440                         ret = -1;
441                         break;
442                 }
443
444                 psk->next = ssid->wpa_psk;
445                 ssid->wpa_psk = psk;
446         }
447
448         fclose(f);
449
450         return ret;
451 }
452
453
454 int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf)
455 {
456         struct hostapd_ssid *ssid = &conf->ssid;
457
458         if (ssid->wpa_passphrase != NULL) {
459                 if (ssid->wpa_psk != NULL) {
460                         wpa_printf(MSG_ERROR, "Warning: both WPA PSK and "
461                                    "passphrase set. Using passphrase.");
462                         os_free(ssid->wpa_psk);
463                 }
464                 ssid->wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
465                 if (ssid->wpa_psk == NULL) {
466                         wpa_printf(MSG_ERROR, "Unable to alloc space for PSK");
467                         return -1;
468                 }
469                 wpa_hexdump_ascii(MSG_DEBUG, "SSID",
470                                   (u8 *) ssid->ssid, ssid->ssid_len);
471                 wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)",
472                                   (u8 *) ssid->wpa_passphrase,
473                                   os_strlen(ssid->wpa_passphrase));
474                 pbkdf2_sha1(ssid->wpa_passphrase,
475                             ssid->ssid, ssid->ssid_len,
476                             4096, ssid->wpa_psk->psk, PMK_LEN);
477                 wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)",
478                             ssid->wpa_psk->psk, PMK_LEN);
479                 ssid->wpa_psk->group = 1;
480         }
481
482         if (ssid->wpa_psk_file) {
483                 if (hostapd_config_read_wpa_psk(ssid->wpa_psk_file,
484                                                 &conf->ssid))
485                         return -1;
486         }
487
488         return 0;
489 }
490
491
492 #ifdef EAP_SERVER
493 static int hostapd_config_read_eap_user(const char *fname,
494                                         struct hostapd_bss_config *conf)
495 {
496         FILE *f;
497         char buf[512], *pos, *start, *pos2;
498         int line = 0, ret = 0, num_methods;
499         struct hostapd_eap_user *user, *tail = NULL;
500
501         if (!fname)
502                 return 0;
503
504         f = fopen(fname, "r");
505         if (!f) {
506                 wpa_printf(MSG_ERROR, "EAP user file '%s' not found.", fname);
507                 return -1;
508         }
509
510         /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
511         while (fgets(buf, sizeof(buf), f)) {
512                 line++;
513
514                 if (buf[0] == '#')
515                         continue;
516                 pos = buf;
517                 while (*pos != '\0') {
518                         if (*pos == '\n') {
519                                 *pos = '\0';
520                                 break;
521                         }
522                         pos++;
523                 }
524                 if (buf[0] == '\0')
525                         continue;
526
527                 user = NULL;
528
529                 if (buf[0] != '"' && buf[0] != '*') {
530                         wpa_printf(MSG_ERROR, "Invalid EAP identity (no \" in "
531                                    "start) on line %d in '%s'", line, fname);
532                         goto failed;
533                 }
534
535                 user = os_zalloc(sizeof(*user));
536                 if (user == NULL) {
537                         wpa_printf(MSG_ERROR, "EAP user allocation failed");
538                         goto failed;
539                 }
540                 user->force_version = -1;
541
542                 if (buf[0] == '*') {
543                         pos = buf;
544                 } else {
545                         pos = buf + 1;
546                         start = pos;
547                         while (*pos != '"' && *pos != '\0')
548                                 pos++;
549                         if (*pos == '\0') {
550                                 wpa_printf(MSG_ERROR, "Invalid EAP identity "
551                                            "(no \" in end) on line %d in '%s'",
552                                            line, fname);
553                                 goto failed;
554                         }
555
556                         user->identity = os_malloc(pos - start);
557                         if (user->identity == NULL) {
558                                 wpa_printf(MSG_ERROR, "Failed to allocate "
559                                            "memory for EAP identity");
560                                 goto failed;
561                         }
562                         os_memcpy(user->identity, start, pos - start);
563                         user->identity_len = pos - start;
564
565                         if (pos[0] == '"' && pos[1] == '*') {
566                                 user->wildcard_prefix = 1;
567                                 pos++;
568                         }
569                 }
570                 pos++;
571                 while (*pos == ' ' || *pos == '\t')
572                         pos++;
573
574                 if (*pos == '\0') {
575                         wpa_printf(MSG_ERROR, "No EAP method on line %d in "
576                                    "'%s'", line, fname);
577                         goto failed;
578                 }
579
580                 start = pos;
581                 while (*pos != ' ' && *pos != '\t' && *pos != '\0')
582                         pos++;
583                 if (*pos == '\0') {
584                         pos = NULL;
585                 } else {
586                         *pos = '\0';
587                         pos++;
588                 }
589                 num_methods = 0;
590                 while (*start) {
591                         char *pos3 = os_strchr(start, ',');
592                         if (pos3) {
593                                 *pos3++ = '\0';
594                         }
595                         user->methods[num_methods].method =
596                                 eap_server_get_type(
597                                         start,
598                                         &user->methods[num_methods].vendor);
599                         if (user->methods[num_methods].vendor ==
600                             EAP_VENDOR_IETF &&
601                             user->methods[num_methods].method == EAP_TYPE_NONE)
602                         {
603                                 if (os_strcmp(start, "TTLS-PAP") == 0) {
604                                         user->ttls_auth |= EAP_TTLS_AUTH_PAP;
605                                         goto skip_eap;
606                                 }
607                                 if (os_strcmp(start, "TTLS-CHAP") == 0) {
608                                         user->ttls_auth |= EAP_TTLS_AUTH_CHAP;
609                                         goto skip_eap;
610                                 }
611                                 if (os_strcmp(start, "TTLS-MSCHAP") == 0) {
612                                         user->ttls_auth |=
613                                                 EAP_TTLS_AUTH_MSCHAP;
614                                         goto skip_eap;
615                                 }
616                                 if (os_strcmp(start, "TTLS-MSCHAPV2") == 0) {
617                                         user->ttls_auth |=
618                                                 EAP_TTLS_AUTH_MSCHAPV2;
619                                         goto skip_eap;
620                                 }
621                                 wpa_printf(MSG_ERROR, "Unsupported EAP type "
622                                            "'%s' on line %d in '%s'",
623                                            start, line, fname);
624                                 goto failed;
625                         }
626
627                         num_methods++;
628                         if (num_methods >= EAP_USER_MAX_METHODS)
629                                 break;
630                 skip_eap:
631                         if (pos3 == NULL)
632                                 break;
633                         start = pos3;
634                 }
635                 if (num_methods == 0 && user->ttls_auth == 0) {
636                         wpa_printf(MSG_ERROR, "No EAP types configured on "
637                                    "line %d in '%s'", line, fname);
638                         goto failed;
639                 }
640
641                 if (pos == NULL)
642                         goto done;
643
644                 while (*pos == ' ' || *pos == '\t')
645                         pos++;
646                 if (*pos == '\0')
647                         goto done;
648
649                 if (os_strncmp(pos, "[ver=0]", 7) == 0) {
650                         user->force_version = 0;
651                         goto done;
652                 }
653
654                 if (os_strncmp(pos, "[ver=1]", 7) == 0) {
655                         user->force_version = 1;
656                         goto done;
657                 }
658
659                 if (os_strncmp(pos, "[2]", 3) == 0) {
660                         user->phase2 = 1;
661                         goto done;
662                 }
663
664                 if (*pos == '"') {
665                         pos++;
666                         start = pos;
667                         while (*pos != '"' && *pos != '\0')
668                                 pos++;
669                         if (*pos == '\0') {
670                                 wpa_printf(MSG_ERROR, "Invalid EAP password "
671                                            "(no \" in end) on line %d in '%s'",
672                                            line, fname);
673                                 goto failed;
674                         }
675
676                         user->password = os_malloc(pos - start);
677                         if (user->password == NULL) {
678                                 wpa_printf(MSG_ERROR, "Failed to allocate "
679                                            "memory for EAP password");
680                                 goto failed;
681                         }
682                         os_memcpy(user->password, start, pos - start);
683                         user->password_len = pos - start;
684
685                         pos++;
686                 } else if (os_strncmp(pos, "hash:", 5) == 0) {
687                         pos += 5;
688                         pos2 = pos;
689                         while (*pos2 != '\0' && *pos2 != ' ' &&
690                                *pos2 != '\t' && *pos2 != '#')
691                                 pos2++;
692                         if (pos2 - pos != 32) {
693                                 wpa_printf(MSG_ERROR, "Invalid password hash "
694                                            "on line %d in '%s'", line, fname);
695                                 goto failed;
696                         }
697                         user->password = os_malloc(16);
698                         if (user->password == NULL) {
699                                 wpa_printf(MSG_ERROR, "Failed to allocate "
700                                            "memory for EAP password hash");
701                                 goto failed;
702                         }
703                         if (hexstr2bin(pos, user->password, 16) < 0) {
704                                 wpa_printf(MSG_ERROR, "Invalid hash password "
705                                            "on line %d in '%s'", line, fname);
706                                 goto failed;
707                         }
708                         user->password_len = 16;
709                         user->password_hash = 1;
710                         pos = pos2;
711                 } else {
712                         pos2 = pos;
713                         while (*pos2 != '\0' && *pos2 != ' ' &&
714                                *pos2 != '\t' && *pos2 != '#')
715                                 pos2++;
716                         if ((pos2 - pos) & 1) {
717                                 wpa_printf(MSG_ERROR, "Invalid hex password "
718                                            "on line %d in '%s'", line, fname);
719                                 goto failed;
720                         }
721                         user->password = os_malloc((pos2 - pos) / 2);
722                         if (user->password == NULL) {
723                                 wpa_printf(MSG_ERROR, "Failed to allocate "
724                                            "memory for EAP password");
725                                 goto failed;
726                         }
727                         if (hexstr2bin(pos, user->password,
728                                        (pos2 - pos) / 2) < 0) {
729                                 wpa_printf(MSG_ERROR, "Invalid hex password "
730                                            "on line %d in '%s'", line, fname);
731                                 goto failed;
732                         }
733                         user->password_len = (pos2 - pos) / 2;
734                         pos = pos2;
735                 }
736
737                 while (*pos == ' ' || *pos == '\t')
738                         pos++;
739                 if (os_strncmp(pos, "[2]", 3) == 0) {
740                         user->phase2 = 1;
741                 }
742
743         done:
744                 if (tail == NULL) {
745                         tail = conf->eap_user = user;
746                 } else {
747                         tail->next = user;
748                         tail = user;
749                 }
750                 continue;
751
752         failed:
753                 if (user) {
754                         os_free(user->password);
755                         os_free(user->identity);
756                         os_free(user);
757                 }
758                 ret = -1;
759                 break;
760         }
761
762         fclose(f);
763
764         return ret;
765 }
766 #endif /* EAP_SERVER */
767
768
769 #ifndef CONFIG_NO_RADIUS
770 static int
771 hostapd_config_read_radius_addr(struct hostapd_radius_server **server,
772                                 int *num_server, const char *val, int def_port,
773                                 struct hostapd_radius_server **curr_serv)
774 {
775         struct hostapd_radius_server *nserv;
776         int ret;
777         static int server_index = 1;
778
779         nserv = os_realloc(*server, (*num_server + 1) * sizeof(*nserv));
780         if (nserv == NULL)
781                 return -1;
782
783         *server = nserv;
784         nserv = &nserv[*num_server];
785         (*num_server)++;
786         (*curr_serv) = nserv;
787
788         os_memset(nserv, 0, sizeof(*nserv));
789         nserv->port = def_port;
790         ret = hostapd_parse_ip_addr(val, &nserv->addr);
791         nserv->index = server_index++;
792
793         return ret;
794 }
795 #endif /* CONFIG_NO_RADIUS */
796
797
798 static int hostapd_config_parse_key_mgmt(int line, const char *value)
799 {
800         int val = 0, last;
801         char *start, *end, *buf;
802
803         buf = os_strdup(value);
804         if (buf == NULL)
805                 return -1;
806         start = buf;
807
808         while (*start != '\0') {
809                 while (*start == ' ' || *start == '\t')
810                         start++;
811                 if (*start == '\0')
812                         break;
813                 end = start;
814                 while (*end != ' ' && *end != '\t' && *end != '\0')
815                         end++;
816                 last = *end == '\0';
817                 *end = '\0';
818                 if (os_strcmp(start, "WPA-PSK") == 0)
819                         val |= WPA_KEY_MGMT_PSK;
820                 else if (os_strcmp(start, "WPA-EAP") == 0)
821                         val |= WPA_KEY_MGMT_IEEE8021X;
822 #ifdef CONFIG_IEEE80211R
823                 else if (os_strcmp(start, "FT-PSK") == 0)
824                         val |= WPA_KEY_MGMT_FT_PSK;
825                 else if (os_strcmp(start, "FT-EAP") == 0)
826                         val |= WPA_KEY_MGMT_FT_IEEE8021X;
827 #endif /* CONFIG_IEEE80211R */
828 #ifdef CONFIG_IEEE80211W
829                 else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
830                         val |= WPA_KEY_MGMT_PSK_SHA256;
831                 else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
832                         val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
833 #endif /* CONFIG_IEEE80211W */
834                 else {
835                         wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
836                                    line, start);
837                         os_free(buf);
838                         return -1;
839                 }
840
841                 if (last)
842                         break;
843                 start = end + 1;
844         }
845
846         os_free(buf);
847         if (val == 0) {
848                 wpa_printf(MSG_ERROR, "Line %d: no key_mgmt values "
849                            "configured.", line);
850                 return -1;
851         }
852
853         return val;
854 }
855
856
857 static int hostapd_config_parse_cipher(int line, const char *value)
858 {
859         int val = 0, last;
860         char *start, *end, *buf;
861
862         buf = os_strdup(value);
863         if (buf == NULL)
864                 return -1;
865         start = buf;
866
867         while (*start != '\0') {
868                 while (*start == ' ' || *start == '\t')
869                         start++;
870                 if (*start == '\0')
871                         break;
872                 end = start;
873                 while (*end != ' ' && *end != '\t' && *end != '\0')
874                         end++;
875                 last = *end == '\0';
876                 *end = '\0';
877                 if (os_strcmp(start, "CCMP") == 0)
878                         val |= WPA_CIPHER_CCMP;
879                 else if (os_strcmp(start, "TKIP") == 0)
880                         val |= WPA_CIPHER_TKIP;
881                 else if (os_strcmp(start, "WEP104") == 0)
882                         val |= WPA_CIPHER_WEP104;
883                 else if (os_strcmp(start, "WEP40") == 0)
884                         val |= WPA_CIPHER_WEP40;
885                 else if (os_strcmp(start, "NONE") == 0)
886                         val |= WPA_CIPHER_NONE;
887                 else {
888                         wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
889                                    line, start);
890                         os_free(buf);
891                         return -1;
892                 }
893
894                 if (last)
895                         break;
896                 start = end + 1;
897         }
898         os_free(buf);
899
900         if (val == 0) {
901                 wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
902                            line);
903                 return -1;
904         }
905         return val;
906 }
907
908
909 static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
910                                     struct hostapd_config *conf)
911 {
912         if (bss->ieee802_1x && !bss->eap_server &&
913             !bss->radius->auth_servers) {
914                 wpa_printf(MSG_ERROR, "Invalid IEEE 802.1X configuration (no "
915                            "EAP authenticator configured).");
916                 return -1;
917         }
918
919         if (bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
920             bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
921             bss->ssid.wpa_psk_file == NULL) {
922                 wpa_printf(MSG_ERROR, "WPA-PSK enabled, but PSK or passphrase "
923                            "is not configured.");
924                 return -1;
925         }
926
927         if (hostapd_mac_comp_empty(bss->bssid) != 0) {
928                 size_t i;
929
930                 for (i = 0; i < conf->num_bss; i++) {
931                         if ((&conf->bss[i] != bss) &&
932                             (hostapd_mac_comp(conf->bss[i].bssid,
933                                               bss->bssid) == 0)) {
934                                 wpa_printf(MSG_ERROR, "Duplicate BSSID " MACSTR
935                                            " on interface '%s' and '%s'.",
936                                            MAC2STR(bss->bssid),
937                                            conf->bss[i].iface, bss->iface);
938                                 return -1;
939                         }
940                 }
941         }
942
943 #ifdef CONFIG_IEEE80211R
944         if ((bss->wpa_key_mgmt &
945              (WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_FT_IEEE8021X)) &&
946             (bss->nas_identifier == NULL ||
947              os_strlen(bss->nas_identifier) < 1 ||
948              os_strlen(bss->nas_identifier) > FT_R0KH_ID_MAX_LEN)) {
949                 wpa_printf(MSG_ERROR, "FT (IEEE 802.11r) requires "
950                            "nas_identifier to be configured as a 1..48 octet "
951                            "string");
952                 return -1;
953         }
954 #endif /* CONFIG_IEEE80211R */
955
956 #ifdef CONFIG_IEEE80211N
957         if (conf->ieee80211n && bss->wpa &&
958             !(bss->wpa_pairwise & WPA_CIPHER_CCMP) &&
959             !(bss->rsn_pairwise & WPA_CIPHER_CCMP)) {
960                 wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WPA/WPA2 "
961                            "requires CCMP to be enabled");
962                 return -1;
963         }
964 #endif /* CONFIG_IEEE80211N */
965
966         return 0;
967 }
968
969
970 static int hostapd_config_check(struct hostapd_config *conf)
971 {
972         size_t i;
973
974         if (conf->ieee80211d && (!conf->country[0] || !conf->country[1])) {
975                 wpa_printf(MSG_ERROR, "Cannot enable IEEE 802.11d without "
976                            "setting the country_code");
977                 return -1;
978         }
979
980         for (i = 0; i < conf->num_bss; i++) {
981                 if (hostapd_config_check_bss(&conf->bss[i], conf))
982                         return -1;
983         }
984
985         return 0;
986 }
987
988
989 static int hostapd_config_read_wep(struct hostapd_wep_keys *wep, int keyidx,
990                                    char *val)
991 {
992         size_t len = os_strlen(val);
993
994         if (keyidx < 0 || keyidx > 3 || wep->key[keyidx] != NULL)
995                 return -1;
996
997         if (val[0] == '"') {
998                 if (len < 2 || val[len - 1] != '"')
999                         return -1;
1000                 len -= 2;
1001                 wep->key[keyidx] = os_malloc(len);
1002                 if (wep->key[keyidx] == NULL)
1003                         return -1;
1004                 os_memcpy(wep->key[keyidx], val + 1, len);
1005                 wep->len[keyidx] = len;
1006         } else {
1007                 if (len & 1)
1008                         return -1;
1009                 len /= 2;
1010                 wep->key[keyidx] = os_malloc(len);
1011                 if (wep->key[keyidx] == NULL)
1012                         return -1;
1013                 wep->len[keyidx] = len;
1014                 if (hexstr2bin(val, wep->key[keyidx], len) < 0)
1015                         return -1;
1016         }
1017
1018         wep->keys_set++;
1019
1020         return 0;
1021 }
1022
1023
1024 static int hostapd_parse_rates(int **rate_list, char *val)
1025 {
1026         int *list;
1027         int count;
1028         char *pos, *end;
1029
1030         os_free(*rate_list);
1031         *rate_list = NULL;
1032
1033         pos = val;
1034         count = 0;
1035         while (*pos != '\0') {
1036                 if (*pos == ' ')
1037                         count++;
1038                 pos++;
1039         }
1040
1041         list = os_malloc(sizeof(int) * (count + 2));
1042         if (list == NULL)
1043                 return -1;
1044         pos = val;
1045         count = 0;
1046         while (*pos != '\0') {
1047                 end = os_strchr(pos, ' ');
1048                 if (end)
1049                         *end = '\0';
1050
1051                 list[count++] = atoi(pos);
1052                 if (!end)
1053                         break;
1054                 pos = end + 1;
1055         }
1056         list[count] = -1;
1057
1058         *rate_list = list;
1059         return 0;
1060 }
1061
1062
1063 static int hostapd_config_bss(struct hostapd_config *conf, const char *ifname)
1064 {
1065         struct hostapd_bss_config *bss;
1066
1067         if (*ifname == '\0')
1068                 return -1;
1069
1070         bss = os_realloc(conf->bss, (conf->num_bss + 1) *
1071                          sizeof(struct hostapd_bss_config));
1072         if (bss == NULL) {
1073                 wpa_printf(MSG_ERROR, "Failed to allocate memory for "
1074                            "multi-BSS entry");
1075                 return -1;
1076         }
1077         conf->bss = bss;
1078
1079         bss = &(conf->bss[conf->num_bss]);
1080         os_memset(bss, 0, sizeof(*bss));
1081         bss->radius = os_zalloc(sizeof(*bss->radius));
1082         if (bss->radius == NULL) {
1083                 wpa_printf(MSG_ERROR, "Failed to allocate memory for "
1084                            "multi-BSS RADIUS data");
1085                 return -1;
1086         }
1087
1088         conf->num_bss++;
1089         conf->last_bss = bss;
1090
1091         hostapd_config_defaults_bss(bss);
1092         os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
1093         os_memcpy(bss->ssid.vlan, bss->iface, IFNAMSIZ + 1);
1094
1095         return 0;
1096 }
1097
1098
1099 static int valid_cw(int cw)
1100 {
1101         return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
1102                 cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023);
1103 }
1104
1105
1106 enum {
1107         IEEE80211_TX_QUEUE_DATA0 = 0, /* used for EDCA AC_VO data */
1108         IEEE80211_TX_QUEUE_DATA1 = 1, /* used for EDCA AC_VI data */
1109         IEEE80211_TX_QUEUE_DATA2 = 2, /* used for EDCA AC_BE data */
1110         IEEE80211_TX_QUEUE_DATA3 = 3, /* used for EDCA AC_BK data */
1111         IEEE80211_TX_QUEUE_DATA4 = 4,
1112         IEEE80211_TX_QUEUE_AFTER_BEACON = 6,
1113         IEEE80211_TX_QUEUE_BEACON = 7
1114 };
1115
1116 static int hostapd_config_tx_queue(struct hostapd_config *conf, char *name,
1117                                    char *val)
1118 {
1119         int num;
1120         char *pos;
1121         struct hostapd_tx_queue_params *queue;
1122
1123         /* skip 'tx_queue_' prefix */
1124         pos = name + 9;
1125         if (os_strncmp(pos, "data", 4) == 0 &&
1126             pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
1127                 num = pos[4] - '0';
1128                 pos += 6;
1129         } else if (os_strncmp(pos, "after_beacon_", 13) == 0) {
1130                 num = IEEE80211_TX_QUEUE_AFTER_BEACON;
1131                 pos += 13;
1132         } else if (os_strncmp(pos, "beacon_", 7) == 0) {
1133                 num = IEEE80211_TX_QUEUE_BEACON;
1134                 pos += 7;
1135         } else {
1136                 wpa_printf(MSG_ERROR, "Unknown tx_queue name '%s'", pos);
1137                 return -1;
1138         }
1139
1140         queue = &conf->tx_queue[num];
1141
1142         if (os_strcmp(pos, "aifs") == 0) {
1143                 queue->aifs = atoi(val);
1144                 if (queue->aifs < 0 || queue->aifs > 255) {
1145                         wpa_printf(MSG_ERROR, "Invalid AIFS value %d",
1146                                    queue->aifs);
1147                         return -1;
1148                 }
1149         } else if (os_strcmp(pos, "cwmin") == 0) {
1150                 queue->cwmin = atoi(val);
1151                 if (!valid_cw(queue->cwmin)) {
1152                         wpa_printf(MSG_ERROR, "Invalid cwMin value %d",
1153                                    queue->cwmin);
1154                         return -1;
1155                 }
1156         } else if (os_strcmp(pos, "cwmax") == 0) {
1157                 queue->cwmax = atoi(val);
1158                 if (!valid_cw(queue->cwmax)) {
1159                         wpa_printf(MSG_ERROR, "Invalid cwMax value %d",
1160                                    queue->cwmax);
1161                         return -1;
1162                 }
1163         } else if (os_strcmp(pos, "burst") == 0) {
1164                 queue->burst = hostapd_config_read_int10(val);
1165         } else {
1166                 wpa_printf(MSG_ERROR, "Unknown tx_queue field '%s'", pos);
1167                 return -1;
1168         }
1169
1170         queue->configured = 1;
1171
1172         return 0;
1173 }
1174
1175
1176 static int hostapd_config_wmm_ac(struct hostapd_config *conf, char *name,
1177                                  char *val)
1178 {
1179         int num, v;
1180         char *pos;
1181         struct hostapd_wmm_ac_params *ac;
1182
1183         /* skip 'wme_ac_' or 'wmm_ac_' prefix */
1184         pos = name + 7;
1185         if (os_strncmp(pos, "be_", 3) == 0) {
1186                 num = 0;
1187                 pos += 3;
1188         } else if (os_strncmp(pos, "bk_", 3) == 0) {
1189                 num = 1;
1190                 pos += 3;
1191         } else if (os_strncmp(pos, "vi_", 3) == 0) {
1192                 num = 2;
1193                 pos += 3;
1194         } else if (os_strncmp(pos, "vo_", 3) == 0) {
1195                 num = 3;
1196                 pos += 3;
1197         } else {
1198                 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
1199                 return -1;
1200         }
1201
1202         ac = &conf->wmm_ac_params[num];
1203
1204         if (os_strcmp(pos, "aifs") == 0) {
1205                 v = atoi(val);
1206                 if (v < 1 || v > 255) {
1207                         wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
1208                         return -1;
1209                 }
1210                 ac->aifs = v;
1211         } else if (os_strcmp(pos, "cwmin") == 0) {
1212                 v = atoi(val);
1213                 if (v < 0 || v > 12) {
1214                         wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
1215                         return -1;
1216                 }
1217                 ac->cwmin = v;
1218         } else if (os_strcmp(pos, "cwmax") == 0) {
1219                 v = atoi(val);
1220                 if (v < 0 || v > 12) {
1221                         wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
1222                         return -1;
1223                 }
1224                 ac->cwmax = v;
1225         } else if (os_strcmp(pos, "txop_limit") == 0) {
1226                 v = atoi(val);
1227                 if (v < 0 || v > 0xffff) {
1228                         wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
1229                         return -1;
1230                 }
1231                 ac->txop_limit = v;
1232         } else if (os_strcmp(pos, "acm") == 0) {
1233                 v = atoi(val);
1234                 if (v < 0 || v > 1) {
1235                         wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
1236                         return -1;
1237                 }
1238                 ac->admission_control_mandatory = v;
1239         } else {
1240                 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
1241                 return -1;
1242         }
1243
1244         return 0;
1245 }
1246
1247
1248 #ifdef CONFIG_IEEE80211R
1249 static int add_r0kh(struct hostapd_bss_config *bss, char *value)
1250 {
1251         struct ft_remote_r0kh *r0kh;
1252         char *pos, *next;
1253
1254         r0kh = os_zalloc(sizeof(*r0kh));
1255         if (r0kh == NULL)
1256                 return -1;
1257
1258         /* 02:01:02:03:04:05 a.example.com 000102030405060708090a0b0c0d0e0f */
1259         pos = value;
1260         next = os_strchr(pos, ' ');
1261         if (next)
1262                 *next++ = '\0';
1263         if (next == NULL || hwaddr_aton(pos, r0kh->addr)) {
1264                 wpa_printf(MSG_ERROR, "Invalid R0KH MAC address: '%s'", pos);
1265                 os_free(r0kh);
1266                 return -1;
1267         }
1268
1269         pos = next;
1270         next = os_strchr(pos, ' ');
1271         if (next)
1272                 *next++ = '\0';
1273         if (next == NULL || next - pos > FT_R0KH_ID_MAX_LEN) {
1274                 wpa_printf(MSG_ERROR, "Invalid R0KH-ID: '%s'", pos);
1275                 os_free(r0kh);
1276                 return -1;
1277         }
1278         r0kh->id_len = next - pos - 1;
1279         os_memcpy(r0kh->id, pos, r0kh->id_len);
1280
1281         pos = next;
1282         if (hexstr2bin(pos, r0kh->key, sizeof(r0kh->key))) {
1283                 wpa_printf(MSG_ERROR, "Invalid R0KH key: '%s'", pos);
1284                 os_free(r0kh);
1285                 return -1;
1286         }
1287
1288         r0kh->next = bss->r0kh_list;
1289         bss->r0kh_list = r0kh;
1290
1291         return 0;
1292 }
1293
1294
1295 static int add_r1kh(struct hostapd_bss_config *bss, char *value)
1296 {
1297         struct ft_remote_r1kh *r1kh;
1298         char *pos, *next;
1299
1300         r1kh = os_zalloc(sizeof(*r1kh));
1301         if (r1kh == NULL)
1302                 return -1;
1303
1304         /* 02:01:02:03:04:05 02:01:02:03:04:05
1305          * 000102030405060708090a0b0c0d0e0f */
1306         pos = value;
1307         next = os_strchr(pos, ' ');
1308         if (next)
1309                 *next++ = '\0';
1310         if (next == NULL || hwaddr_aton(pos, r1kh->addr)) {
1311                 wpa_printf(MSG_ERROR, "Invalid R1KH MAC address: '%s'", pos);
1312                 os_free(r1kh);
1313                 return -1;
1314         }
1315
1316         pos = next;
1317         next = os_strchr(pos, ' ');
1318         if (next)
1319                 *next++ = '\0';
1320         if (next == NULL || hwaddr_aton(pos, r1kh->id)) {
1321                 wpa_printf(MSG_ERROR, "Invalid R1KH-ID: '%s'", pos);
1322                 os_free(r1kh);
1323                 return -1;
1324         }
1325
1326         pos = next;
1327         if (hexstr2bin(pos, r1kh->key, sizeof(r1kh->key))) {
1328                 wpa_printf(MSG_ERROR, "Invalid R1KH key: '%s'", pos);
1329                 os_free(r1kh);
1330                 return -1;
1331         }
1332
1333         r1kh->next = bss->r1kh_list;
1334         bss->r1kh_list = r1kh;
1335
1336         return 0;
1337 }
1338 #endif /* CONFIG_IEEE80211R */
1339
1340
1341 #ifdef CONFIG_IEEE80211N
1342 static int hostapd_config_ht_capab(struct hostapd_config *conf,
1343                                    const char *capab)
1344 {
1345         if (os_strstr(capab, "[LDPC]"))
1346                 conf->ht_capab |= HT_CAP_INFO_LDPC_CODING_CAP;
1347         if (os_strstr(capab, "[HT40-]")) {
1348                 conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
1349                 conf->secondary_channel = -1;
1350         }
1351         if (os_strstr(capab, "[HT40+]")) {
1352                 conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
1353                 conf->secondary_channel = 1;
1354         }
1355         if (os_strstr(capab, "[SMPS-STATIC]")) {
1356                 conf->ht_capab &= ~HT_CAP_INFO_SMPS_MASK;
1357                 conf->ht_capab |= HT_CAP_INFO_SMPS_STATIC;
1358         }
1359         if (os_strstr(capab, "[SMPS-DYNAMIC]")) {
1360                 conf->ht_capab &= ~HT_CAP_INFO_SMPS_MASK;
1361                 conf->ht_capab |= HT_CAP_INFO_SMPS_DYNAMIC;
1362         }
1363         if (os_strstr(capab, "[GF]"))
1364                 conf->ht_capab |= HT_CAP_INFO_GREEN_FIELD;
1365         if (os_strstr(capab, "[SHORT-GI-20]"))
1366                 conf->ht_capab |= HT_CAP_INFO_SHORT_GI20MHZ;
1367         if (os_strstr(capab, "[SHORT-GI-40]"))
1368                 conf->ht_capab |= HT_CAP_INFO_SHORT_GI40MHZ;
1369         if (os_strstr(capab, "[TX-STBC]"))
1370                 conf->ht_capab |= HT_CAP_INFO_TX_STBC;
1371         if (os_strstr(capab, "[RX-STBC1]")) {
1372                 conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
1373                 conf->ht_capab |= HT_CAP_INFO_RX_STBC_1;
1374         }
1375         if (os_strstr(capab, "[RX-STBC12]")) {
1376                 conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
1377                 conf->ht_capab |= HT_CAP_INFO_RX_STBC_12;
1378         }
1379         if (os_strstr(capab, "[RX-STBC123]")) {
1380                 conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
1381                 conf->ht_capab |= HT_CAP_INFO_RX_STBC_123;
1382         }
1383         if (os_strstr(capab, "[DELAYED-BA]"))
1384                 conf->ht_capab |= HT_CAP_INFO_DELAYED_BA;
1385         if (os_strstr(capab, "[MAX-AMSDU-7935]"))
1386                 conf->ht_capab |= HT_CAP_INFO_MAX_AMSDU_SIZE;
1387         if (os_strstr(capab, "[DSSS_CCK-40]"))
1388                 conf->ht_capab |= HT_CAP_INFO_DSSS_CCK40MHZ;
1389         if (os_strstr(capab, "[PSMP]"))
1390                 conf->ht_capab |= HT_CAP_INFO_PSMP_SUPP;
1391         if (os_strstr(capab, "[LSIG-TXOP-PROT]"))
1392                 conf->ht_capab |= HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT;
1393
1394         return 0;
1395 }
1396 #endif /* CONFIG_IEEE80211N */
1397
1398
1399 /**
1400  * hostapd_config_read - Read and parse a configuration file
1401  * @fname: Configuration file name (including path, if needed)
1402  * Returns: Allocated configuration data structure
1403  */
1404 struct hostapd_config * hostapd_config_read(const char *fname)
1405 {
1406         struct hostapd_config *conf;
1407         struct hostapd_bss_config *bss;
1408         FILE *f;
1409         char buf[256], *pos;
1410         int line = 0;
1411         int errors = 0;
1412         int pairwise;
1413         size_t i;
1414
1415         f = fopen(fname, "r");
1416         if (f == NULL) {
1417                 wpa_printf(MSG_ERROR, "Could not open configuration file '%s' "
1418                            "for reading.", fname);
1419                 return NULL;
1420         }
1421
1422         conf = hostapd_config_defaults();
1423         if (conf == NULL) {
1424                 fclose(f);
1425                 return NULL;
1426         }
1427         bss = conf->last_bss = conf->bss;
1428
1429         while (fgets(buf, sizeof(buf), f)) {
1430                 bss = conf->last_bss;
1431                 line++;
1432
1433                 if (buf[0] == '#')
1434                         continue;
1435                 pos = buf;
1436                 while (*pos != '\0') {
1437                         if (*pos == '\n') {
1438                                 *pos = '\0';
1439                                 break;
1440                         }
1441                         pos++;
1442                 }
1443                 if (buf[0] == '\0')
1444                         continue;
1445
1446                 pos = os_strchr(buf, '=');
1447                 if (pos == NULL) {
1448                         wpa_printf(MSG_ERROR, "Line %d: invalid line '%s'",
1449                                    line, buf);
1450                         errors++;
1451                         continue;
1452                 }
1453                 *pos = '\0';
1454                 pos++;
1455
1456                 if (os_strcmp(buf, "interface") == 0) {
1457                         os_strlcpy(conf->bss[0].iface, pos,
1458                                    sizeof(conf->bss[0].iface));
1459                 } else if (os_strcmp(buf, "bridge") == 0) {
1460                         os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
1461                 } else if (os_strcmp(buf, "driver") == 0) {
1462                         int j;
1463                         /* clear to get error below if setting is invalid */
1464                         conf->driver = NULL;
1465                         for (j = 0; wpa_drivers[j]; j++) {
1466                                 if (os_strcmp(pos, wpa_drivers[j]->name) == 0)
1467                                 {
1468                                         conf->driver = wpa_drivers[j];
1469                                         break;
1470                                 }
1471                         }
1472                         if (conf->driver == NULL) {
1473                                 wpa_printf(MSG_ERROR, "Line %d: invalid/"
1474                                            "unknown driver '%s'", line, pos);
1475                                 errors++;
1476                         }
1477                 } else if (os_strcmp(buf, "debug") == 0) {
1478                         wpa_printf(MSG_DEBUG, "Line %d: DEPRECATED: 'debug' "
1479                                    "configuration variable is not used "
1480                                    "anymore", line);
1481                 } else if (os_strcmp(buf, "logger_syslog_level") == 0) {
1482                         bss->logger_syslog_level = atoi(pos);
1483                 } else if (os_strcmp(buf, "logger_stdout_level") == 0) {
1484                         bss->logger_stdout_level = atoi(pos);
1485                 } else if (os_strcmp(buf, "logger_syslog") == 0) {
1486                         bss->logger_syslog = atoi(pos);
1487                 } else if (os_strcmp(buf, "logger_stdout") == 0) {
1488                         bss->logger_stdout = atoi(pos);
1489                 } else if (os_strcmp(buf, "dump_file") == 0) {
1490                         bss->dump_log_name = os_strdup(pos);
1491                 } else if (os_strcmp(buf, "ssid") == 0) {
1492                         bss->ssid.ssid_len = os_strlen(pos);
1493                         if (bss->ssid.ssid_len > HOSTAPD_MAX_SSID_LEN ||
1494                             bss->ssid.ssid_len < 1) {
1495                                 wpa_printf(MSG_ERROR, "Line %d: invalid SSID "
1496                                            "'%s'", line, pos);
1497                                 errors++;
1498                         } else {
1499                                 os_memcpy(bss->ssid.ssid, pos,
1500                                           bss->ssid.ssid_len);
1501                                 bss->ssid.ssid[bss->ssid.ssid_len] = '\0';
1502                                 bss->ssid.ssid_set = 1;
1503                         }
1504                 } else if (os_strcmp(buf, "macaddr_acl") == 0) {
1505                         bss->macaddr_acl = atoi(pos);
1506                         if (bss->macaddr_acl != ACCEPT_UNLESS_DENIED &&
1507                             bss->macaddr_acl != DENY_UNLESS_ACCEPTED &&
1508                             bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
1509                                 wpa_printf(MSG_ERROR, "Line %d: unknown "
1510                                            "macaddr_acl %d",
1511                                            line, bss->macaddr_acl);
1512                         }
1513                 } else if (os_strcmp(buf, "accept_mac_file") == 0) {
1514                         if (hostapd_config_read_maclist(pos, &bss->accept_mac,
1515                                                         &bss->num_accept_mac))
1516                         {
1517                                 wpa_printf(MSG_ERROR, "Line %d: Failed to "
1518                                            "read accept_mac_file '%s'",
1519                                            line, pos);
1520                                 errors++;
1521                         }
1522                 } else if (os_strcmp(buf, "deny_mac_file") == 0) {
1523                         if (hostapd_config_read_maclist(pos, &bss->deny_mac,
1524                                                         &bss->num_deny_mac)) {
1525                                 wpa_printf(MSG_ERROR, "Line %d: Failed to "
1526                                            "read deny_mac_file '%s'",
1527                                            line, pos);
1528                                 errors++;
1529                         }
1530                 } else if (os_strcmp(buf, "ap_max_inactivity") == 0) {
1531                         bss->ap_max_inactivity = atoi(pos);
1532                 } else if (os_strcmp(buf, "country_code") == 0) {
1533                         os_memcpy(conf->country, pos, 2);
1534                         /* FIX: make this configurable */
1535                         conf->country[2] = ' ';
1536                 } else if (os_strcmp(buf, "ieee80211d") == 0) {
1537                         conf->ieee80211d = atoi(pos);
1538                 } else if (os_strcmp(buf, "ieee8021x") == 0) {
1539                         bss->ieee802_1x = atoi(pos);
1540                 } else if (os_strcmp(buf, "eapol_version") == 0) {
1541                         bss->eapol_version = atoi(pos);
1542                         if (bss->eapol_version < 1 ||
1543                             bss->eapol_version > 2) {
1544                                 wpa_printf(MSG_ERROR, "Line %d: invalid EAPOL "
1545                                            "version (%d): '%s'.",
1546                                            line, bss->eapol_version, pos);
1547                                 errors++;
1548                         } else
1549                                 wpa_printf(MSG_DEBUG, "eapol_version=%d",
1550                                            bss->eapol_version);
1551 #ifdef EAP_SERVER
1552                 } else if (os_strcmp(buf, "eap_authenticator") == 0) {
1553                         bss->eap_server = atoi(pos);
1554                         wpa_printf(MSG_ERROR, "Line %d: obsolete "
1555                                    "eap_authenticator used; this has been "
1556                                    "renamed to eap_server", line);
1557                 } else if (os_strcmp(buf, "eap_server") == 0) {
1558                         bss->eap_server = atoi(pos);
1559                 } else if (os_strcmp(buf, "eap_user_file") == 0) {
1560                         if (hostapd_config_read_eap_user(pos, bss))
1561                                 errors++;
1562                 } else if (os_strcmp(buf, "ca_cert") == 0) {
1563                         os_free(bss->ca_cert);
1564                         bss->ca_cert = os_strdup(pos);
1565                 } else if (os_strcmp(buf, "server_cert") == 0) {
1566                         os_free(bss->server_cert);
1567                         bss->server_cert = os_strdup(pos);
1568                 } else if (os_strcmp(buf, "private_key") == 0) {
1569                         os_free(bss->private_key);
1570                         bss->private_key = os_strdup(pos);
1571                 } else if (os_strcmp(buf, "private_key_passwd") == 0) {
1572                         os_free(bss->private_key_passwd);
1573                         bss->private_key_passwd = os_strdup(pos);
1574                 } else if (os_strcmp(buf, "check_crl") == 0) {
1575                         bss->check_crl = atoi(pos);
1576                 } else if (os_strcmp(buf, "dh_file") == 0) {
1577                         os_free(bss->dh_file);
1578                         bss->dh_file = os_strdup(pos);
1579 #ifdef EAP_SERVER_FAST
1580                 } else if (os_strcmp(buf, "pac_opaque_encr_key") == 0) {
1581                         os_free(bss->pac_opaque_encr_key);
1582                         bss->pac_opaque_encr_key = os_malloc(16);
1583                         if (bss->pac_opaque_encr_key == NULL) {
1584                                 wpa_printf(MSG_ERROR, "Line %d: No memory for "
1585                                            "pac_opaque_encr_key", line);
1586                                 errors++;
1587                         } else if (hexstr2bin(pos, bss->pac_opaque_encr_key,
1588                                               16)) {
1589                                 wpa_printf(MSG_ERROR, "Line %d: Invalid "
1590                                            "pac_opaque_encr_key", line);
1591                                 errors++;
1592                         }
1593                 } else if (os_strcmp(buf, "eap_fast_a_id") == 0) {
1594                         size_t idlen = os_strlen(pos);
1595                         if (idlen & 1) {
1596                                 wpa_printf(MSG_ERROR, "Line %d: Invalid "
1597                                            "eap_fast_a_id", line);
1598                                 errors++;
1599                         } else {
1600                                 os_free(bss->eap_fast_a_id);
1601                                 bss->eap_fast_a_id = os_malloc(idlen / 2);
1602                                 if (bss->eap_fast_a_id == NULL ||
1603                                     hexstr2bin(pos, bss->eap_fast_a_id,
1604                                                idlen / 2)) {
1605                                         wpa_printf(MSG_ERROR, "Line %d: "
1606                                                    "Failed to parse "
1607                                                    "eap_fast_a_id", line);
1608                                         errors++;
1609                                 } else
1610                                         bss->eap_fast_a_id_len = idlen / 2;
1611                         }
1612                 } else if (os_strcmp(buf, "eap_fast_a_id_info") == 0) {
1613                         os_free(bss->eap_fast_a_id_info);
1614                         bss->eap_fast_a_id_info = os_strdup(pos);
1615                 } else if (os_strcmp(buf, "eap_fast_prov") == 0) {
1616                         bss->eap_fast_prov = atoi(pos);
1617                 } else if (os_strcmp(buf, "pac_key_lifetime") == 0) {
1618                         bss->pac_key_lifetime = atoi(pos);
1619                 } else if (os_strcmp(buf, "pac_key_refresh_time") == 0) {
1620                         bss->pac_key_refresh_time = atoi(pos);
1621 #endif /* EAP_SERVER_FAST */
1622 #ifdef EAP_SERVER_SIM
1623                 } else if (os_strcmp(buf, "eap_sim_db") == 0) {
1624                         os_free(bss->eap_sim_db);
1625                         bss->eap_sim_db = os_strdup(pos);
1626                 } else if (os_strcmp(buf, "eap_sim_aka_result_ind") == 0) {
1627                         bss->eap_sim_aka_result_ind = atoi(pos);
1628 #endif /* EAP_SERVER_SIM */
1629 #ifdef EAP_SERVER_TNC
1630                 } else if (os_strcmp(buf, "tnc") == 0) {
1631                         bss->tnc = atoi(pos);
1632 #endif /* EAP_SERVER_TNC */
1633 #endif /* EAP_SERVER */
1634                 } else if (os_strcmp(buf, "eap_message") == 0) {
1635                         char *term;
1636                         bss->eap_req_id_text = os_strdup(pos);
1637                         if (bss->eap_req_id_text == NULL) {
1638                                 wpa_printf(MSG_ERROR, "Line %d: Failed to "
1639                                            "allocate memory for "
1640                                            "eap_req_id_text", line);
1641                                 errors++;
1642                                 continue;
1643                         }
1644                         bss->eap_req_id_text_len =
1645                                 os_strlen(bss->eap_req_id_text);
1646                         term = os_strstr(bss->eap_req_id_text, "\\0");
1647                         if (term) {
1648                                 *term++ = '\0';
1649                                 os_memmove(term, term + 1,
1650                                            bss->eap_req_id_text_len -
1651                                            (term - bss->eap_req_id_text) - 1);
1652                                 bss->eap_req_id_text_len--;
1653                         }
1654                 } else if (os_strcmp(buf, "wep_key_len_broadcast") == 0) {
1655                         bss->default_wep_key_len = atoi(pos);
1656                         if (bss->default_wep_key_len > 13) {
1657                                 wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
1658                                            "key len %lu (= %lu bits)", line,
1659                                            (unsigned long)
1660                                            bss->default_wep_key_len,
1661                                            (unsigned long)
1662                                            bss->default_wep_key_len * 8);
1663                                 errors++;
1664                         }
1665                 } else if (os_strcmp(buf, "wep_key_len_unicast") == 0) {
1666                         bss->individual_wep_key_len = atoi(pos);
1667                         if (bss->individual_wep_key_len < 0 ||
1668                             bss->individual_wep_key_len > 13) {
1669                                 wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
1670                                            "key len %d (= %d bits)", line,
1671                                            bss->individual_wep_key_len,
1672                                            bss->individual_wep_key_len * 8);
1673                                 errors++;
1674                         }
1675                 } else if (os_strcmp(buf, "wep_rekey_period") == 0) {
1676                         bss->wep_rekeying_period = atoi(pos);
1677                         if (bss->wep_rekeying_period < 0) {
1678                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
1679                                            "period %d",
1680                                            line, bss->wep_rekeying_period);
1681                                 errors++;
1682                         }
1683                 } else if (os_strcmp(buf, "eap_reauth_period") == 0) {
1684                         bss->eap_reauth_period = atoi(pos);
1685                         if (bss->eap_reauth_period < 0) {
1686                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
1687                                            "period %d",
1688                                            line, bss->eap_reauth_period);
1689                                 errors++;
1690                         }
1691                 } else if (os_strcmp(buf, "eapol_key_index_workaround") == 0) {
1692                         bss->eapol_key_index_workaround = atoi(pos);
1693 #ifdef CONFIG_IAPP
1694                 } else if (os_strcmp(buf, "iapp_interface") == 0) {
1695                         bss->ieee802_11f = 1;
1696                         os_strlcpy(bss->iapp_iface, pos,
1697                                    sizeof(bss->iapp_iface));
1698 #endif /* CONFIG_IAPP */
1699                 } else if (os_strcmp(buf, "own_ip_addr") == 0) {
1700                         if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) {
1701                                 wpa_printf(MSG_ERROR, "Line %d: invalid IP "
1702                                            "address '%s'", line, pos);
1703                                 errors++;
1704                         }
1705                 } else if (os_strcmp(buf, "nas_identifier") == 0) {
1706                         bss->nas_identifier = os_strdup(pos);
1707 #ifndef CONFIG_NO_RADIUS
1708                 } else if (os_strcmp(buf, "auth_server_addr") == 0) {
1709                         if (hostapd_config_read_radius_addr(
1710                                     &bss->radius->auth_servers,
1711                                     &bss->radius->num_auth_servers, pos, 1812,
1712                                     &bss->radius->auth_server)) {
1713                                 wpa_printf(MSG_ERROR, "Line %d: invalid IP "
1714                                            "address '%s'", line, pos);
1715                                 errors++;
1716                         }
1717                 } else if (bss->radius->auth_server &&
1718                            os_strcmp(buf, "auth_server_port") == 0) {
1719                         bss->radius->auth_server->port = atoi(pos);
1720                 } else if (bss->radius->auth_server &&
1721                            os_strcmp(buf, "auth_server_shared_secret") == 0) {
1722                         int len = os_strlen(pos);
1723                         if (len == 0) {
1724                                 /* RFC 2865, Ch. 3 */
1725                                 wpa_printf(MSG_ERROR, "Line %d: empty shared "
1726                                            "secret is not allowed.", line);
1727                                 errors++;
1728                         }
1729                         bss->radius->auth_server->shared_secret =
1730                                 (u8 *) os_strdup(pos);
1731                         bss->radius->auth_server->shared_secret_len = len;
1732                 } else if (os_strcmp(buf, "acct_server_addr") == 0) {
1733                         if (hostapd_config_read_radius_addr(
1734                                     &bss->radius->acct_servers,
1735                                     &bss->radius->num_acct_servers, pos, 1813,
1736                                     &bss->radius->acct_server)) {
1737                                 wpa_printf(MSG_ERROR, "Line %d: invalid IP "
1738                                            "address '%s'", line, pos);
1739                                 errors++;
1740                         }
1741                 } else if (bss->radius->acct_server &&
1742                            os_strcmp(buf, "acct_server_port") == 0) {
1743                         bss->radius->acct_server->port = atoi(pos);
1744                 } else if (bss->radius->acct_server &&
1745                            os_strcmp(buf, "acct_server_shared_secret") == 0) {
1746                         int len = os_strlen(pos);
1747                         if (len == 0) {
1748                                 /* RFC 2865, Ch. 3 */
1749                                 wpa_printf(MSG_ERROR, "Line %d: empty shared "
1750                                            "secret is not allowed.", line);
1751                                 errors++;
1752                         }
1753                         bss->radius->acct_server->shared_secret =
1754                                 (u8 *) os_strdup(pos);
1755                         bss->radius->acct_server->shared_secret_len = len;
1756                 } else if (os_strcmp(buf, "radius_retry_primary_interval") ==
1757                            0) {
1758                         bss->radius->retry_primary_interval = atoi(pos);
1759                 } else if (os_strcmp(buf, "radius_acct_interim_interval") == 0)
1760                 {
1761                         bss->acct_interim_interval = atoi(pos);
1762 #endif /* CONFIG_NO_RADIUS */
1763                 } else if (os_strcmp(buf, "auth_algs") == 0) {
1764                         bss->auth_algs = atoi(pos);
1765                         if (bss->auth_algs == 0) {
1766                                 wpa_printf(MSG_ERROR, "Line %d: no "
1767                                            "authentication algorithms allowed",
1768                                            line);
1769                                 errors++;
1770                         }
1771                 } else if (os_strcmp(buf, "max_num_sta") == 0) {
1772                         bss->max_num_sta = atoi(pos);
1773                         if (bss->max_num_sta < 0 ||
1774                             bss->max_num_sta > MAX_STA_COUNT) {
1775                                 wpa_printf(MSG_ERROR, "Line %d: Invalid "
1776                                            "max_num_sta=%d; allowed range "
1777                                            "0..%d", line, bss->max_num_sta,
1778                                            MAX_STA_COUNT);
1779                                 errors++;
1780                         }
1781                 } else if (os_strcmp(buf, "wpa") == 0) {
1782                         bss->wpa = atoi(pos);
1783                 } else if (os_strcmp(buf, "wpa_group_rekey") == 0) {
1784                         bss->wpa_group_rekey = atoi(pos);
1785                 } else if (os_strcmp(buf, "wpa_strict_rekey") == 0) {
1786                         bss->wpa_strict_rekey = atoi(pos);
1787                 } else if (os_strcmp(buf, "wpa_gmk_rekey") == 0) {
1788                         bss->wpa_gmk_rekey = atoi(pos);
1789                 } else if (os_strcmp(buf, "wpa_ptk_rekey") == 0) {
1790                         bss->wpa_ptk_rekey = atoi(pos);
1791                 } else if (os_strcmp(buf, "wpa_passphrase") == 0) {
1792                         int len = os_strlen(pos);
1793                         if (len < 8 || len > 63) {
1794                                 wpa_printf(MSG_ERROR, "Line %d: invalid WPA "
1795                                            "passphrase length %d (expected "
1796                                            "8..63)", line, len);
1797                                 errors++;
1798                         } else {
1799                                 os_free(bss->ssid.wpa_passphrase);
1800                                 bss->ssid.wpa_passphrase = os_strdup(pos);
1801                         }
1802                 } else if (os_strcmp(buf, "wpa_psk") == 0) {
1803                         os_free(bss->ssid.wpa_psk);
1804                         bss->ssid.wpa_psk =
1805                                 os_zalloc(sizeof(struct hostapd_wpa_psk));
1806                         if (bss->ssid.wpa_psk == NULL)
1807                                 errors++;
1808                         else if (hexstr2bin(pos, bss->ssid.wpa_psk->psk,
1809                                             PMK_LEN) ||
1810                                  pos[PMK_LEN * 2] != '\0') {
1811                                 wpa_printf(MSG_ERROR, "Line %d: Invalid PSK "
1812                                            "'%s'.", line, pos);
1813                                 errors++;
1814                         } else {
1815                                 bss->ssid.wpa_psk->group = 1;
1816                         }
1817                 } else if (os_strcmp(buf, "wpa_psk_file") == 0) {
1818                         os_free(bss->ssid.wpa_psk_file);
1819                         bss->ssid.wpa_psk_file = os_strdup(pos);
1820                         if (!bss->ssid.wpa_psk_file) {
1821                                 wpa_printf(MSG_ERROR, "Line %d: allocation "
1822                                            "failed", line);
1823                                 errors++;
1824                         }
1825                 } else if (os_strcmp(buf, "wpa_key_mgmt") == 0) {
1826                         bss->wpa_key_mgmt =
1827                                 hostapd_config_parse_key_mgmt(line, pos);
1828                         if (bss->wpa_key_mgmt == -1)
1829                                 errors++;
1830                 } else if (os_strcmp(buf, "wpa_pairwise") == 0) {
1831                         bss->wpa_pairwise =
1832                                 hostapd_config_parse_cipher(line, pos);
1833                         if (bss->wpa_pairwise == -1 ||
1834                             bss->wpa_pairwise == 0)
1835                                 errors++;
1836                         else if (bss->wpa_pairwise &
1837                                  (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
1838                                   WPA_CIPHER_WEP104)) {
1839                                 wpa_printf(MSG_ERROR, "Line %d: unsupported "
1840                                            "pairwise cipher suite '%s'",
1841                                            bss->wpa_pairwise, pos);
1842                                 errors++;
1843                         }
1844                 } else if (os_strcmp(buf, "rsn_pairwise") == 0) {
1845                         bss->rsn_pairwise =
1846                                 hostapd_config_parse_cipher(line, pos);
1847                         if (bss->rsn_pairwise == -1 ||
1848                             bss->rsn_pairwise == 0)
1849                                 errors++;
1850                         else if (bss->rsn_pairwise &
1851                                  (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
1852                                   WPA_CIPHER_WEP104)) {
1853                                 wpa_printf(MSG_ERROR, "Line %d: unsupported "
1854                                            "pairwise cipher suite '%s'",
1855                                            bss->rsn_pairwise, pos);
1856                                 errors++;
1857                         }
1858 #ifdef CONFIG_RSN_PREAUTH
1859                 } else if (os_strcmp(buf, "rsn_preauth") == 0) {
1860                         bss->rsn_preauth = atoi(pos);
1861                 } else if (os_strcmp(buf, "rsn_preauth_interfaces") == 0) {
1862                         bss->rsn_preauth_interfaces = os_strdup(pos);
1863 #endif /* CONFIG_RSN_PREAUTH */
1864 #ifdef CONFIG_PEERKEY
1865                 } else if (os_strcmp(buf, "peerkey") == 0) {
1866                         bss->peerkey = atoi(pos);
1867 #endif /* CONFIG_PEERKEY */
1868 #ifdef CONFIG_IEEE80211R
1869                 } else if (os_strcmp(buf, "mobility_domain") == 0) {
1870                         if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN ||
1871                             hexstr2bin(pos, bss->mobility_domain,
1872                                        MOBILITY_DOMAIN_ID_LEN) != 0) {
1873                                 wpa_printf(MSG_DEBUG, "Line %d: Invalid "
1874                                            "mobility_domain '%s'", line, pos);
1875                                 errors++;
1876                                 continue;
1877                         }
1878                 } else if (os_strcmp(buf, "r1_key_holder") == 0) {
1879                         if (os_strlen(pos) != 2 * FT_R1KH_ID_LEN ||
1880                             hexstr2bin(pos, bss->r1_key_holder,
1881                                        FT_R1KH_ID_LEN) != 0) {
1882                                 wpa_printf(MSG_DEBUG, "Line %d: Invalid "
1883                                            "r1_key_holder '%s'", line, pos);
1884                                 errors++;
1885                                 continue;
1886                         }
1887                 } else if (os_strcmp(buf, "r0_key_lifetime") == 0) {
1888                         bss->r0_key_lifetime = atoi(pos);
1889                 } else if (os_strcmp(buf, "reassociation_deadline") == 0) {
1890                         bss->reassociation_deadline = atoi(pos);
1891                 } else if (os_strcmp(buf, "r0kh") == 0) {
1892                         if (add_r0kh(bss, pos) < 0) {
1893                                 wpa_printf(MSG_DEBUG, "Line %d: Invalid "
1894                                            "r0kh '%s'", line, pos);
1895                                 errors++;
1896                                 continue;
1897                         }
1898                 } else if (os_strcmp(buf, "r1kh") == 0) {
1899                         if (add_r1kh(bss, pos) < 0) {
1900                                 wpa_printf(MSG_DEBUG, "Line %d: Invalid "
1901                                            "r1kh '%s'", line, pos);
1902                                 errors++;
1903                                 continue;
1904                         }
1905                 } else if (os_strcmp(buf, "pmk_r1_push") == 0) {
1906                         bss->pmk_r1_push = atoi(pos);
1907 #endif /* CONFIG_IEEE80211R */
1908 #ifndef CONFIG_NO_CTRL_IFACE
1909                 } else if (os_strcmp(buf, "ctrl_interface") == 0) {
1910                         os_free(bss->ctrl_interface);
1911                         bss->ctrl_interface = os_strdup(pos);
1912                 } else if (os_strcmp(buf, "ctrl_interface_group") == 0) {
1913 #ifndef CONFIG_NATIVE_WINDOWS
1914                         struct group *grp;
1915                         char *endp;
1916                         const char *group = pos;
1917
1918                         grp = getgrnam(group);
1919                         if (grp) {
1920                                 bss->ctrl_interface_gid = grp->gr_gid;
1921                                 bss->ctrl_interface_gid_set = 1;
1922                                 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
1923                                            " (from group name '%s')",
1924                                            bss->ctrl_interface_gid, group);
1925                                 continue;
1926                         }
1927
1928                         /* Group name not found - try to parse this as gid */
1929                         bss->ctrl_interface_gid = strtol(group, &endp, 10);
1930                         if (*group == '\0' || *endp != '\0') {
1931                                 wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
1932                                            "'%s'", line, group);
1933                                 errors++;
1934                                 continue;
1935                         }
1936                         bss->ctrl_interface_gid_set = 1;
1937                         wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
1938                                    bss->ctrl_interface_gid);
1939 #endif /* CONFIG_NATIVE_WINDOWS */
1940 #endif /* CONFIG_NO_CTRL_IFACE */
1941 #ifdef RADIUS_SERVER
1942                 } else if (os_strcmp(buf, "radius_server_clients") == 0) {
1943                         os_free(bss->radius_server_clients);
1944                         bss->radius_server_clients = os_strdup(pos);
1945                 } else if (os_strcmp(buf, "radius_server_auth_port") == 0) {
1946                         bss->radius_server_auth_port = atoi(pos);
1947                 } else if (os_strcmp(buf, "radius_server_ipv6") == 0) {
1948                         bss->radius_server_ipv6 = atoi(pos);
1949 #endif /* RADIUS_SERVER */
1950                 } else if (os_strcmp(buf, "test_socket") == 0) {
1951                         os_free(bss->test_socket);
1952                         bss->test_socket = os_strdup(pos);
1953                 } else if (os_strcmp(buf, "use_pae_group_addr") == 0) {
1954                         bss->use_pae_group_addr = atoi(pos);
1955                 } else if (os_strcmp(buf, "hw_mode") == 0) {
1956                         if (os_strcmp(pos, "a") == 0)
1957                                 conf->hw_mode = HOSTAPD_MODE_IEEE80211A;
1958                         else if (os_strcmp(pos, "b") == 0)
1959                                 conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
1960                         else if (os_strcmp(pos, "g") == 0)
1961                                 conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
1962                         else {
1963                                 wpa_printf(MSG_ERROR, "Line %d: unknown "
1964                                            "hw_mode '%s'", line, pos);
1965                                 errors++;
1966                         }
1967                 } else if (os_strcmp(buf, "channel") == 0) {
1968                         conf->channel = atoi(pos);
1969                 } else if (os_strcmp(buf, "beacon_int") == 0) {
1970                         int val = atoi(pos);
1971                         /* MIB defines range as 1..65535, but very small values
1972                          * cause problems with the current implementation.
1973                          * Since it is unlikely that this small numbers are
1974                          * useful in real life scenarios, do not allow beacon
1975                          * period to be set below 15 TU. */
1976                         if (val < 15 || val > 65535) {
1977                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
1978                                            "beacon_int %d (expected "
1979                                            "15..65535)", line, val);
1980                                 errors++;
1981                         } else
1982                                 conf->beacon_int = val;
1983                 } else if (os_strcmp(buf, "dtim_period") == 0) {
1984                         bss->dtim_period = atoi(pos);
1985                         if (bss->dtim_period < 1 || bss->dtim_period > 255) {
1986                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
1987                                            "dtim_period %d",
1988                                            line, bss->dtim_period);
1989                                 errors++;
1990                         }
1991                 } else if (os_strcmp(buf, "rts_threshold") == 0) {
1992                         conf->rts_threshold = atoi(pos);
1993                         if (conf->rts_threshold < 0 ||
1994                             conf->rts_threshold > 2347) {
1995                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
1996                                            "rts_threshold %d",
1997                                            line, conf->rts_threshold);
1998                                 errors++;
1999                         }
2000                 } else if (os_strcmp(buf, "fragm_threshold") == 0) {
2001                         conf->fragm_threshold = atoi(pos);
2002                         if (conf->fragm_threshold < 256 ||
2003                             conf->fragm_threshold > 2346) {
2004                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
2005                                            "fragm_threshold %d",
2006                                            line, conf->fragm_threshold);
2007                                 errors++;
2008                         }
2009                 } else if (os_strcmp(buf, "send_probe_response") == 0) {
2010                         int val = atoi(pos);
2011                         if (val != 0 && val != 1) {
2012                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
2013                                            "send_probe_response %d (expected "
2014                                            "0 or 1)", line, val);
2015                         } else
2016                                 conf->send_probe_response = val;
2017                 } else if (os_strcmp(buf, "supported_rates") == 0) {
2018                         if (hostapd_parse_rates(&conf->supported_rates, pos)) {
2019                                 wpa_printf(MSG_ERROR, "Line %d: invalid rate "
2020                                            "list", line);
2021                                 errors++;
2022                         }
2023                 } else if (os_strcmp(buf, "basic_rates") == 0) {
2024                         if (hostapd_parse_rates(&conf->basic_rates, pos)) {
2025                                 wpa_printf(MSG_ERROR, "Line %d: invalid rate "
2026                                            "list", line);
2027                                 errors++;
2028                         }
2029                 } else if (os_strcmp(buf, "preamble") == 0) {
2030                         if (atoi(pos))
2031                                 conf->preamble = SHORT_PREAMBLE;
2032                         else
2033                                 conf->preamble = LONG_PREAMBLE;
2034                 } else if (os_strcmp(buf, "ignore_broadcast_ssid") == 0) {
2035                         bss->ignore_broadcast_ssid = atoi(pos);
2036                 } else if (os_strcmp(buf, "bridge_packets") == 0) {
2037                         conf->bridge_packets = atoi(pos);
2038                 } else if (os_strcmp(buf, "wep_default_key") == 0) {
2039                         bss->ssid.wep.idx = atoi(pos);
2040                         if (bss->ssid.wep.idx > 3) {
2041                                 wpa_printf(MSG_ERROR, "Invalid "
2042                                            "wep_default_key index %d",
2043                                            bss->ssid.wep.idx);
2044                                 errors++;
2045                         }
2046                 } else if (os_strcmp(buf, "wep_key0") == 0 ||
2047                            os_strcmp(buf, "wep_key1") == 0 ||
2048                            os_strcmp(buf, "wep_key2") == 0 ||
2049                            os_strcmp(buf, "wep_key3") == 0) {
2050                         if (hostapd_config_read_wep(&bss->ssid.wep,
2051                                                     buf[7] - '0', pos)) {
2052                                 wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
2053                                            "key '%s'", line, buf);
2054                                 errors++;
2055                         }
2056 #ifndef CONFIG_NO_VLAN
2057                 } else if (os_strcmp(buf, "dynamic_vlan") == 0) {
2058                         bss->ssid.dynamic_vlan = atoi(pos);
2059                 } else if (os_strcmp(buf, "vlan_file") == 0) {
2060                         if (hostapd_config_read_vlan_file(bss, pos)) {
2061                                 wpa_printf(MSG_ERROR, "Line %d: failed to "
2062                                            "read VLAN file '%s'", line, pos);
2063                                 errors++;
2064                         }
2065 #ifdef CONFIG_FULL_DYNAMIC_VLAN
2066                 } else if (os_strcmp(buf, "vlan_tagged_interface") == 0) {
2067                         bss->ssid.vlan_tagged_interface = os_strdup(pos);
2068 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
2069 #endif /* CONFIG_NO_VLAN */
2070                 } else if (os_strcmp(buf, "ap_table_max_size") == 0) {
2071                         conf->ap_table_max_size = atoi(pos);
2072                 } else if (os_strcmp(buf, "ap_table_expiration_time") == 0) {
2073                         conf->ap_table_expiration_time = atoi(pos);
2074                 } else if (os_strncmp(buf, "tx_queue_", 9) == 0) {
2075                         if (hostapd_config_tx_queue(conf, buf, pos)) {
2076                                 wpa_printf(MSG_ERROR, "Line %d: invalid TX "
2077                                            "queue item", line);
2078                                 errors++;
2079                         }
2080                 } else if (os_strcmp(buf, "wme_enabled") == 0 ||
2081                            os_strcmp(buf, "wmm_enabled") == 0) {
2082                         bss->wmm_enabled = atoi(pos);
2083                 } else if (os_strncmp(buf, "wme_ac_", 7) == 0 ||
2084                            os_strncmp(buf, "wmm_ac_", 7) == 0) {
2085                         if (hostapd_config_wmm_ac(conf, buf, pos)) {
2086                                 wpa_printf(MSG_ERROR, "Line %d: invalid WMM "
2087                                            "ac item", line);
2088                                 errors++;
2089                         }
2090                 } else if (os_strcmp(buf, "bss") == 0) {
2091                         if (hostapd_config_bss(conf, pos)) {
2092                                 wpa_printf(MSG_ERROR, "Line %d: invalid bss "
2093                                            "item", line);
2094                                 errors++;
2095                         }
2096                 } else if (os_strcmp(buf, "bssid") == 0) {
2097                         if (hwaddr_aton(pos, bss->bssid)) {
2098                                 wpa_printf(MSG_ERROR, "Line %d: invalid bssid "
2099                                            "item", line);
2100                                 errors++;
2101                         }
2102 #ifdef CONFIG_IEEE80211W
2103                 } else if (os_strcmp(buf, "ieee80211w") == 0) {
2104                         bss->ieee80211w = atoi(pos);
2105                 } else if (os_strcmp(buf, "assoc_sa_query_max_timeout") == 0) {
2106                         bss->assoc_sa_query_max_timeout = atoi(pos);
2107                         if (bss->assoc_sa_query_max_timeout == 0) {
2108                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
2109                                            "assoc_sa_query_max_timeout", line);
2110                                 errors++;
2111                         }
2112                 } else if (os_strcmp(buf, "assoc_sa_query_retry_timeout") == 0)
2113                 {
2114                         bss->assoc_sa_query_retry_timeout = atoi(pos);
2115                         if (bss->assoc_sa_query_retry_timeout == 0) {
2116                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
2117                                            "assoc_sa_query_retry_timeout",
2118                                            line);
2119                                 errors++;
2120                         }
2121 #endif /* CONFIG_IEEE80211W */
2122 #ifdef CONFIG_IEEE80211N
2123                 } else if (os_strcmp(buf, "ieee80211n") == 0) {
2124                         conf->ieee80211n = atoi(pos);
2125                 } else if (os_strcmp(buf, "ht_capab") == 0) {
2126                         if (hostapd_config_ht_capab(conf, pos) < 0) {
2127                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
2128                                            "ht_capab", line);
2129                                 errors++;
2130                         }
2131 #endif /* CONFIG_IEEE80211N */
2132                 } else if (os_strcmp(buf, "max_listen_interval") == 0) {
2133                         bss->max_listen_interval = atoi(pos);
2134                 } else if (os_strcmp(buf, "okc") == 0) {
2135                         bss->okc = atoi(pos);
2136 #ifdef CONFIG_WPS
2137                 } else if (os_strcmp(buf, "wps_state") == 0) {
2138                         bss->wps_state = atoi(pos);
2139                         if (bss->wps_state < 0 || bss->wps_state > 2) {
2140                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
2141                                            "wps_state", line);
2142                                 errors++;
2143                         }
2144                 } else if (os_strcmp(buf, "ap_setup_locked") == 0) {
2145                         bss->ap_setup_locked = atoi(pos);
2146                 } else if (os_strcmp(buf, "uuid") == 0) {
2147                         if (uuid_str2bin(pos, bss->uuid)) {
2148                                 wpa_printf(MSG_ERROR, "Line %d: invalid UUID",
2149                                            line);
2150                                 errors++;
2151                         }
2152                 } else if (os_strcmp(buf, "wps_pin_requests") == 0) {
2153                         os_free(bss->wps_pin_requests);
2154                         bss->wps_pin_requests = os_strdup(pos);
2155                 } else if (os_strcmp(buf, "device_name") == 0) {
2156                         if (os_strlen(pos) > 32) {
2157                                 wpa_printf(MSG_ERROR, "Line %d: Too long "
2158                                            "device_name", line);
2159                                 errors++;
2160                         }
2161                         os_free(bss->device_name);
2162                         bss->device_name = os_strdup(pos);
2163                 } else if (os_strcmp(buf, "manufacturer") == 0) {
2164                         if (os_strlen(pos) > 64) {
2165                                 wpa_printf(MSG_ERROR, "Line %d: Too long "
2166                                            "manufacturer", line);
2167                                 errors++;
2168                         }
2169                         os_free(bss->manufacturer);
2170                         bss->manufacturer = os_strdup(pos);
2171                 } else if (os_strcmp(buf, "model_name") == 0) {
2172                         if (os_strlen(pos) > 32) {
2173                                 wpa_printf(MSG_ERROR, "Line %d: Too long "
2174                                            "model_name", line);
2175                                 errors++;
2176                         }
2177                         os_free(bss->model_name);
2178                         bss->model_name = os_strdup(pos);
2179                 } else if (os_strcmp(buf, "model_number") == 0) {
2180                         if (os_strlen(pos) > 32) {
2181                                 wpa_printf(MSG_ERROR, "Line %d: Too long "
2182                                            "model_number", line);
2183                                 errors++;
2184                         }
2185                         os_free(bss->model_number);
2186                         bss->model_number = os_strdup(pos);
2187                 } else if (os_strcmp(buf, "serial_number") == 0) {
2188                         if (os_strlen(pos) > 32) {
2189                                 wpa_printf(MSG_ERROR, "Line %d: Too long "
2190                                            "serial_number", line);
2191                                 errors++;
2192                         }
2193                         os_free(bss->serial_number);
2194                         bss->serial_number = os_strdup(pos);
2195                 } else if (os_strcmp(buf, "device_type") == 0) {
2196                         os_free(bss->device_type);
2197                         bss->device_type = os_strdup(pos);
2198                 } else if (os_strcmp(buf, "config_methods") == 0) {
2199                         os_free(bss->config_methods);
2200                         bss->config_methods = os_strdup(pos);
2201                 } else if (os_strcmp(buf, "os_version") == 0) {
2202                         if (hexstr2bin(pos, bss->os_version, 4)) {
2203                                 wpa_printf(MSG_ERROR, "Line %d: invalid "
2204                                            "os_version", line);
2205                                 errors++;
2206                         }
2207                 } else if (os_strcmp(buf, "ap_pin") == 0) {
2208                         os_free(bss->ap_pin);
2209                         bss->ap_pin = os_strdup(pos);
2210                 } else if (os_strcmp(buf, "skip_cred_build") == 0) {
2211                         bss->skip_cred_build = atoi(pos);
2212                 } else if (os_strcmp(buf, "extra_cred") == 0) {
2213                         os_free(bss->extra_cred);
2214                         bss->extra_cred =
2215                                 (u8 *) os_readfile(pos, &bss->extra_cred_len);
2216                         if (bss->extra_cred == NULL) {
2217                                 wpa_printf(MSG_ERROR, "Line %d: could not "
2218                                            "read Credentials from '%s'",
2219                                            line, pos);
2220                                 errors++;
2221                         }
2222                 } else if (os_strcmp(buf, "wps_cred_processing") == 0) {
2223                         bss->wps_cred_processing = atoi(pos);
2224                 } else if (os_strcmp(buf, "ap_settings") == 0) {
2225                         os_free(bss->ap_settings);
2226                         bss->ap_settings =
2227                                 (u8 *) os_readfile(pos, &bss->ap_settings_len);
2228                         if (bss->ap_settings == NULL) {
2229                                 wpa_printf(MSG_ERROR, "Line %d: could not "
2230                                            "read AP Settings from '%s'",
2231                                            line, pos);
2232                                 errors++;
2233                         }
2234                 } else if (os_strcmp(buf, "upnp_iface") == 0) {
2235                         bss->upnp_iface = os_strdup(pos);
2236                 } else if (os_strcmp(buf, "friendly_name") == 0) {
2237                         os_free(bss->friendly_name);
2238                         bss->friendly_name = os_strdup(pos);
2239                 } else if (os_strcmp(buf, "manufacturer_url") == 0) {
2240                         os_free(bss->manufacturer_url);
2241                         bss->manufacturer_url = os_strdup(pos);
2242                 } else if (os_strcmp(buf, "model_description") == 0) {
2243                         os_free(bss->model_description);
2244                         bss->model_description = os_strdup(pos);
2245                 } else if (os_strcmp(buf, "model_url") == 0) {
2246                         os_free(bss->model_url);
2247                         bss->model_url = os_strdup(pos);
2248                 } else if (os_strcmp(buf, "upc") == 0) {
2249                         os_free(bss->upc);
2250                         bss->upc = os_strdup(pos);
2251 #endif /* CONFIG_WPS */
2252                 } else {
2253                         wpa_printf(MSG_ERROR, "Line %d: unknown configuration "
2254                                    "item '%s'", line, buf);
2255                         errors++;
2256                 }
2257         }
2258
2259         fclose(f);
2260
2261         for (i = 0; i < conf->num_bss; i++) {
2262                 bss = &conf->bss[i];
2263
2264                 if (bss->individual_wep_key_len == 0) {
2265                         /* individual keys are not use; can use key idx0 for
2266                          * broadcast keys */
2267                         bss->broadcast_key_idx_min = 0;
2268                 }
2269
2270                 /* Select group cipher based on the enabled pairwise cipher
2271                  * suites */
2272                 pairwise = 0;
2273                 if (bss->wpa & 1)
2274                         pairwise |= bss->wpa_pairwise;
2275                 if (bss->wpa & 2) {
2276                         if (bss->rsn_pairwise == 0)
2277                                 bss->rsn_pairwise = bss->wpa_pairwise;
2278                         pairwise |= bss->rsn_pairwise;
2279                 }
2280                 if (pairwise & WPA_CIPHER_TKIP)
2281                         bss->wpa_group = WPA_CIPHER_TKIP;
2282                 else
2283                         bss->wpa_group = WPA_CIPHER_CCMP;
2284
2285                 bss->radius->auth_server = bss->radius->auth_servers;
2286                 bss->radius->acct_server = bss->radius->acct_servers;
2287
2288                 if (bss->wpa && bss->ieee802_1x) {
2289                         bss->ssid.security_policy = SECURITY_WPA;
2290                 } else if (bss->wpa) {
2291                         bss->ssid.security_policy = SECURITY_WPA_PSK;
2292                 } else if (bss->ieee802_1x) {
2293                         bss->ssid.security_policy = SECURITY_IEEE_802_1X;
2294                         bss->ssid.wep.default_len = bss->default_wep_key_len;
2295                 } else if (bss->ssid.wep.keys_set)
2296                         bss->ssid.security_policy = SECURITY_STATIC_WEP;
2297                 else
2298                         bss->ssid.security_policy = SECURITY_PLAINTEXT;
2299         }
2300
2301         if (hostapd_config_check(conf))
2302                 errors++;
2303
2304         if (errors) {
2305                 wpa_printf(MSG_ERROR, "%d errors found in configuration file "
2306                            "'%s'", errors, fname);
2307                 hostapd_config_free(conf);
2308                 conf = NULL;
2309         }
2310
2311         return conf;
2312 }
2313
2314
2315 int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, struct hostapd_wep_keys *b)
2316 {
2317         int i;
2318
2319         if (a->idx != b->idx || a->default_len != b->default_len)
2320                 return 1;
2321         for (i = 0; i < NUM_WEP_KEYS; i++)
2322                 if (a->len[i] != b->len[i] ||
2323                     os_memcmp(a->key[i], b->key[i], a->len[i]) != 0)
2324                         return 1;
2325         return 0;
2326 }
2327
2328
2329 static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
2330                                        int num_servers)
2331 {
2332         int i;
2333
2334         for (i = 0; i < num_servers; i++) {
2335                 os_free(servers[i].shared_secret);
2336         }
2337         os_free(servers);
2338 }
2339
2340
2341 static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
2342 {
2343         os_free(user->identity);
2344         os_free(user->password);
2345         os_free(user);
2346 }
2347
2348
2349 static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
2350 {
2351         int i;
2352         for (i = 0; i < NUM_WEP_KEYS; i++) {
2353                 os_free(keys->key[i]);
2354                 keys->key[i] = NULL;
2355         }
2356 }
2357
2358
2359 static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
2360 {
2361         struct hostapd_wpa_psk *psk, *prev;
2362         struct hostapd_eap_user *user, *prev_user;
2363
2364         if (conf == NULL)
2365                 return;
2366
2367         psk = conf->ssid.wpa_psk;
2368         while (psk) {
2369                 prev = psk;
2370                 psk = psk->next;
2371                 os_free(prev);
2372         }
2373
2374         os_free(conf->ssid.wpa_passphrase);
2375         os_free(conf->ssid.wpa_psk_file);
2376 #ifdef CONFIG_FULL_DYNAMIC_VLAN
2377         os_free(conf->ssid.vlan_tagged_interface);
2378 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
2379
2380         user = conf->eap_user;
2381         while (user) {
2382                 prev_user = user;
2383                 user = user->next;
2384                 hostapd_config_free_eap_user(prev_user);
2385         }
2386
2387         os_free(conf->dump_log_name);
2388         os_free(conf->eap_req_id_text);
2389         os_free(conf->accept_mac);
2390         os_free(conf->deny_mac);
2391         os_free(conf->nas_identifier);
2392         hostapd_config_free_radius(conf->radius->auth_servers,
2393                                    conf->radius->num_auth_servers);
2394         hostapd_config_free_radius(conf->radius->acct_servers,
2395                                    conf->radius->num_acct_servers);
2396         os_free(conf->rsn_preauth_interfaces);
2397         os_free(conf->ctrl_interface);
2398         os_free(conf->ca_cert);
2399         os_free(conf->server_cert);
2400         os_free(conf->private_key);
2401         os_free(conf->private_key_passwd);
2402         os_free(conf->dh_file);
2403         os_free(conf->pac_opaque_encr_key);
2404         os_free(conf->eap_fast_a_id);
2405         os_free(conf->eap_fast_a_id_info);
2406         os_free(conf->eap_sim_db);
2407         os_free(conf->radius_server_clients);
2408         os_free(conf->test_socket);
2409         os_free(conf->radius);
2410         hostapd_config_free_vlan(conf);
2411         if (conf->ssid.dyn_vlan_keys) {
2412                 struct hostapd_ssid *ssid = &conf->ssid;
2413                 size_t i;
2414                 for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
2415                         if (ssid->dyn_vlan_keys[i] == NULL)
2416                                 continue;
2417                         hostapd_config_free_wep(ssid->dyn_vlan_keys[i]);
2418                         os_free(ssid->dyn_vlan_keys[i]);
2419                 }
2420                 os_free(ssid->dyn_vlan_keys);
2421                 ssid->dyn_vlan_keys = NULL;
2422         }
2423
2424 #ifdef CONFIG_IEEE80211R
2425         {
2426                 struct ft_remote_r0kh *r0kh, *r0kh_prev;
2427                 struct ft_remote_r1kh *r1kh, *r1kh_prev;
2428
2429                 r0kh = conf->r0kh_list;
2430                 conf->r0kh_list = NULL;
2431                 while (r0kh) {
2432                         r0kh_prev = r0kh;
2433                         r0kh = r0kh->next;
2434                         os_free(r0kh_prev);
2435                 }
2436
2437                 r1kh = conf->r1kh_list;
2438                 conf->r1kh_list = NULL;
2439                 while (r1kh) {
2440                         r1kh_prev = r1kh;
2441                         r1kh = r1kh->next;
2442                         os_free(r1kh_prev);
2443                 }
2444         }
2445 #endif /* CONFIG_IEEE80211R */
2446
2447 #ifdef CONFIG_WPS
2448         os_free(conf->wps_pin_requests);
2449         os_free(conf->device_name);
2450         os_free(conf->manufacturer);
2451         os_free(conf->model_name);
2452         os_free(conf->model_number);
2453         os_free(conf->serial_number);
2454         os_free(conf->device_type);
2455         os_free(conf->config_methods);
2456         os_free(conf->ap_pin);
2457         os_free(conf->extra_cred);
2458         os_free(conf->ap_settings);
2459         os_free(conf->upnp_iface);
2460         os_free(conf->friendly_name);
2461         os_free(conf->manufacturer_url);
2462         os_free(conf->model_description);
2463         os_free(conf->model_url);
2464         os_free(conf->upc);
2465 #endif /* CONFIG_WPS */
2466 }
2467
2468
2469 /**
2470  * hostapd_config_free - Free hostapd configuration
2471  * @conf: Configuration data from hostapd_config_read().
2472  */
2473 void hostapd_config_free(struct hostapd_config *conf)
2474 {
2475         size_t i;
2476
2477         if (conf == NULL)
2478                 return;
2479
2480         for (i = 0; i < conf->num_bss; i++)
2481                 hostapd_config_free_bss(&conf->bss[i]);
2482         os_free(conf->bss);
2483
2484         os_free(conf);
2485 }
2486
2487
2488 /**
2489  * hostapd_maclist_found - Find a MAC address from a list
2490  * @list: MAC address list
2491  * @num_entries: Number of addresses in the list
2492  * @addr: Address to search for
2493  * @vlan_id: Buffer for returning VLAN ID or %NULL if not needed
2494  * Returns: 1 if address is in the list or 0 if not.
2495  *
2496  * Perform a binary search for given MAC address from a pre-sorted list.
2497  */
2498 int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
2499                           const u8 *addr, int *vlan_id)
2500 {
2501         int start, end, middle, res;
2502
2503         start = 0;
2504         end = num_entries - 1;
2505
2506         while (start <= end) {
2507                 middle = (start + end) / 2;
2508                 res = os_memcmp(list[middle].addr, addr, ETH_ALEN);
2509                 if (res == 0) {
2510                         if (vlan_id)
2511                                 *vlan_id = list[middle].vlan_id;
2512                         return 1;
2513                 }
2514                 if (res < 0)
2515                         start = middle + 1;
2516                 else
2517                         end = middle - 1;
2518         }
2519
2520         return 0;
2521 }
2522
2523
2524 int hostapd_rate_found(int *list, int rate)
2525 {
2526         int i;
2527
2528         if (list == NULL)
2529                 return 0;
2530
2531         for (i = 0; list[i] >= 0; i++)
2532                 if (list[i] == rate)
2533                         return 1;
2534
2535         return 0;
2536 }
2537
2538
2539 const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
2540 {
2541         struct hostapd_vlan *v = vlan;
2542         while (v) {
2543                 if (v->vlan_id == vlan_id || v->vlan_id == VLAN_ID_WILDCARD)
2544                         return v->ifname;
2545                 v = v->next;
2546         }
2547         return NULL;
2548 }
2549
2550
2551 const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
2552                            const u8 *addr, const u8 *prev_psk)
2553 {
2554         struct hostapd_wpa_psk *psk;
2555         int next_ok = prev_psk == NULL;
2556
2557         for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) {
2558                 if (next_ok &&
2559                     (psk->group || os_memcmp(psk->addr, addr, ETH_ALEN) == 0))
2560                         return psk->psk;
2561
2562                 if (psk->psk == prev_psk)
2563                         next_ok = 1;
2564         }
2565
2566         return NULL;
2567 }
2568
2569
2570 const struct hostapd_eap_user *
2571 hostapd_get_eap_user(const struct hostapd_bss_config *conf, const u8 *identity,
2572                      size_t identity_len, int phase2)
2573 {
2574         struct hostapd_eap_user *user = conf->eap_user;
2575
2576 #ifdef CONFIG_WPS
2577         if (conf->wps_state && identity_len == WSC_ID_ENROLLEE_LEN &&
2578             os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) {
2579                 static struct hostapd_eap_user wsc_enrollee;
2580                 os_memset(&wsc_enrollee, 0, sizeof(wsc_enrollee));
2581                 wsc_enrollee.methods[0].method = eap_server_get_type(
2582                         "WSC", &wsc_enrollee.methods[0].vendor);
2583                 return &wsc_enrollee;
2584         }
2585
2586         if (conf->wps_state && conf->ap_pin &&
2587             identity_len == WSC_ID_REGISTRAR_LEN &&
2588             os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) {
2589                 static struct hostapd_eap_user wsc_registrar;
2590                 os_memset(&wsc_registrar, 0, sizeof(wsc_registrar));
2591                 wsc_registrar.methods[0].method = eap_server_get_type(
2592                         "WSC", &wsc_registrar.methods[0].vendor);
2593                 wsc_registrar.password = (u8 *) conf->ap_pin;
2594                 wsc_registrar.password_len = os_strlen(conf->ap_pin);
2595                 return &wsc_registrar;
2596         }
2597 #endif /* CONFIG_WPS */
2598
2599         while (user) {
2600                 if (!phase2 && user->identity == NULL) {
2601                         /* Wildcard match */
2602                         break;
2603                 }
2604
2605                 if (user->phase2 == !!phase2 && user->wildcard_prefix &&
2606                     identity_len >= user->identity_len &&
2607                     os_memcmp(user->identity, identity, user->identity_len) ==
2608                     0) {
2609                         /* Wildcard prefix match */
2610                         break;
2611                 }
2612
2613                 if (user->phase2 == !!phase2 &&
2614                     user->identity_len == identity_len &&
2615                     os_memcmp(user->identity, identity, identity_len) == 0)
2616                         break;
2617                 user = user->next;
2618         }
2619
2620         return user;
2621 }