]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: VLAN assignment based on SAE Password Identifier
authorJouni Malinen <j@w1.fi>
Sun, 17 Feb 2019 15:22:37 +0000 (17:22 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 17 Feb 2019 15:24:23 +0000 (17:24 +0200)
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>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.h
src/ap/ieee802_11.c
src/common/sae.h

index c8ff7a06a3f46960362b9a407c40ccd40ad95519..c22731e327e36351a961bb5281e77f13bd27b83a 100644 (file)
@@ -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)
index ee8f9610c24fe7df9577e665196119656f9d7755..c7e23ffe1b8bdf1c6814d772e71c8c1ecce7d6a0 100644 (file)
@@ -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
index ac07b577c3ec4788db18ddc29a4eb30ec38f8c61..897af5019e52970bc616cd8d1944b0898b2916b2 100644 (file)
@@ -249,6 +249,7 @@ struct sae_password_entry {
        char *password;
        char *identifier;
        u8 peer_addr[ETH_ALEN];
+       int vlan_id;
 };
 
 /**
index c6138e1afeda034b3588e90b59eb41f35221fd41..bc45cd71f1c91689b33c13cb337e8752ac3db131 100644 (file)
@@ -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);
index 3fbcb58d155a0d6580b94fc7cc87f6d4584a958b..bb33761f9722faa64ea2eae09b0de2a26c1845e6 100644 (file)
@@ -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 {