diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c index ea83e76e6..8dd770f38 100644 --- a/src/rsn_supp/pmksa_cache.c +++ b/src/rsn_supp/pmksa_cache.c @@ -611,12 +611,13 @@ void pmksa_cache_clear_current(struct wpa_sm *sm) * @network_ctx: Network configuration context * @try_opportunistic: Whether to allow opportunistic PMKSA caching * @fils_cache_id: Pointer to FILS Cache Identifier or %NULL if not used + * @associated: Whether the device is associated * Returns: 0 if PMKSA was found or -1 if no matching entry was found */ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, const u8 *bssid, void *network_ctx, int try_opportunistic, const u8 *fils_cache_id, - int akmp) + int akmp, bool associated) { struct rsn_pmksa_cache *pmksa = sm->pmksa; wpa_printf(MSG_DEBUG, "RSN: PMKSA cache search - network_ctx=%p " @@ -654,13 +655,29 @@ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, if (wpa_key_mgmt_sae(sm->cur_pmksa->akmp) && os_get_reltime(&now) == 0 && sm->cur_pmksa->reauth_time < now.sec) { - wpa_printf(MSG_DEBUG, - "RSN: Do not allow PMKSA cache entry for " - MACSTR - " to be used for SAE since its reauth threshold has passed", - MAC2STR(sm->cur_pmksa->aa)); - sm->cur_pmksa = NULL; - return -1; + /* Driver-based roaming might have used a PMKSA entry + * that is already past the reauthentication threshold. + * Remove the related PMKID from the driver to avoid + * further uses for this PMKSA, but allow the + * association to continue since the PMKSA has not yet + * expired. */ + wpa_sm_remove_pmkid(sm, sm->cur_pmksa->network_ctx, + sm->cur_pmksa->aa, + sm->cur_pmksa->pmkid, NULL); + if (associated) { + wpa_printf(MSG_DEBUG, + "RSN: Associated with " MACSTR + " using reauth threshold passed PMKSA cache entry", + MAC2STR(sm->cur_pmksa->aa)); + } else { + wpa_printf(MSG_DEBUG, + "RSN: Do not allow PMKSA cache entry for " + MACSTR + " to be used for SAE since its reauth threshold has passed", + MAC2STR(sm->cur_pmksa->aa)); + sm->cur_pmksa = NULL; + return -1; + } } wpa_hexdump(MSG_DEBUG, "RSN: PMKSA cache entry found - PMKID", diff --git a/src/rsn_supp/pmksa_cache.h b/src/rsn_supp/pmksa_cache.h index 48c9e0465..37c116282 100644 --- a/src/rsn_supp/pmksa_cache.h +++ b/src/rsn_supp/pmksa_cache.h @@ -86,7 +86,7 @@ void pmksa_cache_clear_current(struct wpa_sm *sm); int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, const u8 *bssid, void *network_ctx, int try_opportunistic, const u8 *fils_cache_id, - int akmp); + int akmp, bool associated); struct rsn_pmksa_cache_entry * pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa, void *network_ctx, const u8 *aa, int akmp); @@ -164,7 +164,7 @@ static inline int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, void *network_ctx, int try_opportunistic, const u8 *fils_cache_id, - int akmp) + int akmp, bool associated) { return -1; } diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 32cf24c79..f205b91d5 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -426,7 +426,8 @@ static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s, bool authorized) for (i = 0; i < ie.num_pmkid; i++) { pmksa_set = pmksa_cache_set_current(wpa_s->wpa, ie.pmkid + i * PMKID_LEN, - NULL, NULL, 0, NULL, 0); + NULL, NULL, 0, NULL, 0, + true); if (pmksa_set == 0) { eapol_sm_notify_pmkid_attempt(wpa_s->eapol); if (authorized) @@ -5025,7 +5026,7 @@ static void wpa_supplicant_event_assoc_auth(struct wpa_supplicant *wpa_s, /* Update the current PMKSA used for this connection */ pmksa_cache_set_current(wpa_s->wpa, data->assoc_info.fils_pmkid, - NULL, NULL, 0, NULL, 0); + NULL, NULL, 0, NULL, 0, true); } } #endif /* CONFIG_FILS */ diff --git a/wpa_supplicant/preauth_test.c b/wpa_supplicant/preauth_test.c index 3aa667525..f266ce4f4 100644 --- a/wpa_supplicant/preauth_test.c +++ b/wpa_supplicant/preauth_test.c @@ -357,7 +357,7 @@ int main(int argc, char *argv[]) ret = -2; else { ret = pmksa_cache_set_current(wpa_s.wpa, NULL, bssid, NULL, 0, - NULL, 0) ? 0 : -3; + NULL, 0, false) ? 0 : -3; } test_eapol_clean(&wpa_s); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 4ed0a3003..bb04652f5 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -731,7 +731,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, bss->bssid, wpa_s->current_ssid, try_opportunistic, cache_id, - 0) == 0) + 0, false) == 0) eapol_sm_notify_pmkid_attempt(wpa_s->eapol); wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); if (wpa_supplicant_set_suites(wpa_s, bss, ssid, @@ -1037,7 +1037,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, NULL, wpa_key_mgmt_sae(wpa_s->key_mgmt) ? wpa_s->key_mgmt : - (int) WPA_KEY_MGMT_SAE) == 0) { + (int) WPA_KEY_MGMT_SAE, false) == 0) { wpa_dbg(wpa_s, MSG_DEBUG, "PMKSA cache entry found - try to use PMKSA caching instead of new SAE authentication"); wpa_sm_set_pmk_from_pmksa(wpa_s->wpa); @@ -1135,7 +1135,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, bss->bssid, ssid, 0, wpa_bss_get_fils_cache_id(bss), - 0) == 0) + 0, false) == 0) wpa_printf(MSG_DEBUG, "SME: Try to use FILS with PMKSA caching"); resp = fils_build_auth(wpa_s->wpa, ssid->fils_dh_group, md); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 94f549b6e..69f228919 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3310,7 +3310,7 @@ static u8 * wpas_populate_assoc_ies( #endif /* CONFIG_FILS */ if (pmksa_cache_set_current(wpa_s->wpa, NULL, addr, ssid, try_opportunistic, - cache_id, 0) == 0) { + cache_id, 0, false) == 0) { eapol_sm_notify_pmkid_attempt(wpa_s->eapol); #if defined(CONFIG_SAE) || defined(CONFIG_FILS) pmksa_cached = 1;