]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Assign VLAN when using PMKSA caching
authorJouni Malinen <jouni.malinen@oss.qualcomm.com>
Tue, 26 Aug 2025 08:59:20 +0000 (11:59 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 26 Aug 2025 09:39:32 +0000 (12:39 +0300)
SAE passwords in hostapd can be configured with a specific VLAN ID.
Store that VLAN ID into PMKSA cache entries generated from SAE
authentication and assign it to the STA whenever using PMKSA caching
instead of new SAE authentication for an association. This is needed to
be able to use SAE to assign VLANs without having to disable PMKSA
cahcing.

Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
src/ap/ieee802_11.c
src/ap/pmksa_cache_auth.h
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_ie.c
wpa_supplicant/p2p_supplicant.c

index 7e305c14caad9678b97cf515e13edd7f65989828..9f27ba87c3f12e3c90caf4579d98a1c222f57695 100644 (file)
@@ -1049,41 +1049,52 @@ static void sae_sme_send_external_auth_status(struct hostapd_data *hapd,
 }
 
 
-void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
+static int sae_assign_vlan(struct hostapd_data *hapd, struct sta_info *sta,
+                          int vlan_id)
 {
 #ifndef CONFIG_NO_VLAN
        struct vlan_description vlan_desc;
 
-       if (sta->sae->tmp && sta->sae->tmp->vlan_id > 0) {
+       if (vlan_id > 0) {
                wpa_printf(MSG_DEBUG, "SAE: Assign STA " MACSTR
                           " to VLAN ID %d",
-                          MAC2STR(sta->addr), sta->sae->tmp->vlan_id);
+                          MAC2STR(sta->addr), vlan_id);
 
                if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
                        os_memset(&vlan_desc, 0, sizeof(vlan_desc));
                        vlan_desc.notempty = 1;
-                       vlan_desc.untagged = sta->sae->tmp->vlan_id;
+                       vlan_desc.untagged = 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;
+                                          vlan_id);
+                               return -1;
                        }
 
                        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,
+                                          MACSTR, vlan_id,
                                           MAC2STR(sta->addr));
-                               return;
+                               return -1;
                        }
                } else {
-                       sta->vlan_id = sta->sae->tmp->vlan_id;
+                       sta->vlan_id = vlan_id;
                }
        }
 #endif /* CONFIG_NO_VLAN */
 
+       return 0;
+}
+
+
+void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
+{
+       if (sta->sae->tmp &&
+           sae_assign_vlan(hapd, sta, sta->sae->tmp->vlan_id) < 0)
+               return;
+
        sta->flags |= WLAN_STA_AUTH;
        sta->auth_alg = WLAN_AUTH_SAE;
        mlme_authenticate_indication(hapd, sta);
@@ -1095,7 +1106,7 @@ void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
        wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
                               sta->sae->pmk, sta->sae->pmk_len,
                               sta->sae->pmkid, sta->sae->akmp,
-                              ap_sta_is_mld(hapd, sta));
+                              ap_sta_is_mld(hapd, sta), sta->vlan_id);
        sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS);
 }
 
@@ -4508,6 +4519,7 @@ static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
                        }
                        wpa_printf(MSG_DEBUG, "SAE: " MACSTR
                                   " using PMKSA caching", MAC2STR(sta->addr));
+                       sae_assign_vlan(hapd, sta, sa->sae_vlan_id);
                } else if (wpa_auth_uses_sae(sta->wpa_sm) &&
                           sta->auth_alg != WLAN_AUTH_SAE &&
                           !(sta->auth_alg == WLAN_AUTH_FT &&
index ade1c498950f4f32c3cb970a62e9e33050684098..c653b0306662a7bd07e75366bec2dc3deabe3d4d 100644 (file)
@@ -33,6 +33,7 @@ struct rsn_pmksa_cache_entry {
        struct radius_class_data radius_class;
        u8 eap_type_authsrv;
        struct vlan_description *vlan_desc;
+       int sae_vlan_id;
        int opportunistic;
 
        u64 acct_multi_session_id;
index 333467ce8f323ab038a88429cb9512005730e576..5e51ce809289ef3b44d6a2dafc5c244658889c3a 100644 (file)
@@ -6551,9 +6551,10 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
 
 int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr,
                           const u8 *pmk, size_t pmk_len, const u8 *pmkid,
-                          int akmp, bool is_ml)
+                          int akmp, bool is_ml, int vlan_id)
 {
        struct rsn_pmksa_cache *pmksa = wpa_auth->pmksa;
+       struct rsn_pmksa_cache_entry *entry;
        const u8 *aa = wpa_auth->addr;
 
        if (wpa_auth->conf.disable_pmksa_caching)
@@ -6570,11 +6571,14 @@ int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr,
        }
 #endif /* CONFIG_IEEE80211BE */
 
-       if (pmksa_cache_auth_add(pmksa, pmk, pmk_len, pmkid, NULL, 0, aa, addr,
-                                0, NULL, akmp))
-               return 0;
+       entry = pmksa_cache_auth_add(pmksa, pmk, pmk_len, pmkid, NULL, 0,
+                                    aa, addr, 0, NULL, akmp);
+       if (!entry)
+               return -1;
 
-       return -1;
+       entry->sae_vlan_id = vlan_id;
+
+       return 0;
 }
 
 
index 176ed2c44ca65fd241ccaf5ddbed8ea6aadd115f..9e40c0b82d3b08de457a5fe703774ca5f0dcdc54 100644 (file)
@@ -512,7 +512,7 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
                               struct eapol_state_machine *eapol);
 int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr,
                           const u8 *pmk, size_t pmk_len, const u8 *pmkid,
-                          int akmp, bool is_ml);
+                          int akmp, bool is_ml, int vlan_id);
 void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid);
 int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr,
                        const u8 *pmk, size_t pmk_len, const u8 *pmkid,
index 83ae4e065fa563de3fbb017453dc7c3cd82cf21e..058138996ef7021b9e0e02f5414a2d4bc7606532 100644 (file)
@@ -1280,7 +1280,8 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
                wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
                                 "PMKID found from PMKSA cache eap_type=%d vlan=%d%s",
                                 sm->pmksa->eap_type_authsrv,
-                                vlan ? vlan->untagged : 0,
+                                vlan ? vlan->untagged :
+                                sm->pmksa->sae_vlan_id,
                                 (vlan && vlan->tagged[0]) ? "+" : "");
                os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN);
        }
index e62b74d7b82b9ecb9859c65253d6b58814a427d5..9ee8955f2c177d05637adc09a5debaddac3f3006 100644 (file)
@@ -2267,7 +2267,7 @@ static void p2p_go_configured(void *ctx, void *data)
                                       params->peer_device_addr,
                                       params->pmk, params->pmk_len,
                                       params->pmkid, WPA_KEY_MGMT_SAE,
-                                      false);
+                                      false, 0);
                hostapd_add_pmkid(hapd, params->peer_device_addr,
                                  params->pmk, params->pmk_len,
                                  params->pmkid, WPA_KEY_MGMT_SAE);
@@ -2924,7 +2924,7 @@ static void wpas_set_go_security_config(void *ctx,
                                       params->peer_device_addr,
                                       params->pmk, params->pmk_len,
                                       params->pmkid, WPA_KEY_MGMT_SAE,
-                                      false);
+                                      false, 0);
                hostapd_add_pmkid(hapd, params->peer_device_addr,
                                  params->pmk, params->pmk_len,
                                  params->pmkid, WPA_KEY_MGMT_SAE);