WPS ER: Allow AP to be specified with BSSID
This extends the WPS ER commands that previously accepted only UUID as an identifier for an AP to use either UUID or BSSID for this. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
ea295abcd5
commit
59307b3007
4 changed files with 82 additions and 43 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Wi-Fi Protected Setup
|
* Wi-Fi Protected Setup
|
||||||
* Copyright (c) 2007-2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2007-2013, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -794,13 +794,15 @@ void wps_er_deinit(struct wps_er *er, void (*cb)(void *ctx), void *ctx);
|
||||||
void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
|
void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
|
||||||
u16 sel_reg_config_methods);
|
u16 sel_reg_config_methods);
|
||||||
int wps_er_pbc(struct wps_er *er, const u8 *uuid);
|
int wps_er_pbc(struct wps_er *er, const u8 *uuid);
|
||||||
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
|
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *addr,
|
||||||
size_t pin_len);
|
const u8 *pin, size_t pin_len);
|
||||||
int wps_er_set_config(struct wps_er *er, const u8 *uuid,
|
int wps_er_set_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
|
||||||
const struct wps_credential *cred);
|
const struct wps_credential *cred);
|
||||||
int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin,
|
int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
|
||||||
size_t pin_len, const struct wps_credential *cred);
|
const u8 *pin, size_t pin_len,
|
||||||
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid);
|
const struct wps_credential *cred);
|
||||||
|
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
|
||||||
|
const u8 *addr);
|
||||||
|
|
||||||
int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN]);
|
int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN]);
|
||||||
char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
|
char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Wi-Fi Protected Setup - External Registrar
|
* Wi-Fi Protected Setup - External Registrar
|
||||||
* Copyright (c) 2009-2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2009-2013, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -97,13 +97,16 @@ static void wps_er_sta_remove_all(struct wps_er_ap *ap)
|
||||||
|
|
||||||
|
|
||||||
static struct wps_er_ap * wps_er_ap_get(struct wps_er *er,
|
static struct wps_er_ap * wps_er_ap_get(struct wps_er *er,
|
||||||
struct in_addr *addr, const u8 *uuid)
|
struct in_addr *addr, const u8 *uuid,
|
||||||
|
const u8 *mac_addr)
|
||||||
{
|
{
|
||||||
struct wps_er_ap *ap;
|
struct wps_er_ap *ap;
|
||||||
dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
|
dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
|
||||||
if ((addr == NULL || ap->addr.s_addr == addr->s_addr) &&
|
if ((addr == NULL || ap->addr.s_addr == addr->s_addr) &&
|
||||||
(uuid == NULL ||
|
(uuid == NULL ||
|
||||||
os_memcmp(uuid, ap->uuid, WPS_UUID_LEN) == 0))
|
os_memcmp(uuid, ap->uuid, WPS_UUID_LEN) == 0) &&
|
||||||
|
(mac_addr == NULL ||
|
||||||
|
os_memcmp(mac_addr, ap->mac_addr, ETH_ALEN) == 0))
|
||||||
return ap;
|
return ap;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -290,7 +293,7 @@ int wps_er_ap_cache_settings(struct wps_er *er, struct in_addr *addr)
|
||||||
struct wps_er_ap *ap;
|
struct wps_er_ap *ap;
|
||||||
struct wps_er_ap_settings *settings;
|
struct wps_er_ap_settings *settings;
|
||||||
|
|
||||||
ap = wps_er_ap_get(er, addr, NULL);
|
ap = wps_er_ap_get(er, addr, NULL, NULL);
|
||||||
if (ap == NULL || ap->ap_settings == NULL)
|
if (ap == NULL || ap->ap_settings == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -636,7 +639,7 @@ void wps_er_ap_add(struct wps_er *er, const u8 *uuid, struct in_addr *addr,
|
||||||
{
|
{
|
||||||
struct wps_er_ap *ap;
|
struct wps_er_ap *ap;
|
||||||
|
|
||||||
ap = wps_er_ap_get(er, addr, uuid);
|
ap = wps_er_ap_get(er, addr, uuid, NULL);
|
||||||
if (ap) {
|
if (ap) {
|
||||||
/* Update advertisement timeout */
|
/* Update advertisement timeout */
|
||||||
eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
|
eloop_cancel_timeout(wps_er_ap_timeout, er, ap);
|
||||||
|
@ -1569,7 +1572,7 @@ int wps_er_pbc(struct wps_er *er, const u8 *uuid)
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ap = wps_er_ap_get(er, NULL, uuid);
|
ap = wps_er_ap_get(er, NULL, uuid, NULL);
|
||||||
if (ap == NULL) {
|
if (ap == NULL) {
|
||||||
struct wps_er_sta *sta = NULL;
|
struct wps_er_sta *sta = NULL;
|
||||||
dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
|
dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
|
||||||
|
@ -1877,20 +1880,22 @@ static int wps_er_send_get_device_info(struct wps_er_ap *ap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
|
int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *addr,
|
||||||
size_t pin_len)
|
const u8 *pin, size_t pin_len)
|
||||||
{
|
{
|
||||||
struct wps_er_ap *ap;
|
struct wps_er_ap *ap;
|
||||||
|
|
||||||
if (er == NULL)
|
if (er == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ap = wps_er_ap_get(er, NULL, uuid);
|
ap = wps_er_ap_get(er, NULL, uuid, addr);
|
||||||
if (ap == NULL) {
|
if (ap == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for learn "
|
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for learn "
|
||||||
"request");
|
"request");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (uuid == NULL)
|
||||||
|
uuid = ap->uuid;
|
||||||
if (ap->wps) {
|
if (ap->wps) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
|
wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
|
||||||
"with the AP - cannot start learn");
|
"with the AP - cannot start learn");
|
||||||
|
@ -1908,7 +1913,7 @@ int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *pin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int wps_er_set_config(struct wps_er *er, const u8 *uuid,
|
int wps_er_set_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
|
||||||
const struct wps_credential *cred)
|
const struct wps_credential *cred)
|
||||||
{
|
{
|
||||||
struct wps_er_ap *ap;
|
struct wps_er_ap *ap;
|
||||||
|
@ -1916,7 +1921,7 @@ int wps_er_set_config(struct wps_er *er, const u8 *uuid,
|
||||||
if (er == NULL)
|
if (er == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ap = wps_er_ap_get(er, NULL, uuid);
|
ap = wps_er_ap_get(er, NULL, uuid, addr);
|
||||||
if (ap == NULL) {
|
if (ap == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for set config "
|
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for set config "
|
||||||
"request");
|
"request");
|
||||||
|
@ -1960,20 +1965,23 @@ static void wps_er_ap_config_m1(struct wps_er_ap *ap, struct wpabuf *m1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin,
|
int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
|
||||||
size_t pin_len, const struct wps_credential *cred)
|
const u8 *pin, size_t pin_len,
|
||||||
|
const struct wps_credential *cred)
|
||||||
{
|
{
|
||||||
struct wps_er_ap *ap;
|
struct wps_er_ap *ap;
|
||||||
|
|
||||||
if (er == NULL)
|
if (er == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ap = wps_er_ap_get(er, NULL, uuid);
|
ap = wps_er_ap_get(er, NULL, uuid, addr);
|
||||||
if (ap == NULL) {
|
if (ap == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for config "
|
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for config "
|
||||||
"request");
|
"request");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (uuid == NULL)
|
||||||
|
uuid = ap->uuid;
|
||||||
if (ap->wps) {
|
if (ap->wps) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
|
wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
|
||||||
"with the AP - cannot start config");
|
"with the AP - cannot start config");
|
||||||
|
@ -1999,7 +2007,8 @@ int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin,
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_NFC
|
#ifdef CONFIG_WPS_NFC
|
||||||
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid)
|
struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
|
||||||
|
const u8 *addr)
|
||||||
{
|
{
|
||||||
struct wps_er_ap *ap;
|
struct wps_er_ap *ap;
|
||||||
struct wpabuf *ret;
|
struct wpabuf *ret;
|
||||||
|
@ -2008,7 +2017,7 @@ struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid)
|
||||||
if (er == NULL)
|
if (er == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ap = wps_er_ap_get(er, NULL, uuid);
|
ap = wps_er_ap_get(er, NULL, uuid, addr);
|
||||||
if (ap == NULL)
|
if (ap == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (ap->ap_settings == NULL) {
|
if (ap->ap_settings == NULL) {
|
||||||
|
|
|
@ -259,16 +259,16 @@ wps_er_start [IP address]
|
||||||
wps_er_stop
|
wps_er_stop
|
||||||
- stop WPS ER functionality
|
- stop WPS ER functionality
|
||||||
|
|
||||||
wps_er_learn <UUID> <AP PIN>
|
wps_er_learn <UUID|BSSID> <AP PIN>
|
||||||
- learn AP configuration
|
- learn AP configuration
|
||||||
|
|
||||||
wps_er_set_config <UUID> <network id>
|
wps_er_set_config <UUID|BSSID> <network id>
|
||||||
- use AP configuration from a locally configured network (e.g., from
|
- use AP configuration from a locally configured network (e.g., from
|
||||||
wps_reg command); this does not change the AP's configuration, but
|
wps_reg command); this does not change the AP's configuration, but
|
||||||
only prepares a configuration to be used when enrolling a new device
|
only prepares a configuration to be used when enrolling a new device
|
||||||
to the AP
|
to the AP
|
||||||
|
|
||||||
wps_er_config <UUID> <AP PIN> <new SSID> <auth> <encr> <new key>
|
wps_er_config <UUID|BSSID> <AP PIN> <new SSID> <auth> <encr> <new key>
|
||||||
- examples:
|
- examples:
|
||||||
wps_er_config 87654321-9abc-def0-1234-56789abc0002 12345670 testing WPA2PSK CCMP 12345678
|
wps_er_config 87654321-9abc-def0-1234-56789abc0002 12345670 testing WPA2PSK CCMP 12345678
|
||||||
wpa_er_config 87654321-9abc-def0-1234-56789abc0002 12345670 clear OPEN NONE ""
|
wpa_er_config 87654321-9abc-def0-1234-56789abc0002 12345670 clear OPEN NONE ""
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* wpa_supplicant / WPS integration
|
* wpa_supplicant / WPS integration
|
||||||
* Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2008-2013, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -1630,11 +1630,17 @@ int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid)
|
||||||
int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
|
int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
|
||||||
const char *pin)
|
const char *pin)
|
||||||
{
|
{
|
||||||
u8 u[UUID_LEN];
|
u8 u[UUID_LEN], *use_uuid = NULL;
|
||||||
|
u8 addr[ETH_ALEN], *use_addr = NULL;
|
||||||
|
|
||||||
if (uuid_str2bin(uuid, u))
|
if (uuid_str2bin(uuid, u) == 0)
|
||||||
|
use_uuid = u;
|
||||||
|
else if (hwaddr_aton(uuid, addr) == 0)
|
||||||
|
use_addr = addr;
|
||||||
|
else
|
||||||
return -1;
|
return -1;
|
||||||
return wps_er_learn(wpa_s->wps_er, u, (const u8 *) pin,
|
|
||||||
|
return wps_er_learn(wpa_s->wps_er, use_uuid, use_addr, (const u8 *) pin,
|
||||||
os_strlen(pin));
|
os_strlen(pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1642,11 +1648,16 @@ int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
|
||||||
int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
|
int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
|
||||||
int id)
|
int id)
|
||||||
{
|
{
|
||||||
u8 u[UUID_LEN];
|
u8 u[UUID_LEN], *use_uuid = NULL;
|
||||||
|
u8 addr[ETH_ALEN], *use_addr = NULL;
|
||||||
struct wpa_ssid *ssid;
|
struct wpa_ssid *ssid;
|
||||||
struct wps_credential cred;
|
struct wps_credential cred;
|
||||||
|
|
||||||
if (uuid_str2bin(uuid, u))
|
if (uuid_str2bin(uuid, u) == 0)
|
||||||
|
use_uuid = u;
|
||||||
|
else if (hwaddr_aton(uuid, addr) == 0)
|
||||||
|
use_addr = addr;
|
||||||
|
else
|
||||||
return -1;
|
return -1;
|
||||||
ssid = wpa_config_get_network(wpa_s->conf, id);
|
ssid = wpa_config_get_network(wpa_s->conf, id);
|
||||||
if (ssid == NULL || ssid->ssid == NULL)
|
if (ssid == NULL || ssid->ssid == NULL)
|
||||||
|
@ -1678,18 +1689,23 @@ int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
|
||||||
cred.auth_type = WPS_AUTH_OPEN;
|
cred.auth_type = WPS_AUTH_OPEN;
|
||||||
cred.encr_type = WPS_ENCR_NONE;
|
cred.encr_type = WPS_ENCR_NONE;
|
||||||
}
|
}
|
||||||
return wps_er_set_config(wpa_s->wps_er, u, &cred);
|
return wps_er_set_config(wpa_s->wps_er, use_uuid, use_addr, &cred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
|
int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
|
||||||
const char *pin, struct wps_new_ap_settings *settings)
|
const char *pin, struct wps_new_ap_settings *settings)
|
||||||
{
|
{
|
||||||
u8 u[UUID_LEN];
|
u8 u[UUID_LEN], *use_uuid = NULL;
|
||||||
|
u8 addr[ETH_ALEN], *use_addr = NULL;
|
||||||
struct wps_credential cred;
|
struct wps_credential cred;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (uuid_str2bin(uuid, u))
|
if (uuid_str2bin(uuid, u) == 0)
|
||||||
|
use_uuid = u;
|
||||||
|
else if (hwaddr_aton(uuid, addr) == 0)
|
||||||
|
use_addr = addr;
|
||||||
|
else
|
||||||
return -1;
|
return -1;
|
||||||
if (settings->ssid_hex == NULL || settings->auth == NULL ||
|
if (settings->ssid_hex == NULL || settings->auth == NULL ||
|
||||||
settings->encr == NULL || settings->key_hex == NULL)
|
settings->encr == NULL || settings->key_hex == NULL)
|
||||||
|
@ -1728,8 +1744,8 @@ int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return wps_er_config(wpa_s->wps_er, u, (const u8 *) pin,
|
return wps_er_config(wpa_s->wps_er, use_uuid, use_addr,
|
||||||
os_strlen(pin), &cred);
|
(const u8 *) pin, os_strlen(pin), &cred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1738,15 +1754,20 @@ struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s,
|
||||||
int ndef, const char *uuid)
|
int ndef, const char *uuid)
|
||||||
{
|
{
|
||||||
struct wpabuf *ret;
|
struct wpabuf *ret;
|
||||||
u8 u[UUID_LEN];
|
u8 u[UUID_LEN], *use_uuid = NULL;
|
||||||
|
u8 addr[ETH_ALEN], *use_addr = NULL;
|
||||||
|
|
||||||
if (!wpa_s->wps_er)
|
if (!wpa_s->wps_er)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (uuid_str2bin(uuid, u))
|
if (uuid_str2bin(uuid, u) == 0)
|
||||||
|
use_uuid = u;
|
||||||
|
else if (hwaddr_aton(uuid, addr) == 0)
|
||||||
|
use_addr = addr;
|
||||||
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ret = wps_er_nfc_config_token(wpa_s->wps_er, u);
|
ret = wps_er_nfc_config_token(wpa_s->wps_er, use_uuid, use_addr);
|
||||||
if (ndef && ret) {
|
if (ndef && ret) {
|
||||||
struct wpabuf *tmp;
|
struct wpabuf *tmp;
|
||||||
tmp = ndef_build_wifi(ret);
|
tmp = ndef_build_wifi(ret);
|
||||||
|
@ -2038,19 +2059,26 @@ struct wpabuf * wpas_wps_er_nfc_handover_sel(struct wpa_supplicant *wpa_s,
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_WPS_ER
|
#ifdef CONFIG_WPS_ER
|
||||||
struct wpabuf *ret;
|
struct wpabuf *ret;
|
||||||
u8 u[UUID_LEN];
|
u8 u[UUID_LEN], *use_uuid = NULL;
|
||||||
|
u8 addr[ETH_ALEN], *use_addr = NULL;
|
||||||
|
|
||||||
if (!wpa_s->wps_er)
|
if (!wpa_s->wps_er)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (uuid == NULL || uuid_str2bin(uuid, u))
|
if (uuid == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (uuid_str2bin(uuid, u) == 0)
|
||||||
|
use_uuid = u;
|
||||||
|
else if (hwaddr_aton(uuid, addr) == 0)
|
||||||
|
use_addr = addr;
|
||||||
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handover Select carrier record for WPS uses the same format as
|
* Handover Select carrier record for WPS uses the same format as
|
||||||
* configuration token.
|
* configuration token.
|
||||||
*/
|
*/
|
||||||
ret = wps_er_nfc_config_token(wpa_s->wps_er, u);
|
ret = wps_er_nfc_config_token(wpa_s->wps_er, use_uuid, use_addr);
|
||||||
if (ndef && ret) {
|
if (ndef && ret) {
|
||||||
struct wpabuf *tmp;
|
struct wpabuf *tmp;
|
||||||
tmp = ndef_build_wifi(ret);
|
tmp = ndef_build_wifi(ret);
|
||||||
|
|
Loading…
Reference in a new issue