aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2019-02-17 15:22:37 (GMT)
committerJouni Malinen <j@w1.fi>2019-02-17 15:24:23 (GMT)
commitb0e91e3877b2429c21229fc27fc29dec5115eb97 (patch)
tree97c737d7e26543b5503df093054a59e26e1a13fe
parentcf4643aa7d8139eb431439bd628c4cf3dee7a535 (diff)
downloadhostap-b0e91e3877b2429c21229fc27fc29dec5115eb97.zip
hostap-b0e91e3877b2429c21229fc27fc29dec5115eb97.tar.gz
hostap-b0e91e3877b2429c21229fc27fc29dec5115eb97.tar.bz2
SAE: VLAN assignment based on SAE Password Identifier
The new sae_password parameter [|vlanid=<VLAN ID>] can now be used to assign stations to a specific VLAN based on which SAE Password Identifier they use. This is similar to the WPA2-Enterprise case where the RADIUS server can assign stations to different VLANs and the WPA2-Personal case where vlanid parameter in wpa_psk_file is used. Signed-off-by: Jouni Malinen <j@w1.fi>
-rw-r--r--hostapd/config_file.c8
-rw-r--r--hostapd/hostapd.conf26
-rw-r--r--src/ap/ap_config.h1
-rw-r--r--src/ap/ieee802_11.c38
-rw-r--r--src/common/sae.h1
5 files changed, 65 insertions, 9 deletions
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index c8ff7a0..c22731e 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2333,6 +2333,14 @@ static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)
pos = pos2 + ETH_ALEN * 3 - 1;
}
+ pos2 = os_strstr(pos, "|vlanid=");
+ if (pos2) {
+ if (!end)
+ end = pos2;
+ pos2 += 8;
+ pw->vlan_id = atoi(pos2);
+ }
+
pos2 = os_strstr(pos, "|id=");
if (pos2) {
if (!end)
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index ee8f961..c7e23ff 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -1188,7 +1188,7 @@ own_ip_addr=127.0.0.1
# VLANID as a string). Optionally, the local MAC ACL list (accept_mac_file) can
# be used to set static client MAC address to VLAN ID mapping.
# Dynamic VLAN mode is also used with VLAN ID assignment based on WPA/WPA2
-# passphrase from wpa_psk_file.
+# passphrase from wpa_psk_file or vlan_id parameter from sae_password.
# 0 = disabled (default); only VLAN IDs from accept_mac_file will be used
# 1 = optional; use default interface if RADIUS server does not include VLAN ID
# 2 = required; reject authentication if RADIUS server does not include VLAN ID
@@ -1538,21 +1538,29 @@ own_ip_addr=127.0.0.1
# corresponds to the dot11RSNAConfigPasswordValueEntry. sae_password value
# starts with the password (dot11RSNAConfigPasswordCredential). That value can
# be followed by optional peer MAC address (dot11RSNAConfigPasswordPeerMac) and
-# by optional password identifier (dot11RSNAConfigPasswordIdentifier). If the
-# peer MAC address is not included or is set to the wildcard address
+# by optional password identifier (dot11RSNAConfigPasswordIdentifier). In
+# addition, an optional VLAN ID specification can be used to bind the station
+# to the specified VLAN whenver the specific SAE password entry is used.
+#
+# If the peer MAC address is not included or is set to the wildcard address
# (ff:ff:ff:ff:ff:ff), the entry is available for any station to use. If a
# specific peer MAC address is included, only a station with that MAC address
-# is allowed to use the entry. If the password identifier (with non-zero length)
-# is included, the entry is limited to be used only with that specified
-# identifier. The last matching (based on peer MAC address and identifier) entry
-# is used to select which password to use. Setting sae_password to an empty
-# string has a special meaning of removing all previously added entries.
+# is allowed to use the entry.
+#
+# If the password identifier (with non-zero length) is included, the entry is
+# limited to be used only with that specified identifier.
+
+# The last matching (based on peer MAC address and identifier) entry is used to
+# select which password to use. Setting sae_password to an empty string has a
+# special meaning of removing all previously added entries.
+#
# sae_password uses the following encoding:
-#<password/credential>[|mac=<peer mac>][|id=<identifier>]
+#<password/credential>[|mac=<peer mac>][|vlanid=<VLAN ID>][|id=<identifier>]
# Examples:
#sae_password=secret
#sae_password=really secret|mac=ff:ff:ff:ff:ff:ff
#sae_password=example secret|mac=02:03:04:05:06:07|id=pw identifier
+#sae_password=example secret|vlanid=3|id=pw identifier
# SAE threshold for anti-clogging mechanism (dot11RSNASAEAntiCloggingThreshold)
# This parameter defines how many open SAE instances can be in progress at the
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index ac07b57..897af50 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -249,6 +249,7 @@ struct sae_password_entry {
char *password;
char *identifier;
u8 peer_addr[ETH_ALEN];
+ int vlan_id;
};
/**
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index c6138e1..bc45cd7 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -420,6 +420,15 @@ static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
return NULL;
}
+ if (pw && pw->vlan_id) {
+ if (!sta->sae->tmp) {
+ wpa_printf(MSG_INFO,
+ "SAE: No temporary data allocated - cannot store VLAN ID");
+ return NULL;
+ }
+ sta->sae->tmp->vlan_id = pw->vlan_id;
+ }
+
buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN +
(rx_id ? 3 + os_strlen(rx_id) : 0));
if (buf == NULL)
@@ -629,6 +638,35 @@ static void sae_set_retransmit_timer(struct hostapd_data *hapd,
void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
{
+#ifndef CONFIG_NO_VLAN
+ struct vlan_description vlan_desc;
+
+ if (sta->sae->tmp && sta->sae->tmp->vlan_id > 0) {
+ wpa_printf(MSG_DEBUG, "SAE: Assign STA " MACSTR
+ " to VLAN ID %d",
+ MAC2STR(sta->addr), sta->sae->tmp->vlan_id);
+
+ os_memset(&vlan_desc, 0, sizeof(vlan_desc));
+ vlan_desc.notempty = 1;
+ vlan_desc.untagged = sta->sae->tmp->vlan_id;
+ if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) {
+ wpa_printf(MSG_INFO,
+ "Invalid VLAN ID %d in sae_password",
+ sta->sae->tmp->vlan_id);
+ return;
+ }
+
+ if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0 ||
+ ap_sta_bind_vlan(hapd, sta) < 0) {
+ wpa_printf(MSG_INFO,
+ "Failed to assign VLAN ID %d from sae_password to "
+ MACSTR, sta->sae->tmp->vlan_id,
+ MAC2STR(sta->addr));
+ return;
+ }
+ }
+#endif /* CONFIG_NO_VLAN */
+
sta->flags |= WLAN_STA_AUTH;
sta->auth_alg = WLAN_AUTH_SAE;
mlme_authenticate_indication(hapd, sta);
diff --git a/src/common/sae.h b/src/common/sae.h
index 3fbcb58..bb33761 100644
--- a/src/common/sae.h
+++ b/src/common/sae.h
@@ -40,6 +40,7 @@ struct sae_temporary_data {
struct crypto_bignum *order_buf;
struct wpabuf *anti_clogging_token;
char *pw_id;
+ int vlan_id;
};
enum sae_state {