示例#1
0
static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
					    int i, struct wpa_scan_res *bss,
					    struct wpa_ssid *group)
{
	const u8 *ssid_;
	u8 wpa_ie_len, rsn_ie_len, ssid_len;
	int wpa;
	struct wpa_blacklist *e;
	const u8 *ie;
	struct wpa_ssid *ssid;

	ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
	ssid_ = ie ? ie + 2 : (u8 *) "";
	ssid_len = ie ? ie[1] : 0;

	ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
	wpa_ie_len = ie ? ie[1] : 0;

	ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
	rsn_ie_len = ie ? ie[1] : 0;

	wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
		   "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x level=%d%s",
		   i, MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len),
		   wpa_ie_len, rsn_ie_len, bss->caps, bss->level,
		   wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE) ?
		   " wps" : "");

	e = wpa_blacklist_get(wpa_s, bss->bssid);
	if (e && e->count > 1) {
		wpa_printf(MSG_DEBUG, "   skip - blacklisted");
		return 0;
	}

	if (ssid_len == 0) {
		wpa_printf(MSG_DEBUG, "   skip - SSID not known");
		return 0;
	}

	wpa = wpa_ie_len > 0 || rsn_ie_len > 0;

	for (ssid = group; ssid; ssid = ssid->pnext) {
		int check_ssid = wpa ? 1 : (ssid->ssid_len != 0);

		if (ssid->disabled) {
			wpa_printf(MSG_DEBUG, "   skip - disabled");
			continue;
		}

#ifdef CONFIG_WPS
		if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && e && e->count > 0) {
			wpa_printf(MSG_DEBUG, "   skip - blacklisted (WPS)");
			continue;
		}

		if (wpa && ssid->ssid_len == 0 &&
		    wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
			check_ssid = 0;

		if (!wpa && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
			/* Only allow wildcard SSID match if an AP
			 * advertises active WPS operation that matches
			 * with our mode. */
			check_ssid = 1;
			if (ssid->ssid_len == 0 &&
			    wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
				check_ssid = 0;
		}
#endif /* CONFIG_WPS */

		if (check_ssid &&
		    (ssid_len != ssid->ssid_len ||
		     os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
			wpa_printf(MSG_DEBUG, "   skip - SSID mismatch");
			continue;
		}

		if (ssid->bssid_set &&
		    os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) {
			wpa_printf(MSG_DEBUG, "   skip - BSSID mismatch");
			continue;
		}

		if (wpa && !wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
			continue;

		if (!wpa &&
		    !(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
		    !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
		    !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) {
			wpa_printf(MSG_DEBUG, "   skip - non-WPA network not "
				   "allowed");
			continue;
		}

		if (!wpa && !wpa_supplicant_match_privacy(bss, ssid)) {
			wpa_printf(MSG_DEBUG, "   skip - privacy mismatch");
			continue;
		}

		if (!wpa && (bss->caps & IEEE80211_CAP_IBSS)) {
			wpa_printf(MSG_DEBUG, "   skip - IBSS (adhoc) "
				   "network");
			continue;
		}

		if (!freq_allowed(ssid->freq_list, bss->freq)) {
			wpa_printf(MSG_DEBUG, "   skip - frequency not "
				   "allowed");
			continue;
		}

#ifdef CONFIG_P2P
		/*
		 * TODO: skip the AP if its P2P IE has Group Formation
		 * bit set in the P2P Group Capability Bitmap and we
		 * are not in Group Formation with that device.
		 */
#endif /* CONFIG_P2P */

		/* Matching configuration found */
		return ssid;
	}

	/* No matching configuration found */
	return 0;
}
示例#2
0
static struct wpa_bss *
wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
			      struct wpa_scan_results *scan_res,
			      struct wpa_ssid *group,
			      struct wpa_ssid **selected_ssid)
{
	struct wpa_ssid *ssid;
	struct wpa_scan_res *bss;
	size_t i;
	struct wpa_blacklist *e;
	const u8 *ie;

	wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP");
	for (i = 0; i < scan_res->num; i++) {
		const u8 *ssid_;
		u8 wpa_ie_len, rsn_ie_len, ssid_len;
		bss = scan_res->res[i];

		ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
		ssid_ = ie ? ie + 2 : (u8 *) "";
		ssid_len = ie ? ie[1] : 0;

		ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
		wpa_ie_len = ie ? ie[1] : 0;

		ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
		rsn_ie_len = ie ? ie[1] : 0;

		wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
			   "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x",
			   (int) i, MAC2STR(bss->bssid),
			   wpa_ssid_txt(ssid_, ssid_len),
			   wpa_ie_len, rsn_ie_len, bss->caps);

		e = wpa_blacklist_get(wpa_s, bss->bssid);
		if (e) {
			int limit = 1;
			if (wpa_supplicant_enabled_networks(wpa_s->conf) == 1) {
				/*
				 * When only a single network is enabled, we can
				 * trigger blacklisting on the first failure. This
				 * should not be done with multiple enabled networks to
				 * avoid getting forced to move into a worse ESS on
				 * single error if there are no other BSSes of the
				 * current ESS.
				 */
				limit = 0;
			}
			if (e->count > limit) {
				wpa_printf(MSG_DEBUG, "   skip - blacklisted "
					   "(count=%d limit=%d)", e->count, limit);
				continue;
			}
		}

		if (ssid_len == 0) {
			wpa_printf(MSG_DEBUG, "   skip - SSID not known");
			continue;
		}

		if (wpa_ie_len == 0 && rsn_ie_len == 0) {
			wpa_printf(MSG_DEBUG, "   skip - no WPA/RSN IE");
			continue;
		}

		for (ssid = group; ssid; ssid = ssid->pnext) {
			int check_ssid = 1;

			if (ssid->disabled) {
				wpa_printf(MSG_DEBUG, "   skip - disabled");
				continue;
			}

#ifdef CONFIG_WPS
			if (ssid->ssid_len == 0 &&
			    wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
				check_ssid = 0;
#endif /* CONFIG_WPS */

			if (check_ssid &&
			    (ssid_len != ssid->ssid_len ||
			     os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
				wpa_printf(MSG_DEBUG, "   skip - "
					   "SSID mismatch");
				continue;
			}

			if (ssid->bssid_set &&
			    os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
			{
				wpa_printf(MSG_DEBUG, "   skip - "
					   "BSSID mismatch");
				continue;
			}

			if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
				continue;

			if (!freq_allowed(ssid->freq_list, bss->freq)) {
				wpa_printf(MSG_DEBUG, "   skip - "
					   "frequency not allowed");
				continue;
			}

			wpa_printf(MSG_DEBUG, "   selected WPA AP "
				   MACSTR " ssid='%s'",
				   MAC2STR(bss->bssid),
				   wpa_ssid_txt(ssid_, ssid_len));
			*selected_ssid = ssid;
			return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len);
		}
	}

	return NULL;
}
示例#3
0
static struct wpa_bss *
wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
				  struct wpa_scan_results *scan_res,
				  struct wpa_ssid *group,
				  struct wpa_ssid **selected_ssid)
{
	struct wpa_ssid *ssid;
	struct wpa_scan_res *bss;
	size_t i;
	struct wpa_blacklist *e;
	const u8 *ie;

	wpa_printf(MSG_DEBUG, "Try to find non-WPA AP");
	for (i = 0; i < scan_res->num; i++) {
		const u8 *ssid_;
		u8 wpa_ie_len, rsn_ie_len, ssid_len;
		bss = scan_res->res[i];

		ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
		ssid_ = ie ? ie + 2 : (u8 *) "";
		ssid_len = ie ? ie[1] : 0;

		ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
		wpa_ie_len = ie ? ie[1] : 0;

		ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
		rsn_ie_len = ie ? ie[1] : 0;

		wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
			   "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x",
			   (int) i, MAC2STR(bss->bssid),
			   wpa_ssid_txt(ssid_, ssid_len),
			   wpa_ie_len, rsn_ie_len, bss->caps);

		e = wpa_blacklist_get(wpa_s, bss->bssid);
		if (e && e->count > 1) {
			wpa_printf(MSG_DEBUG, "   skip - blacklisted");
			continue;
		}

		if (ssid_len == 0) {
			wpa_printf(MSG_DEBUG, "   skip - SSID not known");
			continue;
		}

		for (ssid = group; ssid; ssid = ssid->pnext) {
			int check_ssid = ssid->ssid_len != 0;

			if (ssid->disabled) {
				wpa_printf(MSG_DEBUG, "   skip - disabled");
				continue;
			}

#ifdef CONFIG_WPS
			if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
				/* Only allow wildcard SSID match if an AP
				 * advertises active WPS operation that matches
				 * with our mode. */
				check_ssid = 1;
				if (ssid->ssid_len == 0 &&
				    wpas_wps_ssid_wildcard_ok(wpa_s, ssid,
							      bss))
					check_ssid = 0;
			}
#endif /* CONFIG_WPS */

			if (check_ssid &&
			    (ssid_len != ssid->ssid_len ||
			     os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
				wpa_printf(MSG_DEBUG, "   skip - "
					   "SSID mismatch");
				continue;
			}

			if (ssid->bssid_set &&
			    os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
			{
				wpa_printf(MSG_DEBUG, "   skip - "
					   "BSSID mismatch");
				continue;
			}

			if (!(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
			    !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
			    !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA))
			{
				wpa_printf(MSG_DEBUG, "   skip - "
					   "non-WPA network not allowed");
				continue;
			}

			if ((ssid->key_mgmt &
			     (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK |
			      WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK |
			      WPA_KEY_MGMT_IEEE8021X_SHA256 |
			      WPA_KEY_MGMT_PSK_SHA256)) &&
			    (wpa_ie_len != 0 || rsn_ie_len != 0)) {
				wpa_printf(MSG_DEBUG, "   skip - "
					   "WPA network");
				continue;
			}

			if (!wpa_supplicant_match_privacy(bss, ssid)) {
				wpa_printf(MSG_DEBUG, "   skip - "
					   "privacy mismatch");
				continue;
			}

			if (bss->caps & IEEE80211_CAP_IBSS) {
				wpa_printf(MSG_DEBUG, "   skip - "
					   "IBSS (adhoc) network");
				continue;
			}

			if (!freq_allowed(ssid->freq_list, bss->freq)) {
				wpa_printf(MSG_DEBUG, "   skip - "
					   "frequency not allowed");
				continue;
			}

			wpa_printf(MSG_DEBUG, "   selected non-WPA AP "
				   MACSTR " ssid='%s'",
				   MAC2STR(bss->bssid),
				   wpa_ssid_txt(ssid_, ssid_len));
			*selected_ssid = ssid;
			return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len);
		}
	}

	return NULL;
}
示例#4
0
static struct wpa_bss *
wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
			      struct wpa_scan_results *scan_res,
			      struct wpa_ssid *group,
			      struct wpa_ssid **selected_ssid)
{
	struct wpa_ssid *ssid;
	struct wpa_scan_res *bss;
	size_t i;
	struct wpa_blacklist *e;
	const u8 *ie;

	wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP");
	for (i = 0; i < scan_res->num; i++) {
		const u8 *ssid_;
		u8 wpa_ie_len, rsn_ie_len, ssid_len;
		bss = scan_res->res[i];

		ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
		ssid_ = ie ? ie + 2 : (u8 *) "";
		ssid_len = ie ? ie[1] : 0;

		ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
		wpa_ie_len = ie ? ie[1] : 0;

		ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
		rsn_ie_len = ie ? ie[1] : 0;

		wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
			   "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x",
			   (int) i, MAC2STR(bss->bssid),
			   wpa_ssid_txt(ssid_, ssid_len),
			   wpa_ie_len, rsn_ie_len, bss->caps);

		e = wpa_blacklist_get(wpa_s, bss->bssid);
		if (e && e->count > 1) {
			wpa_printf(MSG_DEBUG, "   skip - blacklisted");
			continue;
		}

		if (ssid_len == 0) {
			wpa_printf(MSG_DEBUG, "   skip - SSID not known");
			continue;
		}

		if (wpa_ie_len == 0 && rsn_ie_len == 0) {
			wpa_printf(MSG_DEBUG, "   skip - no WPA/RSN IE");
			continue;
		}

		for (ssid = group; ssid; ssid = ssid->pnext) {
			int check_ssid = 1;

			if (ssid->disabled) {
				wpa_printf(MSG_DEBUG, "   skip - disabled");
				continue;
			}

#ifdef CONFIG_WPS
			if (ssid->ssid_len == 0 &&
			    wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
				check_ssid = 0;
#endif /* CONFIG_WPS */

			if (check_ssid &&
			    (ssid_len != ssid->ssid_len ||
			     os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
				wpa_printf(MSG_DEBUG, "   skip - "
					   "SSID mismatch");
				continue;
			}

			if (ssid->bssid_set &&
			    os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
			{
				wpa_printf(MSG_DEBUG, "   skip - "
					   "BSSID mismatch");
				continue;
			}

			if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
				continue;

			if (!freq_allowed(ssid->freq_list, bss->freq)) {
				wpa_printf(MSG_DEBUG, "   skip - "
					   "frequency not allowed");
				continue;
			}

			wpa_printf(MSG_DEBUG, "   selected WPA AP "
				   MACSTR " ssid='%s'",
				   MAC2STR(bss->bssid),
				   wpa_ssid_txt(ssid_, ssid_len));
			*selected_ssid = ssid;
			return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len);
		}
	}

	return NULL;
}