aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/Makefile5
-rw-r--r--wpa_supplicant/events.c22
-rw-r--r--wpa_supplicant/scan.c34
-rw-r--r--wpa_supplicant/scan.h2
-rw-r--r--wpa_supplicant/wps_supplicant.c22
5 files changed, 85 insertions, 0 deletions
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 514f5c6..e6a51c7 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -496,6 +496,11 @@ OBJS += ../src/wps/wps_nfc_pn531.o
LIBS += ${PN531_PATH}/lib/wpsnfc.dll
LIBS += ${PN531_PATH}/lib/libnfc_mapping_pn53x.dll
endif
+
+ifdef CONFIG_WPS_STRICT
+CFLAGS += -DCONFIG_WPS_STRICT
+OBJS += ../src/wps/wps_validate.o
+endif
endif
ifdef NEED_WPS_OOB
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 54f05e5..cc4f1b7 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -30,6 +30,7 @@
#include "ap/hostapd.h"
#include "notify.h"
#include "common/ieee802_11_defs.h"
+#include "common/ieee802_11_common.h"
#include "blacklist.h"
#include "wpas_glue.h"
#include "wps_supplicant.h"
@@ -921,6 +922,27 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
p = data->assoc_info.resp_ies;
l = data->assoc_info.resp_ies_len;
+#ifdef CONFIG_WPS_STRICT
+ if (wpa_s->current_ssid &&
+ wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
+ struct wpabuf *wps;
+ wps = ieee802_11_vendor_ie_concat(p, l, WPS_IE_VENDOR_TYPE);
+ if (wps == NULL) {
+ wpa_printf(MSG_INFO, "WPS-STRICT: AP did not include "
+ "WPS IE in (Re)Association Response");
+ return -1;
+ }
+
+ if (wps_validate_assoc_resp(wps) < 0) {
+ wpabuf_free(wps);
+ wpa_supplicant_deauthenticate(
+ wpa_s, WLAN_REASON_INVALID_IE);
+ return -1;
+ }
+ wpabuf_free(wps);
+ }
+#endif /* CONFIG_WPS_STRICT */
+
/* Go through the IEs and make a copy of the MDIE, if present. */
while (p && l >= 2) {
len = p[1] + 2;
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index bb24995..19210ec 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -580,6 +580,40 @@ struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
}
+struct wpabuf * wpa_scan_get_vendor_ie_multi_beacon(
+ const struct wpa_scan_res *res, u32 vendor_type)
+{
+ struct wpabuf *buf;
+ const u8 *end, *pos;
+
+ if (res->beacon_ie_len == 0)
+ return NULL;
+ buf = wpabuf_alloc(res->beacon_ie_len);
+ if (buf == NULL)
+ return NULL;
+
+ pos = (const u8 *) (res + 1);
+ pos += res->ie_len;
+ end = pos + res->beacon_ie_len;
+
+ while (pos + 1 < end) {
+ if (pos + 2 + pos[1] > end)
+ break;
+ if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
+ vendor_type == WPA_GET_BE32(&pos[2]))
+ wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
+ pos += 2 + pos[1];
+ }
+
+ if (wpabuf_len(buf) == 0) {
+ wpabuf_free(buf);
+ buf = NULL;
+ }
+
+ return buf;
+}
+
+
/* Compare function for sorting scan results. Return >0 if @b is considered
* better. */
static int wpa_scan_result_compar(const void *a, const void *b)
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 441fdbb..025b815 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -32,6 +32,8 @@ const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
u32 vendor_type);
struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
u32 vendor_type);
+struct wpabuf * wpa_scan_get_vendor_ie_multi_beacon(
+ const struct wpa_scan_res *res, u32 vendor_type);
void wpa_scan_results_free(struct wpa_scan_results *res);
#endif /* SCAN_H */
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 5a471f4..18d80dd 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1029,6 +1029,28 @@ int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
ret = 1;
}
+#ifdef CONFIG_WPS_STRICT
+ if (wps_ie) {
+ if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len >
+ 0) < 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;