diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c index 0cd515982..07f731cca 100644 --- a/src/rsn_supp/pmksa_cache.c +++ b/src/rsn_supp/pmksa_cache.c @@ -45,12 +45,14 @@ static void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa, struct rsn_pmksa_cache_entry *entry, enum pmksa_free_reason reason) { - wpa_sm_remove_pmkid(pmksa->sm, entry->network_ctx, entry->aa, - entry->pmkid, - entry->fils_cache_id_set ? entry->fils_cache_id : - NULL); + if (pmksa->sm) + wpa_sm_remove_pmkid(pmksa->sm, entry->network_ctx, entry->aa, + entry->pmkid, + entry->fils_cache_id_set ? + entry->fils_cache_id : NULL); pmksa->pmksa_count--; - pmksa->free_cb(entry, pmksa->ctx, reason); + if (pmksa->free_cb) + pmksa->free_cb(entry, pmksa->ctx, reason); _pmksa_cache_free_entry(entry); } @@ -64,7 +66,7 @@ static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx) os_get_reltime(&now); while (entry && entry->expiration <= now.sec) { - if (wpa_key_mgmt_sae(entry->akmp) && + if (wpa_key_mgmt_sae(entry->akmp) && pmksa->is_current_cb && pmksa->is_current_cb(entry, pmksa->ctx)) { /* Do not expire the currently used PMKSA entry for SAE * since there is no convenient mechanism for @@ -97,6 +99,10 @@ static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx) static void pmksa_cache_reauth(void *eloop_ctx, void *timeout_ctx) { struct rsn_pmksa_cache *pmksa = eloop_ctx; + + if (!pmksa->sm) + return; + pmksa->sm->cur_pmksa = NULL; eapol_sm_request_reauth(pmksa->sm->eapol); } @@ -117,6 +123,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa) if (sec < 0) { sec = 0; if (wpa_key_mgmt_sae(pmksa->pmksa->akmp) && + pmksa->is_current_cb && pmksa->is_current_cb(pmksa->pmksa, pmksa->ctx)) { /* Do not continue polling for the current PMKSA entry * from SAE to expire every second. Use the expiration @@ -137,6 +144,9 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa) } eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL); + if (!pmksa->sm) + return; + entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa : pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, 0); if (entry && !wpa_key_mgmt_sae(entry->akmp)) { @@ -177,6 +187,8 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, { struct rsn_pmksa_cache_entry *entry; struct os_reltime now; + unsigned int pmk_lifetime = 43200; + unsigned int pmk_reauth_threshold = 70; if (pmk_len > PMK_LEN_MAX) return NULL; @@ -198,9 +210,14 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, else rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid, akmp); os_get_reltime(&now); - entry->expiration = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime; - entry->reauth_time = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime * - pmksa->sm->dot11RSNAConfigPMKReauthThreshold / 100; + if (pmksa->sm) { + pmk_lifetime = pmksa->sm->dot11RSNAConfigPMKLifetime; + pmk_reauth_threshold = + pmksa->sm->dot11RSNAConfigPMKReauthThreshold; + } + entry->expiration = now.sec + pmk_lifetime; + entry->reauth_time = now.sec + + pmk_lifetime * pmk_reauth_threshold / 100; entry->akmp = akmp; if (cache_id) { entry->fils_cache_id_set = 1; @@ -267,7 +284,7 @@ pmksa_cache_add_entry(struct rsn_pmksa_cache *pmksa, /* Remove the oldest entry to make room for the new entry */ pos = pmksa->pmksa; - if (pos == pmksa->sm->cur_pmksa) { + if (pmksa->sm && pos == pmksa->sm->cur_pmksa) { /* * Never remove the current PMKSA cache entry, since * it's in use, and removing it triggers a needless @@ -308,6 +325,10 @@ pmksa_cache_add_entry(struct rsn_pmksa_cache *pmksa, wpa_printf(MSG_DEBUG, "RSN: Added PMKSA cache entry for " MACSTR " network_ctx=%p akmp=0x%x", MAC2STR(entry->aa), entry->network_ctx, entry->akmp); + + if (!pmksa->sm) + return entry; + wpa_sm_add_pmkid(pmksa->sm, entry->network_ctx, entry->aa, entry->pmkid, entry->fils_cache_id_set ? entry->fils_cache_id : NULL, entry->pmk, entry->pmk_len, @@ -423,6 +444,9 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa, os_time_t old_reauth_time = old_entry->reauth_time; const u8 *pmkid = NULL; + if (!pmksa->sm) + return NULL; + if (wpa_key_mgmt_sae(old_entry->akmp) || wpa_key_mgmt_fils(old_entry->akmp)) pmkid = old_entry->pmkid;