]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Add a workaround for Windows 7 capability discovery for PBC
authorJouni Malinen <jouni.malinen@atheros.com>
Tue, 17 May 2011 16:53:02 +0000 (19:53 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 17 May 2011 16:53:02 +0000 (19:53 +0300)
Windows 7 uses incorrect way of figuring out AP's WPS capabilities by
acting as a Registrar and using M1 from the AP. The config methods
attribute in that message is supposed to indicate only the configuration
method supported by the AP in Enrollee role, i.e., to add an external
Registrar. For that case, PBC shall not be used and as such, the
PushButton config method is removed from M1 by default. If pbc_in_m1=1
is included in the configuration file, the PushButton config method is
left in M1 (if included in config_methods parameter) to allow Windows 7
to use PBC instead of PIN (e.g., from a label in the AP).

14 files changed:
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.h
src/ap/ieee802_1x.c
src/eap_server/eap.h
src/eap_server/eap_i.h
src/eap_server/eap_server.c
src/eap_server/eap_server_wsc.c
src/eapol_auth/eapol_auth_sm.c
src/eapol_auth/eapol_auth_sm.h
src/wps/wps.c
src/wps/wps.h
src/wps/wps_enrollee.c
src/wps/wps_i.h

index 11c8bf018f0fbff2159eab3275bbf28dafd0a230..835f0500ab0ad041182a7dd07ff4889d4911c742 100644 (file)
@@ -2021,6 +2021,8 @@ struct hostapd_config * hostapd_config_read(const char *fname)
                } else if (os_strcmp(buf, "upc") == 0) {
                        os_free(bss->upc);
                        bss->upc = os_strdup(pos);
+               } else if (os_strcmp(buf, "pbc_in_m1") == 0) {
+                       bss->pbc_in_m1 = atoi(pos);
 #endif /* CONFIG_WPS */
 #ifdef CONFIG_P2P_MANAGER
                } else if (os_strcmp(buf, "manage_p2p") == 0) {
index 6d7263afd8a7bd5aacfc0e26a2d85671321fbfa9..e0525e4054f0cb4403da7b4fd4133b67922ac844 100644 (file)
@@ -921,6 +921,18 @@ own_ip_addr=127.0.0.1
 #      virtual_push_button physical_push_button
 #config_methods=label virtual_display virtual_push_button keypad
 
+# WPS capability discovery workaround for PBC with Windows 7
+# Windows 7 uses incorrect way of figuring out AP's WPS capabilities by acting
+# as a Registrar and using M1 from the AP. The config methods attribute in that
+# message is supposed to indicate only the configuration method supported by
+# the AP in Enrollee role, i.e., to add an external Registrar. For that case,
+# PBC shall not be used and as such, the PushButton config method is removed
+# from M1 by default. If pbc_in_m1=1 is included in the configuration file,
+# the PushButton config method is left in M1 (if included in config_methods
+# parameter) to allow Windows 7 to use PBC instead of PIN (e.g., from a label
+# in the AP).
+#pbc_in_m1=1
+
 # Static access point PIN for initial configuration and adding Registrars
 # If not set, hostapd will not allow external WPS Registrars to control the
 # access point. The AP PIN can also be set at runtime with hostapd_cli
index 25720b84a3e884c146d67233117c454f8cc620a8..0a3e76ec7be098e6df8f52267d6f7467ebb2ab45 100644 (file)
@@ -318,6 +318,7 @@ struct hostapd_bss_config {
        char *upc;
        struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
 #endif /* CONFIG_WPS */
+       int pbc_in_m1;
 
 #define P2P_ENABLED BIT(0)
 #define P2P_GROUP_OWNER BIT(1)
index ac0c1270010875be7f150ec253a8f62409809ff9..217f9f9cc8e551e1bf9fed62b93a6baa50b92411 100644 (file)
@@ -1701,6 +1701,7 @@ int ieee802_1x_init(struct hostapd_data *hapd)
        conf.wps = hapd->wps;
        conf.fragment_size = hapd->conf->fragment_size;
        conf.pwd_group = hapd->conf->pwd_group;
+       conf.pbc_in_m1 = hapd->conf->pbc_in_m1;
 
        os_memset(&cb, 0, sizeof(cb));
        cb.eapol_send = ieee802_1x_eapol_send;
index 6b2907519e148320746fdfa0314634f5bc969223..e1f500a5f25706730ffa459d8ad0e0ff12ce2909 100644 (file)
@@ -110,6 +110,8 @@ struct eap_config {
        const struct wpabuf *assoc_p2p_ie;
        const u8 *peer_addr;
        int fragment_size;
+
+       int pbc_in_m1;
 };
 
 
index daac746dce126f976b064733d2c855316daa8316..3cba5aa5679630778dcf980ad49e67072e3dbfed 100644 (file)
@@ -192,6 +192,8 @@ struct eap_sm {
 
        /* Fragmentation size for EAP method init() handler */
        int fragment_size;
+
+       int pbc_in_m1;
 };
 
 int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
index 41416b1de92c48c9582372d1e5632288524f8b3b..0f0da29d60e0d4a5b3d6f936253a91fad53b6949 100644 (file)
@@ -1261,6 +1261,7 @@ struct eap_sm * eap_server_sm_init(void *eapol_ctx,
                os_memcpy(sm->peer_addr, conf->peer_addr, ETH_ALEN);
        sm->fragment_size = conf->fragment_size;
        sm->pwd_group = conf->pwd_group;
+       sm->pbc_in_m1 = conf->pbc_in_m1;
 
        wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
 
index e944a4d437273ac2232aae1ebc14278edfb24f4e..556882d26bb3e468414df35a61ba69dbf5f4665f 100644 (file)
@@ -144,6 +144,7 @@ static void * eap_wsc_init(struct eap_sm *sm)
                cfg.p2p_dev_addr = p2p_get_go_dev_addr(sm->assoc_p2p_ie);
        }
 #endif /* CONFIG_P2P */
+       cfg.pbc_in_m1 = sm->pbc_in_m1;
        data->wps = wps_init(&cfg);
        if (data->wps == NULL) {
                os_free(data);
index 841a1c515e9ddf70ea9cb15cdfb1194e9f6972c6..4aa71ad0378ab7dee45fab86cb861627d5615764 100644 (file)
@@ -834,6 +834,7 @@ eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr,
        eap_conf.peer_addr = addr;
        eap_conf.fragment_size = eapol->conf.fragment_size;
        eap_conf.pwd_group = eapol->conf.pwd_group;
+       eap_conf.pbc_in_m1 = eapol->conf.pbc_in_m1;
        sm->eap = eap_server_sm_init(sm, &eapol_cb, &eap_conf);
        if (sm->eap == NULL) {
                eapol_auth_free(sm);
@@ -1039,6 +1040,7 @@ static int eapol_auth_conf_clone(struct eapol_auth_config *dst,
        dst->eap_sim_db_priv = src->eap_sim_db_priv;
        os_free(dst->eap_req_id_text);
        dst->pwd_group = src->pwd_group;
+       dst->pbc_in_m1 = src->pbc_in_m1;
        if (src->eap_req_id_text) {
                dst->eap_req_id_text = os_malloc(src->eap_req_id_text_len);
                if (dst->eap_req_id_text == NULL)
index 59a10b45b2c3103acea5d490c2ff2f0e80303890..724bf8bb62a91e9ede2786762f0250bb25aefbef 100644 (file)
@@ -42,6 +42,7 @@ struct eapol_auth_config {
        struct wps_context *wps;
        int fragment_size;
        u16 pwd_group;
+       int pbc_in_m1;
 
        /* Opaque context pointer to owner data for callback functions */
        void *ctx;
index 7564d60a5f317a5fe0e2051a8266f12a662881c3..5c8c25fea61dfa7742f7140035b0617b4452d43d 100644 (file)
@@ -113,6 +113,7 @@ struct wps_data * wps_init(const struct wps_config *cfg)
                os_memcpy(data->p2p_dev_addr, cfg->p2p_dev_addr, ETH_ALEN);
 
        data->use_psk_key = cfg->use_psk_key;
+       data->pbc_in_m1 = cfg->pbc_in_m1;
 
        return data;
 }
index 918273dd6c942e410e0571f6934db6b4661d8b19..3e4c2185b6989825307dcf3148d24d927fbc6343 100644 (file)
@@ -187,6 +187,14 @@ struct wps_config {
         * to %NULL to indicate the station does not have a P2P Device Address.
         */
        const u8 *p2p_dev_addr;
+
+       /**
+        * pbc_in_m1 - Do not remove PushButton config method in M1 (AP)
+        *
+        * This can be used to enable a workaround to allow Windows 7 to use
+        * PBC with the AP.
+        */
+       int pbc_in_m1;
 };
 
 struct wps_data * wps_init(const struct wps_config *cfg);
index 390254e438296549b8a78adad8a9ad0cacaf0f2b..5b3c0450be4e468f98e391e5b91ef77dc89fe192 100644 (file)
@@ -133,10 +133,17 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
                return NULL;
 
        config_methods = wps->wps->config_methods;
-       if (wps->wps->ap) {
+       if (wps->wps->ap && !wps->pbc_in_m1 &&
+           (wps->dev_password_len != 0 ||
+            (config_methods & WPS_CONFIG_DISPLAY))) {
                /*
                 * These are the methods that the AP supports as an Enrollee
                 * for adding external Registrars, so remove PushButton.
+                *
+                * As a workaround for Windows 7 mechanism for probing WPS
+                * capabilities from M1, leave PushButton option if no PIN
+                * method is available or if WPS configuration enables PBC
+                * workaround.
                 */
                config_methods &= ~WPS_CONFIG_PUSHBUTTON;
 #ifdef CONFIG_WPS2
index 437999bb3503b12f17a7d705dab33654846e00cd..bdb6da2bfa832079836d3008e0c761d2d710e5d4 100644 (file)
@@ -119,6 +119,7 @@ struct wps_data {
        int use_psk_key;
        u8 p2p_dev_addr[ETH_ALEN]; /* P2P Device Address of the client or
                                    * 00:00:00:00:00:00 if not a P2p client */
+       int pbc_in_m1;
 };