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