aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2013-04-02 11:05:36 -0700
committerDmitry Shmidt <dimitrysh@google.com>2013-04-02 11:05:36 -0700
commit1e78e76961664775f58b139f8c6388cfa0485f3d (patch)
treee28923e1f8be4f71cf2671695ed30b6c31b13b52
parent444d567b27731d8572ef37697dd12fd1c37c2f24 (diff)
downloadandroid_external_wpa_supplicant_8-1e78e76961664775f58b139f8c6388cfa0485f3d.tar.gz
android_external_wpa_supplicant_8-1e78e76961664775f58b139f8c6388cfa0485f3d.tar.bz2
android_external_wpa_supplicant_8-1e78e76961664775f58b139f8c6388cfa0485f3d.zip
Accumulative patch from commit 88c8bf311efa4eb64468bed9b41b3110ab9effff
88c8bf3 WPS NFC: Allow configuration token to be built from network block e205401 WPS ER: Allow Enrollee to be specified with MAC address c44a19c WPS ER: Document additional NFC command for ER operations 59307b3 WPS ER: Allow AP to be specified with BSSID 49e160a WPS: Fix use of pre-configured DH keys with multiple operations 5c9d63d WPS: Be more careful with pre-configured DH parameters cd61936 hostapd: Show more helpful message for -g and -G errors Change-Id: I7bfd1fa30214c54f2536679411ccd11bb4dd896d Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r--hostapd/main.c8
-rw-r--r--src/wps/wps.h21
-rw-r--r--src/wps/wps_attr_build.c20
-rw-r--r--src/wps/wps_er.c99
-rw-r--r--wpa_supplicant/README-WPS39
-rw-r--r--wpa_supplicant/ctrl_iface.c6
-rwxr-xr-xwpa_supplicant/examples/wps-nfc.py12
-rw-r--r--wpa_supplicant/wps_supplicant.c199
-rw-r--r--wpa_supplicant/wps_supplicant.h2
9 files changed, 295 insertions, 111 deletions
diff --git a/hostapd/main.c b/hostapd/main.c
index 881a053e..d2ec1a50 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -525,6 +525,8 @@ static int hostapd_get_global_ctrl_iface(struct hapd_interfaces *interfaces,
return -1;
pos = os_strrchr(interfaces->global_iface_path, '/');
if (pos == NULL) {
+ wpa_printf(MSG_ERROR, "No '/' in the global control interface "
+ "file");
os_free(interfaces->global_iface_path);
interfaces->global_iface_path = NULL;
return -1;
@@ -614,10 +616,12 @@ int main(int argc, char *argv[])
exit(1);
break;
case 'g':
- hostapd_get_global_ctrl_iface(&interfaces, optarg);
+ if (hostapd_get_global_ctrl_iface(&interfaces, optarg))
+ return -1;
break;
case 'G':
- hostapd_get_ctrl_iface_group(&interfaces, optarg);
+ if (hostapd_get_ctrl_iface_group(&interfaces, optarg))
+ return -1;
break;
default:
usage();
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 39fce56f..cb03dbdc 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.
@@ -793,14 +793,19 @@ void wps_er_refresh(struct wps_er *er);
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_pbc(struct wps_er *er, const u8 *uuid, const u8 *addr);
+const u8 * wps_er_get_sta_uuid(struct wps_er *er, const u8 *addr);
+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_config_token_from_cred(struct wps_context *wps,
+ 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_attr_build.c b/src/wps/wps_attr_build.c
index 29aee8ee..edcc18cb 100644
--- a/src/wps/wps_attr_build.c
+++ b/src/wps/wps_attr_build.c
@@ -24,8 +24,15 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
wpa_printf(MSG_DEBUG, "WPS: * Public Key");
wpabuf_free(wps->dh_privkey);
- if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey) {
+ wps->dh_privkey = NULL;
+ if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey &&
+ wps->wps->dh_ctx) {
wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys");
+ if (wps->wps->dh_pubkey == NULL) {
+ wpa_printf(MSG_DEBUG,
+ "WPS: wps->wps->dh_pubkey == NULL");
+ return -1;
+ }
wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey);
wps->dh_ctx = wps->wps->dh_ctx;
wps->wps->dh_ctx = NULL;
@@ -34,13 +41,22 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
} else if (wps->dev_pw_id >= 0x10 && wps->wps->ap &&
wps->dev_pw_id == wps->wps->ap_nfc_dev_pw_id) {
wpa_printf(MSG_DEBUG, "WPS: Using NFC password token DH keys");
+ if (wps->wps->ap_nfc_dh_privkey == NULL) {
+ wpa_printf(MSG_DEBUG,
+ "WPS: wps->wps->ap_nfc_dh_privkey == NULL");
+ return -1;
+ }
+ if (wps->wps->ap_nfc_dh_pubkey == NULL) {
+ wpa_printf(MSG_DEBUG,
+ "WPS: wps->wps->ap_nfc_dh_pubkey == NULL");
+ return -1;
+ }
wps->dh_privkey = wpabuf_dup(wps->wps->ap_nfc_dh_privkey);
pubkey = wpabuf_dup(wps->wps->ap_nfc_dh_pubkey);
wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, pubkey);
#endif /* CONFIG_WPS_NFC */
} else {
wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys");
- wps->dh_privkey = NULL;
dh5_free(wps->dh_ctx);
wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey);
pubkey = wpabuf_zeropad(pubkey, 192);
diff --git a/src/wps/wps_er.c b/src/wps/wps_er.c
index 95a0dec0..14c1b779 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);
@@ -1555,7 +1558,7 @@ void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
}
-int wps_er_pbc(struct wps_er *er, const u8 *uuid)
+int wps_er_pbc(struct wps_er *er, const u8 *uuid, const u8 *addr)
{
int res;
struct wps_er_ap *ap;
@@ -1569,11 +1572,14 @@ int wps_er_pbc(struct wps_er *er, const u8 *uuid)
return -2;
}
- ap = wps_er_ap_get(er, NULL, uuid);
+ if (uuid)
+ ap = wps_er_ap_get(er, NULL, uuid, NULL);
+ else
+ ap = NULL;
if (ap == NULL) {
struct wps_er_sta *sta = NULL;
dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
- sta = wps_er_sta_get(ap, NULL, uuid);
+ sta = wps_er_sta_get(ap, addr, uuid);
if (sta) {
uuid = ap->uuid;
break;
@@ -1619,6 +1625,19 @@ static void wps_er_ap_settings_cb(void *ctx, const struct wps_credential *cred)
}
+const u8 * wps_er_get_sta_uuid(struct wps_er *er, const u8 *addr)
+{
+ struct wps_er_ap *ap;
+ dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
+ struct wps_er_sta *sta;
+ sta = wps_er_sta_get(ap, addr, NULL);
+ if (sta)
+ return sta->uuid;
+ }
+ return NULL;
+}
+
+
static void wps_er_http_put_message_cb(void *ctx, struct http_client *c,
enum http_client_event event)
{
@@ -1877,20 +1896,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 +1929,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 +1937,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 +1981,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,31 +2023,20 @@ 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_config_token_from_cred(struct wps_context *wps,
+ struct wps_credential *cred)
{
- struct wps_er_ap *ap;
struct wpabuf *ret;
struct wps_data data;
- if (er == NULL)
- return NULL;
-
- ap = wps_er_ap_get(er, NULL, uuid);
- if (ap == NULL)
- return NULL;
- if (ap->ap_settings == NULL) {
- wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the "
- "selected AP");
- return NULL;
- }
-
ret = wpabuf_alloc(500);
if (ret == NULL)
return NULL;
os_memset(&data, 0, sizeof(data));
- data.wps = er->wps;
- data.use_cred = ap->ap_settings;
+ data.wps = wps;
+ data.use_cred = cred;
if (wps_build_version(ret) ||
wps_build_cred(&data, ret) ||
wps_build_wfa_ext(ret, 0, NULL, 0)) {
@@ -2033,4 +2046,26 @@ struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid)
return ret;
}
+
+
+struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid,
+ const u8 *addr)
+{
+ struct wps_er_ap *ap;
+
+ if (er == NULL)
+ return NULL;
+
+ ap = wps_er_ap_get(er, NULL, uuid, addr);
+ if (ap == NULL)
+ return NULL;
+ if (ap->ap_settings == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the "
+ "selected AP");
+ return NULL;
+ }
+
+ return wps_er_config_token_from_cred(er->wps, ap->ap_settings);
+}
+
#endif /* CONFIG_WPS_NFC */
diff --git a/wpa_supplicant/README-WPS b/wpa_supplicant/README-WPS
index 2a1dda5c..3d071093 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 ""
@@ -277,10 +277,10 @@ wps_er_config <UUID> <AP PIN> <new SSID> <auth> <encr> <new key>
<encr> must be one of the following: NONE WEP TKIP CCMP
-wps_er_pbc <Enrollee UUID>
+wps_er_pbc <Enrollee UUID|MAC address>
- accept an Enrollee PBC using External Registrar
-wps_er_pin <Enrollee UUID> <PIN> [Enrollee MAC address]
+wps_er_pin <Enrollee UUID|"any"|MAC address> <PIN> [Enrollee MAC address]
- add an Enrollee PIN to External Registrar
- if Enrollee UUID is not known, "any" can be used to add a wildcard PIN
- if the MAC address of the enrollee is known, it should be configured
@@ -346,6 +346,10 @@ tag with an external program. Once written, the NFC configuration token
can be used to touch an NFC interface on a station to provision the
credentials needed to access the network.
+The "wps_nfc_config_token <WPS/NDEF> <network id>" command can be used
+to build an NFC configuration token based on a locally configured
+network.
+
If the station includes NFC interface and reads an NFC tag with a MIME
media type "application/vnd.wfa.wsc", the NDEF message payload (with or
without NDEF encapsulation) can be delivered to wpa_supplicant using the
@@ -368,12 +372,15 @@ first argument selects the format of the output data and the second
argument selects which type of connection handover is requested (WPS =
Wi-Fi handover as specified in WSC 2.0).
-"nfc_get_handover_sel <NDEF> <WPS>" command can be used to build the
-contents of a Handover Select Message for connection handover when this
-does not depend on the contents of the Handover Request Message. The
-first argument selects the format of the output data and the second
-argument selects which type of connection handover is requested (WPS =
-Wi-Fi handover as specified in WSC 2.0).
+"nfc_get_handover_sel <NDEF> <WPS> [UUID|BSSID]" command can be used to
+build the contents of a Handover Select Message for connection handover
+when this does not depend on the contents of the Handover Request
+Message. The first argument selects the format of the output data and
+the second argument selects which type of connection handover is
+requested (WPS = Wi-Fi handover as specified in WSC 2.0). If the options
+UUID|BSSID argument is included, this is a request to build the handover
+message for the specified AP when wpa_supplicant is operating as a WPS
+ER.
"nfc_rx_handover_req <hexdump of payload>" is used to indicate receipt
of NFC connection handover request. The payload may include multiple
@@ -392,3 +399,13 @@ reporting completed NFC connection handover. The first parameter
indicates whether the local device initiated or responded to the
connection handover and the carrier records are the selected carrier
from the handover request and select messages as a hexdump.
+
+The "wps_er_nfc_config_token <WPS/NDEF> <UUID|BSSID>" command can be
+used to build an NFC configuration token for the specified AP when
+wpa_supplicant is operating as a WPS ER. The output value from this
+command is a hexdump of the selected AP configuration (WPS parameter
+requests this to include only the WPS attributes; NDEF parameter
+requests additional NDEF encapsulation to be included). This data needs
+to be written to an NFC tag with an external program. Once written, the
+NFC configuration token can be used to touch an NFC interface on a
+station to provision the credentials needed to access the network.
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 6d2b3b14..ad0392f9 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -784,7 +784,11 @@ static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
int ndef;
struct wpabuf *buf;
int res;
+ char *pos;
+ pos = os_strchr(cmd, ' ');
+ if (pos)
+ *pos++ = '\0';
if (os_strcmp(cmd, "WPS") == 0)
ndef = 0;
else if (os_strcmp(cmd, "NDEF") == 0)
@@ -792,7 +796,7 @@ static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
else
return -1;
- buf = wpas_wps_nfc_config_token(wpa_s, ndef);
+ buf = wpas_wps_nfc_config_token(wpa_s, ndef, pos);
if (buf == NULL)
return -1;
diff --git a/wpa_supplicant/examples/wps-nfc.py b/wpa_supplicant/examples/wps-nfc.py
index 86473cd6..dbc143ad 100755
--- a/wpa_supplicant/examples/wps-nfc.py
+++ b/wpa_supplicant/examples/wps-nfc.py
@@ -53,10 +53,12 @@ def wpas_tag_read(message):
print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
-def wpas_get_config_token():
+def wpas_get_config_token(id=None):
wpas = wpas_connect()
if (wpas == None):
return None
+ if id:
+ return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF " + id).rstrip().decode("hex")
return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
@@ -258,9 +260,9 @@ def wps_tag_read(tag):
time.sleep(0.1)
-def wps_write_config_tag(clf):
+def wps_write_config_tag(clf, id=None):
print "Write WPS config token"
- data = wpas_get_config_token()
+ data = wpas_get_config_token(id)
if (data == None):
print "Could not get WPS config token from wpa_supplicant"
return
@@ -364,6 +366,10 @@ def main():
wps_write_config_tag(clf)
raise SystemExit
+ if len(sys.argv) > 2 and sys.argv[1] == "write-config-id":
+ wps_write_config_tag(clf, sys.argv[2])
+ raise SystemExit
+
if len(sys.argv) > 2 and sys.argv[1] == "write-er-config":
wps_write_er_config_tag(clf, sys.argv[2])
raise SystemExit
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 603ce919..9af60849 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.
@@ -1605,91 +1605,128 @@ int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const u8 *addr,
const char *uuid, const char *pin)
{
u8 u[UUID_LEN];
- int any = 0;
-
- if (os_strcmp(uuid, "any") == 0)
- any = 1;
- else if (uuid_str2bin(uuid, u))
+ const u8 *use_uuid = NULL;
+ u8 addr_buf[ETH_ALEN];
+
+ if (os_strcmp(uuid, "any") == 0) {
+ } else if (uuid_str2bin(uuid, u) == 0) {
+ use_uuid = u;
+ } else if (hwaddr_aton(uuid, addr_buf) == 0) {
+ use_uuid = wps_er_get_sta_uuid(wpa_s->wps_er, addr_buf);
+ if (use_uuid == NULL)
+ return -1;
+ } else
return -1;
return wps_registrar_add_pin(wpa_s->wps->registrar, addr,
- any ? NULL : u,
+ use_uuid,
(const u8 *) pin, os_strlen(pin), 300);
}
int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid)
{
- 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_pbc(wpa_s->wps_er, u);
+ return wps_er_pbc(wpa_s->wps_er, use_uuid, use_addr);
}
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));
}
-int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
- int id)
+static int wpas_wps_network_to_cred(struct wpa_ssid *ssid,
+ struct wps_credential *cred)
{
- u8 u[UUID_LEN];
- struct wpa_ssid *ssid;
- struct wps_credential cred;
-
- if (uuid_str2bin(uuid, u))
- return -1;
- ssid = wpa_config_get_network(wpa_s->conf, id);
- if (ssid == NULL || ssid->ssid == NULL)
- return -1;
-
- os_memset(&cred, 0, sizeof(cred));
+ os_memset(cred, 0, sizeof(*cred));
if (ssid->ssid_len > 32)
return -1;
- os_memcpy(cred.ssid, ssid->ssid, ssid->ssid_len);
- cred.ssid_len = ssid->ssid_len;
+ os_memcpy(cred->ssid, ssid->ssid, ssid->ssid_len);
+ cred->ssid_len = ssid->ssid_len;
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
- cred.auth_type = (ssid->proto & WPA_PROTO_RSN) ?
+ cred->auth_type = (ssid->proto & WPA_PROTO_RSN) ?
WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
- cred.encr_type = WPS_ENCR_AES;
+ cred->encr_type = WPS_ENCR_AES;
else
- cred.encr_type = WPS_ENCR_TKIP;
+ cred->encr_type = WPS_ENCR_TKIP;
if (ssid->passphrase) {
- cred.key_len = os_strlen(ssid->passphrase);
- if (cred.key_len >= 64)
+ cred->key_len = os_strlen(ssid->passphrase);
+ if (cred->key_len >= 64)
return -1;
- os_memcpy(cred.key, ssid->passphrase, cred.key_len);
+ os_memcpy(cred->key, ssid->passphrase, cred->key_len);
} else if (ssid->psk_set) {
- cred.key_len = 32;
- os_memcpy(cred.key, ssid->psk, 32);
+ cred->key_len = 32;
+ os_memcpy(cred->key, ssid->psk, 32);
} else
return -1;
} else {
- cred.auth_type = WPS_AUTH_OPEN;
- cred.encr_type = WPS_ENCR_NONE;
+ cred->auth_type = WPS_AUTH_OPEN;
+ cred->encr_type = WPS_ENCR_NONE;
}
- return wps_er_set_config(wpa_s->wps_er, u, &cred);
+
+ return 0;
+}
+
+
+int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
+ int id)
+{
+ 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) == 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)
+ return -1;
+
+ if (wpas_wps_network_to_cred(ssid, &cred) < 0)
+ return -1;
+ 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 +1765,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 +1775,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);
@@ -1854,9 +1896,52 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_WPS_NFC
+#ifdef CONFIG_WPS_ER
+static struct wpabuf *
+wpas_wps_network_config_token(struct wpa_supplicant *wpa_s, int ndef,
+ struct wpa_ssid *ssid)
+{
+ struct wpabuf *ret;
+ struct wps_credential cred;
+
+ if (wpas_wps_network_to_cred(ssid, &cred) < 0)
+ return NULL;
+
+ ret = wps_er_config_token_from_cred(wpa_s->wps, &cred);
+
+ if (ndef && ret) {
+ struct wpabuf *tmp;
+ tmp = ndef_build_wifi(ret);
+ wpabuf_free(ret);
+ if (tmp == NULL)
+ return NULL;
+ ret = tmp;
+ }
+
+ return ret;
+}
+#endif /* CONFIG_WPS_ER */
+
+
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef)
+ int ndef, const char *id_str)
{
+#ifdef CONFIG_WPS_ER
+ if (id_str) {
+ int id;
+ char *end = NULL;
+ struct wpa_ssid *ssid;
+
+ id = strtol(id_str, &end, 10);
+ if (end && *end)
+ return NULL;
+
+ ssid = wpa_config_get_network(wpa_s->conf, id);
+ if (ssid == NULL)
+ return NULL;
+ return wpas_wps_network_config_token(wpa_s, ndef, ssid);
+ }
+#endif /* CONFIG_WPS_ER */
#ifdef CONFIG_AP
if (wpa_s->ap_iface)
return wpas_ap_wps_nfc_config_token(wpa_s, ndef);
@@ -1905,8 +1990,13 @@ int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid)
return -1;
}
wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
- if (wps->dh_ctx == NULL)
+ if (wps->dh_ctx == NULL) {
+ wpabuf_free(wps->dh_pubkey);
+ wps->dh_pubkey = NULL;
+ wpabuf_free(wps->dh_privkey);
+ wps->dh_privkey = NULL;
return -1;
+ }
wpa_snprintf_hex_uppercase(pw, sizeof(pw),
wpabuf_head(wpa_s->conf->wps_nfc_dev_pw),
@@ -2033,19 +2123,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);
diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h
index 8bb9546e..2a212cab 100644
--- a/wpa_supplicant/wps_supplicant.h
+++ b/wpa_supplicant/wps_supplicant.h
@@ -63,7 +63,7 @@ int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s);
int wpas_wps_in_progress(struct wpa_supplicant *wpa_s);
void wpas_wps_update_config(struct wpa_supplicant *wpa_s);
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
- int ndef);
+ int ndef, const char *id_str);
struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef);
int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid);
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,