Split scan processing for RSN preauthentication into parts
This avoids passing the raw scan results into the RSN code and by doing so, removes the only dependency on src/drivers from the src/rsn_supp code (or from any src subdirectory for that matter).
This commit is contained in:
parent
4d69dc3ecc
commit
6ae9318536
3 changed files with 80 additions and 46 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant - RSN pre-authentication
|
* WPA Supplicant - RSN pre-authentication
|
||||||
* Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2009, 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
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "wpa.h"
|
#include "wpa.h"
|
||||||
#include "drivers/driver.h"
|
|
||||||
#include "eloop.h"
|
#include "eloop.h"
|
||||||
#include "l2_packet/l2_packet.h"
|
#include "l2_packet/l2_packet.h"
|
||||||
#include "eapol_supp/eapol_supp_sm.h"
|
#include "eapol_supp/eapol_supp_sm.h"
|
||||||
|
@ -423,23 +422,18 @@ void pmksa_candidate_add(struct wpa_sm *sm, const u8 *bssid,
|
||||||
/* TODO: schedule periodic scans if current AP supports preauth */
|
/* TODO: schedule periodic scans if current AP supports preauth */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rsn_preauth_scan_results - Process scan results to find PMKSA candidates
|
* rsn_preauth_scan_results - Start processing scan results for canditates
|
||||||
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
||||||
* @results: Scan results
|
* Returns: 0 if ready to process results or -1 to skip processing
|
||||||
*
|
*
|
||||||
* This functions goes through the scan results and adds all suitable APs
|
* This functions is used to notify RSN code about start of new scan results
|
||||||
* (Authenticators) into PMKSA candidate list.
|
* processing. The actual scan results will be provided by calling
|
||||||
|
* rsn_preauth_scan_result() for each BSS if this function returned 0.
|
||||||
*/
|
*/
|
||||||
void rsn_preauth_scan_results(struct wpa_sm *sm,
|
int rsn_preauth_scan_results(struct wpa_sm *sm)
|
||||||
struct wpa_scan_results *results)
|
|
||||||
{
|
{
|
||||||
struct wpa_scan_res *r;
|
|
||||||
struct wpa_ie_data ie;
|
|
||||||
int i;
|
|
||||||
struct rsn_pmksa_cache_entry *pmksa;
|
|
||||||
|
|
||||||
if (sm->ssid_len == 0)
|
if (sm->ssid_len == 0)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: is it ok to free all candidates? What about the entries
|
* TODO: is it ok to free all candidates? What about the entries
|
||||||
|
@ -447,37 +441,41 @@ void rsn_preauth_scan_results(struct wpa_sm *sm,
|
||||||
*/
|
*/
|
||||||
pmksa_candidate_free(sm);
|
pmksa_candidate_free(sm);
|
||||||
|
|
||||||
for (i = results->num - 1; i >= 0; i--) {
|
return 0;
|
||||||
const u8 *ssid, *rsn;
|
}
|
||||||
|
|
||||||
r = results->res[i];
|
|
||||||
|
|
||||||
ssid = wpa_scan_get_ie(r, WLAN_EID_SSID);
|
/**
|
||||||
if (ssid == NULL || ssid[1] != sm->ssid_len ||
|
* rsn_preauth_scan_result - Processing scan result for PMKSA canditates
|
||||||
os_memcmp(ssid + 2, sm->ssid, ssid[1]) != 0)
|
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
||||||
continue;
|
*
|
||||||
|
* Add all suitable APs (Authenticators) from scan results into PMKSA
|
||||||
if (os_memcmp(r->bssid, sm->bssid, ETH_ALEN) == 0)
|
* candidate list.
|
||||||
continue;
|
|
||||||
|
|
||||||
rsn = wpa_scan_get_ie(r, WLAN_EID_RSN);
|
|
||||||
if (rsn == NULL || wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pmksa = pmksa_cache_get(sm->pmksa, r->bssid, NULL);
|
|
||||||
if (pmksa &&
|
|
||||||
(!pmksa->opportunistic ||
|
|
||||||
!(ie.capabilities & WPA_CAPABILITY_PREAUTH)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Give less priority to candidates found from normal
|
|
||||||
* scan results.
|
|
||||||
*/
|
*/
|
||||||
pmksa_candidate_add(sm, r->bssid,
|
void rsn_preauth_scan_result(struct wpa_sm *sm, const u8 *bssid,
|
||||||
PMKID_CANDIDATE_PRIO_SCAN,
|
const u8 *ssid, const u8 *rsn)
|
||||||
|
{
|
||||||
|
struct wpa_ie_data ie;
|
||||||
|
struct rsn_pmksa_cache_entry *pmksa;
|
||||||
|
|
||||||
|
if (ssid[1] != sm->ssid_len ||
|
||||||
|
os_memcmp(ssid + 2, sm->ssid, sm->ssid_len) != 0)
|
||||||
|
return; /* Not for the current SSID */
|
||||||
|
|
||||||
|
if (os_memcmp(bssid, sm->bssid, ETH_ALEN) == 0)
|
||||||
|
return; /* Ignore current AP */
|
||||||
|
|
||||||
|
if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pmksa = pmksa_cache_get(sm->pmksa, bssid, NULL);
|
||||||
|
if (pmksa && (!pmksa->opportunistic ||
|
||||||
|
!(ie.capabilities & WPA_CAPABILITY_PREAUTH)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Give less priority to candidates found from normal scan results. */
|
||||||
|
pmksa_candidate_add(sm, bssid, PMKID_CANDIDATE_PRIO_SCAN,
|
||||||
ie.capabilities & WPA_CAPABILITY_PREAUTH);
|
ie.capabilities & WPA_CAPABILITY_PREAUTH);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* wpa_supplicant - WPA2/RSN pre-authentication functions
|
* wpa_supplicant - WPA2/RSN pre-authentication functions
|
||||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2009, 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
|
||||||
|
@ -23,8 +23,9 @@ void pmksa_candidate_free(struct wpa_sm *sm);
|
||||||
int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst,
|
int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst,
|
||||||
struct eap_peer_config *eap_conf);
|
struct eap_peer_config *eap_conf);
|
||||||
void rsn_preauth_deinit(struct wpa_sm *sm);
|
void rsn_preauth_deinit(struct wpa_sm *sm);
|
||||||
void rsn_preauth_scan_results(struct wpa_sm *sm,
|
int rsn_preauth_scan_results(struct wpa_sm *sm);
|
||||||
struct wpa_scan_results *results);
|
void rsn_preauth_scan_result(struct wpa_sm *sm, const u8 *bssid,
|
||||||
|
const u8 *ssid, const u8 *rsn);
|
||||||
void pmksa_candidate_add(struct wpa_sm *sm, const u8 *bssid,
|
void pmksa_candidate_add(struct wpa_sm *sm, const u8 *bssid,
|
||||||
int prio, int preauth);
|
int prio, int preauth);
|
||||||
void rsn_preauth_candidate_process(struct wpa_sm *sm);
|
void rsn_preauth_candidate_process(struct wpa_sm *sm);
|
||||||
|
@ -51,8 +52,14 @@ static inline int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst,
|
||||||
static inline void rsn_preauth_deinit(struct wpa_sm *sm)
|
static inline void rsn_preauth_deinit(struct wpa_sm *sm)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
static inline void rsn_preauth_scan_results(struct wpa_sm *sm,
|
|
||||||
struct wpa_scan_results *results)
|
static inline int rsn_preauth_scan_results(struct wpa_sm *sm)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rsn_preauth_scan_result(struct wpa_sm *sm, const u8 *bssid,
|
||||||
|
const u8 *ssid, const u8 *rsn)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant - Driver event processing
|
* WPA Supplicant - Driver event processing
|
||||||
* Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2009, 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
|
||||||
|
@ -711,7 +711,6 @@ static void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
|
||||||
wpa_printf(MSG_DEBUG, "Already associated with the selected "
|
wpa_printf(MSG_DEBUG, "Already associated with the selected "
|
||||||
"AP");
|
"AP");
|
||||||
}
|
}
|
||||||
rsn_preauth_scan_results(wpa_s->wpa, wpa_s->scan_res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -735,6 +734,34 @@ wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpa_supplicant_rsn_preauth_scan_results(
|
||||||
|
struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = wpa_s->scan_res->num - 1; i >= 0; i--) {
|
||||||
|
const u8 *ssid, *rsn;
|
||||||
|
struct wpa_scan_res *r;
|
||||||
|
|
||||||
|
r = wpa_s->scan_res->res[i];
|
||||||
|
|
||||||
|
ssid = wpa_scan_get_ie(r, WLAN_EID_SSID);
|
||||||
|
if (ssid == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rsn = wpa_scan_get_ie(r, WLAN_EID_RSN);
|
||||||
|
if (rsn == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rsn_preauth_scan_result(wpa_s->wpa, r->bssid, ssid, rsn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
|
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
struct wpa_scan_res *selected;
|
struct wpa_scan_res *selected;
|
||||||
|
@ -778,6 +805,8 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
|
||||||
if (bgscan_notify_scan(wpa_s) == 1)
|
if (bgscan_notify_scan(wpa_s) == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wpa_supplicant_rsn_preauth_scan_results(wpa_s);
|
||||||
|
|
||||||
selected = wpa_supplicant_pick_network(wpa_s, &ssid);
|
selected = wpa_supplicant_pick_network(wpa_s, &ssid);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
wpa_supplicant_connect(wpa_s, selected, ssid);
|
wpa_supplicant_connect(wpa_s, selected, ssid);
|
||||||
|
|
Loading…
Reference in a new issue