]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/wpa/src/ap/ap_config.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / wpa / src / ap / ap_config.c
1 /*
2  * hostapd / Configuration helper functions
3  * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "utils/includes.h"
16
17 #include "utils/common.h"
18 #include "crypto/sha1.h"
19 #include "radius/radius_client.h"
20 #include "common/ieee802_11_defs.h"
21 #include "common/eapol_common.h"
22 #include "eap_common/eap_wsc_common.h"
23 #include "eap_server/eap.h"
24 #include "wpa_auth.h"
25 #include "sta_info.h"
26 #include "ap_config.h"
27
28
29 static void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
30 {
31         struct hostapd_vlan *vlan, *prev;
32
33         vlan = bss->vlan;
34         prev = NULL;
35         while (vlan) {
36                 prev = vlan;
37                 vlan = vlan->next;
38                 os_free(prev);
39         }
40
41         bss->vlan = NULL;
42 }
43
44
45 void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
46 {
47         bss->logger_syslog_level = HOSTAPD_LEVEL_INFO;
48         bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
49         bss->logger_syslog = (unsigned int) -1;
50         bss->logger_stdout = (unsigned int) -1;
51
52         bss->auth_algs = WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED;
53
54         bss->wep_rekeying_period = 300;
55         /* use key0 in individual key and key1 in broadcast key */
56         bss->broadcast_key_idx_min = 1;
57         bss->broadcast_key_idx_max = 2;
58         bss->eap_reauth_period = 3600;
59
60         bss->wpa_group_rekey = 600;
61         bss->wpa_gmk_rekey = 86400;
62         bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
63         bss->wpa_pairwise = WPA_CIPHER_TKIP;
64         bss->wpa_group = WPA_CIPHER_TKIP;
65         bss->rsn_pairwise = 0;
66
67         bss->max_num_sta = MAX_STA_COUNT;
68
69         bss->dtim_period = 2;
70
71         bss->radius_server_auth_port = 1812;
72         bss->ap_max_inactivity = AP_MAX_INACTIVITY;
73         bss->eapol_version = EAPOL_VERSION;
74
75         bss->max_listen_interval = 65535;
76
77 #ifdef CONFIG_IEEE80211W
78         bss->assoc_sa_query_max_timeout = 1000;
79         bss->assoc_sa_query_retry_timeout = 201;
80 #endif /* CONFIG_IEEE80211W */
81 #ifdef EAP_SERVER_FAST
82          /* both anonymous and authenticated provisioning */
83         bss->eap_fast_prov = 3;
84         bss->pac_key_lifetime = 7 * 24 * 60 * 60;
85         bss->pac_key_refresh_time = 1 * 24 * 60 * 60;
86 #endif /* EAP_SERVER_FAST */
87 }
88
89
90 struct hostapd_config * hostapd_config_defaults(void)
91 {
92         struct hostapd_config *conf;
93         struct hostapd_bss_config *bss;
94         int i;
95         const int aCWmin = 4, aCWmax = 10;
96         const struct hostapd_wmm_ac_params ac_bk =
97                 { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
98         const struct hostapd_wmm_ac_params ac_be =
99                 { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
100         const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
101                 { aCWmin - 1, aCWmin, 2, 3000 / 32, 1 };
102         const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
103                 { aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 1 };
104
105         conf = os_zalloc(sizeof(*conf));
106         bss = os_zalloc(sizeof(*bss));
107         if (conf == NULL || bss == NULL) {
108                 wpa_printf(MSG_ERROR, "Failed to allocate memory for "
109                            "configuration data.");
110                 os_free(conf);
111                 os_free(bss);
112                 return NULL;
113         }
114
115         bss->radius = os_zalloc(sizeof(*bss->radius));
116         if (bss->radius == NULL) {
117                 os_free(conf);
118                 os_free(bss);
119                 return NULL;
120         }
121
122         hostapd_config_defaults_bss(bss);
123
124         conf->num_bss = 1;
125         conf->bss = bss;
126
127         conf->beacon_int = 100;
128         conf->rts_threshold = -1; /* use driver default: 2347 */
129         conf->fragm_threshold = -1; /* user driver default: 2346 */
130         conf->send_probe_response = 1;
131
132         for (i = 0; i < NUM_TX_QUEUES; i++)
133                 conf->tx_queue[i].aifs = -1; /* use hw default */
134
135         conf->wmm_ac_params[0] = ac_be;
136         conf->wmm_ac_params[1] = ac_bk;
137         conf->wmm_ac_params[2] = ac_vi;
138         conf->wmm_ac_params[3] = ac_vo;
139
140         conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED;
141
142         return conf;
143 }
144
145
146 int hostapd_mac_comp(const void *a, const void *b)
147 {
148         return os_memcmp(a, b, sizeof(macaddr));
149 }
150
151
152 int hostapd_mac_comp_empty(const void *a)
153 {
154         macaddr empty = { 0 };
155         return os_memcmp(a, empty, sizeof(macaddr));
156 }
157
158
159 static int hostapd_config_read_wpa_psk(const char *fname,
160                                        struct hostapd_ssid *ssid)
161 {
162         FILE *f;
163         char buf[128], *pos;
164         int line = 0, ret = 0, len, ok;
165         u8 addr[ETH_ALEN];
166         struct hostapd_wpa_psk *psk;
167
168         if (!fname)
169                 return 0;
170
171         f = fopen(fname, "r");
172         if (!f) {
173                 wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname);
174                 return -1;
175         }
176
177         while (fgets(buf, sizeof(buf), f)) {
178                 line++;
179
180                 if (buf[0] == '#')
181                         continue;
182                 pos = buf;
183                 while (*pos != '\0') {
184                         if (*pos == '\n') {
185                                 *pos = '\0';
186                                 break;
187                         }
188                         pos++;
189                 }
190                 if (buf[0] == '\0')
191                         continue;
192
193                 if (hwaddr_aton(buf, addr)) {
194                         wpa_printf(MSG_ERROR, "Invalid MAC address '%s' on "
195                                    "line %d in '%s'", buf, line, fname);
196                         ret = -1;
197                         break;
198                 }
199
200                 psk = os_zalloc(sizeof(*psk));
201                 if (psk == NULL) {
202                         wpa_printf(MSG_ERROR, "WPA PSK allocation failed");
203                         ret = -1;
204                         break;
205                 }
206                 if (is_zero_ether_addr(addr))
207                         psk->group = 1;
208                 else
209                         os_memcpy(psk->addr, addr, ETH_ALEN);
210
211                 pos = buf + 17;
212                 if (*pos == '\0') {
213                         wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'",
214                                    line, fname);
215                         os_free(psk);
216                         ret = -1;
217                         break;
218                 }
219                 pos++;
220
221                 ok = 0;
222                 len = os_strlen(pos);
223                 if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
224                         ok = 1;
225                 else if (len >= 8 && len < 64) {
226                         pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
227                                     4096, psk->psk, PMK_LEN);
228                         ok = 1;
229                 }
230                 if (!ok) {
231                         wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in "
232                                    "'%s'", pos, line, fname);
233                         os_free(psk);
234                         ret = -1;
235                         break;
236                 }
237
238                 psk->next = ssid->wpa_psk;
239                 ssid->wpa_psk = psk;
240         }
241
242         fclose(f);
243
244         return ret;
245 }
246
247
248 static int hostapd_derive_psk(struct hostapd_ssid *ssid)
249 {
250         ssid->wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
251         if (ssid->wpa_psk == NULL) {
252                 wpa_printf(MSG_ERROR, "Unable to alloc space for PSK");
253                 return -1;
254         }
255         wpa_hexdump_ascii(MSG_DEBUG, "SSID",
256                           (u8 *) ssid->ssid, ssid->ssid_len);
257         wpa_hexdump_ascii_key(MSG_DEBUG, "PSK (ASCII passphrase)",
258                               (u8 *) ssid->wpa_passphrase,
259                               os_strlen(ssid->wpa_passphrase));
260         pbkdf2_sha1(ssid->wpa_passphrase,
261                     ssid->ssid, ssid->ssid_len,
262                     4096, ssid->wpa_psk->psk, PMK_LEN);
263         wpa_hexdump_key(MSG_DEBUG, "PSK (from passphrase)",
264                         ssid->wpa_psk->psk, PMK_LEN);
265         return 0;
266 }
267
268
269 int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf)
270 {
271         struct hostapd_ssid *ssid = &conf->ssid;
272
273         if (ssid->wpa_passphrase != NULL) {
274                 if (ssid->wpa_psk != NULL) {
275                         wpa_printf(MSG_DEBUG, "Using pre-configured WPA PSK "
276                                    "instead of passphrase");
277                 } else {
278                         wpa_printf(MSG_DEBUG, "Deriving WPA PSK based on "
279                                    "passphrase");
280                         if (hostapd_derive_psk(ssid) < 0)
281                                 return -1;
282                 }
283                 ssid->wpa_psk->group = 1;
284         }
285
286         if (ssid->wpa_psk_file) {
287                 if (hostapd_config_read_wpa_psk(ssid->wpa_psk_file,
288                                                 &conf->ssid))
289                         return -1;
290         }
291
292         return 0;
293 }
294
295
296 int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, struct hostapd_wep_keys *b)
297 {
298         int i;
299
300         if (a->idx != b->idx || a->default_len != b->default_len)
301                 return 1;
302         for (i = 0; i < NUM_WEP_KEYS; i++)
303                 if (a->len[i] != b->len[i] ||
304                     os_memcmp(a->key[i], b->key[i], a->len[i]) != 0)
305                         return 1;
306         return 0;
307 }
308
309
310 static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
311                                        int num_servers)
312 {
313         int i;
314
315         for (i = 0; i < num_servers; i++) {
316                 os_free(servers[i].shared_secret);
317         }
318         os_free(servers);
319 }
320
321
322 static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
323 {
324         os_free(user->identity);
325         os_free(user->password);
326         os_free(user);
327 }
328
329
330 static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
331 {
332         int i;
333         for (i = 0; i < NUM_WEP_KEYS; i++) {
334                 os_free(keys->key[i]);
335                 keys->key[i] = NULL;
336         }
337 }
338
339
340 static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
341 {
342         struct hostapd_wpa_psk *psk, *prev;
343         struct hostapd_eap_user *user, *prev_user;
344
345         if (conf == NULL)
346                 return;
347
348         psk = conf->ssid.wpa_psk;
349         while (psk) {
350                 prev = psk;
351                 psk = psk->next;
352                 os_free(prev);
353         }
354
355         os_free(conf->ssid.wpa_passphrase);
356         os_free(conf->ssid.wpa_psk_file);
357         hostapd_config_free_wep(&conf->ssid.wep);
358 #ifdef CONFIG_FULL_DYNAMIC_VLAN
359         os_free(conf->ssid.vlan_tagged_interface);
360 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
361
362         user = conf->eap_user;
363         while (user) {
364                 prev_user = user;
365                 user = user->next;
366                 hostapd_config_free_eap_user(prev_user);
367         }
368
369         os_free(conf->dump_log_name);
370         os_free(conf->eap_req_id_text);
371         os_free(conf->accept_mac);
372         os_free(conf->deny_mac);
373         os_free(conf->nas_identifier);
374         hostapd_config_free_radius(conf->radius->auth_servers,
375                                    conf->radius->num_auth_servers);
376         hostapd_config_free_radius(conf->radius->acct_servers,
377                                    conf->radius->num_acct_servers);
378         os_free(conf->rsn_preauth_interfaces);
379         os_free(conf->ctrl_interface);
380         os_free(conf->ca_cert);
381         os_free(conf->server_cert);
382         os_free(conf->private_key);
383         os_free(conf->private_key_passwd);
384         os_free(conf->dh_file);
385         os_free(conf->pac_opaque_encr_key);
386         os_free(conf->eap_fast_a_id);
387         os_free(conf->eap_fast_a_id_info);
388         os_free(conf->eap_sim_db);
389         os_free(conf->radius_server_clients);
390         os_free(conf->test_socket);
391         os_free(conf->radius);
392         hostapd_config_free_vlan(conf);
393         if (conf->ssid.dyn_vlan_keys) {
394                 struct hostapd_ssid *ssid = &conf->ssid;
395                 size_t i;
396                 for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
397                         if (ssid->dyn_vlan_keys[i] == NULL)
398                                 continue;
399                         hostapd_config_free_wep(ssid->dyn_vlan_keys[i]);
400                         os_free(ssid->dyn_vlan_keys[i]);
401                 }
402                 os_free(ssid->dyn_vlan_keys);
403                 ssid->dyn_vlan_keys = NULL;
404         }
405
406 #ifdef CONFIG_IEEE80211R
407         {
408                 struct ft_remote_r0kh *r0kh, *r0kh_prev;
409                 struct ft_remote_r1kh *r1kh, *r1kh_prev;
410
411                 r0kh = conf->r0kh_list;
412                 conf->r0kh_list = NULL;
413                 while (r0kh) {
414                         r0kh_prev = r0kh;
415                         r0kh = r0kh->next;
416                         os_free(r0kh_prev);
417                 }
418
419                 r1kh = conf->r1kh_list;
420                 conf->r1kh_list = NULL;
421                 while (r1kh) {
422                         r1kh_prev = r1kh;
423                         r1kh = r1kh->next;
424                         os_free(r1kh_prev);
425                 }
426         }
427 #endif /* CONFIG_IEEE80211R */
428
429 #ifdef CONFIG_WPS
430         os_free(conf->wps_pin_requests);
431         os_free(conf->device_name);
432         os_free(conf->manufacturer);
433         os_free(conf->model_name);
434         os_free(conf->model_number);
435         os_free(conf->serial_number);
436         os_free(conf->device_type);
437         os_free(conf->config_methods);
438         os_free(conf->ap_pin);
439         os_free(conf->extra_cred);
440         os_free(conf->ap_settings);
441         os_free(conf->upnp_iface);
442         os_free(conf->friendly_name);
443         os_free(conf->manufacturer_url);
444         os_free(conf->model_description);
445         os_free(conf->model_url);
446         os_free(conf->upc);
447 #endif /* CONFIG_WPS */
448 }
449
450
451 /**
452  * hostapd_config_free - Free hostapd configuration
453  * @conf: Configuration data from hostapd_config_read().
454  */
455 void hostapd_config_free(struct hostapd_config *conf)
456 {
457         size_t i;
458
459         if (conf == NULL)
460                 return;
461
462         for (i = 0; i < conf->num_bss; i++)
463                 hostapd_config_free_bss(&conf->bss[i]);
464         os_free(conf->bss);
465         os_free(conf->supported_rates);
466         os_free(conf->basic_rates);
467
468         os_free(conf);
469 }
470
471
472 /**
473  * hostapd_maclist_found - Find a MAC address from a list
474  * @list: MAC address list
475  * @num_entries: Number of addresses in the list
476  * @addr: Address to search for
477  * @vlan_id: Buffer for returning VLAN ID or %NULL if not needed
478  * Returns: 1 if address is in the list or 0 if not.
479  *
480  * Perform a binary search for given MAC address from a pre-sorted list.
481  */
482 int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
483                           const u8 *addr, int *vlan_id)
484 {
485         int start, end, middle, res;
486
487         start = 0;
488         end = num_entries - 1;
489
490         while (start <= end) {
491                 middle = (start + end) / 2;
492                 res = os_memcmp(list[middle].addr, addr, ETH_ALEN);
493                 if (res == 0) {
494                         if (vlan_id)
495                                 *vlan_id = list[middle].vlan_id;
496                         return 1;
497                 }
498                 if (res < 0)
499                         start = middle + 1;
500                 else
501                         end = middle - 1;
502         }
503
504         return 0;
505 }
506
507
508 int hostapd_rate_found(int *list, int rate)
509 {
510         int i;
511
512         if (list == NULL)
513                 return 0;
514
515         for (i = 0; list[i] >= 0; i++)
516                 if (list[i] == rate)
517                         return 1;
518
519         return 0;
520 }
521
522
523 const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
524 {
525         struct hostapd_vlan *v = vlan;
526         while (v) {
527                 if (v->vlan_id == vlan_id || v->vlan_id == VLAN_ID_WILDCARD)
528                         return v->ifname;
529                 v = v->next;
530         }
531         return NULL;
532 }
533
534
535 const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
536                            const u8 *addr, const u8 *prev_psk)
537 {
538         struct hostapd_wpa_psk *psk;
539         int next_ok = prev_psk == NULL;
540
541         for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) {
542                 if (next_ok &&
543                     (psk->group || os_memcmp(psk->addr, addr, ETH_ALEN) == 0))
544                         return psk->psk;
545
546                 if (psk->psk == prev_psk)
547                         next_ok = 1;
548         }
549
550         return NULL;
551 }
552
553
554 const struct hostapd_eap_user *
555 hostapd_get_eap_user(const struct hostapd_bss_config *conf, const u8 *identity,
556                      size_t identity_len, int phase2)
557 {
558         struct hostapd_eap_user *user = conf->eap_user;
559
560 #ifdef CONFIG_WPS
561         if (conf->wps_state && identity_len == WSC_ID_ENROLLEE_LEN &&
562             os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) {
563                 static struct hostapd_eap_user wsc_enrollee;
564                 os_memset(&wsc_enrollee, 0, sizeof(wsc_enrollee));
565                 wsc_enrollee.methods[0].method = eap_server_get_type(
566                         "WSC", &wsc_enrollee.methods[0].vendor);
567                 return &wsc_enrollee;
568         }
569
570         if (conf->wps_state && identity_len == WSC_ID_REGISTRAR_LEN &&
571             os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) {
572                 static struct hostapd_eap_user wsc_registrar;
573                 os_memset(&wsc_registrar, 0, sizeof(wsc_registrar));
574                 wsc_registrar.methods[0].method = eap_server_get_type(
575                         "WSC", &wsc_registrar.methods[0].vendor);
576                 wsc_registrar.password = (u8 *) conf->ap_pin;
577                 wsc_registrar.password_len = conf->ap_pin ?
578                         os_strlen(conf->ap_pin) : 0;
579                 return &wsc_registrar;
580         }
581 #endif /* CONFIG_WPS */
582
583         while (user) {
584                 if (!phase2 && user->identity == NULL) {
585                         /* Wildcard match */
586                         break;
587                 }
588
589                 if (user->phase2 == !!phase2 && user->wildcard_prefix &&
590                     identity_len >= user->identity_len &&
591                     os_memcmp(user->identity, identity, user->identity_len) ==
592                     0) {
593                         /* Wildcard prefix match */
594                         break;
595                 }
596
597                 if (user->phase2 == !!phase2 &&
598                     user->identity_len == identity_len &&
599                     os_memcmp(user->identity, identity, identity_len) == 0)
600                         break;
601                 user = user->next;
602         }
603
604         return user;
605 }