WPS: Fix multi-interface WPS operations in hostapd
Couple of the for-each-interface loops used incorrect return value when skipping over non-WPS interfaces. This could result in skipping some WPS interfaces in the loop and returning error. Setting AP PIN did not check for WPS being enabled at all and trigger a NULL pointer dereference if non-WPS interface was enabled. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
a8fd08f7fc
commit
e1938ba934
1 changed files with 45 additions and 11 deletions
|
@ -1304,30 +1304,53 @@ int hostapd_wps_add_pin(struct hostapd_data *hapd, const u8 *addr,
|
|||
}
|
||||
|
||||
|
||||
struct wps_button_pushed_ctx {
|
||||
const u8 *p2p_dev_addr;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
static int wps_button_pushed(struct hostapd_data *hapd, void *ctx)
|
||||
{
|
||||
const u8 *p2p_dev_addr = ctx;
|
||||
if (hapd->wps == NULL)
|
||||
return -1;
|
||||
return wps_registrar_button_pushed(hapd->wps->registrar, p2p_dev_addr);
|
||||
struct wps_button_pushed_ctx *data = ctx;
|
||||
|
||||
if (hapd->wps) {
|
||||
data->count++;
|
||||
return wps_registrar_button_pushed(hapd->wps->registrar,
|
||||
data->p2p_dev_addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_wps_button_pushed(struct hostapd_data *hapd,
|
||||
const u8 *p2p_dev_addr)
|
||||
{
|
||||
return hostapd_wps_for_each(hapd, wps_button_pushed,
|
||||
(void *) p2p_dev_addr);
|
||||
struct wps_button_pushed_ctx ctx;
|
||||
int ret;
|
||||
|
||||
os_memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.p2p_dev_addr = p2p_dev_addr;
|
||||
ret = hostapd_wps_for_each(hapd, wps_button_pushed, &ctx);
|
||||
if (ret == 0 && !ctx.count)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct wps_cancel_ctx {
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
static int wps_cancel(struct hostapd_data *hapd, void *ctx)
|
||||
{
|
||||
if (hapd->wps == NULL)
|
||||
return -1;
|
||||
struct wps_cancel_ctx *data = ctx;
|
||||
|
||||
if (hapd->wps) {
|
||||
data->count++;
|
||||
wps_registrar_wps_cancel(hapd->wps->registrar);
|
||||
ap_for_each_sta(hapd, ap_sta_wps_cancel, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1335,7 +1358,14 @@ static int wps_cancel(struct hostapd_data *hapd, void *ctx)
|
|||
|
||||
int hostapd_wps_cancel(struct hostapd_data *hapd)
|
||||
{
|
||||
return hostapd_wps_for_each(hapd, wps_cancel, NULL);
|
||||
struct wps_cancel_ctx ctx;
|
||||
int ret;
|
||||
|
||||
os_memset(&ctx, 0, sizeof(ctx));
|
||||
ret = hostapd_wps_for_each(hapd, wps_cancel, &ctx);
|
||||
if (ret == 0 && !ctx.count)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1565,6 +1595,10 @@ struct wps_ap_pin_data {
|
|||
static int wps_ap_pin_set(struct hostapd_data *hapd, void *ctx)
|
||||
{
|
||||
struct wps_ap_pin_data *data = ctx;
|
||||
|
||||
if (!hapd->wps)
|
||||
return 0;
|
||||
|
||||
os_free(hapd->conf->ap_pin);
|
||||
hapd->conf->ap_pin = os_strdup(data->pin_txt);
|
||||
#ifdef CONFIG_WPS_UPNP
|
||||
|
|
Loading…
Reference in a new issue