aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2009-12-12 14:40:10 (GMT)
committerJouni Malinen <j@w1.fi>2010-09-09 13:07:47 (GMT)
commit31fcea931d916fd3dec2522822f87a7148b45a99 (patch)
treeefe4ecda6d02fa176ed82da68871ae186dc7261e /wpa_supplicant
parentf439079e93dfff93d184df727bb8bedef4a9fcb2 (diff)
downloadhostap-31fcea931d916fd3dec2522822f87a7148b45a99.zip
hostap-31fcea931d916fd3dec2522822f87a7148b45a99.tar.gz
hostap-31fcea931d916fd3dec2522822f87a7148b45a99.tar.bz2
WPS 2.0: Add support for AuthorizedMACs attribute
Advertize list of authorized enrollee MAC addresses in Beacon and Probe Response frames and use these when selecting the AP. In order to provide the list, the enrollee MAC address should be specified whenever adding a new PIN. In addition, add UUID-R into SetSelectedRegistrar action to make it potentially easier for an AP to figure out which ER sent the action should there be multiple ERs using the same IP address.
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/ap.c3
-rw-r--r--wpa_supplicant/ctrl_iface.c28
-rw-r--r--wpa_supplicant/wpa_cli.c16
-rw-r--r--wpa_supplicant/wpa_gui-qt4/peers.cpp8
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpagui.cpp9
-rw-r--r--wpa_supplicant/wps_supplicant.c27
-rw-r--r--wpa_supplicant/wps_supplicant.h4
7 files changed, 65 insertions, 30 deletions
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 2b93984..e2be10c 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -368,7 +368,8 @@ int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
pin = buf;
}
- ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], "any", pin, 0);
+ ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], bssid, "any", pin,
+ 0);
if (ret)
return -1;
return ret_len;
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 464a226..4a2412f 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -311,12 +311,19 @@ static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
char *cmd)
{
- char *uuid = cmd, *pin;
+ char *uuid = cmd, *pin, *pos;
+ u8 addr_buf[ETH_ALEN], *addr = NULL;
pin = os_strchr(uuid, ' ');
if (pin == NULL)
return -1;
*pin++ = '\0';
- return wpas_wps_er_add_pin(wpa_s, uuid, pin);
+ pos = os_strchr(pin, ' ');
+ if (pos) {
+ *pos++ = '\0';
+ if (hwaddr_aton(pos, addr_buf) == 0)
+ addr = addr_buf;
+ }
+ return wpas_wps_er_add_pin(wpa_s, addr, uuid, pin);
}
@@ -818,7 +825,8 @@ static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
#ifdef CONFIG_WPS
-static char * wpa_supplicant_wps_ie_txt_buf(char *pos, char *end,
+static char * wpa_supplicant_wps_ie_txt_buf(struct wpa_supplicant *wpa_s,
+ char *pos, char *end,
struct wpabuf *wps_ie)
{
int ret;
@@ -828,6 +836,8 @@ static char * wpa_supplicant_wps_ie_txt_buf(char *pos, char *end,
return pos;
if (wps_is_selected_pbc_registrar(wps_ie))
txt = "[WPS-PBC]";
+ else if (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 0))
+ txt = "[WPS-AUTH]";
else if (wps_is_selected_pin_registrar(wps_ie))
txt = "[WPS-PIN]";
else
@@ -842,13 +852,14 @@ static char * wpa_supplicant_wps_ie_txt_buf(char *pos, char *end,
#endif /* CONFIG_WPS */
-static char * wpa_supplicant_wps_ie_txt(char *pos, char *end,
+static char * wpa_supplicant_wps_ie_txt(struct wpa_supplicant *wpa_s,
+ char *pos, char *end,
const struct wpa_bss *bss)
{
#ifdef CONFIG_WPS
struct wpabuf *wps_ie;
wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
- return wpa_supplicant_wps_ie_txt_buf(pos, end, wps_ie);
+ return wpa_supplicant_wps_ie_txt_buf(wpa_s, pos, end, wps_ie);
#else /* CONFIG_WPS */
return pos;
#endif /* CONFIG_WPS */
@@ -857,6 +868,7 @@ static char * wpa_supplicant_wps_ie_txt(char *pos, char *end,
/* Format one result on one text line into a buffer. */
static int wpa_supplicant_ctrl_iface_scan_result(
+ struct wpa_supplicant *wpa_s,
const struct wpa_bss *bss, char *buf, size_t buflen)
{
char *pos, *end;
@@ -877,7 +889,7 @@ static int wpa_supplicant_ctrl_iface_scan_result(
ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
if (ie2)
pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
- pos = wpa_supplicant_wps_ie_txt(pos, end, bss);
+ pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
ret = os_snprintf(pos, end - pos, "[WEP]");
if (ret < 0 || ret >= end - pos)
@@ -928,7 +940,7 @@ static int wpa_supplicant_ctrl_iface_scan_results(
pos += ret;
dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
- ret = wpa_supplicant_ctrl_iface_scan_result(bss, pos,
+ ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
end - pos);
if (ret < 0 || ret >= end - pos)
return pos - buf;
@@ -1616,7 +1628,7 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
if (ie2)
pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
- pos = wpa_supplicant_wps_ie_txt(pos, end, bss);
+ pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
ret = os_snprintf(pos, end - pos, "[WEP]");
if (ret < 0 || ret >= end - pos)
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 2a9261b..b97f05d 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -731,15 +731,21 @@ static int wpa_cli_cmd_wps_er_pin(struct wpa_ctrl *ctrl, int argc,
char cmd[256];
int res;
- if (argc != 2) {
- printf("Invalid WPS_ER_PIN command: need two arguments:\n"
+ if (argc < 2) {
+ printf("Invalid WPS_ER_PIN command: need at least two "
+ "arguments:\n"
"- UUID: use 'any' to select any\n"
- "- PIN: Enrollee PIN\n");
+ "- PIN: Enrollee PIN\n"
+ "optional: - Enrollee MAC address\n");
return -1;
}
- res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
- argv[0], argv[1]);
+ if (argc > 2)
+ res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
+ argv[0], argv[1], argv[2]);
+ else
+ res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
+ argv[0], argv[1]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long WPS_ER_PIN command.\n");
return -1;
diff --git a/wpa_supplicant/wpa_gui-qt4/peers.cpp b/wpa_supplicant/wpa_gui-qt4/peers.cpp
index 7a99299..f14cef4 100644
--- a/wpa_supplicant/wpa_gui-qt4/peers.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/peers.cpp
@@ -197,10 +197,9 @@ void Peers::enter_pin()
int peer_type = ctx_item->data(peer_role_type).toInt();
QString uuid;
QString addr;
+ addr = ctx_item->data(peer_role_address).toString();
if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE)
uuid = ctx_item->data(peer_role_uuid).toString();
- else
- addr = ctx_item->data(peer_role_address).toString();
StringQuery input(tr("PIN:"));
input.setWindowTitle(tr("PIN for ") + ctx_item->text());
@@ -212,9 +211,10 @@ void Peers::enter_pin()
size_t reply_len;
if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
- snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s",
+ snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
uuid.toAscii().constData(),
- input.get_string().toAscii().constData());
+ input.get_string().toAscii().constData(),
+ addr.toAscii().constData());
} else {
snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
addr.toAscii().constData(),
diff --git a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
index 2057d67..865b7b7 100644
--- a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
@@ -899,6 +899,15 @@ void WpaGui::processMsg(char *msg)
if (textStatus->text() == "INACTIVE" ||
textStatus->text() == "DISCONNECTED")
wpaguiTab->setCurrentWidget(wpsTab);
+ } else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_AUTH)) {
+ showTrayMessage(QSystemTrayIcon::Information, 3,
+ "Wi-Fi Protected Setup (WPS) AP\n"
+ "indicating this client is authorized.");
+ wpsStatusText->setText("WPS AP indicating this client is "
+ "authorized");
+ if (textStatus->text() == "INACTIVE" ||
+ textStatus->text() == "DISCONNECTED")
+ wpaguiTab->setCurrentWidget(wpsTab);
} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE)) {
wpsStatusText->setText(tr("WPS AP detected"));
} else if (str_match(pos, WPS_EVENT_OVERLAP)) {
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 92296fc..5a471f4 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -35,7 +35,9 @@
#include "wps_supplicant.h"
+#ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
#define WPS_PIN_SCAN_IGNORE_SEL_REG 3
+#endif /* WPS_PIN_SCAN_IGNORE_SEL_REG */
static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
@@ -966,12 +968,13 @@ int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
}
/*
- * Start with WPS APs that advertise active PIN Registrar and
- * allow any WPS AP after third scan since some APs do not set
- * Selected Registrar attribute properly when using external
- * Registrar.
+ * Start with WPS APs that advertise our address as an
+ * authorized MAC (v2.0) or active PIN Registrar (v1.0) and
+ * allow any WPS AP after couple of scans since some APs do not
+ * set Selected Registrar attribute properly when using
+ * external Registrar.
*/
- if (!wps_is_selected_pin_registrar(wps_ie)) {
+ if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG) {
wpa_printf(MSG_DEBUG, " skip - WPS AP "
"without active PIN Registrar");
@@ -981,7 +984,7 @@ int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, " selected based on WPS IE");
} else {
wpa_printf(MSG_DEBUG, " selected based on WPS IE "
- "(Active PIN)");
+ "(Authorized MAC or Active PIN)");
}
wpabuf_free(wps_ie);
return 1;
@@ -1013,7 +1016,7 @@ int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
} else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
wps_ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
if (wps_ie &&
- (wps_is_selected_pin_registrar(wps_ie) ||
+ (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) ||
wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
/* allow wildcard SSID for WPS PIN */
ret = 1;
@@ -1095,6 +1098,9 @@ void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s)
if (wps_is_selected_pbc_registrar(ie))
wpa_msg_ctrl(wpa_s, MSG_INFO,
WPS_EVENT_AP_AVAILABLE_PBC);
+ else if (wps_is_addr_authorized(ie, wpa_s->own_addr, 0))
+ wpa_msg_ctrl(wpa_s, MSG_INFO,
+ WPS_EVENT_AP_AVAILABLE_AUTH);
else if (wps_is_selected_pin_registrar(ie))
wpa_msg_ctrl(wpa_s, MSG_INFO,
WPS_EVENT_AP_AVAILABLE_PIN);
@@ -1164,8 +1170,8 @@ int wpas_wps_er_stop(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_WPS_ER
-int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const char *uuid,
- const char *pin)
+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;
@@ -1174,7 +1180,8 @@ int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const char *uuid,
any = 1;
else if (uuid_str2bin(uuid, u))
return -1;
- return wps_registrar_add_pin(wpa_s->wps->registrar, any ? NULL : u,
+ return wps_registrar_add_pin(wpa_s->wps->registrar, addr,
+ any ? NULL : u,
(const u8 *) pin, os_strlen(pin), 300);
}
diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h
index 5417c50..2bd6fa7 100644
--- a/wpa_supplicant/wps_supplicant.h
+++ b/wpa_supplicant/wps_supplicant.h
@@ -54,8 +54,8 @@ int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *pos,
char *end);
int wpas_wps_er_start(struct wpa_supplicant *wpa_s, const char *filter);
int wpas_wps_er_stop(struct wpa_supplicant *wpa_s);
-int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const char *uuid,
- const char *pin);
+int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const u8 *addr,
+ const char *uuid, const char *pin);
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);