Beispiel #1
0
static int wpa_supplicant_add_pmkid(void *_wpa_s, void *network_ctx,
				    const u8 *bssid, const u8 *pmkid,
				    const u8 *fils_cache_id,
				    const u8 *pmk, size_t pmk_len)
{
	struct wpa_supplicant *wpa_s = _wpa_s;
	struct wpa_ssid *ssid;
	struct wpa_pmkid_params params;

	os_memset(&params, 0, sizeof(params));
	ssid = wpas_get_network_ctx(wpa_s, network_ctx);
	if (ssid)
		wpa_msg(wpa_s, MSG_INFO, PMKSA_CACHE_ADDED MACSTR " %d",
			MAC2STR(bssid), ssid->id);
	if (ssid && fils_cache_id) {
		params.ssid = ssid->ssid;
		params.ssid_len = ssid->ssid_len;
		params.fils_cache_id = fils_cache_id;
	} else {
		params.bssid = bssid;
	}

	params.pmkid = pmkid;
	params.pmk = pmk;
	params.pmk_len = pmk_len;

	return wpa_drv_add_pmkid(wpa_s, &params);
}
void rsn_preauth_candidate_process(struct wpa_supplicant *wpa_s)
{
	struct rsn_pmksa_candidate *candidate;

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

	/* TODO: drop priority for old candidate entries */

	wpa_msg(wpa_s, MSG_DEBUG, "RSN: processing PMKSA candidate list");
	if (wpa_s->preauth_eapol ||
	    wpa_s->proto != WPA_PROTO_RSN ||
	    wpa_s->wpa_state != WPA_COMPLETED ||
	    wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X) {
		wpa_msg(wpa_s, MSG_DEBUG, "RSN: not in suitable state for new "
			"pre-authentication");
		return; /* invalid state for new pre-auth */
	}

	while (wpa_s->pmksa_candidates) {
		struct rsn_pmksa_cache *p = NULL;
		candidate = wpa_s->pmksa_candidates;
		p = pmksa_cache_get(wpa_s, candidate->bssid, NULL);
		if (memcmp(wpa_s->bssid, candidate->bssid, ETH_ALEN) != 0 &&
		    (p == NULL || p->opportunistic)) {
			wpa_msg(wpa_s, MSG_DEBUG, "RSN: PMKSA candidate "
				MACSTR " selected for pre-authentication",
				MAC2STR(candidate->bssid));
			wpa_s->pmksa_candidates = candidate->next;
			rsn_preauth_init(wpa_s, candidate->bssid);
			free(candidate);
			return;
		}
		wpa_msg(wpa_s, MSG_DEBUG, "RSN: PMKSA candidate " MACSTR
			" does not need pre-authentication anymore",
			MAC2STR(candidate->bssid));
		/* Some drivers (e.g., NDIS) expect to get notified about the
		 * PMKIDs again, so report the existing data now. */
		if (p)
			wpa_drv_add_pmkid(wpa_s, candidate->bssid, p->pmkid);

		wpa_s->pmksa_candidates = candidate->next;
		free(candidate);
	}
	wpa_msg(wpa_s, MSG_DEBUG, "RSN: no more pending PMKSA candidates");
}
Beispiel #3
0
static int wpa_supplicant_add_pmkid(void *wpa_s,
				    const u8 *bssid, const u8 *pmkid)
{
	return wpa_drv_add_pmkid(wpa_s, bssid, pmkid);
}
struct rsn_pmksa_cache *
pmksa_cache_add(struct wpa_supplicant *wpa_s, const u8 *pmk,
		size_t pmk_len, const u8 *aa, const u8 *spa,
		struct wpa_ssid *ssid)
{
	struct rsn_pmksa_cache *entry, *pos, *prev;

	if (wpa_s->proto != WPA_PROTO_RSN || pmk_len > PMK_LEN)
		return NULL;

	entry = malloc(sizeof(*entry));
	if (entry == NULL)
		return NULL;
	memset(entry, 0, sizeof(*entry));
	memcpy(entry->pmk, pmk, pmk_len);
	entry->pmk_len = pmk_len;
	rsn_pmkid(pmk, aa, spa, entry->pmkid);
	entry->expiration = time(NULL) + dot11RSNAConfigPMKLifetime;
	entry->akmp = WPA_KEY_MGMT_IEEE8021X;
	memcpy(entry->aa, aa, ETH_ALEN);
	entry->ssid = ssid;

	/* Replace an old entry for the same Authenticator (if found) with the
	 * new entry */
	pos = wpa_s->pmksa;
	prev = NULL;
	while (pos) {
		if (memcmp(aa, pos->aa, ETH_ALEN) == 0) {
			if (prev == NULL)
				wpa_s->pmksa = pos->next;
			else
				prev->next = pos->next;
			pmksa_cache_free_entry(wpa_s, pos);
			break;
		}
		prev = pos;
		pos = pos->next;
	}

	if (wpa_s->pmksa_count >= pmksa_cache_max_entries && wpa_s->pmksa) {
		/* Remove the oldest entry to make room for the new entry */
		pos = wpa_s->pmksa;
		wpa_s->pmksa = pos->next;
		wpa_printf(MSG_DEBUG, "RSN: removed the oldest PMKSA cache "
			   "entry (for " MACSTR ") to make room for new one",
			   MAC2STR(pos->aa));
		wpa_drv_remove_pmkid(wpa_s, pos->aa, pos->pmkid);
		pmksa_cache_free_entry(wpa_s, pos);
	}

	/* Add the new entry; order by expiration time */
	pos = wpa_s->pmksa;
	prev = NULL;
	while (pos) {
		if (pos->expiration > entry->expiration)
			break;
		prev = pos;
		pos = pos->next;
	}
	if (prev == NULL) {
		entry->next = wpa_s->pmksa;
		wpa_s->pmksa = entry;
	} else {
		entry->next = prev->next;
		prev->next = entry;
	}
	wpa_s->pmksa_count++;
	wpa_printf(MSG_DEBUG, "RSN: added PMKSA cache entry for " MACSTR,
		   MAC2STR(entry->aa));
	wpa_drv_add_pmkid(wpa_s, entry->aa, entry->pmkid);

	return entry;
}