aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2008-11-29 20:06:34 (GMT)
committerJouni Malinen <j@w1.fi>2008-11-29 20:06:34 (GMT)
commit351f09a2218263ccee52c0f73ab7863a7364cf42 (patch)
treed15eee4690d08681045ac156deb16d4e5582c1ba /wpa_supplicant
parent06384c662a6e0131763c19cd32a52e403eb8c851 (diff)
downloadhostap-06-351f09a2218263ccee52c0f73ab7863a7364cf42.zip
hostap-06-351f09a2218263ccee52c0f73ab7863a7364cf42.tar.gz
hostap-06-351f09a2218263ccee52c0f73ab7863a7364cf42.tar.bz2
WPS: Added support for fragmented WPS IE in Beacon and Probe Response
Fragment WPS IE if needed to fit into the IE length limits in hostapd and Reassemble WPS IE data from multiple IEs in wpa_supplicant. In addition, moved WPS code from events.c into wps_supplicant.c to clean up module interfaces.
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/events.c145
-rw-r--r--wpa_supplicant/wps_supplicant.c142
-rw-r--r--wpa_supplicant/wps_supplicant.h26
3 files changed, 175 insertions, 138 deletions
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 34b06e3..a1bd2ba 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -31,7 +31,7 @@
#include "ieee802_11_defs.h"
#include "blacklist.h"
#include "wpas_glue.h"
-#include "wps/wps.h"
+#include "wps_supplicant.h"
static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
@@ -276,53 +276,11 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_ssid *ssid,
struct wpa_ie_data ie;
int proto_match = 0;
const u8 *rsn_ie, *wpa_ie;
+ int ret;
-#ifdef CONFIG_WPS
- if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
- const u8 *wps_ie;
- wps_ie = wpa_scan_get_vendor_ie(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 + 6,
- wps_ie[1] - 4)) {
- wpa_printf(MSG_DEBUG, " skip - WPS AP "
- "without active PBC Registrar");
- return 0;
- }
-
- /* TODO: overlap detection */
- wpa_printf(MSG_DEBUG, " selected based on WPS IE "
- "(Active PBC)");
- return 1;
- }
-
- if (eap_is_wps_pin_enrollee(&ssid->eap)) {
- if (!wps_ie) {
- wpa_printf(MSG_DEBUG, " skip - non-WPS AP");
- return 0;
- }
-
- if (!wps_is_selected_pin_registrar(wps_ie + 6,
- wps_ie[1] - 4)) {
- wpa_printf(MSG_DEBUG, " skip - WPS AP "
- "without active PIN Registrar");
- return 0;
- }
- wpa_printf(MSG_DEBUG, " selected based on WPS IE "
- "(Active PIN)");
- return 1;
- }
-
- if (wps_ie) {
- wpa_printf(MSG_DEBUG, " selected based on WPS IE");
- return 1;
- }
- }
-#endif /* CONFIG_WPS */
+ ret = wpas_wps_ssid_bss_match(ssid, bss);
+ if (ret >= 0)
+ return ret;
rsn_ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
@@ -412,34 +370,6 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_ssid *ssid,
}
-#ifdef CONFIG_WPS
-static int wps_ssid_wildcard_ok(struct wpa_ssid *ssid,
- struct wpa_scan_res *bss)
-{
- const u8 *wps_ie;
-
- if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
- wps_ie = wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
- if (wps_ie &&
- wps_is_selected_pbc_registrar(wps_ie + 6, wps_ie[1] - 4)) {
- /* allow wildcard SSID for WPS PBC */
- return 1;
- }
- }
-
- if (eap_is_wps_pin_enrollee(&ssid->eap)) {
- wps_ie = wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
- if (wps_ie &&
- wps_is_selected_pin_registrar(wps_ie + 6, wps_ie[1] - 4)) {
- /* allow wildcard SSID for WPS PIN */
- return 1;
- }
- }
-
- return 0;
-}
-#endif /* CONFIG_WPS */
-
static struct wpa_scan_res *
wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
struct wpa_ssid *group,
@@ -494,7 +424,7 @@ wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_WPS
if (ssid->ssid_len == 0 &&
- wps_ssid_wildcard_ok(ssid, bss))
+ wpas_wps_ssid_wildcard_ok(ssid, bss))
check_ssid = 0;
#endif /* CONFIG_WPS */
@@ -584,7 +514,7 @@ wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
* with our mode. */
check_ssid = 1;
if (ssid->ssid_len == 0 &&
- wps_ssid_wildcard_ok(ssid, bss))
+ wpas_wps_ssid_wildcard_ok(ssid, bss))
check_ssid = 0;
}
#endif /* CONFIG_WPS */
@@ -670,65 +600,6 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
}
-#ifdef CONFIG_WPS
-
-static int wpa_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;
- const u8 *wps_ie;
-
- 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(selected, WPS_IE_VENDOR_TYPE);
- if (wps_ie)
- sel_uuid = wps_get_uuid_e(wps_ie + 6, wps_ie[1] - 4);
- else
- sel_uuid = NULL;
- if (!sel_uuid) {
- wpa_printf(MSG_DEBUG, "WPS: UUID-E not "
- "available for PBC overlap "
- "detection");
- return 1;
- }
-
- for (i = 0; i < wpa_s->scan_res->num; i++) {
- struct wpa_scan_res *bss = wpa_s->scan_res->res[i];
- if (bss == selected)
- continue;
- wps_ie = wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
- if (!wps_ie)
- continue;
- if (!wps_is_selected_pbc_registrar(wps_ie + 6,
- wps_ie[1] - 4))
- continue;
- uuid = wps_get_uuid_e(wps_ie + 6, wps_ie[1] - 4);
- if (uuid == NULL) {
- wpa_printf(MSG_DEBUG, "WPS: UUID-E not "
- "available for PBC overlap "
- "detection (other BSS)");
- return 1;
- }
- if (os_memcmp(sel_uuid, uuid, 16) != 0)
- return 1; /* PBC overlap */
-
- /* TODO: verify that this is reasonable dual-band situation */
- }
-
- return 0;
-}
-
-#else /* CONFIG_WPS */
-
-#define wpa_scan_pbc_overlap(w, s, i) 0
-
-#endif /* CONFIG_WPS */
-
-
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
{
int prio, timeout;
@@ -778,7 +649,7 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
}
if (selected) {
- if (wpa_scan_pbc_overlap(wpa_s, selected, ssid)) {
+ if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
"PBC session overlap");
timeout = 10;
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 49869f9..2b1e6b8 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -391,3 +391,145 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
os_free(wpa_s->wps);
wpa_s->wps = NULL;
}
+
+
+int wpas_wps_ssid_bss_match(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;
+ }
+
+ if (!wps_is_selected_pin_registrar(wps_ie)) {
+ 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 "
+ "(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;
+}
+
+
+int wpas_wps_ssid_wildcard_ok(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)) {
+ /* allow wildcard SSID for WPS PIN */
+ ret = 1;
+ }
+ }
+
+ wpabuf_free(wps_ie);
+
+ return ret;
+}
+
+
+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;
+ if (!sel_uuid) {
+ wpa_printf(MSG_DEBUG, "WPS: UUID-E not available for PBC "
+ "overlap detection");
+ wpabuf_free(wps_ie);
+ return 1;
+ }
+
+ 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 (uuid == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS: UUID-E not available for "
+ "PBC overlap detection (other BSS)");
+ ret = 1;
+ wpabuf_free(ie);
+ break;
+ }
+ if (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(wps_ie);
+
+ return ret;
+}
diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h
index 1e393e3..bdde6ab 100644
--- a/wpa_supplicant/wps_supplicant.h
+++ b/wpa_supplicant/wps_supplicant.h
@@ -26,6 +26,11 @@ int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
const char *pin);
int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
const char *pin);
+int wpas_wps_ssid_bss_match(struct wpa_ssid *ssid, struct wpa_scan_res *bss);
+int wpas_wps_ssid_wildcard_ok(struct wpa_ssid *ssid, struct wpa_scan_res *bss);
+int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
+ struct wpa_scan_res *selected,
+ struct wpa_ssid *ssid);
#else /* CONFIG_WPS */
@@ -43,7 +48,26 @@ static inline int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
return 0;
}
-u8 wpas_wps_get_req_type(struct wpa_ssid *ssid)
+static inline u8 wpas_wps_get_req_type(struct wpa_ssid *ssid)
+{
+ return 0;
+}
+
+static inline int wpas_wps_ssid_bss_match(struct wpa_ssid *ssid,
+ struct wpa_scan_res *bss)
+{
+ return -1;
+}
+
+static inline int wpas_wps_ssid_wildcard_ok(struct wpa_ssid *ssid,
+ struct wpa_scan_res *bss)
+{
+ return 0;
+}
+
+static inline int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
+ struct wpa_scan_res *selected,
+ struct wpa_ssid *ssid)
{
return 0;
}