Esempio n. 1
0
int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
			      struct wpa_ssid *ssid,
			      struct wpa_scan_res *bss)
{
	struct wpabuf *wps_ie = NULL;
	int ret = 0;

	if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
		wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
		if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) {
			/* allow wildcard SSID for WPS PBC */
			ret = 1;
		}
	} else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
		wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
		if (wps_ie &&
		    (wps_is_selected_pin_registrar(wps_ie) ||
		     wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
			/* allow wildcard SSID for WPS PIN */
			ret = 1;
		}
	}

	if (!ret && ssid->bssid_set &&
	    os_memcmp(ssid->bssid, bss->bssid, ETH_ALEN) == 0) {
		/* allow wildcard SSID due to hardcoded BSSID match */
		ret = 1;
	}

	wpabuf_free(wps_ie);

	return ret;
}
Esempio n. 2
0
enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid)
{
	if (eap_is_wps_pbc_enrollee(&ssid->eap) ||
	    eap_is_wps_pin_enrollee(&ssid->eap))
		return WPS_REQ_ENROLLEE;
	else
		return WPS_REQ_REGISTRAR;
}
Esempio n. 3
0
int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
			      struct wpa_ssid *ssid,
			      struct wpa_scan_res *bss)
{
	struct wpabuf *wps_ie = NULL;
	int ret = 0;

	if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
		wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
		if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) {
			/* allow wildcard SSID for WPS PBC */
			ret = 1;
		}
	} else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
		wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
		if (wps_ie &&
		    (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) ||
		     wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
			/* allow wildcard SSID for WPS PIN */
			ret = 1;
		}
	}

	if (!ret && ssid->bssid_set &&
	    os_memcmp(ssid->bssid, bss->bssid, ETH_ALEN) == 0) {
		/* allow wildcard SSID due to hardcoded BSSID match */
		ret = 1;
	}

#ifdef CONFIG_WPS_STRICT
	if (wps_ie) {
		if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len >
						   0, bss->bssid) < 0)
			ret = 0;
		if (bss->beacon_ie_len) {
			struct wpabuf *bcn_wps;
			bcn_wps = wpa_scan_get_vendor_ie_multi_beacon(
				bss, WPS_IE_VENDOR_TYPE);
			if (bcn_wps == NULL) {
				wpa_printf(MSG_DEBUG, "WPS: Mandatory WPS IE "
					   "missing from AP Beacon");
				ret = 0;
			} else {
				if (wps_validate_beacon(wps_ie) < 0)
					ret = 0;
				wpabuf_free(bcn_wps);
			}
		}
	}
#endif /* CONFIG_WPS_STRICT */

	wpabuf_free(wps_ie);

	return ret;
}
Esempio n. 4
0
int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
			      struct wpa_scan_res *selected,
			      struct wpa_ssid *ssid)
{
	const u8 *sel_uuid, *uuid;
	size_t i;
	struct wpabuf *wps_ie;
	int ret = 0;

	if (!eap_is_wps_pbc_enrollee(&ssid->eap))
		return 0;

	/* Make sure that only one AP is in active PBC mode */
	wps_ie = wpa_scan_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE);
	if (wps_ie)
		sel_uuid = wps_get_uuid_e(wps_ie);
	else
		sel_uuid = NULL;

	for (i = 0; i < wpa_s->scan_res->num; i++) {
		struct wpa_scan_res *bss = wpa_s->scan_res->res[i];
		struct wpabuf *ie;
		if (bss == selected)
			continue;
		ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
		if (!ie)
			continue;
		if (!wps_is_selected_pbc_registrar(ie)) {
			wpabuf_free(ie);
			continue;
		}
		uuid = wps_get_uuid_e(ie);
		if (sel_uuid == NULL || uuid == NULL ||
		    os_memcmp(sel_uuid, uuid, 16) != 0) {
			ret = 1; /* PBC overlap */
			wpabuf_free(ie);
			break;
		}

		/* TODO: verify that this is reasonable dual-band situation */

		wpabuf_free(ie);
	}

	wpabuf_free(wps_ie);

	return ret;
}
Esempio n. 5
0
int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
			    struct wpa_ssid *ssid, struct wpa_scan_res *bss)
{
	struct wpabuf *wps_ie;

