/**
 * rsn_preauth_scan_results - Process scan results to find PMKSA candidates
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 * @results: Scan results
 *
 * This functions goes through the scan results and adds all suitable APs
 * (Authenticators) into PMKSA candidate list.
 */
void 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)
		return;

	/*
	 * TODO: is it ok to free all candidates? What about the entries
	 * received from EVENT_PMKID_CANDIDATE?
	 */
	pmksa_candidate_free(sm);

	for (i = results->num - 1; i >= 0; i--) {
		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 ||
		    os_memcmp(ssid + 2, sm->ssid, ssid[1]) != 0)
			continue;

		if (os_memcmp(r->bssid, sm->bssid, ETH_ALEN) == 0)
			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,
				    PMKID_CANDIDATE_PRIO_SCAN,
				    ie.capabilities & WPA_CAPABILITY_PREAUTH);
	}
}
Exemple #2
0
static void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s,
						 union wpa_event_data *data)
{
	if (data == NULL) {
		wpa_printf(MSG_DEBUG, "RSN: No data in PMKID candidate event");
		return;
	}
	wpa_printf(MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR
		   " index=%d preauth=%d",
		   MAC2STR(data->pmkid_candidate.bssid),
		   data->pmkid_candidate.index,
		   data->pmkid_candidate.preauth);

	pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid,
			    data->pmkid_candidate.index,
			    data->pmkid_candidate.preauth);
}
/**
 * rsn_preauth_scan_results - Process scan results to find PMKSA candidates
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 * @results: Scan results
 * @count: Number of BSSes in scan results
 *
 * This functions goes through the scan results and adds all suitable APs
 * (Authenticators) into PMKSA candidate list.
 */
void rsn_preauth_scan_results(struct wpa_sm *sm,
			      struct wpa_scan_result *results, int count)
{
	struct wpa_scan_result *r;
	struct wpa_ie_data ie;
	int i;
	struct rsn_pmksa_cache *pmksa;

	if (sm->cur_ssid == NULL)
		return;

	/*
	 * TODO: is it ok to free all candidates? What about the entries
	 * received from EVENT_PMKID_CANDIDATE?
	 */
	pmksa_candidate_free(sm);

	for (i = count - 1; i >= 0; i--) {
		r = &results[i];
		if (r->ssid_len != sm->cur_ssid->ssid_len ||
		    memcmp(r->ssid, sm->cur_ssid->ssid,
			   r->ssid_len) != 0)
			continue;

		if (memcmp(r->bssid, sm->bssid, ETH_ALEN) == 0)
			continue;

		if (r->rsn_ie_len == 0 ||
		    wpa_parse_wpa_ie(r->rsn_ie, r->rsn_ie_len, &ie))
			continue;

		pmksa = pmksa_cache_get(sm, 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,
				    PMKID_CANDIDATE_PRIO_SCAN,
				    ie.capabilities & WPA_CAPABILITY_PREAUTH);
	}
}
/* TODO: schedule periodic scans if current AP supports preauth */
void rsn_preauth_scan_results(struct wpa_supplicant *wpa_s,
			      struct wpa_scan_result *results, int count)
{
	struct wpa_scan_result *r;
	struct wpa_ie_data ie;
	int i;
	struct rsn_pmksa_cache *pmksa;

	if (wpa_s->current_ssid == NULL)
		return;

	pmksa_candidate_free(wpa_s);

	for (i = count - 1; i >= 0; i--) {
		r = &results[i];
		if (r->ssid_len != wpa_s->current_ssid->ssid_len ||
		    memcmp(r->ssid, wpa_s->current_ssid->ssid,
			   r->ssid_len) != 0)
			continue;

		if (memcmp(r->bssid, wpa_s->bssid, ETH_ALEN) == 0)
			continue;

		if (r->rsn_ie_len == 0 ||
		    wpa_parse_wpa_ie(wpa_s, r->rsn_ie, r->rsn_ie_len, &ie))
			continue;

		pmksa = pmksa_cache_get(wpa_s, 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(wpa_s, r->bssid,
				    PMKID_CANDIDATE_PRIO_SCAN,
				    ie.capabilities & WPA_CAPABILITY_PREAUTH);
	}
}