Browse Source

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>
Jouni Malinen 8 years ago
parent
commit
26bf70e3d2
5 changed files with 74 additions and 4 deletions
  1. 26 0
      hostapd/config_file.c
  2. 7 0
      hostapd/hostapd.conf
  3. 20 0
      src/ap/ap_config.c
  4. 7 0
      src/ap/ap_config.h
  5. 14 4
      src/ap/ieee802_11_shared.c

+ 26 - 0
hostapd/config_file.c

@@ -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);

+ 7 - 0
hostapd/hostapd.conf

@@ -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)

+ 20 - 0
src/ap/ap_config.c

@@ -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);
 }
 }
 
 

+ 7 - 0
src/ap/ap_config.h

@@ -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;

+ 14 - 4
src/ap/ieee802_11_shared.c

@@ -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;