	if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
		return -1;

	wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
	if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
		if (!wps_ie) {
			wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
			return 0;
		}

		if (!wps_is_selected_pbc_registrar(wps_ie)) {
			wpa_printf(MSG_DEBUG, "   skip - WPS AP "
				   "without active PBC Registrar");
			wpabuf_free(wps_ie);
			return 0;
		}

		/* TODO: overlap detection */
		wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
			   "(Active PBC)");
		wpabuf_free(wps_ie);
		return 1;
	}

	if (eap_is_wps_pin_enrollee(&ssid->eap)) {
		if (!wps_ie) {
			wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
			return 0;
		}

		/*
		 * Start with WPS APs that advertise active PIN Registrar and
		 * allow any WPS AP after third scan since some APs do not set
		 * Selected Registrar attribute properly when using external
		 * Registrar.
		 */
		if (!wps_is_selected_pin_registrar(wps_ie)) {
			if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG) {
				wpa_printf(MSG_DEBUG, "   skip - WPS AP "
					   "without active PIN Registrar");
				wpabuf_free(wps_ie);
				return 0;
			}
			wpa_printf(MSG_DEBUG, "   selected based on WPS IE");
		} else {
			wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
				   "(Active PIN)");
		}
		wpabuf_free(wps_ie);
		return 1;
	}

	if (wps_ie) {
		wpa_printf(MSG_DEBUG, "   selected based on WPS IE");
		wpabuf_free(wps_ie);
		return 1;
	}

	return -1;
}
Esempio n. 6
0
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
{
	int prio, timeout;
	struct wpa_scan_res *selected = NULL;
	struct wpa_ssid *ssid = NULL;

	wpa_supplicant_notify_scanning(wpa_s, 0);
	if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
		if (wpa_s->conf->ap_scan == 2)
			return;
		wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
			   "scanning again");
		timeout = 1;
		goto req_scan;
	}

	/*
	 * Don't post the results if this was the initial cached
	 * and there were no results.
	 */
	if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 &&
	    wpa_s->scan_res->num == 0) {
		wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are "
			"empty - not posting");
	} else {
		wpa_printf(MSG_DEBUG, "New scan results available");
		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
		wpa_supplicant_dbus_notify_scan_results(wpa_s);
/* WPS availability is fetched from scan results. Reduce logging. */
#ifndef ANDROID
		wpas_wps_notify_scan_results(wpa_s);
#endif
	}

	if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)))
		return;

	if (wpa_s->disconnected) {
		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
		return;
	}

	while (selected == NULL) {
		
#ifdef CONFIG_ORANGE_SUPPORT
		for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
			selected = wpa_supplicant_select_bss_private(
				wpa_s, wpa_s->conf->pssid[prio], &ssid);
			if (selected)
				break;
		}
		if(selected == NULL)
		{
			for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
				selected = wpa_supplicant_select_bss_public(
					wpa_s, wpa_s->conf->pssid[prio], &ssid);
				if (selected)
					break;
			}
		}
#else		
		for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
			selected = wpa_supplicant_select_bss(
				wpa_s, wpa_s->conf->pssid[prio], &ssid);
			if (selected)
				break;
		}
