]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS ER: Allow AP to be specified with BSSID
authorJouni Malinen <j@w1.fi>
Mon, 1 Apr 2013 17:32:09 +0000 (20:32 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 1 Apr 2013 17:32:09 +0000 (20:32 +0300)
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>

src/wps/wps.h
src/wps/wps_er.c
wpa_supplicant/README-WPS
wpa_supplicant/wps_supplicant.c

index 39fce56fb7d67b688d6a5fb65517482ab3ffccf3..f52b74f04e582ab2a7324c8603f212134fe9c2d2 100644 (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,
index 95a0dec0533cb8e3b24cac6c88ac4a044aa1f291..d96ae1b80c440e35e8a0c68eeabee91215ba79f6 100644 (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) {
index 2a1dda5cf4dc72bd9ae5dba6c98a418d8b9771d5..7891fef61161d6ac061b3ec0fa4701235ee55ee2 100644 (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 ""
index cd0f493fe687b7809e0e105a9d2c7800aeb978ac..6707b7910aa11ec8d2069fb59e24cfd46544cc3b 100644 (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);