2 * hostapd / Configuration helper functions
3 * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
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"
26 #include "ap_config.h"
29 static void hostapd_config_free_vlan(struct hostapd_bss_config
*bss
)
31 struct hostapd_vlan
*vlan
, *prev
;
45 void hostapd_config_defaults_bss(struct hostapd_bss_config
*bss
)
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;
52 bss
->auth_algs
= WPA_AUTH_ALG_OPEN
| WPA_AUTH_ALG_SHARED
;
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;
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;
67 bss
->max_num_sta
= MAX_STA_COUNT
;
71 bss
->radius_server_auth_port
= 1812;
72 bss
->ap_max_inactivity
= AP_MAX_INACTIVITY
;
73 bss
->eapol_version
= EAPOL_VERSION
;
75 bss
->max_listen_interval
= 65535;
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 */
90 struct hostapd_config
* hostapd_config_defaults(void)
92 struct hostapd_config
*conf
;
93 struct hostapd_bss_config
*bss
;
95 const int aCWmin
= 15, aCWmax
= 1024;
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 };
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.");
115 bss
->radius
= os_zalloc(sizeof(*bss
->radius
));
116 if (bss
->radius
== NULL
) {
122 hostapd_config_defaults_bss(bss
);
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;
132 for (i
= 0; i
< NUM_TX_QUEUES
; i
++)
133 conf
->tx_queue
[i
].aifs
= -1; /* use hw default */
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
;
140 conf
->ht_capab
= HT_CAP_INFO_SMPS_DISABLED
;
146 int hostapd_mac_comp(const void *a
, const void *b
)
148 return os_memcmp(a
, b
, sizeof(macaddr
));
152 int hostapd_mac_comp_empty(const void *a
)
154 macaddr empty
= { 0 };
155 return os_memcmp(a
, empty
, sizeof(macaddr
));
159 static int hostapd_config_read_wpa_psk(const char *fname
,
160 struct hostapd_ssid
*ssid
)
164 int line
= 0, ret
= 0, len
, ok
;
166 struct hostapd_wpa_psk
*psk
;
171 f
= fopen(fname
, "r");
173 wpa_printf(MSG_ERROR
, "WPA PSK file '%s' not found.", fname
);
177 while (fgets(buf
, sizeof(buf
), f
)) {
183 while (*pos
!= '\0') {
193 if (hwaddr_aton(buf
, addr
)) {
194 wpa_printf(MSG_ERROR
, "Invalid MAC address '%s' on "
195 "line %d in '%s'", buf
, line
, fname
);
200 psk
= os_zalloc(sizeof(*psk
));
202 wpa_printf(MSG_ERROR
, "WPA PSK allocation failed");
206 if (is_zero_ether_addr(addr
))
209 os_memcpy(psk
->addr
, addr
, ETH_ALEN
);
213 wpa_printf(MSG_ERROR
, "No PSK on line %d in '%s'",
222 len
= os_strlen(pos
);
223 if (len
== 64 && hexstr2bin(pos
, psk
->psk
, PMK_LEN
) == 0)
225 else if (len
>= 8 && len
< 64) {
226 pbkdf2_sha1(pos
, ssid
->ssid
, ssid
->ssid_len
,
227 4096, psk
->psk
, PMK_LEN
);
231 wpa_printf(MSG_ERROR
, "Invalid PSK '%s' on line %d in "
232 "'%s'", pos
, line
, fname
);
238 psk
->next
= ssid
->wpa_psk
;
248 static int hostapd_derive_psk(struct hostapd_ssid
*ssid
)
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");
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
);
269 int hostapd_setup_wpa_psk(struct hostapd_bss_config
*conf
)
271 struct hostapd_ssid
*ssid
= &conf
->ssid
;
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");
278 wpa_printf(MSG_DEBUG
, "Deriving WPA PSK based on "
280 if (hostapd_derive_psk(ssid
) < 0)
283 ssid
->wpa_psk
->group
= 1;
286 if (ssid
->wpa_psk_file
) {
287 if (hostapd_config_read_wpa_psk(ssid
->wpa_psk_file
,
296 int hostapd_wep_key_cmp(struct hostapd_wep_keys
*a
, struct hostapd_wep_keys
*b
)
300 if (a
->idx
!= b
->idx
|| a
->default_len
!= b
->default_len
)
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)
310 static void hostapd_config_free_radius(struct hostapd_radius_server
*servers
,
315 for (i
= 0; i
< num_servers
; i
++) {
316 os_free(servers
[i
].shared_secret
);
322 static void hostapd_config_free_eap_user(struct hostapd_eap_user
*user
)
324 os_free(user
->identity
);
325 os_free(user
->password
);
330 static void hostapd_config_free_wep(struct hostapd_wep_keys
*keys
)
333 for (i
= 0; i
< NUM_WEP_KEYS
; i
++) {
334 os_free(keys
->key
[i
]);
340 static void hostapd_config_free_bss(struct hostapd_bss_config
*conf
)
342 struct hostapd_wpa_psk
*psk
, *prev
;
343 struct hostapd_eap_user
*user
, *prev_user
;
348 psk
= conf
->ssid
.wpa_psk
;
355 os_free(conf
->ssid
.wpa_passphrase
);
356 os_free(conf
->ssid
.wpa_psk_file
);
357 #ifdef CONFIG_FULL_DYNAMIC_VLAN
358 os_free(conf
->ssid
.vlan_tagged_interface
);
359 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
361 user
= conf
->eap_user
;
365 hostapd_config_free_eap_user(prev_user
);
368 os_free(conf
->dump_log_name
);
369 os_free(conf
->eap_req_id_text
);
370 os_free(conf
->accept_mac
);
371 os_free(conf
->deny_mac
);
372 os_free(conf
->nas_identifier
);
373 hostapd_config_free_radius(conf
->radius
->auth_servers
,
374 conf
->radius
->num_auth_servers
);
375 hostapd_config_free_radius(conf
->radius
->acct_servers
,
376 conf
->radius
->num_acct_servers
);
377 os_free(conf
->rsn_preauth_interfaces
);
378 os_free(conf
->ctrl_interface
);
379 os_free(conf
->ca_cert
);
380 os_free(conf
->server_cert
);
381 os_free(conf
->private_key
);
382 os_free(conf
->private_key_passwd
);
383 os_free(conf
->dh_file
);
384 os_free(conf
->pac_opaque_encr_key
);
385 os_free(conf
->eap_fast_a_id
);
386 os_free(conf
->eap_fast_a_id_info
);
387 os_free(conf
->eap_sim_db
);
388 os_free(conf
->radius_server_clients
);
389 os_free(conf
->test_socket
);
390 os_free(conf
->radius
);
391 hostapd_config_free_vlan(conf
);
392 if (conf
->ssid
.dyn_vlan_keys
) {
393 struct hostapd_ssid
*ssid
= &conf
->ssid
;
395 for (i
= 0; i
<= ssid
->max_dyn_vlan_keys
; i
++) {
396 if (ssid
->dyn_vlan_keys
[i
] == NULL
)
398 hostapd_config_free_wep(ssid
->dyn_vlan_keys
[i
]);
399 os_free(ssid
->dyn_vlan_keys
[i
]);
401 os_free(ssid
->dyn_vlan_keys
);
402 ssid
->dyn_vlan_keys
= NULL
;
405 #ifdef CONFIG_IEEE80211R
407 struct ft_remote_r0kh
*r0kh
, *r0kh_prev
;
408 struct ft_remote_r1kh
*r1kh
, *r1kh_prev
;
410 r0kh
= conf
->r0kh_list
;
411 conf
->r0kh_list
= NULL
;
418 r1kh
= conf
->r1kh_list
;
419 conf
->r1kh_list
= NULL
;
426 #endif /* CONFIG_IEEE80211R */
429 os_free(conf
->wps_pin_requests
);
430 os_free(conf
->device_name
);
431 os_free(conf
->manufacturer
);
432 os_free(conf
->model_name
);
433 os_free(conf
->model_number
);
434 os_free(conf
->serial_number
);
435 os_free(conf
->device_type
);
436 os_free(conf
->config_methods
);
437 os_free(conf
->ap_pin
);
438 os_free(conf
->extra_cred
);
439 os_free(conf
->ap_settings
);
440 os_free(conf
->upnp_iface
);
441 os_free(conf
->friendly_name
);
442 os_free(conf
->manufacturer_url
);
443 os_free(conf
->model_description
);
444 os_free(conf
->model_url
);
446 #endif /* CONFIG_WPS */
451 * hostapd_config_free - Free hostapd configuration
452 * @conf: Configuration data from hostapd_config_read().
454 void hostapd_config_free(struct hostapd_config
*conf
)
461 for (i
= 0; i
< conf
->num_bss
; i
++)
462 hostapd_config_free_bss(&conf
->bss
[i
]);
464 os_free(conf
->supported_rates
);
465 os_free(conf
->basic_rates
);
472 * hostapd_maclist_found - Find a MAC address from a list
473 * @list: MAC address list
474 * @num_entries: Number of addresses in the list
475 * @addr: Address to search for
476 * @vlan_id: Buffer for returning VLAN ID or %NULL if not needed
477 * Returns: 1 if address is in the list or 0 if not.
479 * Perform a binary search for given MAC address from a pre-sorted list.
481 int hostapd_maclist_found(struct mac_acl_entry
*list
, int num_entries
,
482 const u8
*addr
, int *vlan_id
)
484 int start
, end
, middle
, res
;
487 end
= num_entries
- 1;
489 while (start
<= end
) {
490 middle
= (start
+ end
) / 2;
491 res
= os_memcmp(list
[middle
].addr
, addr
, ETH_ALEN
);
494 *vlan_id
= list
[middle
].vlan_id
;
507 int hostapd_rate_found(int *list
, int rate
)
514 for (i
= 0; list
[i
] >= 0; i
++)
522 const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan
*vlan
, int vlan_id
)
524 struct hostapd_vlan
*v
= vlan
;
526 if (v
->vlan_id
== vlan_id
|| v
->vlan_id
== VLAN_ID_WILDCARD
)
534 const u8
* hostapd_get_psk(const struct hostapd_bss_config
*conf
,
535 const u8
*addr
, const u8
*prev_psk
)
537 struct hostapd_wpa_psk
*psk
;
538 int next_ok
= prev_psk
== NULL
;
540 for (psk
= conf
->ssid
.wpa_psk
; psk
!= NULL
; psk
= psk
->next
) {
542 (psk
->group
|| os_memcmp(psk
->addr
, addr
, ETH_ALEN
) == 0))
545 if (psk
->psk
== prev_psk
)
553 const struct hostapd_eap_user
*
554 hostapd_get_eap_user(const struct hostapd_bss_config
*conf
, const u8
*identity
,
555 size_t identity_len
, int phase2
)
557 struct hostapd_eap_user
*user
= conf
->eap_user
;
560 if (conf
->wps_state
&& identity_len
== WSC_ID_ENROLLEE_LEN
&&
561 os_memcmp(identity
, WSC_ID_ENROLLEE
, WSC_ID_ENROLLEE_LEN
) == 0) {
562 static struct hostapd_eap_user wsc_enrollee
;
563 os_memset(&wsc_enrollee
, 0, sizeof(wsc_enrollee
));
564 wsc_enrollee
.methods
[0].method
= eap_server_get_type(
565 "WSC", &wsc_enrollee
.methods
[0].vendor
);
566 return &wsc_enrollee
;
569 if (conf
->wps_state
&& conf
->ap_pin
&&
570 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
= os_strlen(conf
->ap_pin
);
578 return &wsc_registrar
;
580 #endif /* CONFIG_WPS */
583 if (!phase2
&& user
->identity
== NULL
) {
588 if (user
->phase2
== !!phase2
&& user
->wildcard_prefix
&&
589 identity_len
>= user
->identity_len
&&
590 os_memcmp(user
->identity
, identity
, user
->identity_len
) ==
592 /* Wildcard prefix match */
596 if (user
->phase2
== !!phase2
&&
597 user
->identity_len
== identity_len
&&
598 os_memcmp(user
->identity
, identity
, identity_len
) == 0)