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)
|
static int wps_button_pushed(struct hostapd_data *hapd, void *ctx)
|
||||||
{
|
{
|
||||||
const u8 *p2p_dev_addr = ctx;
|
struct wps_button_pushed_ctx *data = ctx;
|
||||||
if (hapd->wps == NULL)
|
|
||||||
return -1;
|
if (hapd->wps) {
|
||||||
return wps_registrar_button_pushed(hapd->wps->registrar, p2p_dev_addr);
|
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,
|
int hostapd_wps_button_pushed(struct hostapd_data *hapd,
|
||||||
const u8 *p2p_dev_addr)
|
const u8 *p2p_dev_addr)
|
||||||
{
|
{
|
||||||
return hostapd_wps_for_each(hapd, wps_button_pushed,
|
struct wps_button_pushed_ctx ctx;
|
||||||
(void *) p2p_dev_addr);
|
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)
|
static int wps_cancel(struct hostapd_data *hapd, void *ctx)
|
||||||
{
|
{
|
||||||
if (hapd->wps == NULL)
|
struct wps_cancel_ctx *data = ctx;
|
||||||
return -1;
|
|
||||||
|
|
||||||
wps_registrar_wps_cancel(hapd->wps->registrar);
|
if (hapd->wps) {
|
||||||
ap_for_each_sta(hapd, ap_sta_wps_cancel, NULL);
|
data->count++;
|
||||||
|
wps_registrar_wps_cancel(hapd->wps->registrar);
|
||||||
|
ap_for_each_sta(hapd, ap_sta_wps_cancel, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1335,7 +1358,14 @@ static int wps_cancel(struct hostapd_data *hapd, void *ctx)
|
||||||
|
|
||||||
int hostapd_wps_cancel(struct hostapd_data *hapd)
|
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)
|
static int wps_ap_pin_set(struct hostapd_data *hapd, void *ctx)
|
||||||
{
|
{
|
||||||
struct wps_ap_pin_data *data = ctx;
|
struct wps_ap_pin_data *data = ctx;
|
||||||
|
|
||||||
|
if (!hapd->wps)
|
||||||
|
return 0;
|
||||||
|
|
||||||
os_free(hapd->conf->ap_pin);
|
os_free(hapd->conf->ap_pin);
|
||||||
hapd->conf->ap_pin = os_strdup(data->pin_txt);
|
hapd->conf->ap_pin = os_strdup(data->pin_txt);
|
||||||
#ifdef CONFIG_WPS_UPNP
|
#ifdef CONFIG_WPS_UPNP
|
||||||
|
|
Loading…
Reference in a new issue