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>
}
-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);
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);
}
}
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 &&
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;
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)
}
#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;
}
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,
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);
}
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);
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);