* @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 "
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",
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);
void *network_ctx,
int try_opportunistic,
const u8 *fils_cache_id,
- int akmp)
+ int akmp, bool associated)
{
return -1;
}
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)
/* 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 */
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);
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,
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);
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);
#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;