aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2011-05-17 16:53:02 (GMT)
committerJouni Malinen <j@w1.fi>2011-05-17 16:53:02 (GMT)
commitfa5165586fa11ecdccb7c81d40979b51c2583fd2 (patch)
treee687abcd778d5ebb37fdbd50f3cabb2eccdacc3d
parentbcb90f750d16c9cab4c7699ab211616d0cd9bf46 (diff)
downloadhostap-fa5165586fa11ecdccb7c81d40979b51c2583fd2.zip
hostap-fa5165586fa11ecdccb7c81d40979b51c2583fd2.tar.gz
hostap-fa5165586fa11ecdccb7c81d40979b51c2583fd2.tar.bz2
WPS: Add a workaround for Windows 7 capability discovery for PBC
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).
-rw-r--r--hostapd/config_file.c2
-rw-r--r--hostapd/hostapd.conf12
-rw-r--r--src/ap/ap_config.h1
-rw-r--r--src/ap/ieee802_1x.c1
-rw-r--r--src/eap_server/eap.h2
-rw-r--r--src/eap_server/eap_i.h2
-rw-r--r--src/eap_server/eap_server.c1
-rw-r--r--src/eap_server/eap_server_wsc.c1
-rw-r--r--src/eapol_auth/eapol_auth_sm.c2
-rw-r--r--src/eapol_auth/eapol_auth_sm.h1
-rw-r--r--src/wps/wps.c1
-rw-r--r--src/wps/wps.h8
-rw-r--r--src/wps/wps_enrollee.c9
-rw-r--r--src/wps/wps_i.h1
14 files changed, 43 insertions, 1 deletions
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 11c8bf0..835f050 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -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) {
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 6d7263a..e0525e4 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -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
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 25720b8..0a3e76e 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -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)
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index ac0c127..217f9f9 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -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;
diff --git a/src/eap_server/eap.h b/src/eap_server/eap.h
index 6b29075..e1f500a 100644
--- a/src/eap_server/eap.h
+++ b/src/eap_server/eap.h
@@ -110,6 +110,8 @@ struct eap_config {
const struct wpabuf *assoc_p2p_ie;
const u8 *peer_addr;
int fragment_size;
+
+ int pbc_in_m1;
};
diff --git a/src/eap_server/eap_i.h b/src/eap_server/eap_i.h
index daac746..3cba5aa 100644
--- a/src/eap_server/eap_i.h
+++ b/src/eap_server/eap_i.h
@@ -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,
diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c
index 41416b1..0f0da29 100644
--- a/src/eap_server/eap_server.c
+++ b/src/eap_server/eap_server.c
@@ -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");
diff --git a/src/eap_server/eap_server_wsc.c b/src/eap_server/eap_server_wsc.c
index e944a4d..556882d 100644
--- a/src/eap_server/eap_server_wsc.c
+++ b/src/eap_server/eap_server_wsc.c
@@ -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);
diff --git a/src/eapol_auth/eapol_auth_sm.c b/src/eapol_auth/eapol_auth_sm.c
index 841a1c5..4aa71ad 100644
--- a/src/eapol_auth/eapol_auth_sm.c
+++ b/src/eapol_auth/eapol_auth_sm.c
@@ -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)
diff --git a/src/eapol_auth/eapol_auth_sm.h b/src/eapol_auth/eapol_auth_sm.h
index 59a10b4..724bf8b 100644
--- a/src/eapol_auth/eapol_auth_sm.h
+++ b/src/eapol_auth/eapol_auth_sm.h
@@ -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;
diff --git a/src/wps/wps.c b/src/wps/wps.c
index 7564d60..5c8c25f 100644
--- a/src/wps/wps.c
+++ b/src/wps/wps.c
@@ -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;
}
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 918273d..3e4c218 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -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);
diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c
index 390254e..5b3c045 100644
--- a/src/wps/wps_enrollee.c
+++ b/src/wps/wps_enrollee.c
@@ -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
diff --git a/src/wps/wps_i.h b/src/wps/wps_i.h
index 437999b..bdb6da2 100644
--- a/src/wps/wps_i.h
+++ b/src/wps/wps_i.h
@@ -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;
};