From: Jouni Malinen Date: Tue, 26 Aug 2025 08:59:20 +0000 (+0300) Subject: SAE: Assign VLAN when using PMKSA caching X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c1e8b1c6462b2f1361648e540a6374ed3f8f1902;p=thirdparty%2Fhostap.git SAE: Assign VLAN when using PMKSA caching 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 --- diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 7e305c14c..9f27ba87c 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -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 && diff --git a/src/ap/pmksa_cache_auth.h b/src/ap/pmksa_cache_auth.h index ade1c4989..c653b0306 100644 --- a/src/ap/pmksa_cache_auth.h +++ b/src/ap/pmksa_cache_auth.h @@ -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; diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 333467ce8..5e51ce809 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -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; } diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 176ed2c44..9e40c0b82 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -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, diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index 83ae4e065..058138996 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -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); } diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index e62b74d7b..9ee8955f2 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -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);