diff --git a/src/wps/wps.h b/src/wps/wps.h index 39fce56fb..f52b74f04 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 + * Copyright (c) 2007-2013, Jouni Malinen * * 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 95a0dec05..d96ae1b80 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 + * Copyright (c) 2009-2013, Jouni Malinen * * 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 2a1dda5cf..7891fef61 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 +wps_er_learn - learn AP configuration -wps_er_set_config +wps_er_set_config - 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 +wps_er_config - 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 cd0f493fe..6707b7910 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 + * Copyright (c) 2008-2013, Jouni Malinen * * 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);