aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2013-04-01 17:32:09 (GMT)
committerJouni Malinen <j@w1.fi>2013-04-01 17:32:09 (GMT)
commit59307b3007339024871dbddff4439cbcc7f9aec8 (patch)
tree0a822bbe51f803a864c82c9ea4215fe578c8088b
parentea295abcd5e76c8cde9f5260cd49a3f7fcd1d75d (diff)
downloadhostap-59307b3007339024871dbddff4439cbcc7f9aec8.zip
hostap-59307b3007339024871dbddff4439cbcc7f9aec8.tar.gz
hostap-59307b3007339024871dbddff4439cbcc7f9aec8.tar.bz2
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>
-rw-r--r--src/wps/wps.h16
-rw-r--r--src/wps/wps_er.c41
-rw-r--r--wpa_supplicant/README-WPS6
-rw-r--r--wpa_supplicant/wps_supplicant.c62
4 files changed, 82 insertions, 43 deletions
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 39fce56..f52b74f 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -1,6 +1,6 @@
/*
* 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.
* 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,
u16 sel_reg_config_methods);
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,
- size_t pin_len);
-int wps_er_set_config(struct wps_er *er, const u8 *uuid,
+int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *addr,
+ const u8 *pin, size_t pin_len);
+int wps_er_set_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
const struct wps_credential *cred);
-int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin,
- size_t pin_len, const struct wps_credential *cred);
-struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid);
+int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
+ const u8 *pin, size_t pin_len,
+ 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]);
char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
diff --git a/src/wps/wps_er.c b/src/wps/wps_er.c
index 95a0dec..d96ae1b 100644
--- a/src/wps/wps_er.c
+++ b/src/wps/wps_er.c
@@ -1,6 +1,6 @@
/*
* 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.
* 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,
- struct in_addr *addr, const u8 *uuid)
+ struct in_addr *addr, const u8 *uuid,
+ const u8 *mac_addr)
{
struct wps_er_ap *ap;
dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
if ((addr == NULL || ap->addr.s_addr == addr->s_addr) &&
(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 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_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)
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;
- ap = wps_er_ap_get(er, addr, uuid);
+ ap = wps_er_ap_get(er, addr, uuid, NULL);
if (ap) {
/* Update advertisement timeout */
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;
}
- ap = wps_er_ap_get(er, NULL, uuid);
+ ap = wps_er_ap_get(er, NULL, uuid, NULL);
if (ap == NULL) {
struct wps_er_sta *sta = NULL;
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,
- size_t pin_len)
+int wps_er_learn(struct wps_er *er, const u8 *uuid, const u8 *addr,
+ const u8 *pin, size_t pin_len)
{
struct wps_er_ap *ap;
if (er == NULL)
return -1;
- ap = wps_er_ap_get(er, NULL, uuid);
+ ap = wps_er_ap_get(er, NULL, uuid, addr);
if (ap == NULL) {
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for learn "
"request");
return -1;
}
+ if (uuid == NULL)
+ uuid = ap->uuid;
if (ap->wps) {
wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
"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)
{
struct wps_er_ap *ap;
@@ -1916,7 +1921,7 @@ int wps_er_set_config(struct wps_er *er, const u8 *uuid,
if (er == NULL)
return -1;
- ap = wps_er_ap_get(er, NULL, uuid);
+ ap = wps_er_ap_get(er, NULL, uuid, addr);
if (ap == NULL) {
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for set config "
"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,
- size_t pin_len, const struct wps_credential *cred)
+int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *addr,
+ const u8 *pin, size_t pin_len,
+ const struct wps_credential *cred)
{
struct wps_er_ap *ap;
if (er == NULL)
return -1;
- ap = wps_er_ap_get(er, NULL, uuid);
+ ap = wps_er_ap_get(er, NULL, uuid, addr);
if (ap == NULL) {
wpa_printf(MSG_DEBUG, "WPS ER: AP not found for config "
"request");
return -1;
}
+ if (uuid == NULL)
+ uuid = ap->uuid;
if (ap->wps) {
wpa_printf(MSG_DEBUG, "WPS ER: Pending operation ongoing "
"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
-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 wpabuf *ret;
@@ -2008,7 +2017,7 @@ struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid)
if (er == NULL)
return NULL;
- ap = wps_er_ap_get(er, NULL, uuid);
+ ap = wps_er_ap_get(er, NULL, uuid, addr);
if (ap == NULL)
return NULL;
if (ap->ap_settings == NULL) {
diff --git a/wpa_supplicant/README-WPS b/wpa_supplicant/README-WPS
index 2a1dda5..7891fef 100644
--- a/wpa_supplicant/README-WPS
+++ b/wpa_supplicant/README-WPS
@@ -259,16 +259,16 @@ wps_er_start [IP address]
wps_er_stop
- stop WPS ER functionality
-wps_er_learn <UUID> <AP PIN>
+wps_er_learn <UUID|BSSID> <AP PIN>
- 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
wps_reg command); this does not change the AP's configuration, but
only prepares a configuration to be used when enrolling a new device
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:
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 ""
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index cd0f493..6707b79 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1,6 +1,6 @@
/*
* 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.
* 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,
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 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));
}
@@ -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 id)
{
- u8 u[UUID_LEN];
+ u8 u[UUID_LEN], *use_uuid = NULL;
+ u8 addr[ETH_ALEN], *use_addr = NULL;
struct wpa_ssid *ssid;
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;
ssid = wpa_config_get_network(wpa_s->conf, id);
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.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,
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;
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;
if (settings->ssid_hex == NULL || settings->auth == 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
return -1;
- return wps_er_config(wpa_s->wps_er, u, (const u8 *) pin,
- os_strlen(pin), &cred);
+ return wps_er_config(wpa_s->wps_er, use_uuid, use_addr,
+ (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)
{
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)
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;
- 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) {
struct wpabuf *tmp;
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
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)
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;
/*
* Handover Select carrier record for WPS uses the same format as
* 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) {
struct wpabuf *tmp;
tmp = ndef_build_wifi(ret);