FILS: Separate FILS realm configuration from ERP domain
The new hostapd configuration parameter fils_realm=<realm> can now be used to configure one or more FILS realms to advertise for ERP domains when using FILS. This replaces the use of erp_domain=<domain> parameter for the FILS use case. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
42b847ac1e
commit
26bf70e3d2
5 changed files with 74 additions and 4 deletions
|
@ -2017,6 +2017,29 @@ static int parse_wpabuf_hex(int line, const char *name, struct wpabuf **buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_FILS
|
||||||
|
static int parse_fils_realm(struct hostapd_bss_config *bss, const char *val)
|
||||||
|
{
|
||||||
|
struct fils_realm *realm;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = os_strlen(val);
|
||||||
|
realm = os_zalloc(sizeof(*realm) + len + 1);
|
||||||
|
if (!realm)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
os_memcpy(realm->realm, val, len);
|
||||||
|
if (fils_domain_name_hash(val, realm->hash) < 0) {
|
||||||
|
os_free(realm);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dl_list_add_tail(&bss->fils_realms, &realm->list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FILS */
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_config_fill(struct hostapd_config *conf,
|
static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
struct hostapd_bss_config *bss,
|
struct hostapd_bss_config *bss,
|
||||||
const char *buf, char *pos, int line)
|
const char *buf, char *pos, int line)
|
||||||
|
@ -3577,6 +3600,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
bss->fils_cache_id_set = 1;
|
bss->fils_cache_id_set = 1;
|
||||||
|
} else if (os_strcmp(buf, "fils_realm") == 0) {
|
||||||
|
if (parse_fils_realm(bss, pos) < 0)
|
||||||
|
return 1;
|
||||||
#endif /* CONFIG_FILS */
|
#endif /* CONFIG_FILS */
|
||||||
} else if (os_strcmp(buf, "multicast_to_unicast") == 0) {
|
} else if (os_strcmp(buf, "multicast_to_unicast") == 0) {
|
||||||
bss->multicast_to_unicast = atoi(pos);
|
bss->multicast_to_unicast = atoi(pos);
|
||||||
|
|
|
@ -1309,6 +1309,13 @@ own_ip_addr=127.0.0.1
|
||||||
# FILS Cache Identifier (16-bit value in hexdump format)
|
# FILS Cache Identifier (16-bit value in hexdump format)
|
||||||
#fils_cache_id=0011
|
#fils_cache_id=0011
|
||||||
|
|
||||||
|
# FILS Realm Information
|
||||||
|
# One or more FILS realms need to be configured when FILS is enabled. This list
|
||||||
|
# of realms is used to define which realms (used in keyName-NAI by the client)
|
||||||
|
# can be used with FILS shared key authentication for ERP.
|
||||||
|
#fils_realm=example.com
|
||||||
|
#fils_realm=example.org
|
||||||
|
|
||||||
##### IEEE 802.11r configuration ##############################################
|
##### IEEE 802.11r configuration ##############################################
|
||||||
|
|
||||||
# Mobility Domain identifier (dot11FTMobilityDomainID, MDID)
|
# Mobility Domain identifier (dot11FTMobilityDomainID, MDID)
|
||||||
|
|
|
@ -95,6 +95,10 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
|
||||||
bss->radius_das_time_window = 300;
|
bss->radius_das_time_window = 300;
|
||||||
|
|
||||||
bss->sae_anti_clogging_threshold = 5;
|
bss->sae_anti_clogging_threshold = 5;
|
||||||
|
|
||||||
|
#ifdef CONFIG_FILS
|
||||||
|
dl_list_init(&bss->fils_realms);
|
||||||
|
#endif /* CONFIG_FILS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -420,6 +424,20 @@ static void hostapd_config_free_anqp_elem(struct hostapd_bss_config *conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_config_free_fils_realms(struct hostapd_bss_config *conf)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_FILS
|
||||||
|
struct fils_realm *realm;
|
||||||
|
|
||||||
|
while ((realm = dl_list_first(&conf->fils_realms, struct fils_realm,
|
||||||
|
list))) {
|
||||||
|
dl_list_del(&realm->list);
|
||||||
|
os_free(realm);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FILS */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void hostapd_config_free_bss(struct hostapd_bss_config *conf)
|
void hostapd_config_free_bss(struct hostapd_bss_config *conf)
|
||||||
{
|
{
|
||||||
struct hostapd_eap_user *user, *prev_user;
|
struct hostapd_eap_user *user, *prev_user;
|
||||||
|
@ -582,6 +600,8 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
|
||||||
os_free(conf->no_probe_resp_if_seen_on);
|
os_free(conf->no_probe_resp_if_seen_on);
|
||||||
os_free(conf->no_auth_if_seen_on);
|
os_free(conf->no_auth_if_seen_on);
|
||||||
|
|
||||||
|
hostapd_config_free_fils_realms(conf);
|
||||||
|
|
||||||
os_free(conf);
|
os_free(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -224,6 +224,12 @@ struct anqp_element {
|
||||||
struct wpabuf *payload;
|
struct wpabuf *payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fils_realm {
|
||||||
|
struct dl_list list;
|
||||||
|
u8 hash[2];
|
||||||
|
char realm[];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct hostapd_bss_config - Per-BSS configuration
|
* struct hostapd_bss_config - Per-BSS configuration
|
||||||
|
@ -600,6 +606,7 @@ struct hostapd_bss_config {
|
||||||
#ifdef CONFIG_FILS
|
#ifdef CONFIG_FILS
|
||||||
u8 fils_cache_id[FILS_CACHE_ID_LEN];
|
u8 fils_cache_id[FILS_CACHE_ID_LEN];
|
||||||
int fils_cache_id_set;
|
int fils_cache_id_set;
|
||||||
|
struct dl_list fils_realms; /* list of struct fils_realm */
|
||||||
#endif /* CONFIG_FILS */
|
#endif /* CONFIG_FILS */
|
||||||
|
|
||||||
int multicast_to_unicast;
|
int multicast_to_unicast;
|
||||||
|
|
|
@ -605,18 +605,23 @@ u8 * hostapd_eid_fils_indic(struct hostapd_data *hapd, u8 *eid, int hessid)
|
||||||
#ifdef CONFIG_FILS
|
#ifdef CONFIG_FILS
|
||||||
u8 *len;
|
u8 *len;
|
||||||
u16 fils_info = 0;
|
u16 fils_info = 0;
|
||||||
|
size_t realms;
|
||||||
|
struct fils_realm *realm;
|
||||||
|
|
||||||
if (!(hapd->conf->wpa & WPA_PROTO_RSN) ||
|
if (!(hapd->conf->wpa & WPA_PROTO_RSN) ||
|
||||||
!wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt))
|
!wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt))
|
||||||
return pos;
|
return pos;
|
||||||
|
|
||||||
|
realms = dl_list_len(&hapd->conf->fils_realms);
|
||||||
|
if (realms > 7)
|
||||||
|
realms = 7; /* 3 bit count field limits this to max 7 */
|
||||||
|
|
||||||
*pos++ = WLAN_EID_FILS_INDICATION;
|
*pos++ = WLAN_EID_FILS_INDICATION;
|
||||||
len = pos++;
|
len = pos++;
|
||||||
/* TODO: B0..B2: Number of Public Key Identifiers */
|
/* TODO: B0..B2: Number of Public Key Identifiers */
|
||||||
if (hapd->conf->erp_domain) {
|
if (hapd->conf->erp_domain) {
|
||||||
/* TODO: Support for setting multiple domain identifiers */
|
|
||||||
/* B3..B5: Number of Realm Identifiers */
|
/* B3..B5: Number of Realm Identifiers */
|
||||||
fils_info |= BIT(3);
|
fils_info |= realms << 3;
|
||||||
}
|
}
|
||||||
/* TODO: B6: FILS IP Address Configuration */
|
/* TODO: B6: FILS IP Address Configuration */
|
||||||
if (hapd->conf->fils_cache_id_set)
|
if (hapd->conf->fils_cache_id_set)
|
||||||
|
@ -638,8 +643,13 @@ u8 * hostapd_eid_fils_indic(struct hostapd_data *hapd, u8 *eid, int hessid)
|
||||||
os_memcpy(pos, hapd->conf->hessid, ETH_ALEN);
|
os_memcpy(pos, hapd->conf->hessid, ETH_ALEN);
|
||||||
pos += ETH_ALEN;
|
pos += ETH_ALEN;
|
||||||
}
|
}
|
||||||
if (hapd->conf->erp_domain) {
|
|
||||||
fils_domain_name_hash(hapd->conf->erp_domain, pos);
|
dl_list_for_each(realm, &hapd->conf->fils_realms, struct fils_realm,
|
||||||
|
list) {
|
||||||
|
if (realms == 0)
|
||||||
|
break;
|
||||||
|
realms--;
|
||||||
|
os_memcpy(pos, realm->hash, 2);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
}
|
}
|
||||||
*len = pos - len - 1;
|
*len = pos - len - 1;
|
||||||
|
|
Loading…
Reference in a new issue