]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/ap/ap_config.c
HE: Verify supported capabilities
[thirdparty/hostap.git] / src / ap / ap_config.c
CommitLineData
6fc6879b 1/*
41d719d6 2 * hostapd / Configuration helper functions
08081ad8 3 * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
6fc6879b 4 *
0f3d578e
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
6fc6879b
JM
7 */
8
6226e38d 9#include "utils/includes.h"
6fc6879b 10
6226e38d 11#include "utils/common.h"
03da66bd 12#include "crypto/sha1.h"
d501c27c 13#include "crypto/tls.h"
6fc6879b 14#include "radius/radius_client.h"
df84268a 15#include "common/ieee802_11_defs.h"
41d719d6 16#include "common/eapol_common.h"
91d91abf 17#include "common/dhcp.h"
03da66bd
JM
18#include "eap_common/eap_wsc_common.h"
19#include "eap_server/eap.h"
6226e38d 20#include "wpa_auth.h"
97234b50 21#include "sta_info.h"
ef721751 22#include "airtime_policy.h"
6226e38d 23#include "ap_config.h"
6fc6879b
JM
24
25
6fc6879b
JM
26static void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
27{
28 struct hostapd_vlan *vlan, *prev;
29
30 vlan = bss->vlan;
31 prev = NULL;
32 while (vlan) {
33 prev = vlan;
34 vlan = vlan->next;
35 os_free(prev);
36 }
37
38 bss->vlan = NULL;
39}
40
41
6f234c1e
JM
42#ifndef DEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES
43#define DEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES 0
44#endif /* DEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES */
45
41d719d6 46void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
6fc6879b 47{
695dbbea
JM
48 dl_list_init(&bss->anqp_elem);
49
6fc6879b
JM
50 bss->logger_syslog_level = HOSTAPD_LEVEL_INFO;
51 bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
52 bss->logger_syslog = (unsigned int) -1;
53 bss->logger_stdout = (unsigned int) -1;
54
55 bss->auth_algs = WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED;
56
57 bss->wep_rekeying_period = 300;
58 /* use key0 in individual key and key1 in broadcast key */
59 bss->broadcast_key_idx_min = 1;
60 bss->broadcast_key_idx_max = 2;
61 bss->eap_reauth_period = 3600;
62
63 bss->wpa_group_rekey = 600;
64 bss->wpa_gmk_rekey = 86400;
41f140d3
GK
65 bss->wpa_group_update_count = 4;
66 bss->wpa_pairwise_update_count = 4;
6f234c1e
JM
67 bss->wpa_disable_eapol_key_retries =
68 DEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES;
6fc6879b
JM
69 bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
70 bss->wpa_pairwise = WPA_CIPHER_TKIP;
71 bss->wpa_group = WPA_CIPHER_TKIP;
72 bss->rsn_pairwise = 0;
73
74 bss->max_num_sta = MAX_STA_COUNT;
75
76 bss->dtim_period = 2;
77
78 bss->radius_server_auth_port = 1812;
7b0f5500 79 bss->eap_sim_db_timeout = 1;
6fc6879b
JM
80 bss->ap_max_inactivity = AP_MAX_INACTIVITY;
81 bss->eapol_version = EAPOL_VERSION;
b0194fe0
JM
82
83 bss->max_listen_interval = 65535;
5d22a1d5 84
df684d82
DH
85 bss->pwd_group = 19; /* ECC: GF(p=256) */
86
5d22a1d5 87#ifdef CONFIG_IEEE80211W
45c94154
JM
88 bss->assoc_sa_query_max_timeout = 1000;
89 bss->assoc_sa_query_retry_timeout = 201;
8dd9f9cd 90 bss->group_mgmt_cipher = WPA_CIPHER_AES_128_CMAC;
5d22a1d5 91#endif /* CONFIG_IEEE80211W */
1e5839e0 92#ifdef EAP_SERVER_FAST
378eae5e
JM
93 /* both anonymous and authenticated provisioning */
94 bss->eap_fast_prov = 3;
a11c90a6
JM
95 bss->pac_key_lifetime = 7 * 24 * 60 * 60;
96 bss->pac_key_refresh_time = 1 * 24 * 60 * 60;
1e5839e0 97#endif /* EAP_SERVER_FAST */
d2da2249
JB
98
99 /* Set to -1 as defaults depends on HT in setup */
100 bss->wmm_enabled = -1;
d7956add 101
4ec1fd8e 102#ifdef CONFIG_IEEE80211R_AP
d7956add 103 bss->ft_over_ds = 1;
3a46cf93
MB
104 bss->rkh_pos_timeout = 86400;
105 bss->rkh_neg_timeout = 60;
106 bss->rkh_pull_timeout = 1000;
107 bss->rkh_pull_retries = 4;
83fe4bd3 108 bss->r0_key_lifetime = 1209600;
4ec1fd8e 109#endif /* CONFIG_IEEE80211R_AP */
bde7ba6c
JM
110
111 bss->radius_das_time_window = 300;
d136c376
JM
112
113 bss->sae_anti_clogging_threshold = 5;
d8b841eb 114 bss->sae_sync = 5;
26bf70e3 115
2977f519
JM
116 bss->gas_frag_limit = 1400;
117
26bf70e3
JM
118#ifdef CONFIG_FILS
119 dl_list_init(&bss->fils_realms);
91d91abf
JM
120 bss->fils_hlp_wait_time = 30;
121 bss->dhcp_server_port = DHCP_SERVER_PORT;
122 bss->dhcp_relay_port = DHCP_SERVER_PORT;
26bf70e3 123#endif /* CONFIG_FILS */
57a2aaca
JM
124
125 bss->broadcast_deauth = 1;
941caed9
JM
126
127#ifdef CONFIG_MBO
128 bss->mbo_cell_data_conn_pref = -1;
129#endif /* CONFIG_MBO */
d501c27c
JM
130
131 /* Disable TLS v1.3 by default for now to avoid interoperability issue.
132 * This can be enabled by default once the implementation has been fully
133 * completed and tested with other implementations. */
134 bss->tls_flags = TLS_CONN_DISABLE_TLSv1_3;
678d8410
JM
135
136 bss->send_probe_response = 1;
6ae04d7b
JM
137
138#ifdef CONFIG_HS20
139 bss->hs20_release = (HS20_VERSION >> 4) + 1;
140#endif /* CONFIG_HS20 */
dd5d325b
SV
141
142 /* Default to strict CRL checking. */
143 bss->check_crl_strict = 1;
6fc6879b
JM
144}
145
146
89111f3b 147struct hostapd_config * hostapd_config_defaults(void)
6fc6879b 148{
d2da2249
JB
149#define ecw2cw(ecw) ((1 << (ecw)) - 1)
150
6fc6879b
JM
151 struct hostapd_config *conf;
152 struct hostapd_bss_config *bss;
594cf8b9 153 const int aCWmin = 4, aCWmax = 10;
3ae0800c 154 const struct hostapd_wmm_ac_params ac_bk =
6fc6879b 155 { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
3ae0800c 156 const struct hostapd_wmm_ac_params ac_be =
6fc6879b 157 { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
3ae0800c 158 const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
f4e3860f 159 { aCWmin - 1, aCWmin, 2, 3008 / 32, 0 };
3ae0800c 160 const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
f4e3860f 161 { aCWmin - 2, aCWmin - 1, 2, 1504 / 32, 0 };
d2da2249
JB
162 const struct hostapd_tx_queue_params txq_bk =
163 { 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 };
164 const struct hostapd_tx_queue_params txq_be =
165 { 3, ecw2cw(aCWmin), 4 * (ecw2cw(aCWmin) + 1) - 1, 0};
166 const struct hostapd_tx_queue_params txq_vi =
167 { 1, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30};
168 const struct hostapd_tx_queue_params txq_vo =
169 { 1, (ecw2cw(aCWmin) + 1) / 4 - 1,
170 (ecw2cw(aCWmin) + 1) / 2 - 1, 15};
171
172#undef ecw2cw
6fc6879b
JM
173
174 conf = os_zalloc(sizeof(*conf));
175 bss = os_zalloc(sizeof(*bss));
176 if (conf == NULL || bss == NULL) {
10656fc2
JM
177 wpa_printf(MSG_ERROR, "Failed to allocate memory for "
178 "configuration data.");
6fc6879b
JM
179 os_free(conf);
180 os_free(bss);
181 return NULL;
182 }
ebd79f07
JM
183 conf->bss = os_calloc(1, sizeof(struct hostapd_bss_config *));
184 if (conf->bss == NULL) {
185 os_free(conf);
186 os_free(bss);
187 return NULL;
188 }
189 conf->bss[0] = bss;
6fc6879b 190
6fc6879b
JM
191 bss->radius = os_zalloc(sizeof(*bss->radius));
192 if (bss->radius == NULL) {
04c366cb 193 os_free(conf->bss);
6fc6879b
JM
194 os_free(conf);
195 os_free(bss);
196 return NULL;
197 }
198
199 hostapd_config_defaults_bss(bss);
200
201 conf->num_bss = 1;
6fc6879b
JM
202
203 conf->beacon_int = 100;
bf0021ed
JM
204 conf->rts_threshold = -2; /* use driver default: 2347 */
205 conf->fragm_threshold = -2; /* user driver default: 2346 */
e0392f82
S
206 /* Set to invalid value means do not add Power Constraint IE */
207 conf->local_pwr_constraint = -1;
6fc6879b 208
3ae0800c
JM
209 conf->wmm_ac_params[0] = ac_be;
210 conf->wmm_ac_params[1] = ac_bk;
211 conf->wmm_ac_params[2] = ac_vi;
212 conf->wmm_ac_params[3] = ac_vo;
6fc6879b 213
d2da2249
JB
214 conf->tx_queue[0] = txq_vo;
215 conf->tx_queue[1] = txq_vi;
216 conf->tx_queue[2] = txq_be;
217 conf->tx_queue[3] = txq_bk;
218
fc14f567 219 conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED;
de9289c8 220
f1b44874
SE
221 conf->ap_table_max_size = 255;
222 conf->ap_table_expiration_time = 60;
a65a9b8d 223 conf->track_sta_max_age = 180;
f1b44874 224
c2aff6b1 225#ifdef CONFIG_TESTING_OPTIONS
06df2aa6
JM
226 conf->ignore_probe_probability = 0.0;
227 conf->ignore_auth_probability = 0.0;
228 conf->ignore_assoc_probability = 0.0;
229 conf->ignore_reassoc_probability = 0.0;
230 conf->corrupt_gtk_rekey_mic_probability = 0.0;
2b6e1216 231 conf->ecsa_ie_only = 0;
c2aff6b1
JB
232#endif /* CONFIG_TESTING_OPTIONS */
233
857d9422
MM
234 conf->acs = 0;
235 conf->acs_ch_list.num = 0;
50f4f2a0
MK
236#ifdef CONFIG_ACS
237 conf->acs_num_scans = 5;
238#endif /* CONFIG_ACS */
239
83f30fab
JC
240#ifdef CONFIG_IEEE80211AX
241 conf->he_op.he_rts_threshold = HE_OPERATION_RTS_THRESHOLD_MASK >>
242 HE_OPERATION_RTS_THRESHOLD_OFFSET;
243#endif /* CONFIG_IEEE80211AX */
244
ff936bc7
JM
245 /* The third octet of the country string uses an ASCII space character
246 * by default to indicate that the regulations encompass all
247 * environments for the current frequency band in the country. */
248 conf->country[2] = ' ';
249
076f1ea1
BL
250 conf->rssi_reject_assoc_rssi = 0;
251 conf->rssi_reject_assoc_timeout = 30;
252
ef721751
THJ
253#ifdef CONFIG_AIRTIME_POLICY
254 conf->airtime_update_interval = AIRTIME_DEFAULT_UPDATE_INTERVAL;
255#endif /* CONFIG_AIRTIME_POLICY */
256
6fc6879b
JM
257 return conf;
258}
259
260
261int hostapd_mac_comp(const void *a, const void *b)
262{
263 return os_memcmp(a, b, sizeof(macaddr));
264}
265
266
6fc6879b
JM
267static int hostapd_config_read_wpa_psk(const char *fname,
268 struct hostapd_ssid *ssid)
269{
270 FILE *f;
271 char buf[128], *pos;
ec5c39a5
MK
272 const char *keyid;
273 char *context;
274 char *context2;
275 char *token;
276 char *name;
277 char *value;
6fc6879b
JM
278 int line = 0, ret = 0, len, ok;
279 u8 addr[ETH_ALEN];
280 struct hostapd_wpa_psk *psk;
281
282 if (!fname)
283 return 0;
284
285 f = fopen(fname, "r");
286 if (!f) {
10656fc2 287 wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname);
6fc6879b
JM
288 return -1;
289 }
290
291 while (fgets(buf, sizeof(buf), f)) {
dbfa691d
JM
292 int vlan_id = 0;
293
6fc6879b
JM
294 line++;
295
296 if (buf[0] == '#')
297 continue;
298 pos = buf;
299 while (*pos != '\0') {
300 if (*pos == '\n') {
301 *pos = '\0';
302 break;
303 }
304 pos++;
305 }
306 if (buf[0] == '\0')
307 continue;
308
ec5c39a5
MK
309 context = NULL;
310 keyid = NULL;
311 while ((token = str_token(buf, " ", &context))) {
312 if (!os_strchr(token, '='))
313 break;
314 context2 = NULL;
315 name = str_token(token, "=", &context2);
2fae58fd
JM
316 if (!name)
317 break;
ec5c39a5
MK
318 value = str_token(token, "", &context2);
319 if (!value)
320 value = "";
321 if (!os_strcmp(name, "keyid")) {
322 keyid = value;
dbfa691d
JM
323 } else if (!os_strcmp(name, "vlanid")) {
324 vlan_id = atoi(value);
ec5c39a5
MK
325 } else {
326 wpa_printf(MSG_ERROR,
327 "Unrecognized '%s=%s' on line %d in '%s'",
328 name, value, line, fname);
329 ret = -1;
330 break;
331 }
332 }
333
334 if (ret == -1)
335 break;
336
337 if (!token)
338 token = "";
339 if (hwaddr_aton(token, addr)) {
10656fc2 340 wpa_printf(MSG_ERROR, "Invalid MAC address '%s' on "
ec5c39a5 341 "line %d in '%s'", token, line, fname);
6fc6879b
JM
342 ret = -1;
343 break;
344 }
345
346 psk = os_zalloc(sizeof(*psk));
347 if (psk == NULL) {
10656fc2 348 wpa_printf(MSG_ERROR, "WPA PSK allocation failed");
6fc6879b
JM
349 ret = -1;
350 break;
351 }
dbfa691d 352 psk->vlan_id = vlan_id;
a8e16edc 353 if (is_zero_ether_addr(addr))
6fc6879b
JM
354 psk->group = 1;
355 else
356 os_memcpy(psk->addr, addr, ETH_ALEN);
357
ec5c39a5
MK
358 pos = str_token(buf, "", &context);
359 if (!pos) {
10656fc2
JM
360 wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'",
361 line, fname);
6fc6879b
JM
362 os_free(psk);
363 ret = -1;
364 break;
365 }
6fc6879b
JM
366
367 ok = 0;
368 len = os_strlen(pos);
369 if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
370 ok = 1;
371 else if (len >= 8 && len < 64) {
372 pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
373 4096, psk->psk, PMK_LEN);
374 ok = 1;
375 }
376 if (!ok) {
10656fc2
JM
377 wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in "
378 "'%s'", pos, line, fname);
6fc6879b
JM
379 os_free(psk);
380 ret = -1;
381 break;
382 }
383
ec5c39a5
MK
384 if (keyid) {
385 len = os_strlcpy(psk->keyid, keyid, sizeof(psk->keyid));
386 if ((size_t) len >= sizeof(psk->keyid)) {
387 wpa_printf(MSG_ERROR,
388 "PSK keyid too long on line %d in '%s'",
389 line, fname);
390 os_free(psk);
391 ret = -1;
392 break;
393 }
394 }
395
6fc6879b
JM
396 psk->next = ssid->wpa_psk;
397 ssid->wpa_psk = psk;
398 }
399
400 fclose(f);
401
402 return ret;
403}
404
405
0ae687bd
JM
406static int hostapd_derive_psk(struct hostapd_ssid *ssid)
407{
408 ssid->wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
409 if (ssid->wpa_psk == NULL) {
410 wpa_printf(MSG_ERROR, "Unable to alloc space for PSK");
411 return -1;
412 }
413 wpa_hexdump_ascii(MSG_DEBUG, "SSID",
414 (u8 *) ssid->ssid, ssid->ssid_len);
415 wpa_hexdump_ascii_key(MSG_DEBUG, "PSK (ASCII passphrase)",
416 (u8 *) ssid->wpa_passphrase,
417 os_strlen(ssid->wpa_passphrase));
418 pbkdf2_sha1(ssid->wpa_passphrase,
419 ssid->ssid, ssid->ssid_len,
420 4096, ssid->wpa_psk->psk, PMK_LEN);
421 wpa_hexdump_key(MSG_DEBUG, "PSK (from passphrase)",
422 ssid->wpa_psk->psk, PMK_LEN);
423 return 0;
424}
425
426
6fc6879b
JM
427int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf)
428{
429 struct hostapd_ssid *ssid = &conf->ssid;
430
431 if (ssid->wpa_passphrase != NULL) {
432 if (ssid->wpa_psk != NULL) {
0ae687bd
JM
433 wpa_printf(MSG_DEBUG, "Using pre-configured WPA PSK "
434 "instead of passphrase");
435 } else {
436 wpa_printf(MSG_DEBUG, "Deriving WPA PSK based on "
437 "passphrase");
438 if (hostapd_derive_psk(ssid) < 0)
439 return -1;
6fc6879b 440 }
6fc6879b 441 ssid->wpa_psk->group = 1;
6fc6879b
JM
442 }
443
34e29dfd 444 return hostapd_config_read_wpa_psk(ssid->wpa_psk_file, &conf->ssid);
6fc6879b
JM
445}
446
447
6fc6879b
JM
448static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
449 int num_servers)
450{
451 int i;
452
453 for (i = 0; i < num_servers; i++) {
454 os_free(servers[i].shared_secret);
455 }
456 os_free(servers);
457}
458
459
af35e7af
JM
460struct hostapd_radius_attr *
461hostapd_config_get_radius_attr(struct hostapd_radius_attr *attr, u8 type)
462{
463 for (; attr; attr = attr->next) {
464 if (attr->type == type)
465 return attr;
466 }
467 return NULL;
468}
469
470
471static void hostapd_config_free_radius_attr(struct hostapd_radius_attr *attr)
472{
473 struct hostapd_radius_attr *prev;
474
475 while (attr) {
476 prev = attr;
477 attr = attr->next;
478 wpabuf_free(prev->val);
479 os_free(prev);
480 }
481}
482
483
d0ee16ed 484void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
6fc6879b 485{
d0ee16ed 486 hostapd_config_free_radius_attr(user->accept_attr);
6fc6879b 487 os_free(user->identity);
b7175b4d 488 bin_clear_free(user->password, user->password_len);
d52ead3d 489 bin_clear_free(user->salt, user->salt_len);
6fc6879b
JM
490 os_free(user);
491}
492
493
78022c83
JM
494void hostapd_config_free_eap_users(struct hostapd_eap_user *user)
495{
496 struct hostapd_eap_user *prev_user;
497
498 while (user) {
499 prev_user = user;
500 user = user->next;
501 hostapd_config_free_eap_user(prev_user);
502 }
503}
504
505
6fc6879b
JM
506static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
507{
508 int i;
509 for (i = 0; i < NUM_WEP_KEYS; i++) {
b7175b4d 510 bin_clear_free(keys->key[i], keys->len[i]);
6fc6879b
JM
511 keys->key[i] = NULL;
512 }
513}
514
515
891dfb33
ST
516void hostapd_config_clear_wpa_psk(struct hostapd_wpa_psk **l)
517{
518 struct hostapd_wpa_psk *psk, *tmp;
519
520 for (psk = *l; psk;) {
521 tmp = psk;
522 psk = psk->next;
523 bin_clear_free(tmp, sizeof(*tmp));
524 }
525 *l = NULL;
526}
527
528
695dbbea
JM
529static void hostapd_config_free_anqp_elem(struct hostapd_bss_config *conf)
530{
531 struct anqp_element *elem;
532
533 while ((elem = dl_list_first(&conf->anqp_elem, struct anqp_element,
534 list))) {
535 dl_list_del(&elem->list);
536 wpabuf_free(elem->payload);
537 os_free(elem);
538 }
539}
540
541
26bf70e3
JM
542static void hostapd_config_free_fils_realms(struct hostapd_bss_config *conf)
543{
544#ifdef CONFIG_FILS
545 struct fils_realm *realm;
546
547 while ((realm = dl_list_first(&conf->fils_realms, struct fils_realm,
548 list))) {
549 dl_list_del(&realm->list);
550 os_free(realm);
551 }
552#endif /* CONFIG_FILS */
553}
554
555
9be19d0b
JM
556static void hostapd_config_free_sae_passwords(struct hostapd_bss_config *conf)
557{
558 struct sae_password_entry *pw, *tmp;
559
560 pw = conf->sae_passwords;
561 conf->sae_passwords = NULL;
562 while (pw) {
563 tmp = pw;
564 pw = pw->next;
565 str_clear_free(tmp->password);
566 os_free(tmp->identifier);
567 os_free(tmp);
568 }
569}
570
571
e00f780e
JM
572#ifdef CONFIG_DPP2
573static void hostapd_dpp_controller_conf_free(struct dpp_controller_conf *conf)
574{
575 struct dpp_controller_conf *prev;
576
577 while (conf) {
578 prev = conf;
579 conf = conf->next;
580 os_free(prev);
581 }
582}
583#endif /* CONFIG_DPP2 */
584
585
55920658 586void hostapd_config_free_bss(struct hostapd_bss_config *conf)
6fc6879b 587{
6fc6879b
JM
588 if (conf == NULL)
589 return;
590
891dfb33 591 hostapd_config_clear_wpa_psk(&conf->ssid.wpa_psk);
6fc6879b 592
b7175b4d 593 str_clear_free(conf->ssid.wpa_passphrase);
6fc6879b 594 os_free(conf->ssid.wpa_psk_file);
43dd46b3 595 hostapd_config_free_wep(&conf->ssid.wep);
6fc6879b
JM
596#ifdef CONFIG_FULL_DYNAMIC_VLAN
597 os_free(conf->ssid.vlan_tagged_interface);
598#endif /* CONFIG_FULL_DYNAMIC_VLAN */
599
78022c83 600 hostapd_config_free_eap_users(conf->eap_user);
ee431d77 601 os_free(conf->eap_user_sqlite);
6fc6879b 602
6fc6879b 603 os_free(conf->eap_req_id_text);
2a5156a6 604 os_free(conf->erp_domain);
6fc6879b
JM
605 os_free(conf->accept_mac);
606 os_free(conf->deny_mac);
607 os_free(conf->nas_identifier);
5afaa067
JM
608 if (conf->radius) {
609 hostapd_config_free_radius(conf->radius->auth_servers,
610 conf->radius->num_auth_servers);
611 hostapd_config_free_radius(conf->radius->acct_servers,
612 conf->radius->num_acct_servers);
613 }
af35e7af
JM
614 hostapd_config_free_radius_attr(conf->radius_auth_req_attr);
615 hostapd_config_free_radius_attr(conf->radius_acct_req_attr);
6fc6879b
JM
616 os_free(conf->rsn_preauth_interfaces);
617 os_free(conf->ctrl_interface);
618 os_free(conf->ca_cert);
619 os_free(conf->server_cert);
620 os_free(conf->private_key);
621 os_free(conf->private_key_passwd);
841205a1 622 os_free(conf->check_cert_subject);
080585c0 623 os_free(conf->ocsp_stapling_response);
5addb0df 624 os_free(conf->ocsp_stapling_response_multi);
6fc6879b 625 os_free(conf->dh_file);
f8995f8f 626 os_free(conf->openssl_ciphers);
d01203ca 627 os_free(conf->openssl_ecdh_curves);
6fc6879b
JM
628 os_free(conf->pac_opaque_encr_key);
629 os_free(conf->eap_fast_a_id);
2d867244 630 os_free(conf->eap_fast_a_id_info);
6fc6879b
JM
631 os_free(conf->eap_sim_db);
632 os_free(conf->radius_server_clients);
6fc6879b 633 os_free(conf->radius);
b031338c 634 os_free(conf->radius_das_shared_secret);
6fc6879b 635 hostapd_config_free_vlan(conf);
39b97072
JM
636 os_free(conf->time_zone);
637
4ec1fd8e 638#ifdef CONFIG_IEEE80211R_AP
6fc6879b
JM
639 {
640 struct ft_remote_r0kh *r0kh, *r0kh_prev;
641 struct ft_remote_r1kh *r1kh, *r1kh_prev;
642
643 r0kh = conf->r0kh_list;
644 conf->r0kh_list = NULL;
645 while (r0kh) {
646 r0kh_prev = r0kh;
647 r0kh = r0kh->next;
648 os_free(r0kh_prev);
649 }
650
651 r1kh = conf->r1kh_list;
652 conf->r1kh_list = NULL;
653 while (r1kh) {
654 r1kh_prev = r1kh;
655 r1kh = r1kh->next;
656 os_free(r1kh_prev);
657 }
658 }
4ec1fd8e 659#endif /* CONFIG_IEEE80211R_AP */
ad08c363
JM
660
661#ifdef CONFIG_WPS
662 os_free(conf->wps_pin_requests);
663 os_free(conf->device_name);
664 os_free(conf->manufacturer);
665 os_free(conf->model_name);
666 os_free(conf->model_number);
667 os_free(conf->serial_number);
ad08c363
JM
668 os_free(conf->config_methods);
669 os_free(conf->ap_pin);
62966253 670 os_free(conf->extra_cred);
4c29cae9 671 os_free(conf->ap_settings);
66819b07
DL
672 hostapd_config_clear_wpa_psk(&conf->multi_ap_backhaul_ssid.wpa_psk);
673 str_clear_free(conf->multi_ap_backhaul_ssid.wpa_passphrase);
f620268f
JM
674 os_free(conf->upnp_iface);
675 os_free(conf->friendly_name);
676 os_free(conf->manufacturer_url);
677 os_free(conf->model_description);
678 os_free(conf->model_url);
679 os_free(conf->upc);
8509fb5c
JM
680 {
681 unsigned int i;
682
683 for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
684 wpabuf_free(conf->wps_vendor_ext[i]);
685 }
ffdaa05a
JM
686 wpabuf_free(conf->wps_nfc_dh_pubkey);
687 wpabuf_free(conf->wps_nfc_dh_privkey);
688 wpabuf_free(conf->wps_nfc_dev_pw);
ad08c363 689#endif /* CONFIG_WPS */
4b2a77ab
JM
690
691 os_free(conf->roaming_consortium);
648cc711 692 os_free(conf->venue_name);
7e1d3ee9 693 os_free(conf->venue_url);
8047b186 694 os_free(conf->nai_realm_data);
550a3958 695 os_free(conf->network_auth_type);
7515adb2 696 os_free(conf->anqp_3gpp_cell_net);
26fac8b6 697 os_free(conf->domain_name);
695dbbea 698 hostapd_config_free_anqp_elem(conf);
505a3694
JM
699
700#ifdef CONFIG_RADIUS_TEST
701 os_free(conf->dump_msk_file);
702#endif /* CONFIG_RADIUS_TEST */
df5934f1
JK
703
704#ifdef CONFIG_HS20
a9277e85 705 os_free(conf->hs20_oper_friendly_name);
4065a309 706 os_free(conf->hs20_wan_metrics);
5ccc54aa 707 os_free(conf->hs20_connection_capability);
df5934f1 708 os_free(conf->hs20_operating_class);
f7bd7a01 709 os_free(conf->hs20_icons);
ae6d15c7
JM
710 if (conf->hs20_osu_providers) {
711 size_t i;
712 for (i = 0; i < conf->hs20_osu_providers_count; i++) {
713 struct hs20_osu_provider *p;
714 size_t j;
715 p = &conf->hs20_osu_providers[i];
716 os_free(p->friendly_name);
717 os_free(p->server_uri);
718 os_free(p->method_list);
719 for (j = 0; j < p->icons_count; j++)
720 os_free(p->icons[j]);
721 os_free(p->icons);
722 os_free(p->osu_nai);
cad810a9 723 os_free(p->osu_nai2);
ae6d15c7
JM
724 os_free(p->service_desc);
725 }
726 os_free(conf->hs20_osu_providers);
727 }
0e450db2
JM
728 if (conf->hs20_operator_icon) {
729 size_t i;
730
731 for (i = 0; i < conf->hs20_operator_icon_count; i++)
732 os_free(conf->hs20_operator_icon[i]);
733 os_free(conf->hs20_operator_icon);
734 }
8d2a9921 735 os_free(conf->subscr_remediation_url);
7bd8c76a 736 os_free(conf->hs20_sim_provisioning_url);
6cb8f4f3 737 os_free(conf->t_c_filename);
8760b984 738 os_free(conf->t_c_server_url);
df5934f1 739#endif /* CONFIG_HS20 */
b52f084c
JM
740
741 wpabuf_free(conf->vendor_elements);
a9112270 742 wpabuf_free(conf->assocresp_elements);
625f202a
JM
743
744 os_free(conf->sae_groups);
91cc34bf
JM
745#ifdef CONFIG_OWE
746 os_free(conf->owe_groups);
747#endif /* CONFIG_OWE */
67fe933d 748
88cb27c7
DS
749 os_free(conf->wowlan_triggers);
750
67fe933d 751 os_free(conf->server_id);
ebd79f07 752
bc02843e
JM
753#ifdef CONFIG_TESTING_OPTIONS
754 wpabuf_free(conf->own_ie_override);
3648d8a1 755 wpabuf_free(conf->sae_commit_override);
bc02843e
JM
756#endif /* CONFIG_TESTING_OPTIONS */
757
964f64e2 758 os_free(conf->no_probe_resp_if_seen_on);
0e2412d0 759 os_free(conf->no_auth_if_seen_on);
964f64e2 760
26bf70e3
JM
761 hostapd_config_free_fils_realms(conf);
762
56c75495
JM
763#ifdef CONFIG_DPP
764 os_free(conf->dpp_connector);
765 wpabuf_free(conf->dpp_netaccesskey);
766 wpabuf_free(conf->dpp_csign);
e00f780e
JM
767#ifdef CONFIG_DPP2
768 hostapd_dpp_controller_conf_free(conf->dpp_controller);
769#endif /* CONFIG_DPP2 */
56c75495
JM
770#endif /* CONFIG_DPP */
771
9be19d0b 772 hostapd_config_free_sae_passwords(conf);
2377c1ca 773
ef721751
THJ
774#ifdef CONFIG_AIRTIME_POLICY
775 {
776 struct airtime_sta_weight *wt, *wt_prev;
777
778 wt = conf->airtime_weight_list;
779 conf->airtime_weight_list = NULL;
780 while (wt) {
781 wt_prev = wt;
782 wt = wt->next;
783 os_free(wt_prev);
784 }
785 }
786#endif /* CONFIG_AIRTIME_POLICY */
787
ebd79f07 788 os_free(conf);
6fc6879b
JM
789}
790
791
1c6e69cc
JM
792/**
793 * hostapd_config_free - Free hostapd configuration
794 * @conf: Configuration data from hostapd_config_read().
795 */
6fc6879b
JM
796void hostapd_config_free(struct hostapd_config *conf)
797{
798 size_t i;
799
800 if (conf == NULL)
801 return;
802
803 for (i = 0; i < conf->num_bss; i++)
ebd79f07 804 hostapd_config_free_bss(conf->bss[i]);
6fc6879b 805 os_free(conf->bss);
79d6c85f
JM
806 os_free(conf->supported_rates);
807 os_free(conf->basic_rates);
857d9422 808 os_free(conf->acs_ch_list.range);
0ecff8d7 809 os_free(conf->driver_params);
68fa00c3
JM
810#ifdef CONFIG_ACS
811 os_free(conf->acs_chan_bias);
812#endif /* CONFIG_ACS */
74e982d8
DS
813 wpabuf_free(conf->lci);
814 wpabuf_free(conf->civic);
6fc6879b
JM
815
816 os_free(conf);
817}
818
819
1c6e69cc
JM
820/**
821 * hostapd_maclist_found - Find a MAC address from a list
822 * @list: MAC address list
823 * @num_entries: Number of addresses in the list
824 * @addr: Address to search for
825 * @vlan_id: Buffer for returning VLAN ID or %NULL if not needed
826 * Returns: 1 if address is in the list or 0 if not.
827 *
828 * Perform a binary search for given MAC address from a pre-sorted list.
829 */
271d2830 830int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
1889af2e 831 const u8 *addr, struct vlan_description *vlan_id)
6fc6879b
JM
832{
833 int start, end, middle, res;
834
835 start = 0;
836 end = num_entries - 1;
837
838 while (start <= end) {
839 middle = (start + end) / 2;
271d2830
JM
840 res = os_memcmp(list[middle].addr, addr, ETH_ALEN);
841 if (res == 0) {
842 if (vlan_id)
843 *vlan_id = list[middle].vlan_id;
6fc6879b 844 return 1;
271d2830 845 }
6fc6879b
JM
846 if (res < 0)
847 start = middle + 1;
848 else
849 end = middle - 1;
850 }
851
852 return 0;
853}
854
855
856int hostapd_rate_found(int *list, int rate)
857{
858 int i;
859
860 if (list == NULL)
861 return 0;
862
863 for (i = 0; list[i] >= 0; i++)
864 if (list[i] == rate)
865 return 1;
866
867 return 0;
868}
869
870
1889af2e
MB
871int hostapd_vlan_valid(struct hostapd_vlan *vlan,
872 struct vlan_description *vlan_desc)
6fc6879b
JM
873{
874 struct hostapd_vlan *v = vlan;
8e44c192 875 int i;
1889af2e 876
8e44c192 877 if (!vlan_desc->notempty || vlan_desc->untagged < 0 ||
1889af2e
MB
878 vlan_desc->untagged > MAX_VLAN_ID)
879 return 0;
8e44c192
MB
880 for (i = 0; i < MAX_NUM_TAGGED_VLAN; i++) {
881 if (vlan_desc->tagged[i] < 0 ||
882 vlan_desc->tagged[i] > MAX_VLAN_ID)
883 return 0;
884 }
885 if (!vlan_desc->untagged && !vlan_desc->tagged[0])
886 return 0;
1889af2e 887
6fc6879b 888 while (v) {
1889af2e
MB
889 if (!vlan_compare(&v->vlan_desc, vlan_desc) ||
890 v->vlan_id == VLAN_ID_WILDCARD)
80ebfd95
MB
891 return 1;
892 v = v->next;
893 }
894 return 0;
895}
896
897
898const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
899{
900 struct hostapd_vlan *v = vlan;
901 while (v) {
902 if (v->vlan_id == vlan_id)
6fc6879b
JM
903 return v->ifname;
904 v = v->next;
905 }
906 return NULL;
907}
908
909
910const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
759fd76b 911 const u8 *addr, const u8 *p2p_dev_addr,
dbfa691d 912 const u8 *prev_psk, int *vlan_id)
6fc6879b
JM
913{
914 struct hostapd_wpa_psk *psk;
915 int next_ok = prev_psk == NULL;
916
dbfa691d
JM
917 if (vlan_id)
918 *vlan_id = 0;
919
dc87541e 920 if (p2p_dev_addr && !is_zero_ether_addr(p2p_dev_addr)) {
759fd76b
JM
921 wpa_printf(MSG_DEBUG, "Searching a PSK for " MACSTR
922 " p2p_dev_addr=" MACSTR " prev_psk=%p",
923 MAC2STR(addr), MAC2STR(p2p_dev_addr), prev_psk);
dc87541e 924 addr = NULL; /* Use P2P Device Address for matching */
759fd76b
JM
925 } else {
926 wpa_printf(MSG_DEBUG, "Searching a PSK for " MACSTR
927 " prev_psk=%p",
928 MAC2STR(addr), prev_psk);
929 }
930
6fc6879b
JM
931 for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) {
932 if (next_ok &&
759fd76b
JM
933 (psk->group ||
934 (addr && os_memcmp(psk->addr, addr, ETH_ALEN) == 0) ||
935 (!addr && p2p_dev_addr &&
936 os_memcmp(psk->p2p_dev_addr, p2p_dev_addr, ETH_ALEN) ==
dbfa691d
JM
937 0))) {
938 if (vlan_id)
939 *vlan_id = psk->vlan_id;
6fc6879b 940 return psk->psk;
dbfa691d 941 }
6fc6879b
JM
942
943 if (psk->psk == prev_psk)
944 next_ok = 1;
945 }
946
947 return NULL;
948}
eff0fd1e
JM
949
950
951static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
08081ad8
JM
952 struct hostapd_config *conf,
953 int full_config)
eff0fd1e 954{
08081ad8 955 if (full_config && bss->ieee802_1x && !bss->eap_server &&
eff0fd1e
JM
956 !bss->radius->auth_servers) {
957 wpa_printf(MSG_ERROR, "Invalid IEEE 802.1X configuration (no "
958 "EAP authenticator configured).");
959 return -1;
960 }
961
962 if (bss->wpa) {
963 int wep, i;
964
965 wep = bss->default_wep_key_len > 0 ||
966 bss->individual_wep_key_len > 0;
967 for (i = 0; i < NUM_WEP_KEYS; i++) {
968 if (bss->ssid.wep.keys_set) {
969 wep = 1;
970 break;
971 }
972 }
973
974 if (wep) {
975 wpa_printf(MSG_ERROR, "WEP configuration in a WPA network is not supported");
976 return -1;
977 }
978 }
979
08081ad8
JM
980 if (full_config && bss->wpa &&
981 bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
eff0fd1e
JM
982 bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
983 wpa_printf(MSG_ERROR, "WPA-PSK using RADIUS enabled, but no "
984 "RADIUS checking (macaddr_acl=2) enabled.");
985 return -1;
986 }
987
08081ad8 988 if (full_config && bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
eff0fd1e
JM
989 bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
990 bss->ssid.wpa_psk_file == NULL &&
991 (bss->wpa_psk_radius != PSK_RADIUS_REQUIRED ||
992 bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH)) {
993 wpa_printf(MSG_ERROR, "WPA-PSK enabled, but PSK or passphrase "
994 "is not configured.");
995 return -1;
996 }
997
902c07a7 998 if (full_config && !is_zero_ether_addr(bss->bssid)) {
eff0fd1e
JM
999 size_t i;
1000
1001 for (i = 0; i < conf->num_bss; i++) {
1002 if (conf->bss[i] != bss &&
1003 (hostapd_mac_comp(conf->bss[i]->bssid,
1004 bss->bssid) == 0)) {
1005 wpa_printf(MSG_ERROR, "Duplicate BSSID " MACSTR
1006 " on interface '%s' and '%s'.",
1007 MAC2STR(bss->bssid),
1008 conf->bss[i]->iface, bss->iface);
1009 return -1;
1010 }
1011 }
1012 }
1013
4ec1fd8e 1014#ifdef CONFIG_IEEE80211R_AP
08081ad8 1015 if (full_config && wpa_key_mgmt_ft(bss->wpa_key_mgmt) &&
eff0fd1e
JM
1016 (bss->nas_identifier == NULL ||
1017 os_strlen(bss->nas_identifier) < 1 ||
1018 os_strlen(bss->nas_identifier) > FT_R0KH_ID_MAX_LEN)) {
1019 wpa_printf(MSG_ERROR, "FT (IEEE 802.11r) requires "
1020 "nas_identifier to be configured as a 1..48 octet "
1021 "string");
1022 return -1;
1023 }
4ec1fd8e 1024#endif /* CONFIG_IEEE80211R_AP */
eff0fd1e
JM
1025
1026#ifdef CONFIG_IEEE80211N
08081ad8
JM
1027 if (full_config && conf->ieee80211n &&
1028 conf->hw_mode == HOSTAPD_MODE_IEEE80211B) {
eff0fd1e
JM
1029 bss->disable_11n = 1;
1030 wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) in 11b mode is not "
8c6f4a5a 1031 "allowed, disabling HT capabilities");
eff0fd1e
JM
1032 }
1033
08081ad8 1034 if (full_config && conf->ieee80211n &&
eff0fd1e
JM
1035 bss->ssid.security_policy == SECURITY_STATIC_WEP) {
1036 bss->disable_11n = 1;
1037 wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WEP is not "
1038 "allowed, disabling HT capabilities");
1039 }
1040
08081ad8 1041 if (full_config && conf->ieee80211n && bss->wpa &&
eff0fd1e 1042 !(bss->wpa_pairwise & WPA_CIPHER_CCMP) &&
30675c34
JM
1043 !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
1044 WPA_CIPHER_CCMP_256 | WPA_CIPHER_GCMP_256)))
1045 {
eff0fd1e
JM
1046 bss->disable_11n = 1;
1047 wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WPA/WPA2 "
1048 "requires CCMP/GCMP to be enabled, disabling HT "
1049 "capabilities");
1050 }
1051#endif /* CONFIG_IEEE80211N */
1052
551817a5
WG
1053#ifdef CONFIG_IEEE80211AC
1054 if (full_config && conf->ieee80211ac &&
1055 bss->ssid.security_policy == SECURITY_STATIC_WEP) {
1056 bss->disable_11ac = 1;
1057 wpa_printf(MSG_ERROR,
1058 "VHT (IEEE 802.11ac) with WEP is not allowed, disabling VHT capabilities");
1059 }
59d7cff7
FM
1060
1061 if (full_config && conf->ieee80211ac && bss->wpa &&
1062 !(bss->wpa_pairwise & WPA_CIPHER_CCMP) &&
1063 !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
1064 WPA_CIPHER_CCMP_256 | WPA_CIPHER_GCMP_256)))
1065 {
1066 bss->disable_11ac = 1;
1067 wpa_printf(MSG_ERROR,
1068 "VHT (IEEE 802.11ac) with WPA/WPA2 requires CCMP/GCMP to be enabled, disabling VHT capabilities");
1069 }
551817a5
WG
1070#endif /* CONFIG_IEEE80211AC */
1071
c201f93a 1072#ifdef CONFIG_WPS
08081ad8 1073 if (full_config && bss->wps_state && bss->ignore_broadcast_ssid) {
eff0fd1e
JM
1074 wpa_printf(MSG_INFO, "WPS: ignore_broadcast_ssid "
1075 "configuration forced WPS to be disabled");
1076 bss->wps_state = 0;
1077 }
1078
08081ad8
JM
1079 if (full_config && bss->wps_state &&
1080 bss->ssid.wep.keys_set && bss->wpa == 0) {
eff0fd1e
JM
1081 wpa_printf(MSG_INFO, "WPS: WEP configuration forced WPS to be "
1082 "disabled");
1083 bss->wps_state = 0;
1084 }
1085
08081ad8 1086 if (full_config && bss->wps_state && bss->wpa &&
eff0fd1e 1087 (!(bss->wpa & 2) ||
a2660890
SSG
1088 !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
1089 WPA_CIPHER_CCMP_256 |
1090 WPA_CIPHER_GCMP_256)))) {
eff0fd1e 1091 wpa_printf(MSG_INFO, "WPS: WPA/TKIP configuration without "
01a02593 1092 "WPA2/CCMP/GCMP forced WPS to be disabled");
eff0fd1e
JM
1093 bss->wps_state = 0;
1094 }
c201f93a 1095#endif /* CONFIG_WPS */
eff0fd1e
JM
1096
1097#ifdef CONFIG_HS20
08081ad8 1098 if (full_config && bss->hs20 &&
eff0fd1e 1099 (!(bss->wpa & 2) ||
30675c34
JM
1100 !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
1101 WPA_CIPHER_CCMP_256 |
1102 WPA_CIPHER_GCMP_256)))) {
eff0fd1e
JM
1103 wpa_printf(MSG_ERROR, "HS 2.0: WPA2-Enterprise/CCMP "
1104 "configuration is required for Hotspot 2.0 "
1105 "functionality");
1106 return -1;
1107 }
1108#endif /* CONFIG_HS20 */
1109
4c572281
JM
1110#ifdef CONFIG_MBO
1111 if (full_config && bss->mbo_enabled && (bss->wpa & 2) &&
1112 bss->ieee80211w == NO_MGMT_FRAME_PROTECTION) {
1113 wpa_printf(MSG_ERROR,
1114 "MBO: PMF needs to be enabled whenever using WPA2 with MBO");
1115 return -1;
1116 }
1117#endif /* CONFIG_MBO */
1118
9c55fdb0
MV
1119#ifdef CONFIG_OCV
1120 if (full_config && bss->ieee80211w == NO_MGMT_FRAME_PROTECTION &&
1121 bss->ocv) {
1122 wpa_printf(MSG_ERROR,
1123 "OCV: PMF needs to be enabled whenever using OCV");
1124 return -1;
1125 }
1126#endif /* CONFIG_OCV */
1127
eff0fd1e
JM
1128 return 0;
1129}
1130
1131
8884ce03
MM
1132static int hostapd_config_check_cw(struct hostapd_config *conf, int queue)
1133{
1134 int tx_cwmin = conf->tx_queue[queue].cwmin;
1135 int tx_cwmax = conf->tx_queue[queue].cwmax;
1136 int ac_cwmin = conf->wmm_ac_params[queue].cwmin;
1137 int ac_cwmax = conf->wmm_ac_params[queue].cwmax;
1138
1139 if (tx_cwmin > tx_cwmax) {
1140 wpa_printf(MSG_ERROR,
1141 "Invalid TX queue cwMin/cwMax values. cwMin(%d) greater than cwMax(%d)",
1142 tx_cwmin, tx_cwmax);
1143 return -1;
1144 }
1145 if (ac_cwmin > ac_cwmax) {
1146 wpa_printf(MSG_ERROR,
1147 "Invalid WMM AC cwMin/cwMax values. cwMin(%d) greater than cwMax(%d)",
1148 ac_cwmin, ac_cwmax);
1149 return -1;
1150 }
1151 return 0;
1152}
1153
1154
08081ad8 1155int hostapd_config_check(struct hostapd_config *conf, int full_config)
eff0fd1e
JM
1156{
1157 size_t i;
1158
08081ad8
JM
1159 if (full_config && conf->ieee80211d &&
1160 (!conf->country[0] || !conf->country[1])) {
eff0fd1e
JM
1161 wpa_printf(MSG_ERROR, "Cannot enable IEEE 802.11d without "
1162 "setting the country_code");
1163 return -1;
1164 }
1165
08081ad8 1166 if (full_config && conf->ieee80211h && !conf->ieee80211d) {
eff0fd1e
JM
1167 wpa_printf(MSG_ERROR, "Cannot enable IEEE 802.11h without "
1168 "IEEE 802.11d enabled");
1169 return -1;
1170 }
1171
e0392f82
S
1172 if (full_config && conf->local_pwr_constraint != -1 &&
1173 !conf->ieee80211d) {
1174 wpa_printf(MSG_ERROR, "Cannot add Power Constraint element without Country element");
1175 return -1;
1176 }
1177
3d7ad2f6
C
1178 if (full_config && conf->spectrum_mgmt_required &&
1179 conf->local_pwr_constraint == -1) {
1180 wpa_printf(MSG_ERROR, "Cannot set Spectrum Management bit without Country and Power Constraint elements");
1181 return -1;
1182 }
1183
ef721751
THJ
1184#ifdef CONFIG_AIRTIME_POLICY
1185 if (full_config && conf->airtime_mode > AIRTIME_MODE_STATIC &&
1186 !conf->airtime_update_interval) {
1187 wpa_printf(MSG_ERROR, "Airtime update interval cannot be zero");
1188 return -1;
1189 }
1190#endif /* CONFIG_AIRTIME_POLICY */
8884ce03
MM
1191 for (i = 0; i < NUM_TX_QUEUES; i++) {
1192 if (hostapd_config_check_cw(conf, i))
1193 return -1;
1194 }
1195
eff0fd1e 1196 for (i = 0; i < conf->num_bss; i++) {
08081ad8 1197 if (hostapd_config_check_bss(conf->bss[i], conf, full_config))
eff0fd1e
JM
1198 return -1;
1199 }
1200
1201 return 0;
1202}
1203
1204
5d67bf15
JM
1205void hostapd_set_security_params(struct hostapd_bss_config *bss,
1206 int full_config)
eff0fd1e
JM
1207{
1208 if (bss->individual_wep_key_len == 0) {
1209 /* individual keys are not use; can use key idx0 for
1210 * broadcast keys */
1211 bss->broadcast_key_idx_min = 0;
1212 }
1213
1214 if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
1215 bss->rsn_pairwise = bss->wpa_pairwise;
27781c0a
JM
1216 if (bss->group_cipher)
1217 bss->wpa_group = bss->group_cipher;
1218 else
1219 bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa,
1220 bss->wpa_pairwise,
1221 bss->rsn_pairwise);
90f837b0
JM
1222 if (!bss->wpa_group_rekey_set)
1223 bss->wpa_group_rekey = bss->wpa_group == WPA_CIPHER_TKIP ?
1224 600 : 86400;
eff0fd1e 1225
5d67bf15
JM
1226 if (full_config) {
1227 bss->radius->auth_server = bss->radius->auth_servers;
1228 bss->radius->acct_server = bss->radius->acct_servers;
1229 }
eff0fd1e
JM
1230
1231 if (bss->wpa && bss->ieee802_1x) {
1232 bss->ssid.security_policy = SECURITY_WPA;
1233 } else if (bss->wpa) {
1234 bss->ssid.security_policy = SECURITY_WPA_PSK;
1235 } else if (bss->ieee802_1x) {
1236 int cipher = WPA_CIPHER_NONE;
1237 bss->ssid.security_policy = SECURITY_IEEE_802_1X;
1238 bss->ssid.wep.default_len = bss->default_wep_key_len;
13a3a20d 1239 if (full_config && bss->default_wep_key_len) {
eff0fd1e
JM
1240 cipher = bss->default_wep_key_len >= 13 ?
1241 WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
13a3a20d
JM
1242 } else if (full_config && bss->ssid.wep.keys_set) {
1243 if (bss->ssid.wep.len[0] >= 13)
1244 cipher = WPA_CIPHER_WEP104;
1245 else
1246 cipher = WPA_CIPHER_WEP40;
1247 }
eff0fd1e
JM
1248 bss->wpa_group = cipher;
1249 bss->wpa_pairwise = cipher;
1250 bss->rsn_pairwise = cipher;
13a3a20d
JM
1251 if (full_config)
1252 bss->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
eff0fd1e
JM
1253 } else if (bss->ssid.wep.keys_set) {
1254 int cipher = WPA_CIPHER_WEP40;
1255 if (bss->ssid.wep.len[0] >= 13)
1256 cipher = WPA_CIPHER_WEP104;
1257 bss->ssid.security_policy = SECURITY_STATIC_WEP;
1258 bss->wpa_group = cipher;
1259 bss->wpa_pairwise = cipher;
1260 bss->rsn_pairwise = cipher;
13a3a20d
JM
1261 if (full_config)
1262 bss->wpa_key_mgmt = WPA_KEY_MGMT_NONE;
a14896e8
JM
1263 } else if (bss->osen) {
1264 bss->ssid.security_policy = SECURITY_OSEN;
1265 bss->wpa_group = WPA_CIPHER_CCMP;
1266 bss->wpa_pairwise = 0;
1267 bss->rsn_pairwise = WPA_CIPHER_CCMP;
eff0fd1e
JM
1268 } else {
1269 bss->ssid.security_policy = SECURITY_PLAINTEXT;
29767152
JM
1270 if (full_config) {
1271 bss->wpa_group = WPA_CIPHER_NONE;
1272 bss->wpa_pairwise = WPA_CIPHER_NONE;
1273 bss->rsn_pairwise = WPA_CIPHER_NONE;
13a3a20d 1274 bss->wpa_key_mgmt = WPA_KEY_MGMT_NONE;
29767152 1275 }
eff0fd1e
JM
1276 }
1277}
42d30863
JM
1278
1279
1280int hostapd_sae_pw_id_in_use(struct hostapd_bss_config *conf)
1281{
1282 int with_id = 0, without_id = 0;
1283 struct sae_password_entry *pw;
1284
1285 if (conf->ssid.wpa_passphrase)
1286 without_id = 1;
1287
1288 for (pw = conf->sae_passwords; pw; pw = pw->next) {
1289 if (pw->identifier)
1290 with_id = 1;
1291 else
1292 without_id = 1;
1293 if (with_id && without_id)
1294 break;
1295 }
1296
1297 if (with_id && !without_id)
1298 return 2;
1299 return with_id;
1300}