18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / Configuration file parser
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#ifndef CONFIG_NATIVE_WINDOWS
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <grp.h>
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/uuid.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "drivers/driver.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/wpa_auth.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ap_config.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config_file.h"
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern struct wpa_driver_ops *wpa_drivers[];
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_VLAN
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 const char *fname)
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	FILE *f;
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char buf[128], *pos, *pos2;
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int line = 0, vlan_id;
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_vlan *vlan;
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	f = fopen(fname, "r");
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!f) {
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "VLAN file '%s' not readable.", fname);
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (fgets(buf, sizeof(buf), f)) {
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		line++;
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '#')
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = buf;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos != '\0') {
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (*pos == '\n') {
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*pos = '\0';
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '\0')
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '*') {
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			vlan_id = VLAN_ID_WILDCARD;
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos = buf + 1;
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			vlan_id = strtol(buf, &pos, 10);
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (buf == pos || vlan_id < 1 ||
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    vlan_id > MAX_VLAN_ID) {
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Invalid VLAN ID at "
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "line %d in '%s'", line, fname);
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				fclose(f);
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos == ' ' || *pos == '\t')
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos2 = pos;
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0')
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos2++;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*pos2 = '\0';
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) {
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d "
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "in '%s'", line, fname);
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			fclose(f);
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		vlan = os_malloc(sizeof(*vlan));
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (vlan == NULL) {
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Out of memory while reading "
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "VLAN interfaces from '%s'", fname);
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			fclose(f);
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(vlan, 0, sizeof(*vlan));
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		vlan->vlan_id = vlan_id;
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname));
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss->vlan_tail)
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->vlan_tail->next = vlan;
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->vlan = vlan;
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->vlan_tail = vlan;
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fclose(f);
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_VLAN */
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_acl_comp(const void *a, const void *b)
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct mac_acl_entry *aa = a;
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct mac_acl_entry *bb = b;
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_read_maclist(const char *fname,
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       struct mac_acl_entry **acl, int *num)
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	FILE *f;
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char buf[128], *pos;
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int line = 0;
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 addr[ETH_ALEN];
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct mac_acl_entry *newacl;
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int vlan_id;
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!fname)
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	f = fopen(fname, "r");
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!f) {
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "MAC list file '%s' not found.", fname);
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (fgets(buf, sizeof(buf), f)) {
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		line++;
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '#')
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = buf;
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos != '\0') {
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (*pos == '\n') {
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*pos = '\0';
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '\0')
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hwaddr_aton(buf, addr)) {
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Invalid MAC address '%s' at "
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "line %d in '%s'", buf, line, fname);
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			fclose(f);
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		vlan_id = 0;
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = buf;
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos != '\0' && *pos != ' ' && *pos != '\t')
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos == ' ' || *pos == '\t')
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos != '\0')
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			vlan_id = atoi(pos);
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		newacl = os_realloc_array(*acl, *num + 1, sizeof(**acl));
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (newacl == NULL) {
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "MAC list reallocation failed");
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			fclose(f);
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*acl = newacl;
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		(*acl)[*num].vlan_id = vlan_id;
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		(*num)++;
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fclose(f);
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_read_eap_user(const char *fname,
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					struct hostapd_bss_config *conf)
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	FILE *f;
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char buf[512], *pos, *start, *pos2;
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int line = 0, ret = 0, num_methods;
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_eap_user *user, *tail = NULL;
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!fname)
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	f = fopen(fname, "r");
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!f) {
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "EAP user file '%s' not found.", fname);
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Lines: "user" METHOD,METHOD2 "password" (password optional) */
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (fgets(buf, sizeof(buf), f)) {
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		line++;
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '#')
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = buf;
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos != '\0') {
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (*pos == '\n') {
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*pos = '\0';
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '\0')
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		user = NULL;
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] != '"' && buf[0] != '*') {
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Invalid EAP identity (no \" in "
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "start) on line %d in '%s'", line, fname);
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto failed;
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		user = os_zalloc(sizeof(*user));
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (user == NULL) {
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "EAP user allocation failed");
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto failed;
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		user->force_version = -1;
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (buf[0] == '*') {
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos = buf;
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos = buf + 1;
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			start = pos;
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			while (*pos != '"' && *pos != '\0')
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				pos++;
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (*pos == '\0') {
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Invalid EAP identity "
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "(no \" in end) on line %d in '%s'",
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, fname);
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->identity = os_malloc(pos - start);
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (user->identity == NULL) {
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Failed to allocate "
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "memory for EAP identity");
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(user->identity, start, pos - start);
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->identity_len = pos - start;
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (pos[0] == '"' && pos[1] == '*') {
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				user->wildcard_prefix = 1;
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				pos++;
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos++;
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos == ' ' || *pos == '\t')
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos == '\0') {
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "No EAP method on line %d in "
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "'%s'", line, fname);
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto failed;
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		start = pos;
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos != ' ' && *pos != '\t' && *pos != '\0')
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos == '\0') {
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos = NULL;
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos = '\0';
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		num_methods = 0;
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*start) {
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			char *pos3 = os_strchr(start, ',');
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (pos3) {
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*pos3++ = '\0';
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->methods[num_methods].method =
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				eap_server_get_type(
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					start,
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					&user->methods[num_methods].vendor);
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (user->methods[num_methods].vendor ==
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    EAP_VENDOR_IETF &&
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    user->methods[num_methods].method == EAP_TYPE_NONE)
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			{
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (os_strcmp(start, "TTLS-PAP") == 0) {
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					user->ttls_auth |= EAP_TTLS_AUTH_PAP;
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto skip_eap;
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				}
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (os_strcmp(start, "TTLS-CHAP") == 0) {
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					user->ttls_auth |= EAP_TTLS_AUTH_CHAP;
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto skip_eap;
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				}
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (os_strcmp(start, "TTLS-MSCHAP") == 0) {
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					user->ttls_auth |=
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						EAP_TTLS_AUTH_MSCHAP;
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto skip_eap;
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				}
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (os_strcmp(start, "TTLS-MSCHAPV2") == 0) {
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					user->ttls_auth |=
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						EAP_TTLS_AUTH_MSCHAPV2;
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto skip_eap;
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				}
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Unsupported EAP type "
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "'%s' on line %d in '%s'",
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   start, line, fname);
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			num_methods++;
3271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (num_methods >= EAP_MAX_METHODS)
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		skip_eap:
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (pos3 == NULL)
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			start = pos3;
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (num_methods == 0 && user->ttls_auth == 0) {
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "No EAP types configured on "
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "line %d in '%s'", line, fname);
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto failed;
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos == NULL)
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto done;
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos == ' ' || *pos == '\t')
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos == '\0')
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto done;
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strncmp(pos, "[ver=0]", 7) == 0) {
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->force_version = 0;
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto done;
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strncmp(pos, "[ver=1]", 7) == 0) {
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->force_version = 1;
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto done;
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strncmp(pos, "[2]", 3) == 0) {
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->phase2 = 1;
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto done;
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos == '"') {
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			start = pos;
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			while (*pos != '"' && *pos != '\0')
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				pos++;
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (*pos == '\0') {
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Invalid EAP password "
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "(no \" in end) on line %d in '%s'",
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, fname);
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->password = os_malloc(pos - start);
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (user->password == NULL) {
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Failed to allocate "
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "memory for EAP password");
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(user->password, start, pos - start);
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->password_len = pos - start;
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strncmp(pos, "hash:", 5) == 0) {
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos += 5;
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos2 = pos;
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			while (*pos2 != '\0' && *pos2 != ' ' &&
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       *pos2 != '\t' && *pos2 != '#')
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				pos2++;
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (pos2 - pos != 32) {
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Invalid password hash "
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "on line %d in '%s'", line, fname);
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->password = os_malloc(16);
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (user->password == NULL) {
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Failed to allocate "
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "memory for EAP password hash");
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hexstr2bin(pos, user->password, 16) < 0) {
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Invalid hash password "
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "on line %d in '%s'", line, fname);
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->password_len = 16;
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->password_hash = 1;
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos = pos2;
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos2 = pos;
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			while (*pos2 != '\0' && *pos2 != ' ' &&
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       *pos2 != '\t' && *pos2 != '#')
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				pos2++;
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if ((pos2 - pos) & 1) {
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Invalid hex password "
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "on line %d in '%s'", line, fname);
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->password = os_malloc((pos2 - pos) / 2);
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (user->password == NULL) {
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Failed to allocate "
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "memory for EAP password");
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hexstr2bin(pos, user->password,
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       (pos2 - pos) / 2) < 0) {
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Invalid hex password "
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "on line %d in '%s'", line, fname);
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->password_len = (pos2 - pos) / 2;
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos = pos2;
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos == ' ' || *pos == '\t')
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strncmp(pos, "[2]", 3) == 0) {
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			user->phase2 = 1;
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	done:
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (tail == NULL) {
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tail = conf->eap_user = user;
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tail->next = user;
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tail = user;
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		continue;
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	failed:
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (user) {
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(user->password);
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(user->identity);
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(user);
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = -1;
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fclose(f);
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER */
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_config_read_radius_addr(struct hostapd_radius_server **server,
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				int *num_server, const char *val, int def_port,
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				struct hostapd_radius_server **curr_serv)
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_radius_server *nserv;
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	static int server_index = 1;
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
47861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	nserv = os_realloc_array(*server, *num_server + 1, sizeof(*nserv));
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (nserv == NULL)
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*server = nserv;
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	nserv = &nserv[*num_server];
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(*num_server)++;
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(*curr_serv) = nserv;
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(nserv, 0, sizeof(*nserv));
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	nserv->port = def_port;
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = hostapd_parse_ip_addr(val, &nserv->addr);
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	nserv->index = server_index++;
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
49404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
49504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
49604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic struct hostapd_radius_attr *
49704949598a23f501be6eec21697465fd46a28840aDmitry Shmidthostapd_parse_radius_attr(const char *value)
49804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
49904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	const char *pos;
50004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char syntax;
50104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct hostapd_radius_attr *attr;
50204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t len;
50304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
50404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	attr = os_zalloc(sizeof(*attr));
50504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (attr == NULL)
50604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return NULL;
50704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
50804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	attr->type = atoi(value);
50904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
51004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pos = os_strchr(value, ':');
51104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (pos == NULL) {
51204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		attr->val = wpabuf_alloc(1);
51304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (attr->val == NULL) {
51404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			os_free(attr);
51504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return NULL;
51604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
51704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpabuf_put_u8(attr->val, 0);
51804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return attr;
51904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
52004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
52104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pos++;
52204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (pos[0] == '\0' || pos[1] != ':') {
52304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(attr);
52404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return NULL;
52504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
52604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	syntax = *pos++;
52704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pos++;
52804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
52904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	switch (syntax) {
53004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case 's':
53104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		attr->val = wpabuf_alloc_copy(pos, os_strlen(pos));
53204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
53304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case 'x':
53404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		len = os_strlen(pos);
53504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (len & 1)
53604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
53704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		len /= 2;
53804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		attr->val = wpabuf_alloc(len);
53904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (attr->val == NULL)
54004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
54104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (hexstr2bin(pos, wpabuf_put(attr->val, len), len) < 0) {
54204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpabuf_free(attr->val);
54304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			os_free(attr);
54404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return NULL;
54504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
54604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
54704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case 'd':
54804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		attr->val = wpabuf_alloc(4);
54904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (attr->val)
55004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpabuf_put_be32(attr->val, atoi(pos));
55104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
55204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	default:
55304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(attr);
55404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return NULL;
55504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
55604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
55704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (attr->val == NULL) {
55804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(attr);
55904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return NULL;
56004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
56104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
56204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return attr;
56304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
56404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
56504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
56604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_parse_das_client(struct hostapd_bss_config *bss,
56704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    const char *val)
56804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
56904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *secret;
57004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
57104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	secret = os_strchr(val, ' ');
57204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (secret == NULL)
57304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
57404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
57504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	secret++;
57604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
57704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (hostapd_parse_ip_addr(val, &bss->radius_das_client_addr))
57804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
57904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
58004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(bss->radius_das_shared_secret);
58161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss->radius_das_shared_secret = (u8 *) os_strdup(secret);
58204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (bss->radius_das_shared_secret == NULL)
58304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
58461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss->radius_das_shared_secret_len = os_strlen(secret);
58504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
58604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
58704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_parse_key_mgmt(int line, const char *value)
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int val = 0, last;
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *start, *end, *buf;
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	buf = os_strdup(value);
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (buf == NULL)
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	start = buf;
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (*start != '\0') {
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*start == ' ' || *start == '\t')
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			start++;
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*start == '\0')
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		end = start;
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*end != ' ' && *end != '\t' && *end != '\0')
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			end++;
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		last = *end == '\0';
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*end = '\0';
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(start, "WPA-PSK") == 0)
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_KEY_MGMT_PSK;
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(start, "WPA-EAP") == 0)
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_KEY_MGMT_IEEE8021X;
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(start, "FT-PSK") == 0)
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_KEY_MGMT_FT_PSK;
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(start, "FT-EAP") == 0)
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_KEY_MGMT_FT_IEEE8021X;
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_KEY_MGMT_PSK_SHA256;
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else {
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   line, start);
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(buf);
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (last)
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		start = end + 1;
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(buf);
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (val == 0) {
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Line %d: no key_mgmt values "
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "configured.", line);
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return val;
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_parse_cipher(int line, const char *value)
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int val = 0, last;
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *start, *end, *buf;
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	buf = os_strdup(value);
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (buf == NULL)
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	start = buf;
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (*start != '\0') {
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*start == ' ' || *start == '\t')
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			start++;
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*start == '\0')
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		end = start;
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*end != ' ' && *end != '\t' && *end != '\0')
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			end++;
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		last = *end == '\0';
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*end = '\0';
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(start, "CCMP") == 0)
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_CIPHER_CCMP;
67261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		else if (os_strcmp(start, "GCMP") == 0)
67361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			val |= WPA_CIPHER_GCMP;
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(start, "TKIP") == 0)
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_CIPHER_TKIP;
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(start, "WEP104") == 0)
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_CIPHER_WEP104;
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(start, "WEP40") == 0)
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_CIPHER_WEP40;
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(start, "NONE") == 0)
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			val |= WPA_CIPHER_NONE;
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else {
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   line, start);
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(buf);
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (last)
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		start = end + 1;
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(buf);
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (val == 0) {
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   line);
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return val;
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_read_wep(struct hostapd_wep_keys *wep, int keyidx,
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   char *val)
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len = os_strlen(val);
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (keyidx < 0 || keyidx > 3 || wep->key[keyidx] != NULL)
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (val[0] == '"') {
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len < 2 || val[len - 1] != '"')
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len -= 2;
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wep->key[keyidx] = os_malloc(len);
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wep->key[keyidx] == NULL)
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(wep->key[keyidx], val + 1, len);
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wep->len[keyidx] = len;
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len & 1)
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len /= 2;
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wep->key[keyidx] = os_malloc(len);
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wep->key[keyidx] == NULL)
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wep->len[keyidx] = len;
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hexstr2bin(val, wep->key[keyidx], len) < 0)
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wep->keys_set++;
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_parse_rates(int **rate_list, char *val)
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int *list;
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int count;
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *end;
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(*rate_list);
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*rate_list = NULL;
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = val;
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	count = 0;
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (*pos != '\0') {
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos == ' ')
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			count++;
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos++;
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	list = os_malloc(sizeof(int) * (count + 2));
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (list == NULL)
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = val;
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	count = 0;
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (*pos != '\0') {
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		end = os_strchr(pos, ' ');
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (end)
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*end = '\0';
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		list[count++] = atoi(pos);
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!end)
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = end + 1;
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	list[count] = -1;
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*rate_list = list;
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_bss(struct hostapd_config *conf, const char *ifname)
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_bss_config *bss;
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*ifname == '\0')
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
78561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss = os_realloc_array(conf->bss, conf->num_bss + 1,
78661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			       sizeof(struct hostapd_bss_config));
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss == NULL) {
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to allocate memory for "
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "multi-BSS entry");
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->bss = bss;
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss = &(conf->bss[conf->num_bss]);
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(bss, 0, sizeof(*bss));
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->radius = os_zalloc(sizeof(*bss->radius));
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->radius == NULL) {
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to allocate memory for "
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "multi-BSS RADIUS data");
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->num_bss++;
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->last_bss = bss;
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_config_defaults_bss(bss);
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(bss->ssid.vlan, bss->iface, IFNAMSIZ + 1);
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* convert floats with one decimal place to value*10 int, i.e.,
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * "1.5" will return 15 */
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_read_int10(const char *value)
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i, d;
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	i = atoi(value);
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = os_strchr(value, '.');
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	d = 0;
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pos) {
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos++;
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (*pos >= '0' && *pos <= '9')
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			d = *pos - '0';
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return i * 10 + d;
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int valid_cw(int cw)
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023);
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtenum {
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	IEEE80211_TX_QUEUE_DATA0 = 0, /* used for EDCA AC_VO data */
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	IEEE80211_TX_QUEUE_DATA1 = 1, /* used for EDCA AC_VI data */
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	IEEE80211_TX_QUEUE_DATA2 = 2, /* used for EDCA AC_BE data */
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	IEEE80211_TX_QUEUE_DATA3 = 3 /* used for EDCA AC_BK data */
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_tx_queue(struct hostapd_config *conf, char *name,
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   char *val)
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int num;
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_tx_queue_params *queue;
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* skip 'tx_queue_' prefix */
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = name + 9;
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strncmp(pos, "data", 4) == 0 &&
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		num = pos[4] - '0';
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += 6;
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strncmp(pos, "after_beacon_", 13) == 0 ||
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   os_strncmp(pos, "beacon_", 7) == 0) {
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Unknown tx_queue name '%s'", pos);
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (num >= NUM_TX_QUEUES) {
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* for backwards compatibility, do not trigger failure */
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	queue = &conf->tx_queue[num];
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(pos, "aifs") == 0) {
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		queue->aifs = atoi(val);
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (queue->aifs < 0 || queue->aifs > 255) {
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Invalid AIFS value %d",
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   queue->aifs);
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(pos, "cwmin") == 0) {
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		queue->cwmin = atoi(val);
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!valid_cw(queue->cwmin)) {
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Invalid cwMin value %d",
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   queue->cwmin);
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(pos, "cwmax") == 0) {
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		queue->cwmax = atoi(val);
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!valid_cw(queue->cwmax)) {
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Invalid cwMax value %d",
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   queue->cwmax);
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (os_strcmp(pos, "burst") == 0) {
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		queue->burst = hostapd_config_read_int10(val);
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Unknown tx_queue field '%s'", pos);
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int add_r0kh(struct hostapd_bss_config *bss, char *value)
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct ft_remote_r0kh *r0kh;
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *next;
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	r0kh = os_zalloc(sizeof(*r0kh));
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (r0kh == NULL)
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* 02:01:02:03:04:05 a.example.com 000102030405060708090a0b0c0d0e0f */
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = value;
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	next = os_strchr(pos, ' ');
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (next)
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*next++ = '\0';
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (next == NULL || hwaddr_aton(pos, r0kh->addr)) {
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Invalid R0KH MAC address: '%s'", pos);
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(r0kh);
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = next;
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	next = os_strchr(pos, ' ');
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (next)
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*next++ = '\0';
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (next == NULL || next - pos > FT_R0KH_ID_MAX_LEN) {
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Invalid R0KH-ID: '%s'", pos);
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(r0kh);
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	r0kh->id_len = next - pos - 1;
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(r0kh->id, pos, r0kh->id_len);
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = next;
9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(pos, r0kh->key, sizeof(r0kh->key))) {
9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Invalid R0KH key: '%s'", pos);
9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(r0kh);
9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	r0kh->next = bss->r0kh_list;
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->r0kh_list = r0kh;
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int add_r1kh(struct hostapd_bss_config *bss, char *value)
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct ft_remote_r1kh *r1kh;
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos, *next;
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	r1kh = os_zalloc(sizeof(*r1kh));
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (r1kh == NULL)
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* 02:01:02:03:04:05 02:01:02:03:04:05
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * 000102030405060708090a0b0c0d0e0f */
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = value;
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	next = os_strchr(pos, ' ');
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (next)
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*next++ = '\0';
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (next == NULL || hwaddr_aton(pos, r1kh->addr)) {
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Invalid R1KH MAC address: '%s'", pos);
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(r1kh);
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = next;
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	next = os_strchr(pos, ' ');
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (next)
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*next++ = '\0';
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (next == NULL || hwaddr_aton(pos, r1kh->id)) {
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Invalid R1KH-ID: '%s'", pos);
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(r1kh);
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = next;
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hexstr2bin(pos, r1kh->key, sizeof(r1kh->key))) {
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Invalid R1KH key: '%s'", pos);
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(r1kh);
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	r1kh->next = bss->r1kh_list;
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->r1kh_list = r1kh;
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_ht_capab(struct hostapd_config *conf,
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   const char *capab)
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[LDPC]"))
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_LDPC_CODING_CAP;
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[HT40-]")) {
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->secondary_channel = -1;
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[HT40+]")) {
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->secondary_channel = 1;
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[SMPS-STATIC]")) {
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab &= ~HT_CAP_INFO_SMPS_MASK;
10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_SMPS_STATIC;
10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[SMPS-DYNAMIC]")) {
10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab &= ~HT_CAP_INFO_SMPS_MASK;
10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_SMPS_DYNAMIC;
10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[GF]"))
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_GREEN_FIELD;
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[SHORT-GI-20]"))
10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_SHORT_GI20MHZ;
10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[SHORT-GI-40]"))
10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_SHORT_GI40MHZ;
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[TX-STBC]"))
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_TX_STBC;
10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[RX-STBC1]")) {
10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_RX_STBC_1;
10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[RX-STBC12]")) {
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_RX_STBC_12;
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[RX-STBC123]")) {
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_RX_STBC_123;
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[DELAYED-BA]"))
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_DELAYED_BA;
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[MAX-AMSDU-7935]"))
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_MAX_AMSDU_SIZE;
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[DSSS_CCK-40]"))
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_DSSS_CCK40MHZ;
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[PSMP]"))
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_PSMP_SUPP;
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strstr(capab, "[LSIG-TXOP-PROT]"))
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->ht_capab |= HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT;
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */
10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
106104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_IEEE80211AC
106204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_config_vht_capab(struct hostapd_config *conf,
106304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    const char *capab)
106404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
106504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[MAX-MPDU-7991]"))
106604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_MAX_MPDU_LENGTH_7991;
106704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[MAX-MPDU-11454]"))
106804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_MAX_MPDU_LENGTH_11454;
106904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[VHT160]"))
107004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
107104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[VHT160-80PLUS80]"))
107204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
107304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[VHT160-80PLUS80]"))
107404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
107504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[RXLDPC]"))
107604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_RXLDPC;
107704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[SHORT-GI-80]"))
107804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_SHORT_GI_80;
107904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[SHORT-GI-160]"))
108004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_SHORT_GI_160;
108104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[TX-STBC-2BY1]"))
108204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_TXSTBC;
108304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[RX-STBC-1]"))
108404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_RXSTBC_1;
108504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[RX-STBC-12]"))
108604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_RXSTBC_2;
108704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[RX-STBC-123]"))
108804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_RXSTBC_3;
108904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[RX-STBC-1234]"))
109004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_RXSTBC_4;
109104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[SU-BEAMFORMER]"))
109204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_MU_BEAMFORMER_CAPABLE;
109304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[SU-BEAMFORMEE]"))
109404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_MU_BEAMFORMEE_CAPABLE;
109504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[BF-ANTENNA-2]") &&
109604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    (conf->vht_capab & VHT_CAP_MU_BEAMFORMER_CAPABLE))
109704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_BEAMFORMER_ANTENNAS_MAX;
109804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[SOUNDING-DIMENSION-2]") &&
109904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    (conf->vht_capab & VHT_CAP_MU_BEAMFORMER_CAPABLE))
110004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_SOUNDING_DIMENTION_MAX;
110104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[MU-BEAMFORMER]"))
110204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_MU_BEAMFORMER_CAPABLE;
110304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[MU-BEAMFORMEE]"))
110404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_MU_BEAMFORMEE_CAPABLE;
110504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[VHT-TXOP-PS]"))
110604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_VHT_TXOP_PS;
110704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[HTC-VHT]"))
110804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_HTC_VHT;
110904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP0]"))
111004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT;
111104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[VHT-LINK-ADAPT2]") &&
111204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    (conf->vht_capab & VHT_CAP_HTC_VHT))
111304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB;
111404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[VHT-LINK-ADAPT3]") &&
111504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    (conf->vht_capab & VHT_CAP_HTC_VHT))
111604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
111704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[RX-ANTENNA-PATTERN]"))
111804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_RX_ANTENNA_PATTERN;
111904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_strstr(capab, "[TX-ANTENNA-PATTERN]"))
112004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		conf->vht_capab |= VHT_CAP_TX_ANTENNA_PATTERN;
112104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
112204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
112304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_IEEE80211AC */
112404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
112504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_check_bss(struct hostapd_bss_config *bss,
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    struct hostapd_config *conf)
11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->ieee802_1x && !bss->eap_server &&
11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !bss->radius->auth_servers) {
11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Invalid IEEE 802.1X configuration (no "
11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "EAP authenticator configured).");
11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (bss->wpa && bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
11381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_ERROR, "WPA-PSK using RADIUS enabled, but no "
11391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   "RADIUS checking (macaddr_acl=2) enabled.");
11401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
11411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
11421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
11451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    bss->ssid.wpa_psk_file == NULL &&
11461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    (bss->wpa_psk_radius != PSK_RADIUS_REQUIRED ||
11471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	     bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH)) {
11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "WPA-PSK enabled, but PSK or passphrase "
11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "is not configured.");
11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hostapd_mac_comp_empty(bss->bssid) != 0) {
11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		size_t i;
11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (i = 0; i < conf->num_bss; i++) {
11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if ((&conf->bss[i] != bss) &&
11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    (hostapd_mac_comp(conf->bss[i].bssid,
11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      bss->bssid) == 0)) {
11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Duplicate BSSID " MACSTR
11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   " on interface '%s' and '%s'.",
11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   MAC2STR(bss->bssid),
11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   conf->bss[i].iface, bss->iface);
11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return -1;
11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
11701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_key_mgmt_ft(bss->wpa_key_mgmt) &&
11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (bss->nas_identifier == NULL ||
11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     os_strlen(bss->nas_identifier) < 1 ||
11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     os_strlen(bss->nas_identifier) > FT_R0KH_ID_MAX_LEN)) {
11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "FT (IEEE 802.11r) requires "
11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "nas_identifier to be configured as a 1..48 octet "
11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "string");
11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N
118204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (conf->ieee80211n && conf->hw_mode == HOSTAPD_MODE_IEEE80211B) {
118304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->disable_11n = 1;
118404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) in 11b mode is not "
118504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "allowed, disabling HT capabilites");
118604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
118704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf->ieee80211n &&
11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    bss->ssid.security_policy == SECURITY_STATIC_WEP) {
11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->disable_11n = 1;
11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WEP is not "
11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "allowed, disabling HT capabilities");
11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf->ieee80211n && bss->wpa &&
11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !(bss->wpa_pairwise & WPA_CIPHER_CCMP) &&
119761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP))) {
11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->disable_11n = 1;
11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WPA/WPA2 "
120061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "requires CCMP/GCMP to be enabled, disabling HT "
12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "capabilities");
12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */
12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS2
12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->wps_state && bss->ignore_broadcast_ssid) {
12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS: ignore_broadcast_ssid "
12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "configuration forced WPS to be disabled");
12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->wps_state = 0;
12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->wps_state && bss->ssid.wep.keys_set && bss->wpa == 0) {
12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS: WEP configuration forced WPS to be "
12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "disabled");
12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->wps_state = 0;
12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
121761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
121861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (bss->wps_state && bss->wpa &&
121961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    (!(bss->wpa & 2) ||
122061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	     !(bss->rsn_pairwise & WPA_CIPHER_CCMP))) {
122161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS: WPA/TKIP configuration without "
122261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "WPA2/CCMP forced WPS to be disabled");
122361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		bss->wps_state = 0;
122461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS2 */
12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
122761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_HS20
122861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (bss->hs20 &&
122961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    (!(bss->wpa & 2) ||
123061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	     !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)))) {
123161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_ERROR, "HS 2.0: WPA2-Enterprise/CCMP "
123261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "configuration is required for Hotspot 2.0 "
123361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "functionality");
123461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
123561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
123661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_HS20 */
123761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_config_check(struct hostapd_config *conf)
12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf->ieee80211d && (!conf->country[0] || !conf->country[1])) {
12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Cannot enable IEEE 802.11d without "
12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "setting the country_code");
12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < conf->num_bss; i++) {
12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hostapd_config_check_bss(&conf->bss[i], conf))
12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING
12621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int parse_roaming_consortium(struct hostapd_bss_config *bss, char *pos,
12631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				    int line)
12641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
12651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	size_t len = os_strlen(pos);
12661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	u8 oi[MAX_ROAMING_CONSORTIUM_LEN];
12671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct hostapd_roaming_consortium *rc;
12691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if ((len & 1) || len < 2 * 3 || len / 2 > MAX_ROAMING_CONSORTIUM_LEN ||
12711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    hexstr2bin(pos, oi, len / 2)) {
12721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_ERROR, "Line %d: invalid roaming_consortium "
12731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   "'%s'", line, pos);
12741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
12751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
12761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	len /= 2;
12771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
127861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	rc = os_realloc_array(bss->roaming_consortium,
127961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			      bss->roaming_consortium_count + 1,
128061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			      sizeof(struct hostapd_roaming_consortium));
12811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (rc == NULL)
12821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
12831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_memcpy(rc[bss->roaming_consortium_count].oi, oi, len);
12851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	rc[bss->roaming_consortium_count].len = len;
12861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	bss->roaming_consortium = rc;
12881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	bss->roaming_consortium_count++;
12891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
12901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
12911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
129204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
129304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
129461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int parse_lang_string(struct hostapd_lang_string **array,
129561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			     unsigned int *count, char *pos)
129604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
129704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *sep;
129804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t clen, nlen;
129961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	struct hostapd_lang_string *ls;
130004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
130104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	sep = os_strchr(pos, ':');
130204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (sep == NULL)
130361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
130404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	*sep++ = '\0';
130504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
130604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	clen = os_strlen(pos);
130704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (clen < 2)
130861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
130904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	nlen = os_strlen(sep);
131004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (nlen > 252)
131161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
131261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
131361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ls = os_realloc_array(*array, *count + 1,
131461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			      sizeof(struct hostapd_lang_string));
131561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ls == NULL)
131661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
131761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
131861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	*array = ls;
131961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ls = &(*array)[*count];
132061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	(*count)++;
132161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
132261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_memset(ls->lang, 0, sizeof(ls->lang));
132361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_memcpy(ls->lang, pos, clen);
132461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ls->name_len = nlen;
132561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_memcpy(ls->name, sep, nlen);
132661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
132761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
132861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
132961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
133061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
133161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int parse_venue_name(struct hostapd_bss_config *bss, char *pos,
133261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    int line)
133361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
133461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (parse_lang_string(&bss->venue_name, &bss->venue_name_count, pos)) {
133561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_ERROR, "Line %d: Invalid venue_name '%s'",
133661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   line, pos);
133761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
133861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
133961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
134061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
134161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
134261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
134361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int parse_3gpp_cell_net(struct hostapd_bss_config *bss, char *buf,
134461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			       int line)
134561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
134661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	size_t count;
134761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	char *pos;
134861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	u8 *info = NULL, *ipos;
134961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
135061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* format: <MCC1,MNC1>[;<MCC2,MNC2>][;...] */
135161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
135261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	count = 1;
135361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	for (pos = buf; *pos; pos++) {
135461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if ((*pos < '0' && *pos > '9') && *pos != ';' && *pos != ',')
135561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			goto fail;
135661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (*pos == ';')
135761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			count++;
135861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
135961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (1 + count * 3 > 0x7f)
136004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		goto fail;
136104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
136261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	info = os_zalloc(2 + 3 + count * 3);
136361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (info == NULL)
136404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
136504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
136661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ipos = info;
136761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	*ipos++ = 0; /* GUD - Version 1 */
136861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	*ipos++ = 3 + count * 3; /* User Data Header Length (UDHL) */
136961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	*ipos++ = 0; /* PLMN List IEI */
137061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* ext(b8) | Length of PLMN List value contents(b7..1) */
137161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	*ipos++ = 1 + count * 3;
137261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	*ipos++ = count; /* Number of PLMNs */
137361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
137461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = buf;
137561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	while (pos && *pos) {
137661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		char *mcc, *mnc;
137761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		size_t mnc_len;
137861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
137961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		mcc = pos;
138061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		mnc = os_strchr(pos, ',');
138161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (mnc == NULL)
138261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			goto fail;
138361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		*mnc++ = '\0';
138461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos = os_strchr(mnc, ';');
138561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (pos)
138661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			*pos++ = '\0';
138761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
138861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		mnc_len = os_strlen(mnc);
138961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (os_strlen(mcc) != 3 || (mnc_len != 2 && mnc_len != 3))
139061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			goto fail;
139161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
139261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		/* BC coded MCC,MNC */
139361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		/* MCC digit 2 | MCC digit 1 */
139461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		*ipos++ = ((mcc[1] - '0') << 4) | (mcc[0] - '0');
139561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		/* MNC digit 3 | MCC digit 3 */
139661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		*ipos++ = (((mnc_len == 2) ? 0xf0 : ((mnc[2] - '0') << 4))) |
139761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			(mcc[2] - '0');
139861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		/* MNC digit 2 | MNC digit 1 */
139961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		*ipos++ = ((mnc[1] - '0') << 4) | (mnc[0] - '0');
140061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
140104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
140261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(bss->anqp_3gpp_cell_net);
140361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss->anqp_3gpp_cell_net = info;
140461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss->anqp_3gpp_cell_net_len = 2 + 3 + 3 * count;
140561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_hexdump(MSG_MSGDUMP, "3GPP Cellular Network information",
140661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		    bss->anqp_3gpp_cell_net, bss->anqp_3gpp_cell_net_len);
140704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
140804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
140904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
141004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtfail:
141161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_printf(MSG_ERROR, "Line %d: Invalid anqp_3gpp_cell_net: %s",
141261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		   line, buf);
141361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(info);
141404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return -1;
141504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
141661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
141761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
141861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int parse_nai_realm(struct hostapd_bss_config *bss, char *buf, int line)
141961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
142061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	struct hostapd_nai_realm_data *realm;
142161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	size_t i, j, len;
142261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int *offsets;
142361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	char *pos, *end, *rpos;
142461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
142561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	offsets = os_calloc(bss->nai_realm_count * MAX_NAI_REALMS,
142661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    sizeof(int));
142761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (offsets == NULL)
142861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
142961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
143061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	for (i = 0; i < bss->nai_realm_count; i++) {
143161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		realm = &bss->nai_realm_data[i];
143261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		for (j = 0; j < MAX_NAI_REALMS; j++) {
143361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			offsets[i * MAX_NAI_REALMS + j] =
143461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				realm->realm[j] ?
143561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				realm->realm[j] - realm->realm_buf : -1;
143661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
143761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
143861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
143961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	realm = os_realloc_array(bss->nai_realm_data, bss->nai_realm_count + 1,
144061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				 sizeof(struct hostapd_nai_realm_data));
144161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (realm == NULL) {
144261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		os_free(offsets);
144361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
144461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
144561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss->nai_realm_data = realm;
144661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
144761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* patch the pointers after realloc */
144861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	for (i = 0; i < bss->nai_realm_count; i++) {
144961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		realm = &bss->nai_realm_data[i];
145061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		for (j = 0; j < MAX_NAI_REALMS; j++) {
145161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			int offs = offsets[i * MAX_NAI_REALMS + j];
145261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (offs >= 0)
145361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				realm->realm[j] = realm->realm_buf + offs;
145461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			else
145561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				realm->realm[j] = NULL;
145661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
145761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
145861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(offsets);
145961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
146061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	realm = &bss->nai_realm_data[bss->nai_realm_count];
146161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_memset(realm, 0, sizeof(*realm));
146261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
146361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = buf;
146461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	realm->encoding = atoi(pos);
146561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(pos, ',');
146661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos == NULL)
146761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		goto fail;
146861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos++;
146961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
147061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	end = os_strchr(pos, ',');
147161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (end) {
147261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		len = end - pos;
147361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		*end = '\0';
147461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else {
147561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		len = os_strlen(pos);
147661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
147761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
147861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (len > MAX_NAI_REALMLEN) {
147961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_ERROR, "Too long a realm string (%d > max %d "
148061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "characters)", (int) len, MAX_NAI_REALMLEN);
148161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		goto fail;
148261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
148361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_memcpy(realm->realm_buf, pos, len);
148461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
148561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (end)
148661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos = end + 1;
148761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else
148861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos = NULL;
148961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
149061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	while (pos && *pos) {
149161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		struct hostapd_nai_realm_eap *eap;
149261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
149361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (realm->eap_method_count >= MAX_NAI_EAP_METHODS) {
149461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_printf(MSG_ERROR, "Too many EAP methods");
149561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			goto fail;
149661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
149761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
149861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		eap = &realm->eap_method[realm->eap_method_count];
149961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		realm->eap_method_count++;
150061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
150161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		end = os_strchr(pos, ',');
150261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (end == NULL)
150361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			end = pos + os_strlen(pos);
150461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
150561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		eap->eap_method = atoi(pos);
150661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		for (;;) {
150761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos = os_strchr(pos, '[');
150861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (pos == NULL || pos > end)
150961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				break;
151061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos++;
151161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (eap->num_auths >= MAX_NAI_AUTH_TYPES) {
151261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_printf(MSG_ERROR, "Too many auth params");
151361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				goto fail;
151461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
151561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			eap->auth_id[eap->num_auths] = atoi(pos);
151661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos = os_strchr(pos, ':');
151761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (pos == NULL || pos > end)
151861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				goto fail;
151961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos++;
152061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			eap->auth_val[eap->num_auths] = atoi(pos);
152161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos = os_strchr(pos, ']');
152261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (pos == NULL || pos > end)
152361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				goto fail;
152461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pos++;
152561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			eap->num_auths++;
152661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
152761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
152861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (*end != ',')
152961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			break;
153061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
153161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		pos = end + 1;
153261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
153361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
153461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* Split realm list into null terminated realms */
153561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	rpos = realm->realm_buf;
153661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	i = 0;
153761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	while (*rpos) {
153861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (i >= MAX_NAI_REALMS) {
153961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_printf(MSG_ERROR, "Too many realms");
154061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			goto fail;
154161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
154261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		realm->realm[i++] = rpos;
154361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		rpos = os_strchr(rpos, ';');
154461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (rpos == NULL)
154561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			break;
154661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		*rpos++ = '\0';
154761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
154861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
154961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss->nai_realm_count++;
155061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
155161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
155261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
155361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtfail:
155461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_printf(MSG_ERROR, "Line %d: invalid nai_realm '%s'", line, buf);
155561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return -1;
155661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
155761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
15581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */
15591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
15601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
156161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_HS20
156261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf,
156361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				 int line)
156461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
156561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	u8 *conn_cap;
156661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	char *pos;
156761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
156861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (bss->hs20_connection_capability_len >= 0xfff0)
156961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
157061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
157161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	conn_cap = os_realloc(bss->hs20_connection_capability,
157261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			      bss->hs20_connection_capability_len + 4);
157361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (conn_cap == NULL)
157461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
157561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
157661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss->hs20_connection_capability = conn_cap;
157761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	conn_cap += bss->hs20_connection_capability_len;
157861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = buf;
157961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	conn_cap[0] = atoi(pos);
158061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(pos, ':');
158161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos == NULL)
158261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
158361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos++;
158461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	WPA_PUT_LE16(conn_cap + 1, atoi(pos));
158561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(pos, ':');
158661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos == NULL)
158761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
158861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos++;
158961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	conn_cap[3] = atoi(pos);
159061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss->hs20_connection_capability_len += 4;
159161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
159261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
159361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
159461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
159561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
159661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int hs20_parse_wan_metrics(struct hostapd_bss_config *bss, char *buf,
159761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				  int line)
159861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
159961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	u8 *wan_metrics;
160061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	char *pos;
160161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
160261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* <WAN Info>:<DL Speed>:<UL Speed>:<DL Load>:<UL Load>:<LMD> */
160361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
160461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wan_metrics = os_zalloc(13);
160561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wan_metrics == NULL)
160661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
160761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
160861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = buf;
160961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* WAN Info */
161061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (hexstr2bin(pos, wan_metrics, 1) < 0)
161161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		goto fail;
161261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos += 2;
161361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (*pos != ':')
161461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		goto fail;
161561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos++;
161661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
161761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* Downlink Speed */
161861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	WPA_PUT_LE32(wan_metrics + 1, atoi(pos));
161961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(pos, ':');
162061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos == NULL)
162161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		goto fail;
162261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos++;
162361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
162461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* Uplink Speed */
162561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	WPA_PUT_LE32(wan_metrics + 5, atoi(pos));
162661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(pos, ':');
162761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos == NULL)
162861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		goto fail;
162961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos++;
163061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
163161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* Downlink Load */
163261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wan_metrics[9] = atoi(pos);
163361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(pos, ':');
163461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos == NULL)
163561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		goto fail;
163661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos++;
163761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
163861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* Uplink Load */
163961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wan_metrics[10] = atoi(pos);
164061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(pos, ':');
164161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos == NULL)
164261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		goto fail;
164361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos++;
164461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
164561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	/* LMD */
164661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	WPA_PUT_LE16(wan_metrics + 11, atoi(pos));
164761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
164861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(bss->hs20_wan_metrics);
164961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	bss->hs20_wan_metrics = wan_metrics;
165061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
165161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
165261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
165361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtfail:
165461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_printf(MSG_ERROR, "Line %d: Invalid hs20_wan_metrics '%s'",
165561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		   line, pos);
165661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(wan_metrics);
165761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return -1;
165861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
165961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
166061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
166161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int hs20_parse_oper_friendly_name(struct hostapd_bss_config *bss,
166261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					 char *pos, int line)
166361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
166461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (parse_lang_string(&bss->hs20_oper_friendly_name,
166561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			      &bss->hs20_oper_friendly_name_count, pos)) {
166661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_ERROR, "Line %d: Invalid "
166761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "hs20_oper_friendly_name '%s'", line, pos);
166861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
166961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
167061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
167161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
167261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_HS20 */
167361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
167461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
167504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WPS_NFC
167604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic struct wpabuf * hostapd_parse_bin(const char *buf)
16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
167804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t len;
167904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpabuf *ret;
16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
168104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	len = os_strlen(buf);
168204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (len & 0x01)
16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
168404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	len /= 2;
16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
168604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	ret = wpabuf_alloc(len);
168704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ret == NULL)
16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
169004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (hexstr2bin(buf, wpabuf_put(ret, len), len)) {
169104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpabuf_free(ret);
16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
169504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return ret;
169604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
169704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WPS_NFC */
16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
170004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_config_fill(struct hostapd_config *conf,
170104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       struct hostapd_bss_config *bss,
170204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       char *buf, char *pos, int line)
170304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
170404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int errors = 0;
17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
170604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	{
17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(buf, "interface") == 0) {
17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strlcpy(conf->bss[0].iface, pos,
17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   sizeof(conf->bss[0].iface));
17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "bridge") == 0) {
17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wds_bridge") == 0) {
17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strlcpy(bss->wds_bridge, pos,
17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   sizeof(bss->wds_bridge));
17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "driver") == 0) {
17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int j;
17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* clear to get error below if setting is invalid */
17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->driver = NULL;
17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			for (j = 0; wpa_drivers[j]; j++) {
17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (os_strcmp(pos, wpa_drivers[j]->name) == 0)
17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				{
17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					conf->driver = wpa_drivers[j];
17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					break;
17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				}
17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (conf->driver == NULL) {
17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid/"
17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "unknown driver '%s'", line, pos);
17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "debug") == 0) {
17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "Line %d: DEPRECATED: 'debug' "
17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "configuration variable is not used "
17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "anymore", line);
17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "logger_syslog_level") == 0) {
17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->logger_syslog_level = atoi(pos);
17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "logger_stdout_level") == 0) {
17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->logger_stdout_level = atoi(pos);
17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "logger_syslog") == 0) {
17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->logger_syslog = atoi(pos);
17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "logger_stdout") == 0) {
17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->logger_stdout = atoi(pos);
17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "dump_file") == 0) {
17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->dump_log_name = os_strdup(pos);
17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ssid") == 0) {
17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ssid.ssid_len = os_strlen(pos);
17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->ssid.ssid_len > HOSTAPD_MAX_SSID_LEN ||
17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    bss->ssid.ssid_len < 1) {
17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid SSID "
17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "'%s'", line, pos);
17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else {
17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_memcpy(bss->ssid.ssid, pos,
17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  bss->ssid.ssid_len);
17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->ssid.ssid_set = 1;
17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
175761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "ssid2") == 0) {
175861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			size_t slen;
175961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			char *str = wpa_config_parse_string(pos, &slen);
176061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (str == NULL || slen < 1 ||
176161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				   slen > HOSTAPD_MAX_SSID_LEN) {
176261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid SSID "
176361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   "'%s'", line, pos);
176461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
176561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			} else {
176661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				os_memcpy(bss->ssid.ssid, str, slen);
176761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				bss->ssid.ssid_len = slen;
176861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				bss->ssid.ssid_set = 1;
176961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
177061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_free(str);
17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "macaddr_acl") == 0) {
17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->macaddr_acl = atoi(pos);
17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->macaddr_acl != ACCEPT_UNLESS_DENIED &&
17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    bss->macaddr_acl != DENY_UNLESS_ACCEPTED &&
17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: unknown "
17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "macaddr_acl %d",
17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, bss->macaddr_acl);
17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "accept_mac_file") == 0) {
17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_read_maclist(pos, &bss->accept_mac,
17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							&bss->num_accept_mac))
17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			{
17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Failed to "
17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "read accept_mac_file '%s'",
17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, pos);
17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "deny_mac_file") == 0) {
17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_read_maclist(pos, &bss->deny_mac,
17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							&bss->num_deny_mac)) {
17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Failed to "
17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "read deny_mac_file '%s'",
17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, pos);
17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wds_sta") == 0) {
17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wds_sta = atoi(pos);
17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ap_isolate") == 0) {
18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->isolate = atoi(pos);
18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ap_max_inactivity") == 0) {
18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ap_max_inactivity = atoi(pos);
18031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "skip_inactivity_poll") == 0) {
18041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->skip_inactivity_poll = atoi(pos);
18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "country_code") == 0) {
18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(conf->country, pos, 2);
18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* FIX: make this configurable */
18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->country[2] = ' ';
18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ieee80211d") == 0) {
18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->ieee80211d = atoi(pos);
18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ieee8021x") == 0) {
18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ieee802_1x = atoi(pos);
18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eapol_version") == 0) {
18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eapol_version = atoi(pos);
18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->eapol_version < 1 ||
18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    bss->eapol_version > 2) {
18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid EAPOL "
18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "version (%d): '%s'.",
18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, bss->eapol_version, pos);
18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else
18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_DEBUG, "eapol_version=%d",
18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->eapol_version);
18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER
18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_authenticator") == 0) {
18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eap_server = atoi(pos);
18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Line %d: obsolete "
18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "eap_authenticator used; this has been "
18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "renamed to eap_server", line);
18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_server") == 0) {
18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eap_server = atoi(pos);
18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_user_file") == 0) {
18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_read_eap_user(pos, bss))
18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ca_cert") == 0) {
18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->ca_cert);
18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ca_cert = os_strdup(pos);
18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "server_cert") == 0) {
18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->server_cert);
18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->server_cert = os_strdup(pos);
18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "private_key") == 0) {
18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->private_key);
18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->private_key = os_strdup(pos);
18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "private_key_passwd") == 0) {
18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->private_key_passwd);
18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->private_key_passwd = os_strdup(pos);
18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "check_crl") == 0) {
18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->check_crl = atoi(pos);
18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "dh_file") == 0) {
18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->dh_file);
18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->dh_file = os_strdup(pos);
18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "fragment_size") == 0) {
18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->fragment_size = atoi(pos);
18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_FAST
18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "pac_opaque_encr_key") == 0) {
18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->pac_opaque_encr_key);
18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->pac_opaque_encr_key = os_malloc(16);
18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->pac_opaque_encr_key == NULL) {
18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: No memory for "
18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "pac_opaque_encr_key", line);
18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else if (hexstr2bin(pos, bss->pac_opaque_encr_key,
18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      16)) {
18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "pac_opaque_encr_key", line);
18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_fast_a_id") == 0) {
18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			size_t idlen = os_strlen(pos);
18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (idlen & 1) {
18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "eap_fast_a_id", line);
18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else {
18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_free(bss->eap_fast_a_id);
18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->eap_fast_a_id = os_malloc(idlen / 2);
18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (bss->eap_fast_a_id == NULL ||
18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    hexstr2bin(pos, bss->eap_fast_a_id,
18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       idlen / 2)) {
18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_printf(MSG_ERROR, "Line %d: "
18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   "Failed to parse "
18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						   "eap_fast_a_id", line);
18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					errors++;
18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				} else
18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					bss->eap_fast_a_id_len = idlen / 2;
18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_fast_a_id_info") == 0) {
18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->eap_fast_a_id_info);
18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eap_fast_a_id_info = os_strdup(pos);
18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_fast_prov") == 0) {
18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eap_fast_prov = atoi(pos);
18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "pac_key_lifetime") == 0) {
18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->pac_key_lifetime = atoi(pos);
18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "pac_key_refresh_time") == 0) {
18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->pac_key_refresh_time = atoi(pos);
18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_FAST */
18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_SIM
18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_sim_db") == 0) {
18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->eap_sim_db);
19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eap_sim_db = os_strdup(pos);
19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_sim_aka_result_ind") == 0) {
19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eap_sim_aka_result_ind = atoi(pos);
19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_SIM */
19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC
19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "tnc") == 0) {
19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->tnc = atoi(pos);
19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */
19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_PWD
19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "pwd_group") == 0) {
19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->pwd_group = atoi(pos);
19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_PWD */
19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER */
19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_message") == 0) {
19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			char *term;
19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eap_req_id_text = os_strdup(pos);
19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->eap_req_id_text == NULL) {
19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Failed to "
19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "allocate memory for "
19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "eap_req_id_text", line);
19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
192104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return errors;
19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eap_req_id_text_len =
19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_strlen(bss->eap_req_id_text);
19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			term = os_strstr(bss->eap_req_id_text, "\\0");
19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (term) {
19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*term++ = '\0';
19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_memmove(term, term + 1,
19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->eap_req_id_text_len -
19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   (term - bss->eap_req_id_text) - 1);
19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->eap_req_id_text_len--;
19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wep_key_len_broadcast") == 0) {
19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->default_wep_key_len = atoi(pos);
19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->default_wep_key_len > 13) {
19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "key len %lu (= %lu bits)", line,
19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   (unsigned long)
19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->default_wep_key_len,
19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   (unsigned long)
19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->default_wep_key_len * 8);
19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wep_key_len_unicast") == 0) {
19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->individual_wep_key_len = atoi(pos);
19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->individual_wep_key_len < 0 ||
19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    bss->individual_wep_key_len > 13) {
19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "key len %d (= %d bits)", line,
19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->individual_wep_key_len,
19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->individual_wep_key_len * 8);
19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wep_rekey_period") == 0) {
19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wep_rekeying_period = atoi(pos);
19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->wep_rekeying_period < 0) {
19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "period %d",
19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, bss->wep_rekeying_period);
19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eap_reauth_period") == 0) {
19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eap_reauth_period = atoi(pos);
19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->eap_reauth_period < 0) {
19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "period %d",
19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, bss->eap_reauth_period);
19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "eapol_key_index_workaround") == 0) {
19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->eapol_key_index_workaround = atoi(pos);
19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IAPP
19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "iapp_interface") == 0) {
19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ieee802_11f = 1;
19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strlcpy(bss->iapp_iface, pos,
19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   sizeof(bss->iapp_iface));
19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IAPP */
19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "own_ip_addr") == 0) {
19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) {
19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid IP "
19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "address '%s'", line, pos);
19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "nas_identifier") == 0) {
19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->nas_identifier = os_strdup(pos);
19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS
19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "auth_server_addr") == 0) {
19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_read_radius_addr(
19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &bss->radius->auth_servers,
19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &bss->radius->num_auth_servers, pos, 1812,
19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &bss->radius->auth_server)) {
19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid IP "
19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "address '%s'", line, pos);
19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (bss->radius->auth_server &&
19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   os_strcmp(buf, "auth_server_port") == 0) {
19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius->auth_server->port = atoi(pos);
19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (bss->radius->auth_server &&
20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   os_strcmp(buf, "auth_server_shared_secret") == 0) {
20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int len = os_strlen(pos);
20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (len == 0) {
20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				/* RFC 2865, Ch. 3 */
20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: empty shared "
20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "secret is not allowed.", line);
20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius->auth_server->shared_secret =
20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				(u8 *) os_strdup(pos);
20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius->auth_server->shared_secret_len = len;
20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "acct_server_addr") == 0) {
20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_read_radius_addr(
20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &bss->radius->acct_servers,
20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &bss->radius->num_acct_servers, pos, 1813,
20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &bss->radius->acct_server)) {
20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid IP "
20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "address '%s'", line, pos);
20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (bss->radius->acct_server &&
20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   os_strcmp(buf, "acct_server_port") == 0) {
20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius->acct_server->port = atoi(pos);
20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (bss->radius->acct_server &&
20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   os_strcmp(buf, "acct_server_shared_secret") == 0) {
20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int len = os_strlen(pos);
20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (len == 0) {
20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				/* RFC 2865, Ch. 3 */
20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: empty shared "
20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "secret is not allowed.", line);
20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius->acct_server->shared_secret =
20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				(u8 *) os_strdup(pos);
20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius->acct_server->shared_secret_len = len;
20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "radius_retry_primary_interval") ==
20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   0) {
20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius->retry_primary_interval = atoi(pos);
20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "radius_acct_interim_interval") == 0)
20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->acct_interim_interval = atoi(pos);
204104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "radius_request_cui") == 0) {
204204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->radius_request_cui = atoi(pos);
204304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "radius_auth_req_attr") == 0) {
204404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			struct hostapd_radius_attr *attr, *a;
204504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			attr = hostapd_parse_radius_attr(pos);
204604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (attr == NULL) {
204704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
204804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   "radius_auth_req_attr", line);
204904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				errors++;
205004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			} else if (bss->radius_auth_req_attr == NULL) {
205104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				bss->radius_auth_req_attr = attr;
205204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			} else {
205304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				a = bss->radius_auth_req_attr;
205404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				while (a->next)
205504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					a = a->next;
205604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				a->next = attr;
205704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
205804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "radius_acct_req_attr") == 0) {
205904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			struct hostapd_radius_attr *attr, *a;
206004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			attr = hostapd_parse_radius_attr(pos);
206104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (attr == NULL) {
206204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
206304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   "radius_acct_req_attr", line);
206404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				errors++;
206504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			} else if (bss->radius_acct_req_attr == NULL) {
206604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				bss->radius_acct_req_attr = attr;
206704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			} else {
206804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				a = bss->radius_acct_req_attr;
206904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				while (a->next)
207004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					a = a->next;
207104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				a->next = attr;
207204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
207304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "radius_das_port") == 0) {
207404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->radius_das_port = atoi(pos);
207504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "radius_das_client") == 0) {
207604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (hostapd_parse_das_client(bss, pos) < 0) {
207704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
207804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   "DAS client", line);
207904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				errors++;
208004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
208104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "radius_das_time_window") == 0) {
208204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->radius_das_time_window = atoi(pos);
208304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "radius_das_require_event_timestamp")
208404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   == 0) {
208504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->radius_das_require_event_timestamp = atoi(pos);
20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */
20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "auth_algs") == 0) {
20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->auth_algs = atoi(pos);
20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->auth_algs == 0) {
20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: no "
20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "authentication algorithms allowed",
20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line);
20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "max_num_sta") == 0) {
20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->max_num_sta = atoi(pos);
20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->max_num_sta < 0 ||
20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    bss->max_num_sta > MAX_STA_COUNT) {
20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "max_num_sta=%d; allowed range "
21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "0..%d", line, bss->max_num_sta,
21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   MAX_STA_COUNT);
21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa") == 0) {
21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wpa = atoi(pos);
21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa_group_rekey") == 0) {
21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wpa_group_rekey = atoi(pos);
21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa_strict_rekey") == 0) {
21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wpa_strict_rekey = atoi(pos);
21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa_gmk_rekey") == 0) {
21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wpa_gmk_rekey = atoi(pos);
21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa_ptk_rekey") == 0) {
21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wpa_ptk_rekey = atoi(pos);
21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa_passphrase") == 0) {
21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int len = os_strlen(pos);
21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (len < 8 || len > 63) {
21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid WPA "
21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "passphrase length %d (expected "
21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "8..63)", line, len);
21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else {
21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_free(bss->ssid.wpa_passphrase);
21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->ssid.wpa_passphrase = os_strdup(pos);
212504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				os_free(bss->ssid.wpa_psk);
212604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				bss->ssid.wpa_psk = NULL;
21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa_psk") == 0) {
21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->ssid.wpa_psk);
21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ssid.wpa_psk =
21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_zalloc(sizeof(struct hostapd_wpa_psk));
21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->ssid.wpa_psk == NULL)
21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else if (hexstr2bin(pos, bss->ssid.wpa_psk->psk,
21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    PMK_LEN) ||
21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 pos[PMK_LEN * 2] != '\0') {
21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid PSK "
21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "'%s'.", line, pos);
21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else {
21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->ssid.wpa_psk->group = 1;
214204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				os_free(bss->ssid.wpa_passphrase);
214304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				bss->ssid.wpa_passphrase = NULL;
21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa_psk_file") == 0) {
21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->ssid.wpa_psk_file);
21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ssid.wpa_psk_file = os_strdup(pos);
21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!bss->ssid.wpa_psk_file) {
21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: allocation "
21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "failed", line);
21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa_key_mgmt") == 0) {
21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wpa_key_mgmt =
21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				hostapd_config_parse_key_mgmt(line, pos);
21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->wpa_key_mgmt == -1)
21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "wpa_psk_radius") == 0) {
21591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->wpa_psk_radius = atoi(pos);
21601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
21611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			    bss->wpa_psk_radius != PSK_RADIUS_ACCEPTED &&
21621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			    bss->wpa_psk_radius != PSK_RADIUS_REQUIRED) {
21631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: unknown "
21641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   "wpa_psk_radius %d",
21651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   line, bss->wpa_psk_radius);
21661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				errors++;
21671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wpa_pairwise") == 0) {
21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wpa_pairwise =
21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				hostapd_config_parse_cipher(line, pos);
21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->wpa_pairwise == -1 ||
21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    bss->wpa_pairwise == 0)
21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else if (bss->wpa_pairwise &
21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  WPA_CIPHER_WEP104)) {
21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: unsupported "
21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "pairwise cipher suite '%s'",
21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->wpa_pairwise, pos);
21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "rsn_pairwise") == 0) {
21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->rsn_pairwise =
21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				hostapd_config_parse_cipher(line, pos);
21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->rsn_pairwise == -1 ||
21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    bss->rsn_pairwise == 0)
21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else if (bss->rsn_pairwise &
21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  WPA_CIPHER_WEP104)) {
21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: unsupported "
21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "pairwise cipher suite '%s'",
21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->rsn_pairwise, pos);
21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_PREAUTH
21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "rsn_preauth") == 0) {
21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->rsn_preauth = atoi(pos);
21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "rsn_preauth_interfaces") == 0) {
22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->rsn_preauth_interfaces = os_strdup(pos);
22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_PREAUTH */
22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_PEERKEY
22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "peerkey") == 0) {
22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->peerkey = atoi(pos);
22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_PEERKEY */
22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "mobility_domain") == 0) {
22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN ||
22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    hexstr2bin(pos, bss->mobility_domain,
22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       MOBILITY_DOMAIN_ID_LEN) != 0) {
22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_DEBUG, "Line %d: Invalid "
22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "mobility_domain '%s'", line, pos);
22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
221404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return errors;
22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "r1_key_holder") == 0) {
22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strlen(pos) != 2 * FT_R1KH_ID_LEN ||
22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    hexstr2bin(pos, bss->r1_key_holder,
22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       FT_R1KH_ID_LEN) != 0) {
22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_DEBUG, "Line %d: Invalid "
22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "r1_key_holder '%s'", line, pos);
22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
222304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return errors;
22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "r0_key_lifetime") == 0) {
22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->r0_key_lifetime = atoi(pos);
22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "reassociation_deadline") == 0) {
22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->reassociation_deadline = atoi(pos);
22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "r0kh") == 0) {
22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (add_r0kh(bss, pos) < 0) {
22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_DEBUG, "Line %d: Invalid "
22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "r0kh '%s'", line, pos);
22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
223404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return errors;
22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "r1kh") == 0) {
22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (add_r1kh(bss, pos) < 0) {
22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_DEBUG, "Line %d: Invalid "
22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "r1kh '%s'", line, pos);
22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
224104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return errors;
22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "pmk_r1_push") == 0) {
22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->pmk_r1_push = atoi(pos);
22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ft_over_ds") == 0) {
22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ft_over_ds = atoi(pos);
22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_CTRL_IFACE
22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ctrl_interface") == 0) {
22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->ctrl_interface);
22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ctrl_interface = os_strdup(pos);
22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ctrl_interface_group") == 0) {
22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS
22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			struct group *grp;
22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			char *endp;
22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const char *group = pos;
22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			grp = getgrnam(group);
22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (grp) {
22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->ctrl_interface_gid = grp->gr_gid;
22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->ctrl_interface_gid_set = 1;
22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   " (from group name '%s')",
22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->ctrl_interface_gid, group);
226504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return errors;
22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Group name not found - try to parse this as gid */
22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ctrl_interface_gid = strtol(group, &endp, 10);
22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (*group == '\0' || *endp != '\0') {
22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "'%s'", line, group);
22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
227404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return errors;
22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ctrl_interface_gid_set = 1;
22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   bss->ctrl_interface_gid);
22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */
22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_CTRL_IFACE */
22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef RADIUS_SERVER
22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "radius_server_clients") == 0) {
22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->radius_server_clients);
22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius_server_clients = os_strdup(pos);
22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "radius_server_auth_port") == 0) {
22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius_server_auth_port = atoi(pos);
22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "radius_server_ipv6") == 0) {
22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->radius_server_ipv6 = atoi(pos);
22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* RADIUS_SERVER */
22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "test_socket") == 0) {
22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->test_socket);
22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->test_socket = os_strdup(pos);
22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "use_pae_group_addr") == 0) {
22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->use_pae_group_addr = atoi(pos);
22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "hw_mode") == 0) {
22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strcmp(pos, "a") == 0)
22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				conf->hw_mode = HOSTAPD_MODE_IEEE80211A;
22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else if (os_strcmp(pos, "b") == 0)
22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else if (os_strcmp(pos, "g") == 0)
23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else {
23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: unknown "
23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "hw_mode '%s'", line, pos);
23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
23071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "wps_rf_bands") == 0) {
23081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (os_strcmp(pos, "a") == 0)
23091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				bss->wps_rf_bands = WPS_RF_50GHZ;
23101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (os_strcmp(pos, "g") == 0 ||
23111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 os_strcmp(pos, "b") == 0)
23121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				bss->wps_rf_bands = WPS_RF_24GHZ;
23131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (os_strcmp(pos, "ag") == 0 ||
23141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 os_strcmp(pos, "ga") == 0)
23151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				bss->wps_rf_bands =
23161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					WPS_RF_24GHZ | WPS_RF_50GHZ;
23171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else {
23181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: unknown "
23191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   "wps_rf_band '%s'", line, pos);
23201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				errors++;
23211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "channel") == 0) {
23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->channel = atoi(pos);
23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "beacon_int") == 0) {
23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int val = atoi(pos);
23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* MIB defines range as 1..65535, but very small values
23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * cause problems with the current implementation.
23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * Since it is unlikely that this small numbers are
23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * useful in real life scenarios, do not allow beacon
23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * period to be set below 15 TU. */
23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (val < 15 || val > 65535) {
23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "beacon_int %d (expected "
23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "15..65535)", line, val);
23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else
23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				conf->beacon_int = val;
23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "dtim_period") == 0) {
23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->dtim_period = atoi(pos);
23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->dtim_period < 1 || bss->dtim_period > 255) {
23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "dtim_period %d",
23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, bss->dtim_period);
23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "rts_threshold") == 0) {
23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->rts_threshold = atoi(pos);
23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (conf->rts_threshold < 0 ||
23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    conf->rts_threshold > 2347) {
23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "rts_threshold %d",
23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, conf->rts_threshold);
23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "fragm_threshold") == 0) {
23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->fragm_threshold = atoi(pos);
23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (conf->fragm_threshold < 256 ||
23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    conf->fragm_threshold > 2346) {
23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "fragm_threshold %d",
23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, conf->fragm_threshold);
23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "send_probe_response") == 0) {
23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int val = atoi(pos);
23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (val != 0 && val != 1) {
23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "send_probe_response %d (expected "
23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "0 or 1)", line, val);
23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else
23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				conf->send_probe_response = val;
23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "supported_rates") == 0) {
23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_parse_rates(&conf->supported_rates, pos)) {
23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid rate "
23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "list", line);
23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "basic_rates") == 0) {
23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_parse_rates(&conf->basic_rates, pos)) {
23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid rate "
23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "list", line);
23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "preamble") == 0) {
23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (atoi(pos))
23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				conf->preamble = SHORT_PREAMBLE;
23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				conf->preamble = LONG_PREAMBLE;
23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ignore_broadcast_ssid") == 0) {
23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ignore_broadcast_ssid = atoi(pos);
23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wep_default_key") == 0) {
23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ssid.wep.idx = atoi(pos);
23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->ssid.wep.idx > 3) {
23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Invalid "
23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "wep_default_key index %d",
23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   bss->ssid.wep.idx);
23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wep_key0") == 0 ||
24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   os_strcmp(buf, "wep_key1") == 0 ||
24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   os_strcmp(buf, "wep_key2") == 0 ||
24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   os_strcmp(buf, "wep_key3") == 0) {
24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_read_wep(&bss->ssid.wep,
24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    buf[7] - '0', pos)) {
24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "key '%s'", line, buf);
24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_VLAN
24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "dynamic_vlan") == 0) {
24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ssid.dynamic_vlan = atoi(pos);
24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "vlan_file") == 0) {
24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_read_vlan_file(bss, pos)) {
24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: failed to "
24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "read VLAN file '%s'", line, pos);
24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
241861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "vlan_naming") == 0) {
241961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->ssid.vlan_naming = atoi(pos);
242061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (bss->ssid.vlan_naming >= DYNAMIC_VLAN_NAMING_END ||
242161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    bss->ssid.vlan_naming < 0) {
242261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
242361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   "naming scheme %d", line,
242461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt                                           bss->ssid.vlan_naming);
242561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
242661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt                        }
24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_FULL_DYNAMIC_VLAN
24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "vlan_tagged_interface") == 0) {
24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ssid.vlan_tagged_interface = os_strdup(pos);
24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_FULL_DYNAMIC_VLAN */
24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_VLAN */
24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ap_table_max_size") == 0) {
24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->ap_table_max_size = atoi(pos);
24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ap_table_expiration_time") == 0) {
24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->ap_table_expiration_time = atoi(pos);
24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strncmp(buf, "tx_queue_", 9) == 0) {
24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_tx_queue(conf, buf, pos)) {
24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid TX "
24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "queue item", line);
24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wme_enabled") == 0 ||
24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   os_strcmp(buf, "wmm_enabled") == 0) {
24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wmm_enabled = atoi(pos);
24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "uapsd_advertisement_enabled") == 0) {
24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wmm_uapsd = atoi(pos);
24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strncmp(buf, "wme_ac_", 7) == 0 ||
24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   os_strncmp(buf, "wmm_ac_", 7) == 0) {
244961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (hostapd_config_wmm_ac(conf->wmm_ac_params, buf,
245061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						  pos)) {
24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid WMM "
24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "ac item", line);
24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "bss") == 0) {
24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_bss(conf, pos)) {
24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid bss "
24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "item", line);
24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "bssid") == 0) {
24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hwaddr_aton(pos, bss->bssid)) {
24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid bssid "
24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "item", line);
24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ieee80211w") == 0) {
24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ieee80211w = atoi(pos);
24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "assoc_sa_query_max_timeout") == 0) {
24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->assoc_sa_query_max_timeout = atoi(pos);
24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->assoc_sa_query_max_timeout == 0) {
24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "assoc_sa_query_max_timeout", line);
24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "assoc_sa_query_retry_timeout") == 0)
24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		{
24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->assoc_sa_query_retry_timeout = atoi(pos);
24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->assoc_sa_query_retry_timeout == 0) {
24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "assoc_sa_query_retry_timeout",
24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line);
24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N
24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ieee80211n") == 0) {
24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->ieee80211n = atoi(pos);
24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ht_capab") == 0) {
24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hostapd_config_ht_capab(conf, pos) < 0) {
24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "ht_capab", line);
24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "require_ht") == 0) {
24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			conf->require_ht = atoi(pos);
24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */
249904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_IEEE80211AC
250004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "ieee80211ac") == 0) {
250104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			conf->ieee80211ac = atoi(pos);
250204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "vht_capab") == 0) {
250304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (hostapd_config_vht_capab(conf, pos) < 0) {
250404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
250504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   "vht_capab", line);
250604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				errors++;
250704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
250861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "require_vht") == 0) {
250961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			conf->require_vht = atoi(pos);
251004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "vht_oper_chwidth") == 0) {
251161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			conf->vht_oper_chwidth = atoi(pos);
251261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "vht_oper_centr_freq_seg0_idx") == 0)
251361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		{
251461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			conf->vht_oper_centr_freq_seg0_idx = atoi(pos);
251504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_IEEE80211AC */
25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "max_listen_interval") == 0) {
25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->max_listen_interval = atoi(pos);
2518c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		} else if (os_strcmp(buf, "disable_pmksa_caching") == 0) {
2519c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt			bss->disable_pmksa_caching = atoi(pos);
25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "okc") == 0) {
25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->okc = atoi(pos);
25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wps_state") == 0) {
25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wps_state = atoi(pos);
25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->wps_state < 0 || bss->wps_state > 2) {
25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "wps_state", line);
25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ap_setup_locked") == 0) {
25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ap_setup_locked = atoi(pos);
25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "uuid") == 0) {
25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (uuid_str2bin(pos, bss->uuid)) {
25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid UUID",
25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line);
25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wps_pin_requests") == 0) {
25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->wps_pin_requests);
25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wps_pin_requests = os_strdup(pos);
25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "device_name") == 0) {
25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strlen(pos) > 32) {
25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Too long "
25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "device_name", line);
25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->device_name);
25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->device_name = os_strdup(pos);
25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "manufacturer") == 0) {
25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strlen(pos) > 64) {
25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Too long "
25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "manufacturer", line);
25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->manufacturer);
25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->manufacturer = os_strdup(pos);
25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "model_name") == 0) {
25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strlen(pos) > 32) {
25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Too long "
25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "model_name", line);
25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->model_name);
25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->model_name = os_strdup(pos);
25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "model_number") == 0) {
25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strlen(pos) > 32) {
25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Too long "
25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "model_number", line);
25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->model_number);
25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->model_number = os_strdup(pos);
25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "serial_number") == 0) {
25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strlen(pos) > 32) {
25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Too long "
25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "serial_number", line);
25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->serial_number);
25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->serial_number = os_strdup(pos);
25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "device_type") == 0) {
25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (wps_dev_type_str2bin(pos, bss->device_type))
25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "config_methods") == 0) {
25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->config_methods);
25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->config_methods = os_strdup(pos);
25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "os_version") == 0) {
25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (hexstr2bin(pos, bss->os_version, 4)) {
25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "os_version", line);
25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ap_pin") == 0) {
25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->ap_pin);
25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ap_pin = os_strdup(pos);
25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "skip_cred_build") == 0) {
25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->skip_cred_build = atoi(pos);
25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "extra_cred") == 0) {
25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->extra_cred);
26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->extra_cred =
26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				(u8 *) os_readfile(pos, &bss->extra_cred_len);
26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->extra_cred == NULL) {
26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: could not "
26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "read Credentials from '%s'",
26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, pos);
26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "wps_cred_processing") == 0) {
26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->wps_cred_processing = atoi(pos);
26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "ap_settings") == 0) {
26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->ap_settings);
26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->ap_settings =
26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				(u8 *) os_readfile(pos, &bss->ap_settings_len);
26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (bss->ap_settings == NULL) {
26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: could not "
26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   "read AP Settings from '%s'",
26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   line, pos);
26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				errors++;
26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "upnp_iface") == 0) {
26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->upnp_iface = os_strdup(pos);
26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "friendly_name") == 0) {
26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->friendly_name);
26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->friendly_name = os_strdup(pos);
26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "manufacturer_url") == 0) {
26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->manufacturer_url);
26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->manufacturer_url = os_strdup(pos);
26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "model_description") == 0) {
26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->model_description);
26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->model_description = os_strdup(pos);
26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "model_url") == 0) {
26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->model_url);
26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->model_url = os_strdup(pos);
26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "upc") == 0) {
26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(bss->upc);
26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->upc = os_strdup(pos);
263787fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen		} else if (os_strcmp(buf, "pbc_in_m1") == 0) {
263887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen			bss->pbc_in_m1 = atoi(pos);
263904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WPS_NFC
264004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "wps_nfc_dev_pw_id") == 0) {
264104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->wps_nfc_dev_pw_id = atoi(pos);
264204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (bss->wps_nfc_dev_pw_id < 0x10 ||
264304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    bss->wps_nfc_dev_pw_id > 0xffff) {
264404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
264504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   "wps_nfc_dev_pw_id value", line);
264604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				errors++;
264704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
264804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "wps_nfc_dh_pubkey") == 0) {
264904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpabuf_free(bss->wps_nfc_dh_pubkey);
265004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->wps_nfc_dh_pubkey = hostapd_parse_bin(pos);
265104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "wps_nfc_dh_privkey") == 0) {
265204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpabuf_free(bss->wps_nfc_dh_privkey);
265304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->wps_nfc_dh_privkey = hostapd_parse_bin(pos);
265404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "wps_nfc_dev_pw") == 0) {
265504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpabuf_free(bss->wps_nfc_dev_pw);
265604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->wps_nfc_dev_pw = hostapd_parse_bin(pos);
265704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WPS_NFC */
26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER
26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "manage_p2p") == 0) {
26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int manage = atoi(pos);
26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (manage)
26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->p2p |= P2P_MANAGE;
26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->p2p &= ~P2P_MANAGE;
26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "allow_cross_connection") == 0) {
26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (atoi(pos))
26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->p2p |= P2P_ALLOW_CROSS_CONNECTION;
26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->p2p &= ~P2P_ALLOW_CROSS_CONNECTION;
26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */
26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "disassoc_low_ack") == 0) {
26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss->disassoc_low_ack = atoi(pos);
26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "tdls_prohibit") == 0) {
26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int val = atoi(pos);
26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (val)
26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->tdls |= TDLS_PROHIBIT;
26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->tdls &= ~TDLS_PROHIBIT;
26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "tdls_prohibit_chan_switch") == 0) {
26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int val = atoi(pos);
26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (val)
26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->tdls |= TDLS_PROHIBIT_CHAN_SWITCH;
26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->tdls &= ~TDLS_PROHIBIT_CHAN_SWITCH;
26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_RSN_TESTING
26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (os_strcmp(buf, "rsn_testing") == 0) {
26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			extern int rsn_testing;
26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			rsn_testing = atoi(pos);
26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_RSN_TESTING */
26911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "time_advertisement") == 0) {
26921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->time_advertisement = atoi(pos);
26931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "time_zone") == 0) {
26941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			size_t tz_len = os_strlen(pos);
26951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (tz_len < 4 || tz_len > 255) {
26961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				wpa_printf(MSG_DEBUG, "Line %d: invalid "
26971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   "time_zone", line);
26981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				errors++;
269904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return errors;
27001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
27011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			os_free(bss->time_zone);
27021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->time_zone = os_strdup(pos);
27031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (bss->time_zone == NULL)
27041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				errors++;
27051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING
27061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "interworking") == 0) {
27071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->interworking = atoi(pos);
27081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "access_network_type") == 0) {
27091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->access_network_type = atoi(pos);
27101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (bss->access_network_type < 0 ||
27111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			    bss->access_network_type > 15) {
27121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
27131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   "access_network_type", line);
27141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				errors++;
27151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
27161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "internet") == 0) {
27171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->internet = atoi(pos);
27181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "asra") == 0) {
27191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->asra = atoi(pos);
27201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "esr") == 0) {
27211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->esr = atoi(pos);
27221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "uesa") == 0) {
27231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->uesa = atoi(pos);
27241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "venue_group") == 0) {
27251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->venue_group = atoi(pos);
27261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->venue_info_set = 1;
27271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "venue_type") == 0) {
27281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->venue_type = atoi(pos);
27291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->venue_info_set = 1;
27301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "hessid") == 0) {
27311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (hwaddr_aton(pos, bss->hessid)) {
27321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: invalid "
27331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   "hessid", line);
27341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				errors++;
27351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
27361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "roaming_consortium") == 0) {
27371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (parse_roaming_consortium(bss, pos, line) < 0)
27381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				errors++;
273904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "venue_name") == 0) {
274004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (parse_venue_name(bss, pos, line) < 0)
274104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				errors++;
274261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "network_auth_type") == 0) {
274361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			u8 auth_type;
274461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			u16 redirect_url_len;
274561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (hexstr2bin(pos, &auth_type, 1)) {
274661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
274761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   "network_auth_type '%s'",
274861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   line, pos);
274961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
275061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return errors;
275161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
275261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (auth_type == 0 || auth_type == 2)
275361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				redirect_url_len = os_strlen(pos + 2);
275461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			else
275561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				redirect_url_len = 0;
275661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_free(bss->network_auth_type);
275761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->network_auth_type =
275861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				os_malloc(redirect_url_len + 3 + 1);
275961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (bss->network_auth_type == NULL) {
276061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
276161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return errors;
276261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
276361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			*bss->network_auth_type = auth_type;
276461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			WPA_PUT_LE16(bss->network_auth_type + 1,
276561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				     redirect_url_len);
276661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (redirect_url_len)
276761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				os_memcpy(bss->network_auth_type + 3,
276861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					  pos + 2, redirect_url_len);
276961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->network_auth_type_len = 3 + redirect_url_len;
277061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "ipaddr_type_availability") == 0) {
277161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (hexstr2bin(pos, &bss->ipaddr_type_availability, 1))
277261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			{
277361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
277461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   "ipaddr_type_availability '%s'",
277561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   line, pos);
277661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				bss->ipaddr_type_configured = 0;
277761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
277861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return errors;
277961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
278061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->ipaddr_type_configured = 1;
278161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "domain_name") == 0) {
278261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			int j, num_domains, domain_len, domain_list_len = 0;
278361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			char *tok_start, *tok_prev;
278461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			u8 *domain_list, *domain_ptr;
278561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
278661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			domain_list_len = os_strlen(pos) + 1;
278761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			domain_list = os_malloc(domain_list_len);
278861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (domain_list == NULL) {
278961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
279061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return errors;
279161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
279261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
279361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			domain_ptr = domain_list;
279461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			tok_prev = pos;
279561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			num_domains = 1;
279661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			while ((tok_prev = os_strchr(tok_prev, ','))) {
279761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				num_domains++;
279861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				tok_prev++;
279961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
280061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			tok_prev = pos;
280161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			for (j = 0; j < num_domains; j++) {
280261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				tok_start = os_strchr(tok_prev, ',');
280361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				if (tok_start) {
280461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					domain_len = tok_start - tok_prev;
280561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					*domain_ptr = domain_len;
280661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					os_memcpy(domain_ptr + 1, tok_prev,
280761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						  domain_len);
280861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					domain_ptr += domain_len + 1;
280961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					tok_prev = ++tok_start;
281061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				} else {
281161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					domain_len = os_strlen(tok_prev);
281261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					*domain_ptr = domain_len;
281361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					os_memcpy(domain_ptr + 1, tok_prev,
281461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						  domain_len);
281561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					domain_ptr += domain_len + 1;
281661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				}
281761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
281861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
281961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_free(bss->domain_name);
282061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->domain_name = domain_list;
282161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->domain_name_len = domain_list_len;
282261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "anqp_3gpp_cell_net") == 0) {
282361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (parse_3gpp_cell_net(bss, pos, line) < 0)
282461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
282561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "nai_realm") == 0) {
282661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (parse_nai_realm(bss, pos, line) < 0)
282761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
282804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "gas_frag_limit") == 0) {
282904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->gas_frag_limit = atoi(pos);
283004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (os_strcmp(buf, "gas_comeback_delay") == 0) {
283104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->gas_comeback_delay = atoi(pos);
28321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */
28331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_RADIUS_TEST
28341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (os_strcmp(buf, "dump_msk_file") == 0) {
28351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			os_free(bss->dump_msk_file);
28361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			bss->dump_msk_file = os_strdup(pos);
28371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_RADIUS_TEST */
283861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_HS20
283961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "hs20") == 0) {
284061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->hs20 = atoi(pos);
284161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "disable_dgaf") == 0) {
284261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->disable_dgaf = atoi(pos);
284361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "hs20_oper_friendly_name") == 0) {
284461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (hs20_parse_oper_friendly_name(bss, pos, line) < 0)
284561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
284661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "hs20_wan_metrics") == 0) {
284761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (hs20_parse_wan_metrics(bss, pos, line) < 0) {
284861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
284961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return errors;
285061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
285161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "hs20_conn_capab") == 0) {
285261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (hs20_parse_conn_capab(bss, pos, line) < 0) {
285361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
285461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return errors;
285561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
285661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "hs20_operating_class") == 0) {
285761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			u8 *oper_class;
285861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			size_t oper_class_len;
285961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			oper_class_len = os_strlen(pos);
286061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (oper_class_len < 2 || (oper_class_len & 0x01)) {
286161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
286261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   "hs20_operating_class '%s'",
286361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   line, pos);
286461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
286561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return errors;
286661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
286761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			oper_class_len /= 2;
286861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			oper_class = os_malloc(oper_class_len);
286961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (oper_class == NULL) {
287061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
287161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return errors;
287261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
287361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (hexstr2bin(pos, oper_class, oper_class_len)) {
287461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
287561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   "hs20_operating_class '%s'",
287661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   line, pos);
287761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				os_free(oper_class);
287861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				errors++;
287961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return errors;
288061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
288161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_free(bss->hs20_operating_class);
288261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->hs20_operating_class = oper_class;
288361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->hs20_operating_class_len = oper_class_len;
288461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_HS20 */
288561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else if (os_strcmp(buf, "vendor_elements") == 0) {
288661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			struct wpabuf *elems;
288761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			size_t len = os_strlen(pos);
288861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (len & 0x01) {
288961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
289061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   "vendor_elements '%s'", line, pos);
289161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return 1;
289261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
289361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			len /= 2;
289461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (len == 0) {
289561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpabuf_free(bss->vendor_elements);
289661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				bss->vendor_elements = NULL;
289761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return 0;
289861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
289961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
290061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			elems = wpabuf_alloc(len);
290161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (elems == NULL)
290261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return 1;
290361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
290461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (hexstr2bin(pos, wpabuf_put(elems, len), len)) {
290561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpabuf_free(elems);
290661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_printf(MSG_ERROR, "Line %d: Invalid "
290761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					   "vendor_elements '%s'", line, pos);
290861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return 1;
290961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
291061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
291161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpabuf_free(bss->vendor_elements);
291261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			bss->vendor_elements = elems;
29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Line %d: unknown configuration "
29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "item '%s'", line, buf);
29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			errors++;
29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
292004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return errors;
292104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
292404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_set_security_params(struct hostapd_bss_config *bss)
292504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
292604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int pairwise;
292704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
292804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (bss->individual_wep_key_len == 0) {
292904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		/* individual keys are not use; can use key idx0 for
293004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		 * broadcast keys */
293104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->broadcast_key_idx_min = 0;
293204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
293304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
293404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* Select group cipher based on the enabled pairwise cipher
293504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	 * suites */
293604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	pairwise = 0;
293704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (bss->wpa & 1)
293804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pairwise |= bss->wpa_pairwise;
293904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (bss->wpa & 2) {
294004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (bss->rsn_pairwise == 0)
294104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			bss->rsn_pairwise = bss->wpa_pairwise;
294204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pairwise |= bss->rsn_pairwise;
294304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
294404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (pairwise & WPA_CIPHER_TKIP)
294504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->wpa_group = WPA_CIPHER_TKIP;
294661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else if ((pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) ==
294761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 WPA_CIPHER_GCMP)
294861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		bss->wpa_group = WPA_CIPHER_GCMP;
294904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
295004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->wpa_group = WPA_CIPHER_CCMP;
295104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
295204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	bss->radius->auth_server = bss->radius->auth_servers;
295304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	bss->radius->acct_server = bss->radius->acct_servers;
295404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
295504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (bss->wpa && bss->ieee802_1x) {
295604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->ssid.security_policy = SECURITY_WPA;
295704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (bss->wpa) {
295804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->ssid.security_policy = SECURITY_WPA_PSK;
295904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (bss->ieee802_1x) {
296004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		int cipher = WPA_CIPHER_NONE;
296104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->ssid.security_policy = SECURITY_IEEE_802_1X;
296204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->ssid.wep.default_len = bss->default_wep_key_len;
296304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (bss->default_wep_key_len)
296404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			cipher = bss->default_wep_key_len >= 13 ?
296504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
296604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->wpa_group = cipher;
296704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->wpa_pairwise = cipher;
296804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->rsn_pairwise = cipher;
296904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else if (bss->ssid.wep.keys_set) {
297004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		int cipher = WPA_CIPHER_WEP40;
297104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (bss->ssid.wep.len[0] >= 13)
297204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			cipher = WPA_CIPHER_WEP104;
297304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->ssid.security_policy = SECURITY_STATIC_WEP;
297404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->wpa_group = cipher;
297504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->wpa_pairwise = cipher;
297604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->rsn_pairwise = cipher;
297704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else {
297804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->ssid.security_policy = SECURITY_PLAINTEXT;
297904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->wpa_group = WPA_CIPHER_NONE;
298004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->wpa_pairwise = WPA_CIPHER_NONE;
298104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->rsn_pairwise = WPA_CIPHER_NONE;
298204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
298304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
298404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
298604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/**
298704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * hostapd_config_read - Read and parse a configuration file
298804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @fname: Configuration file name (including path, if needed)
298904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Returns: Allocated configuration data structure
299004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */
299104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstruct hostapd_config * hostapd_config_read(const char *fname)
299204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
299304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct hostapd_config *conf;
299404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct hostapd_bss_config *bss;
299504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	FILE *f;
299604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char buf[512], *pos;
299704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int line = 0;
299804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int errors = 0;
299904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t i;
300004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
300104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	f = fopen(fname, "r");
300204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (f == NULL) {
300304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_ERROR, "Could not open configuration file '%s' "
300404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "for reading.", fname);
300504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return NULL;
300604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
300704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
300804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	conf = hostapd_config_defaults();
300904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (conf == NULL) {
301004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		fclose(f);
301104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return NULL;
301204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
301304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
301404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* set default driver based on configuration */
301504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	conf->driver = wpa_drivers[0];
301604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (conf->driver == NULL) {
301704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_ERROR, "No driver wrappers registered!");
301804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		hostapd_config_free(conf);
301904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		fclose(f);
302004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return NULL;
302104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
302204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
302304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	bss = conf->last_bss = conf->bss;
302404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
302504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	while (fgets(buf, sizeof(buf), f)) {
302604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss = conf->last_bss;
302704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		line++;
302804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
302904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (buf[0] == '#')
303004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
303104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos = buf;
303204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		while (*pos != '\0') {
303304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (*pos == '\n') {
303404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				*pos = '\0';
303504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				break;
303604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
303704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			pos++;
30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
303904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (buf[0] == '\0')
304004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
304104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
304204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos = os_strchr(buf, '=');
304304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (pos == NULL) {
304404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_ERROR, "Line %d: invalid line '%s'",
304504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   line, buf);
304604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			errors++;
304704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
30481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
304904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		*pos = '\0';
305004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		pos++;
305104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		errors += hostapd_config_fill(conf, bss, buf, pos, line);
30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
305404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	fclose(f);
305504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
305604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (i = 0; i < conf->num_bss; i++)
305704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		hostapd_set_security_params(&conf->bss[i]);
305804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hostapd_config_check(conf))
30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		errors++;
30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPA_IGNORE_CONFIG_ERRORS
30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (errors) {
30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "%d errors found in configuration file "
30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "'%s'", errors, fname);
30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hostapd_config_free(conf);
30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf = NULL;
30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_IGNORE_CONFIG_ERRORS */
30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return conf;
30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
307304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
307404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
307504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_set_iface(struct hostapd_config *conf,
307604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		      struct hostapd_bss_config *bss, char *field, char *value)
307704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
307804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int errors;
307904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t i;
308004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
308104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	errors = hostapd_config_fill(conf, bss, field, value, 0);
308204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (errors) {
308304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_INFO, "Failed to set configuration field '%s' "
308404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "to value '%s'", field, value);
308504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
308604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
308704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
308804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (i = 0; i < conf->num_bss; i++)
308904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		hostapd_set_security_params(&conf->bss[i]);
309004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
309104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (hostapd_config_check(conf)) {
309204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_ERROR, "Configuration check failed");
309304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
309404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
309504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
309604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
309704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
3098