Use PMKSA cache entries with only a single network context
When looking for PMKSA cache entries to use with a new association, only accept entries created with the same network block that was used to create the cache entry. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
d93dfbd588
commit
96efeeb66b
5 changed files with 37 additions and 17 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant - RSN PMKSA cache
|
* WPA Supplicant - RSN PMKSA cache
|
||||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2009, 2011-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -99,7 +99,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
|
||||||
eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL);
|
eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL);
|
||||||
|
|
||||||
entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa :
|
entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa :
|
||||||
pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL);
|
pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
sec = pmksa->pmksa->reauth_time - now.sec;
|
sec = pmksa->pmksa->reauth_time - now.sec;
|
||||||
if (sec < 0)
|
if (sec < 0)
|
||||||
|
@ -228,8 +228,8 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||||
prev->next = entry;
|
prev->next = entry;
|
||||||
}
|
}
|
||||||
pmksa->pmksa_count++;
|
pmksa->pmksa_count++;
|
||||||
wpa_printf(MSG_DEBUG, "RSN: added PMKSA cache entry for " MACSTR,
|
wpa_printf(MSG_DEBUG, "RSN: Added PMKSA cache entry for " MACSTR
|
||||||
MAC2STR(entry->aa));
|
" network_ctx=%p", MAC2STR(entry->aa), network_ctx);
|
||||||
wpa_sm_add_pmkid(pmksa->sm, entry->aa, entry->pmkid);
|
wpa_sm_add_pmkid(pmksa->sm, entry->aa, entry->pmkid);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
|
@ -297,16 +297,19 @@ void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa)
|
||||||
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
|
||||||
* @aa: Authenticator address or %NULL to match any
|
* @aa: Authenticator address or %NULL to match any
|
||||||
* @pmkid: PMKID or %NULL to match any
|
* @pmkid: PMKID or %NULL to match any
|
||||||
|
* @network_ctx: Network context or %NULL to match any
|
||||||
* Returns: Pointer to PMKSA cache entry or %NULL if no match was found
|
* Returns: Pointer to PMKSA cache entry or %NULL if no match was found
|
||||||
*/
|
*/
|
||||||
struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
|
struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
|
||||||
const u8 *aa, const u8 *pmkid)
|
const u8 *aa, const u8 *pmkid,
|
||||||
|
const void *network_ctx)
|
||||||
{
|
{
|
||||||
struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
|
struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
|
||||||
while (entry) {
|
while (entry) {
|
||||||
if ((aa == NULL || os_memcmp(entry->aa, aa, ETH_ALEN) == 0) &&
|
if ((aa == NULL || os_memcmp(entry->aa, aa, ETH_ALEN) == 0) &&
|
||||||
(pmkid == NULL ||
|
(pmkid == NULL ||
|
||||||
os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0))
|
os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0) &&
|
||||||
|
(network_ctx == NULL || network_ctx == entry->network_ctx))
|
||||||
return entry;
|
return entry;
|
||||||
entry = entry->next;
|
entry = entry->next;
|
||||||
}
|
}
|
||||||
|
@ -410,20 +413,32 @@ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid,
|
||||||
int try_opportunistic)
|
int try_opportunistic)
|
||||||
{
|
{
|
||||||
struct rsn_pmksa_cache *pmksa = sm->pmksa;
|
struct rsn_pmksa_cache *pmksa = sm->pmksa;
|
||||||
|
wpa_printf(MSG_DEBUG, "RSN: PMKSA cache search - network_ctx=%p "
|
||||||
|
"try_opportunistic=%d", network_ctx, try_opportunistic);
|
||||||
|
if (pmkid)
|
||||||
|
wpa_hexdump(MSG_DEBUG, "RSN: Search for PMKID",
|
||||||
|
pmkid, PMKID_LEN);
|
||||||
|
if (bssid)
|
||||||
|
wpa_printf(MSG_DEBUG, "RSN: Search for BSSID " MACSTR,
|
||||||
|
MAC2STR(bssid));
|
||||||
|
|
||||||
sm->cur_pmksa = NULL;
|
sm->cur_pmksa = NULL;
|
||||||
if (pmkid)
|
if (pmkid)
|
||||||
sm->cur_pmksa = pmksa_cache_get(pmksa, NULL, pmkid);
|
sm->cur_pmksa = pmksa_cache_get(pmksa, NULL, pmkid,
|
||||||
|
network_ctx);
|
||||||
if (sm->cur_pmksa == NULL && bssid)
|
if (sm->cur_pmksa == NULL && bssid)
|
||||||
sm->cur_pmksa = pmksa_cache_get(pmksa, bssid, NULL);
|
sm->cur_pmksa = pmksa_cache_get(pmksa, bssid, NULL,
|
||||||
|
network_ctx);
|
||||||
if (sm->cur_pmksa == NULL && try_opportunistic && bssid)
|
if (sm->cur_pmksa == NULL && try_opportunistic && bssid)
|
||||||
sm->cur_pmksa = pmksa_cache_get_opportunistic(pmksa,
|
sm->cur_pmksa = pmksa_cache_get_opportunistic(pmksa,
|
||||||
network_ctx,
|
network_ctx,
|
||||||
bssid);
|
bssid);
|
||||||
if (sm->cur_pmksa) {
|
if (sm->cur_pmksa) {
|
||||||
wpa_hexdump(MSG_DEBUG, "RSN: PMKID",
|
wpa_hexdump(MSG_DEBUG, "RSN: PMKSA cache entry found - PMKID",
|
||||||
sm->cur_pmksa->pmkid, PMKID_LEN);
|
sm->cur_pmksa->pmkid, PMKID_LEN);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "RSN: No PMKSA cache entry found");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* wpa_supplicant - WPA2/RSN PMKSA cache functions
|
* wpa_supplicant - WPA2/RSN PMKSA cache functions
|
||||||
* Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2009, 2011-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -52,7 +52,8 @@ pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
|
||||||
void *ctx, struct wpa_sm *sm);
|
void *ctx, struct wpa_sm *sm);
|
||||||
void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa);
|
void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa);
|
||||||
struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
|
struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
|
||||||
const u8 *aa, const u8 *pmkid);
|
const u8 *aa, const u8 *pmkid,
|
||||||
|
const void *network_ctx);
|
||||||
int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len);
|
int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len);
|
||||||
struct rsn_pmksa_cache_entry *
|
struct rsn_pmksa_cache_entry *
|
||||||
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* RSN pre-authentication (supplicant)
|
* RSN pre-authentication (supplicant)
|
||||||
* Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -311,7 +311,7 @@ void rsn_preauth_candidate_process(struct wpa_sm *sm)
|
||||||
dl_list_for_each_safe(candidate, n, &sm->pmksa_candidates,
|
dl_list_for_each_safe(candidate, n, &sm->pmksa_candidates,
|
||||||
struct rsn_pmksa_candidate, list) {
|
struct rsn_pmksa_candidate, list) {
|
||||||
struct rsn_pmksa_cache_entry *p = NULL;
|
struct rsn_pmksa_cache_entry *p = NULL;
|
||||||
p = pmksa_cache_get(sm->pmksa, candidate->bssid, NULL);
|
p = pmksa_cache_get(sm->pmksa, candidate->bssid, NULL, NULL);
|
||||||
if (os_memcmp(sm->bssid, candidate->bssid, ETH_ALEN) != 0 &&
|
if (os_memcmp(sm->bssid, candidate->bssid, ETH_ALEN) != 0 &&
|
||||||
(p == NULL || p->opportunistic)) {
|
(p == NULL || p->opportunistic)) {
|
||||||
wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA "
|
wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA "
|
||||||
|
@ -458,7 +458,7 @@ void rsn_preauth_scan_result(struct wpa_sm *sm, const u8 *bssid,
|
||||||
if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie))
|
if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pmksa = pmksa_cache_get(sm->pmksa, bssid, NULL);
|
pmksa = pmksa_cache_get(sm->pmksa, bssid, NULL, NULL);
|
||||||
if (pmksa && (!pmksa->opportunistic ||
|
if (pmksa && (!pmksa->opportunistic ||
|
||||||
!(ie.capabilities & WPA_CAPABILITY_PREAUTH)))
|
!(ie.capabilities & WPA_CAPABILITY_PREAUTH)))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant - WPA state machine and EAPOL-Key processing
|
* WPA Supplicant - WPA state machine and EAPOL-Key processing
|
||||||
* Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -151,7 +151,8 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
|
||||||
* not have enough time to get the association information
|
* not have enough time to get the association information
|
||||||
* event before receiving this 1/4 message, so try to find a
|
* event before receiving this 1/4 message, so try to find a
|
||||||
* matching PMKSA cache entry here. */
|
* matching PMKSA cache entry here. */
|
||||||
sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid);
|
sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid,
|
||||||
|
NULL);
|
||||||
if (sm->cur_pmksa) {
|
if (sm->cur_pmksa) {
|
||||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
||||||
"RSN: found matching PMKID from PMKSA cache");
|
"RSN: found matching PMKID from PMKSA cache");
|
||||||
|
@ -205,7 +206,8 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
|
||||||
sm->network_ctx, sm->key_mgmt);
|
sm->network_ctx, sm->key_mgmt);
|
||||||
}
|
}
|
||||||
if (!sm->cur_pmksa && pmkid &&
|
if (!sm->cur_pmksa && pmkid &&
|
||||||
pmksa_cache_get(sm->pmksa, src_addr, pmkid)) {
|
pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL))
|
||||||
|
{
|
||||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
||||||
"RSN: the new PMK matches with the "
|
"RSN: the new PMK matches with the "
|
||||||
"PMKID");
|
"PMKID");
|
||||||
|
|
|
@ -1698,6 +1698,8 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssid)
|
||||||
|
wpa_s->current_ssid = ssid;
|
||||||
wpa_s->connect_without_scan = NULL;
|
wpa_s->connect_without_scan = NULL;
|
||||||
wpa_s->disconnected = 0;
|
wpa_s->disconnected = 0;
|
||||||
wpa_s->reassociate = 1;
|
wpa_s->reassociate = 1;
|
||||||
|
|
Loading…
Reference in a new issue