const struct wps_device_data *dev);
void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
const u8 *uuid_e);
+ void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
+ u16 sel_reg_config_methods);
void *cb_ctx;
struct wps_uuid_pin *pins;
int static_wep_only;
struct wps_registrar_device *devices;
+
+ int force_pbc_overlap;
};
static int wps_set_ie(struct wps_registrar *reg);
+static void wps_cb_set_sel_reg(struct wps_registrar *reg);
static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
static void wps_registrar_set_selected_timeout(void *eloop_ctx,
void *timeout_ctx);
reg->set_ie_cb = cfg->set_ie_cb;
reg->pin_needed_cb = cfg->pin_needed_cb;
reg->reg_success_cb = cfg->reg_success_cb;
+ reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
reg->cb_ctx = cfg->cb_ctx;
reg->skip_cred_build = cfg->skip_cred_build;
if (cfg->extra_cred) {
reg->selected_registrar = 1;
reg->pbc = 0;
wps_set_ie(reg);
+ wps_cb_set_sel_reg(reg);
+ eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
+ eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
+ wps_registrar_set_selected_timeout,
+ reg, NULL);
return 0;
}
reg->selected_registrar = 0;
reg->pbc = 0;
wps_set_ie(reg);
+ wps_cb_set_sel_reg(reg);
}
return -1;
}
wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
+ reg->force_pbc_overlap = 0;
reg->selected_registrar = 1;
reg->pbc = 1;
wps_set_ie(reg);
+ wps_cb_set_sel_reg(reg);
eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
wps_registrar_stop_pbc(reg);
}
+static void wps_registrar_pin_completed(struct wps_registrar *reg)
+{
+ wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
+ eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
+ reg->selected_registrar = 0;
+ wps_set_ie(reg);
+ wps_cb_set_sel_reg(reg);
+}
+
/**
* wps_registrar_probe_req_rx - Notify Registrar of Probe Request
MACSTR, MAC2STR(addr));
wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
+ if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
+ wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
+ reg->force_pbc_overlap = 1;
+ wps_pbc_overlap_event(reg->wps);
+ }
}
}
+static void wps_cb_set_sel_reg(struct wps_registrar *reg)
+{
+ u16 methods = 0;
+ if (reg->set_sel_reg_cb == NULL)
+ return;
+
+ if (reg->selected_registrar) {
+ methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
+ if (reg->pbc)
+ methods |= WPS_CONFIG_PUSHBUTTON;
+ }
+
+ reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar,
+ reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT,
+ methods);
+}
+
+
/* Encapsulate WPS IE data with one (or more, if needed) IE headers */
static struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
{
#endif /* CONFIG_WPS_OOB */
if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
- if (wps_registrar_pbc_overlap(wps->wps->registrar,
+ if (wps->wps->registrar->force_pbc_overlap ||
+ wps_registrar_pbc_overlap(wps->wps->registrar,
wps->mac_addr_e, wps->uuid_e)) {
wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
"negotiation");
wps->state = SEND_M2D;
wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
wps_pbc_overlap_event(wps->wps);
+ wps->wps->registrar->force_pbc_overlap = 1;
return WPS_CONTINUE;
}
wps_registrar_add_pbc_session(wps->wps->registrar,
return WPS_CONTINUE;
}
+ if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
+ wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
+ "session overlap");
+ wps->state = SEND_WSC_NACK;
+ wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
+ return WPS_CONTINUE;
+ }
+
if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
wps_process_authenticator(wps, attr->authenticator, msg) ||
wps_process_e_hash1(wps, attr->e_hash1) ||
return WPS_CONTINUE;
}
+ if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
+ wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
+ "session overlap");
+ wps->state = SEND_WSC_NACK;
+ wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
+ return WPS_CONTINUE;
+ }
+
if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
wps_process_authenticator(wps, attr->authenticator, msg)) {
wps->state = SEND_WSC_NACK;
return WPS_CONTINUE;
}
+ if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
+ wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
+ "session overlap");
+ wps->state = SEND_WSC_NACK;
+ wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
+ return WPS_CONTINUE;
+ }
+
if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
wps_process_authenticator(wps, attr->authenticator, msg)) {
wps->state = SEND_WSC_NACK;
wps_registrar_remove_pbc_session(wps->wps->registrar,
wps->mac_addr_e, wps->uuid_e);
wps_registrar_pbc_completed(wps->wps->registrar);
+ } else {
+ wps_registrar_pin_completed(wps->wps->registrar);
}
wps_success_event(wps->wps);
reg->sel_reg_dev_password_id_override = -1;
reg->sel_reg_config_methods_override = -1;
wps_set_ie(reg);
+ wps_cb_set_sel_reg(reg);
}