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:
Jouni Malinen 2013-04-01 20:32:09 +03:00
parent ea295abcd5
commit 59307b3007
4 changed files with 82 additions and 43 deletions

View File

@ -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,

View File

@ -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) {

View File

@ -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 ""

View File

@ -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);