#endif

		if (selected == NULL && wpa_s->blacklist) {
			wpa_printf(MSG_DEBUG, "No APs found - clear blacklist "
				   "and try again");
			wpa_blacklist_clear(wpa_s);
			wpa_s->blacklist_cleared++;
		} else if (selected == NULL) {
			break;
		}
	}

	if (selected) {
		if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
			wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
				"PBC session overlap");
			timeout = 10;
			goto req_scan;
		}
		else
		{
			if(eap_is_wps_pbc_enrollee(&ssid->eap))
			{
				wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_NO_OVERLAP);
			}
		}

		/* Do not trigger new association unless the BSSID has changed
		 * or if reassociation is requested. If we are in process of
		 * associating with the selected BSSID, do not trigger new
		 * attempt. */

        wpa_printf(MSG_DEBUG, "[associate] %s:: wpa_s->reassociate = %d, selected->bssid ="
				   MACSTR "\nwpa_s->bssid = "  MACSTR "wpa_s->wpa_state = %d"  "wpa_s->pending_bssid = " MACSTR,
				   __FUNCTION__,
				   wpa_s->reassociate,
                    MAC2STR(selected->bssid),
                    MAC2STR(wpa_s->bssid),
                    wpa_s->wpa_state,
                    MAC2STR(wpa_s->pending_bssid)
                    );

		if (wpa_s->reassociate ||
		    (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
		     (wpa_s->wpa_state != WPA_ASSOCIATING ||
		      os_memcmp(selected->bssid, wpa_s->pending_bssid,
				ETH_ALEN) != 0))) {
			if (wpa_supplicant_scard_init(wpa_s, ssid)) {
				wpa_supplicant_req_scan(wpa_s, 10, 0);
				return;
			}
			wpa_supplicant_associate(wpa_s, selected, ssid);
		} else {
			wpa_printf(MSG_DEBUG, "Already associated with the "
				   "selected AP.");
		}
		rsn_preauth_scan_results(wpa_s->wpa, wpa_s->scan_res);
	} else {
		wpa_printf(MSG_DEBUG, "No suitable AP found.");
#ifdef ANDROID
		timeout = wpa_s->scan_interval;
		if (wpas_wps_searching(wpa_s)) {
			timeout = 5;
		} else {
			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_NO_SUITABLE_AP);
		}
#else
		timeout = 5;
#endif
		goto req_scan;
	}

	return;

req_scan:
	if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) {
		/*
		 * Quick recovery if the initial scan results were not
		 * complete when fetched before the first scan request.
		 */
		wpa_s->scan_res_tried++;
		timeout = 0;
	} else if (!wpa_supplicant_enabled_networks(wpa_s->conf)) {
		/*
		 * No networks are enabled; short-circuit request so
		 * we don't wait timeout seconds before transitioning
		 * to INACTIVE state.
		 */
		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
		return;
	}
	wpa_supplicant_req_scan(wpa_s, timeout, 0);
}
Esempio n. 7
0
int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
			      struct wpa_bss *selected, struct wpa_ssid *ssid)
{
	const u8 *sel_uuid, *uuid;
	struct wpabuf *wps_ie;
	int ret = 0;
	struct wpa_bss *bss;

	if (!eap_is_wps_pbc_enrollee(&ssid->eap))
		return 0;

	wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is "
		   "present in scan results; selected BSSID " MACSTR,
		   MAC2STR(selected->bssid));

	/* Make sure that only one AP is in active PBC mode */
	wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE);
	if (wps_ie) {
		sel_uuid = wps_get_uuid_e(wps_ie);
		wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS",
			    sel_uuid, UUID_LEN);
	} else {
		wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include "
			   "WPS IE?!");
		sel_uuid = NULL;
	}

	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
		struct wpabuf *ie;
		if (bss == selected)
			continue;
		ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
		if (!ie)
			continue;
		if (!wps_is_selected_pbc_registrar(ie)) {
			wpabuf_free(ie);
			continue;
		}
		wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: "
			   MACSTR, MAC2STR(bss->bssid));
		uuid = wps_get_uuid_e(ie);
		wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS",
			    uuid, UUID_LEN);
		if (sel_uuid == NULL || uuid == NULL ||
		    os_memcmp(sel_uuid, uuid, UUID_LEN) != 0) {
			ret = 1; /* PBC overlap */
			wpa_msg(wpa_s, MSG_INFO, "WPS: PBC overlap detected: "
				MACSTR " and " MACSTR,
				MAC2STR(selected->bssid),
				MAC2STR(bss->bssid));
			wpabuf_free(ie);
			break;
		}

		/* TODO: verify that this is reasonable dual-band situation */

		wpabuf_free(ie);
	}

	wpabuf_free(wps_ie);

	return ret;
}