]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Add a workaround for PBC session overlap detection
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 15 Nov 2012 17:59:04 +0000 (19:59 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 15 Nov 2012 17:59:04 +0000 (19:59 +0200)
Some deployed station implementations implement WPS incorrectly and
end up causing PBC session overlap issues by indicating active PBC
mode in a scan after the WPS provisioning step. Work around this by
ignoring active PBC indication in a Probe Request from a station that
completed PBC provisioning during the last five seconds.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/wps/wps_registrar.c

index a355812a8d98bb0f9be6e9ababc08e6e84fae6b8..d8e0d6fbc20ab779a4fe1e8effd6765e0f56189f 100644 (file)
@@ -180,6 +180,9 @@ struct wps_registrar {
        u8 authorized_macs_union[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN];
 
        u8 p2p_dev_addr[ETH_ALEN];
+
+       u8 pbc_ignore_uuid[WPS_UUID_LEN];
+       struct os_time pbc_ignore_start;
 };
 
 
@@ -1030,6 +1033,8 @@ void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e,
                wps_registrar_remove_pbc_session(registrar,
                                                 uuid_e, NULL);
                wps_registrar_pbc_completed(registrar);
+               os_get_time(&registrar->pbc_ignore_start);
+               os_memcpy(registrar->pbc_ignore_uuid, uuid_e, WPS_UUID_LEN);
        } else {
                wps_registrar_pin_completed(registrar);
        }
@@ -1076,6 +1081,7 @@ void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
                                int p2p_wildcard)
 {
        struct wps_parse_attr attr;
+       int skip_add = 0;
 
        wpa_hexdump_buf(MSG_MSGDUMP,
                        "WPS: Probe Request with WPS data received",
@@ -1127,7 +1133,24 @@ void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
        wpa_hexdump(MSG_DEBUG, "WPS: UUID-E from Probe Request", attr.uuid_e,
                    WPS_UUID_LEN);
 
-       wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
+#ifdef WPS_WORKAROUNDS
+       if (reg->pbc_ignore_start.sec &&
+           os_memcmp(attr.uuid_e, reg->pbc_ignore_uuid, WPS_UUID_LEN) == 0) {
+               struct os_time now, dur;
+               os_get_time(&now);
+               os_time_sub(&now, &reg->pbc_ignore_start, &dur);
+               if (dur.sec >= 0 && dur.sec < 5) {
+                       wpa_printf(MSG_DEBUG, "WPS: Ignore PBC activation "
+                                  "based on Probe Request from the Enrollee "
+                                  "that just completed PBC provisioning");
+                       skip_add = 1;
+               } else
+                       reg->pbc_ignore_start.sec = 0;
+       }
+#endif /* WPS_WORKAROUNDS */
+
+       if (!skip_add)
+               wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
        if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
                wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
                reg->force_pbc_overlap = 1;
@@ -3157,6 +3180,9 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
                                                 wps->uuid_e,
                                                 wps->p2p_dev_addr);
                wps_registrar_pbc_completed(wps->wps->registrar);
+               os_get_time(&wps->wps->registrar->pbc_ignore_start);
+               os_memcpy(wps->wps->registrar->pbc_ignore_uuid, wps->uuid_e,
+                         WPS_UUID_LEN);
        } else {
                wps_registrar_pin_completed(wps->wps->registrar);
        }