From 3379a3a795803335b3f464f34a15f06843369fb1 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 20 Sep 2010 15:32:29 -0700 Subject: [PATCH] WPS: Fix Beacon WPS IE on concurrent dualband AP in PBC mode The Beacon frame must include UUID-E and RF Bands attributes when in active PBC mode to allow stations to figure out that two BSSes in PBC mode is not a PBC session overlap. --- src/ap/wps_hostapd.c | 22 +++++++++++++++++++++- src/wps/wps.h | 5 +++++ src/wps/wps_registrar.c | 18 ++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c index 6b7c492..7968471 100644 --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -529,6 +529,23 @@ static const u8 * get_own_uuid(struct hostapd_iface *iface) } +static int count_interface_cb(struct hostapd_iface *iface, void *ctx) +{ + int *count= ctx; + (*count)++; + return 0; +} + + +static int interface_count(struct hostapd_iface *iface) +{ + int count = 0; + iface->for_each_interface(iface->interfaces, count_interface_cb, + &count); + return count; +} + + int hostapd_init_wps(struct hostapd_data *hapd, struct hostapd_bss_config *conf) { @@ -688,10 +705,13 @@ int hostapd_init_wps(struct hostapd_data *hapd, conf->skip_cred_build; if (conf->ssid.security_policy == SECURITY_STATIC_WEP) cfg.static_wep_only = 1; + cfg.dualband = interface_count(hapd->iface) > 1; + if (cfg.dualband) + wpa_printf(MSG_DEBUG, "WPS: Dualband AP"); wps->registrar = wps_registrar_init(wps, &cfg); if (wps->registrar == NULL) { - printf("Failed to initialize WPS Registrar\n"); + wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar"); os_free(wps->network_key); os_free(wps); return -1; diff --git a/src/wps/wps.h b/src/wps/wps.h index a1b7ae7..8bc7547 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -352,6 +352,11 @@ struct wps_registrar_config { * static_wep_only - Whether the BSS supports only static WEP */ int static_wep_only; + + /** + * dualband - Whether this is a concurrent dualband AP + */ + int dualband; }; diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 0b71484..8a8f691 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -126,6 +126,7 @@ struct wps_registrar { int sel_reg_dev_password_id_override; int sel_reg_config_methods_override; int static_wep_only; + int dualband; struct wps_registrar_device *devices; @@ -430,6 +431,20 @@ static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg, } +static int wps_build_sel_pbc_reg_uuid_e(struct wps_registrar *reg, + struct wpabuf *msg) +{ + u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT; + if (!reg->sel_reg_union) + return 0; + if (reg->sel_reg_dev_password_id_override >= 0) + id = reg->sel_reg_dev_password_id_override; + if (id != DEV_PW_PUSHBUTTON || !reg->dualband) + return 0; + return wps_build_uuid_e(msg, reg->wps->uuid); +} + + static void wps_set_pushbutton(u16 *methods, u16 conf_methods) { *methods |= WPS_CONFIG_PUSHBUTTON; @@ -572,6 +587,7 @@ wps_registrar_init(struct wps_context *wps, reg->sel_reg_dev_password_id_override = -1; reg->sel_reg_config_methods_override = -1; reg->static_wep_only = cfg->static_wep_only; + reg->dualband = cfg->dualband; if (wps_set_ie(reg)) { wps_registrar_deinit(reg); @@ -1069,6 +1085,8 @@ static int wps_set_ie(struct wps_registrar *reg) wps_build_selected_registrar(reg, beacon) || wps_build_sel_reg_dev_password_id(reg, beacon) || wps_build_sel_reg_config_methods(reg, beacon) || + wps_build_sel_pbc_reg_uuid_e(reg, beacon) || + (reg->dualband && wps_build_rf_bands(®->wps->dev, beacon)) || wps_build_wfa_ext(beacon, 0, auth_macs, count)) { wpabuf_free(beacon); wpabuf_free(probe); -- 2.1.4