18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / Configuration helper functions
304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/eapol_common.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_wsc_common.h"
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_vlan *vlan, *prev;
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	vlan = bss->vlan;
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	prev = NULL;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (vlan) {
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		prev = vlan;
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		vlan = vlan->next;
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(prev);
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->vlan = NULL;
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->logger_syslog_level = HOSTAPD_LEVEL_INFO;
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->logger_syslog = (unsigned int) -1;
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->logger_stdout = (unsigned int) -1;
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->auth_algs = WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED;
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->wep_rekeying_period = 300;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* use key0 in individual key and key1 in broadcast key */
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->broadcast_key_idx_min = 1;
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->broadcast_key_idx_max = 2;
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->eap_reauth_period = 3600;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->wpa_group_rekey = 600;
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->wpa_gmk_rekey = 86400;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->wpa_pairwise = WPA_CIPHER_TKIP;
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->wpa_group = WPA_CIPHER_TKIP;
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->rsn_pairwise = 0;
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->max_num_sta = MAX_STA_COUNT;
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->dtim_period = 2;
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->radius_server_auth_port = 1812;
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->ap_max_inactivity = AP_MAX_INACTIVITY;
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->eapol_version = EAPOL_VERSION;
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->max_listen_interval = 65535;
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->pwd_group = 19; /* ECC: GF(p=256) */
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->assoc_sa_query_max_timeout = 1000;
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->assoc_sa_query_retry_timeout = 201;
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_FAST
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 /* both anonymous and authenticated provisioning */
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->eap_fast_prov = 3;
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->pac_key_lifetime = 7 * 24 * 60 * 60;
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->pac_key_refresh_time = 1 * 24 * 60 * 60;
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_FAST */
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Set to -1 as defaults depends on HT in setup */
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->wmm_enabled = -1;
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->ft_over_ds = 1;
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
9004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
9104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	bss->radius_das_time_window = 300;
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_config * hostapd_config_defaults(void)
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define ecw2cw(ecw) ((1 << (ecw)) - 1)
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_config *conf;
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_bss_config *bss;
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const int aCWmin = 4, aCWmax = 10;
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct hostapd_wmm_ac_params ac_bk =
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{ aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct hostapd_wmm_ac_params ac_be =
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{ aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
10761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		{ aCWmin - 1, aCWmin, 2, 3000 / 32, 0 };
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
10961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		{ aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 0 };
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct hostapd_tx_queue_params txq_bk =
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{ 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 };
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct hostapd_tx_queue_params txq_be =
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{ 3, ecw2cw(aCWmin), 4 * (ecw2cw(aCWmin) + 1) - 1, 0};
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct hostapd_tx_queue_params txq_vi =
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{ 1, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30};
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct hostapd_tx_queue_params txq_vo =
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{ 1, (ecw2cw(aCWmin) + 1) / 4 - 1,
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  (ecw2cw(aCWmin) + 1) / 2 - 1, 15};
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef ecw2cw
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf = os_zalloc(sizeof(*conf));
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss = os_zalloc(sizeof(*bss));
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf == NULL || bss == NULL) {
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to allocate memory for "
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "configuration data.");
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(conf);
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(bss);
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->radius = os_zalloc(sizeof(*bss->radius));
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->radius == NULL) {
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(conf);
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(bss);
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_config_defaults_bss(bss);
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->num_bss = 1;
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->bss = bss;
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->beacon_int = 100;
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->rts_threshold = -1; /* use driver default: 2347 */
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->fragm_threshold = -1; /* user driver default: 2346 */
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->send_probe_response = 1;
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->wmm_ac_params[0] = ac_be;
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->wmm_ac_params[1] = ac_bk;
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->wmm_ac_params[2] = ac_vi;
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->wmm_ac_params[3] = ac_vo;
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->tx_queue[0] = txq_vo;
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->tx_queue[1] = txq_vi;
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->tx_queue[2] = txq_be;
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->tx_queue[3] = txq_bk;
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED;
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return conf;
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_mac_comp(const void *a, const void *b)
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return os_memcmp(a, b, sizeof(macaddr));
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_mac_comp_empty(const void *a)
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	macaddr empty = { 0 };
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return os_memcmp(a, empty, sizeof(macaddr));
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_read_wpa_psk(const char *fname,
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       struct hostapd_ssid *ssid)
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	FILE *f;
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char buf[128], *pos;
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int line = 0, ret = 0, len, ok;
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 addr[ETH_ALEN];
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_wpa_psk *psk;
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!fname)
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	f = fopen(fname, "r");
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!f) {
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname);
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (fgets(buf, sizeof(buf), f)) {
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		line++;
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '#')
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = buf;
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos != '\0') {
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (*pos == '\n') {
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*pos = '\0';
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '\0')
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hwaddr_aton(buf, addr)) {
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Invalid MAC address '%s' on "
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "line %d in '%s'", buf, line, fname);
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		psk = os_zalloc(sizeof(*psk));
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (psk == NULL) {
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "WPA PSK allocation failed");
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (is_zero_ether_addr(addr))
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			psk->group = 1;
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(psk->addr, addr, ETH_ALEN);
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = buf + 17;
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos == '\0') {
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'",
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   line, fname);
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(psk);
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos++;
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ok = 0;
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = os_strlen(pos);
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ok = 1;
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (len >= 8 && len < 64) {
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    4096, psk->psk, PMK_LEN);
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ok = 1;
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!ok) {
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in "
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "'%s'", pos, line, fname);
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(psk);
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = -1;
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		psk->next = ssid->wpa_psk;
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->wpa_psk = psk;
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fclose(f);
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_derive_psk(struct hostapd_ssid *ssid)
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->wpa_psk == NULL) {
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Unable to alloc space for PSK");
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_ascii(MSG_DEBUG, "SSID",
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  (u8 *) ssid->ssid, ssid->ssid_len);
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_ascii_key(MSG_DEBUG, "PSK (ASCII passphrase)",
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      (u8 *) ssid->wpa_passphrase,
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      os_strlen(ssid->wpa_passphrase));
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pbkdf2_sha1(ssid->wpa_passphrase,
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    ssid->ssid, ssid->ssid_len,
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    4096, ssid->wpa_psk->psk, PMK_LEN);
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_key(MSG_DEBUG, "PSK (from passphrase)",
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ssid->wpa_psk->psk, PMK_LEN);
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_setup_wpa_psk(struct hostapd_bss_config *conf)
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_ssid *ssid = &conf->ssid;
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->wpa_passphrase != NULL) {
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->wpa_psk != NULL) {
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "Using pre-configured WPA PSK "
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "instead of passphrase");
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "Deriving WPA PSK based on "
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "passphrase");
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_derive_psk(ssid) < 0)
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->wpa_psk->group = 1;
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->wpa_psk_file) {
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hostapd_config_read_wpa_psk(ssid->wpa_psk_file,
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						&conf->ssid))
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_wep_key_cmp(struct hostapd_wep_keys *a, struct hostapd_wep_keys *b)
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (a->idx != b->idx || a->default_len != b->default_len)
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 1;
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++)
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (a->len[i] != b->len[i] ||
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(a->key[i], b->key[i], a->len[i]) != 0)
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_config_free_radius(struct hostapd_radius_server *servers,
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       int num_servers)
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < num_servers; i++) {
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(servers[i].shared_secret);
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(servers);
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstruct hostapd_radius_attr *
34204949598a23f501be6eec21697465fd46a28840aDmitry Shmidthostapd_config_get_radius_attr(struct hostapd_radius_attr *attr, u8 type)
34304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
34404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (; attr; attr = attr->next) {
34504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (attr->type == type)
34604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return attr;
34704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
34804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return NULL;
34904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
35004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
35104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
35204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_config_free_radius_attr(struct hostapd_radius_attr *attr)
35304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
35404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct hostapd_radius_attr *prev;
35504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
35604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	while (attr) {
35704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		prev = attr;
35804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		attr = attr->next;
35904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpabuf_free(prev->val);
36004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(prev);
36104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
36204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
36304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
36404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(user->identity);
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(user->password);
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(user);
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(keys->key[i]);
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		keys->key[i] = NULL;
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_config_free_bss(struct hostapd_bss_config *conf)
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_wpa_psk *psk, *prev;
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_eap_user *user, *prev_user;
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf == NULL)
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	psk = conf->ssid.wpa_psk;
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (psk) {
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		prev = psk;
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		psk = psk->next;
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(prev);
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->ssid.wpa_passphrase);
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->ssid.wpa_psk_file);
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_config_free_wep(&conf->ssid.wep);
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_FULL_DYNAMIC_VLAN
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->ssid.vlan_tagged_interface);
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_FULL_DYNAMIC_VLAN */
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	user = conf->eap_user;
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (user) {
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		prev_user = user;
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		user = user->next;
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hostapd_config_free_eap_user(prev_user);
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->dump_log_name);
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->eap_req_id_text);
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->accept_mac);
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->deny_mac);
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->nas_identifier);
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_config_free_radius(conf->radius->auth_servers,
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   conf->radius->num_auth_servers);
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_config_free_radius(conf->radius->acct_servers,
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   conf->radius->num_acct_servers);
42104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	hostapd_config_free_radius_attr(conf->radius_auth_req_attr);
42204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	hostapd_config_free_radius_attr(conf->radius_acct_req_attr);
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->rsn_preauth_interfaces);
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->ctrl_interface);
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->ca_cert);
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->server_cert);
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->private_key);
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->private_key_passwd);
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->dh_file);
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->pac_opaque_encr_key);
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->eap_fast_a_id);
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->eap_fast_a_id_info);
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->eap_sim_db);
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->radius_server_clients);
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->test_socket);
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->radius);
43704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(conf->radius_das_shared_secret);
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_config_free_vlan(conf);
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf->ssid.dyn_vlan_keys) {
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct hostapd_ssid *ssid = &conf->ssid;
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		size_t i;
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ssid->dyn_vlan_keys[i] == NULL)
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue;
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			hostapd_config_free_wep(ssid->dyn_vlan_keys[i]);
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(ssid->dyn_vlan_keys[i]);
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(ssid->dyn_vlan_keys);
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->dyn_vlan_keys = NULL;
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_free(conf->time_zone);
4531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	{
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct ft_remote_r0kh *r0kh, *r0kh_prev;
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct ft_remote_r1kh *r1kh, *r1kh_prev;
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		r0kh = conf->r0kh_list;
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->r0kh_list = NULL;
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (r0kh) {
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			r0kh_prev = r0kh;
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			r0kh = r0kh->next;
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(r0kh_prev);
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		r1kh = conf->r1kh_list;
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->r1kh_list = NULL;
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (r1kh) {
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			r1kh_prev = r1kh;
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			r1kh = r1kh->next;
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(r1kh_prev);
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->wps_pin_requests);
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->device_name);
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->manufacturer);
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->model_name);
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->model_number);
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->serial_number);
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->config_methods);
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->ap_pin);
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->extra_cred);
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->ap_settings);
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->upnp_iface);
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->friendly_name);
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->manufacturer_url);
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->model_description);
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->model_url);
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->upc);
49404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpabuf_free(conf->wps_nfc_dh_pubkey);
49504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpabuf_free(conf->wps_nfc_dh_privkey);
49604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpabuf_free(conf->wps_nfc_dev_pw);
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
4981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_free(conf->roaming_consortium);
50004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(conf->venue_name);
50161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(conf->nai_realm_data);
50261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(conf->network_auth_type);
50361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(conf->anqp_3gpp_cell_net);
50461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(conf->domain_name);
5051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
5061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST
5071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_free(conf->dump_msk_file);
5081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */
50961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
51061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_HS20
51161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(conf->hs20_oper_friendly_name);
51261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(conf->hs20_wan_metrics);
51361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(conf->hs20_connection_capability);
51461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(conf->hs20_operating_class);
51561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_HS20 */
51661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
51761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpabuf_free(conf->vendor_elements);
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_config_free - Free hostapd configuration
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Configuration data from hostapd_config_read().
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_config_free(struct hostapd_config *conf)
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf == NULL)
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < conf->num_bss; i++)
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hostapd_config_free_bss(&conf->bss[i]);
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->bss);
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->supported_rates);
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->basic_rates);
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf);
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_maclist_found - Find a MAC address from a list
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @list: MAC address list
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @num_entries: Number of addresses in the list
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Address to search for
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vlan_id: Buffer for returning VLAN ID or %NULL if not needed
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if address is in the list or 0 if not.
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Perform a binary search for given MAC address from a pre-sorted list.
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  const u8 *addr, int *vlan_id)
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int start, end, middle, res;
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	start = 0;
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = num_entries - 1;
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (start <= end) {
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		middle = (start + end) / 2;
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res = os_memcmp(list[middle].addr, addr, ETH_ALEN);
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res == 0) {
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (vlan_id)
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*vlan_id = list[middle].vlan_id;
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res < 0)
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			start = middle + 1;
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			end = middle - 1;
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_rate_found(int *list, int rate)
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (list == NULL)
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; list[i] >= 0; i++)
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (list[i] == rate)
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_vlan *v = vlan;
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (v) {
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (v->vlan_id == vlan_id || v->vlan_id == VLAN_ID_WILDCARD)
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return v->ifname;
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		v = v->next;
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   const u8 *addr, const u8 *prev_psk)
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_wpa_psk *psk;
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int next_ok = prev_psk == NULL;
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) {
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (next_ok &&
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (psk->group || os_memcmp(psk->addr, addr, ETH_ALEN) == 0))
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return psk->psk;
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (psk->psk == prev_psk)
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			next_ok = 1;
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst struct hostapd_eap_user *
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_get_eap_user(const struct hostapd_bss_config *conf, const u8 *identity,
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     size_t identity_len, int phase2)
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_eap_user *user = conf->eap_user;
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf->wps_state && identity_len == WSC_ID_ENROLLEE_LEN &&
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) {
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		static struct hostapd_eap_user wsc_enrollee;
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(&wsc_enrollee, 0, sizeof(wsc_enrollee));
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wsc_enrollee.methods[0].method = eap_server_get_type(
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"WSC", &wsc_enrollee.methods[0].vendor);
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return &wsc_enrollee;
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf->wps_state && identity_len == WSC_ID_REGISTRAR_LEN &&
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) {
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		static struct hostapd_eap_user wsc_registrar;
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(&wsc_registrar, 0, sizeof(wsc_registrar));
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wsc_registrar.methods[0].method = eap_server_get_type(
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"WSC", &wsc_registrar.methods[0].vendor);
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wsc_registrar.password = (u8 *) conf->ap_pin;
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wsc_registrar.password_len = conf->ap_pin ?
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strlen(conf->ap_pin) : 0;
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return &wsc_registrar;
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (user) {
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!phase2 && user->identity == NULL) {
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Wildcard match */
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (user->phase2 == !!phase2 && user->wildcard_prefix &&
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    identity_len >= user->identity_len &&
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(user->identity, identity, user->identity_len) ==
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    0) {
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Wildcard prefix match */
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (user->phase2 == !!phase2 &&
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    user->identity_len == identity_len &&
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(user->identity, identity, identity_len) == 0)
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		user = user->next;
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return user;
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
676