WPS: Invalidate wildcard PIN on other radios after successful use

If a wildcard PIN is used on any of the radios that hostapd is
controlling, invalidate the matching PIN on all the other radios
to avoid multiple uses of the same PIN.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2012-02-29 20:42:48 +02:00 committed by Jouni Malinen
parent 85ea132a13
commit 1affa36cb5
3 changed files with 40 additions and 11 deletions

View File

@ -183,19 +183,23 @@ static void hostapd_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
struct wps_stop_reg_data {
struct hostapd_data *current_hapd;
const u8 *uuid_e;
const u8 *dev_pw;
size_t dev_pw_len;
};
static int wps_stop_registrar(struct hostapd_data *hapd, void *ctx)
{
struct wps_stop_reg_data *data = ctx;
if (hapd != data->current_hapd && hapd->wps != NULL)
wps_registrar_complete(hapd->wps->registrar, data->uuid_e);
wps_registrar_complete(hapd->wps->registrar, data->uuid_e,
data->dev_pw, data->dev_pw_len);
return 0;
}
static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
const u8 *uuid_e)
const u8 *uuid_e, const u8 *dev_pw,
size_t dev_pw_len)
{
struct hostapd_data *hapd = ctx;
char uuid[40];
@ -209,6 +213,8 @@ static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
mac_addr, uuid_e);
data.current_hapd = hapd;
data.uuid_e = uuid_e;
data.dev_pw = dev_pw;
data.dev_pw_len = dev_pw_len;
hostapd_wps_for_each(hapd, wps_stop_registrar, &data);
}

View File

@ -294,12 +294,15 @@ struct wps_registrar_config {
* @ctx: Higher layer context data (cb_ctx)
* @mac_addr: MAC address of the Enrollee
* @uuid_e: UUID-E of the Enrollee
* @dev_pw: Device Password (PIN) used during registration
* @dev_pw_len: Length of dev_pw in octets
*
* This callback is called whenever an Enrollee completes registration
* successfully.
*/
void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
const u8 *uuid_e);
const u8 *uuid_e, const u8 *dev_pw,
size_t dev_pw_len);
/**
* set_sel_reg_cb - Callback for reporting selected registrar changes
@ -783,7 +786,8 @@ int wps_registrar_wps_cancel(struct wps_registrar *reg);
int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid);
int wps_registrar_button_pushed(struct wps_registrar *reg,
const u8 *p2p_dev_addr);
void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e);
void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e,
const u8 *dev_pw, size_t dev_pw_len);
void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
const struct wpabuf *wps_data,
int p2p_wildcard);

View File

@ -102,7 +102,8 @@ struct wps_registrar {
void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
const struct wps_device_data *dev);
void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
const u8 *uuid_e);
const u8 *uuid_e, const u8 *dev_pw,
size_t dev_pw_len);
void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
u16 sel_reg_config_methods);
void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e,
@ -735,14 +736,22 @@ static void wps_registrar_expire_pins(struct wps_registrar *reg)
/**
* wps_registrar_invalidate_wildcard_pin - Invalidate a wildcard PIN
* @reg: Registrar data from wps_registrar_init()
* @dev_pw: PIN to search for or %NULL to match any
* @dev_pw_len: Length of dev_pw in octets
* Returns: 0 on success, -1 if not wildcard PIN is enabled
*/
static int wps_registrar_invalidate_wildcard_pin(struct wps_registrar *reg)
static int wps_registrar_invalidate_wildcard_pin(struct wps_registrar *reg,
const u8 *dev_pw,
size_t dev_pw_len)
{
struct wps_uuid_pin *pin, *prev;
dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
{
if (dev_pw && pin->pin &&
(dev_pw_len != pin->pin_len ||
os_memcmp(dev_pw, pin->pin, dev_pw_len) != 0))
continue; /* different PIN */
if (pin->wildcard_uuid) {
wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
pin->uuid, WPS_UUID_LEN);
@ -940,7 +949,8 @@ static void wps_registrar_pin_completed(struct wps_registrar *reg)
}
void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e)
void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e,
const u8 *dev_pw, size_t dev_pw_len)
{
if (registrar->pbc) {
wps_registrar_remove_pbc_session(registrar,
@ -949,6 +959,13 @@ void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e)
} else {
wps_registrar_pin_completed(registrar);
}
if (dev_pw &&
wps_registrar_invalidate_wildcard_pin(registrar, dev_pw,
dev_pw_len) == 0) {
wpa_hexdump_key(MSG_DEBUG, "WPS: Invalidated wildcard PIN",
dev_pw, dev_pw_len);
}
}
@ -963,7 +980,7 @@ int wps_registrar_wps_cancel(struct wps_registrar *reg)
/* PIN Method */
wpa_printf(MSG_DEBUG, "WPS: PIN is set - cancelling it");
wps_registrar_pin_completed(reg);
wps_registrar_invalidate_wildcard_pin(reg);
wps_registrar_invalidate_wildcard_pin(reg, NULL, 0);
return 1;
}
return 0;
@ -1066,12 +1083,13 @@ static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
const u8 *uuid_e)
const u8 *uuid_e, const u8 *dev_pw,
size_t dev_pw_len)
{
if (reg->reg_success_cb == NULL)
return;
reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e, dev_pw, dev_pw_len);
}
@ -3050,7 +3068,8 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
wps->new_psk = NULL;
}
wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e,
wps->dev_password, wps->dev_password_len);
if (wps->pbc) {
wps_registrar_remove_pbc_session(wps->wps->registrar,