} 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) {
# 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
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)
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;
const struct wpabuf *assoc_p2p_ie;
const u8 *peer_addr;
int fragment_size;
+
+ int pbc_in_m1;
};
/* 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,
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");
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);
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);
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)
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;
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;
}
* 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);
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
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;
};