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).
master
Jouni Malinen 13 years ago committed by Jouni Malinen
parent bcb90f750d
commit fa5165586f

@ -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) {

@ -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

@ -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)

@ -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;

@ -110,6 +110,8 @@ struct eap_config {
const struct wpabuf *assoc_p2p_ie;
const u8 *peer_addr;
int fragment_size;
int pbc_in_m1;
};

@ -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,

@ -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");

@ -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);

@ -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)

@ -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;

@ -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;
}

@ -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);

@ -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

@ -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;
};

Loading…
Cancel
Save