aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-04-21 13:45:16 (GMT)
committerJouni Malinen <j@w1.fi>2009-04-21 13:45:16 (GMT)
commit3ec97afe571f159ea95213262c1c6b89965827d4 (patch)
tree88828514155a3f5052505716d8bdcdb67796f6aa /wpa_supplicant
parenta8d6ffa48f52648f344a06976303410bc7256e0f (diff)
downloadhostap-3ec97afe571f159ea95213262c1c6b89965827d4.zip
hostap-3ec97afe571f159ea95213262c1c6b89965827d4.tar.gz
hostap-3ec97afe571f159ea95213262c1c6b89965827d4.tar.bz2
wpa_supplicant AP: Add preliminary support for WPS Internal Registrar
When in AP mode, wpa_supplicant is now enabling WPS (only Internal Registrar). wpa_cli wps_pbc and wps_pin commands can be used to initiate WPS negotiation similarly to how this is done in station mode (though, the BSSID parameter is ignored).
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/ap.c41
-rw-r--r--wpa_supplicant/ap.h3
-rw-r--r--wpa_supplicant/ctrl_iface.c21
-rw-r--r--wpa_supplicant/wpa_supplicant.c15
4 files changed, 75 insertions, 5 deletions
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 684ec85..999d7e0 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -21,9 +21,11 @@
#ifdef NEED_MLME
#include "../hostapd/ieee802_11.h"
#endif /* NEED_MLME */
+#include "../hostapd/wps_hostapd.h"
#include "eap_common/eap_defs.h"
#include "eap_server/eap_methods.h"
#include "eap_common/eap_wsc_common.h"
+#include "wps/wps.h"
#include "config_ssid.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
@@ -382,6 +384,17 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
else
bss->ssid.security_policy = SECURITY_PLAINTEXT;
+#ifdef CONFIG_WPS
+ /*
+ * Enable WPS by default, but require user interaction to actually use
+ * it. Only the internal Registrar is supported.
+ */
+ bss->eap_server = 1;
+ bss->wps_state = 2;
+ bss->ap_setup_locked = 1;
+ bss->config_methods = os_strdup("display push_button");
+#endif /* CONFIG_WPS */
+
return 0;
}
@@ -507,3 +520,31 @@ void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
{
hostapd_eapol_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
}
+
+
+#ifdef CONFIG_WPS
+
+int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+ return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0]);
+}
+
+
+int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
+ const char *pin, char *buf, size_t buflen)
+{
+ int ret, ret_len = 0;
+
+ if (pin == NULL) {
+ unsigned int rpin = wps_generate_pin();
+ ret_len = os_snprintf(buf, buflen, "%d", rpin);
+ pin = buf;
+ }
+
+ ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], "any", pin);
+ if (ret)
+ return -1;
+ return ret_len;
+}
+
+#endif /* CONFIG_WPS */
diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h
index 782c53a..935dba1 100644
--- a/wpa_supplicant/ap.h
+++ b/wpa_supplicant/ap.h
@@ -21,5 +21,8 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s);
void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
const u8 *src_addr, const u8 *buf, size_t len);
+int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid);
+int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
+ const char *pin, char *buf, size_t buflen);
#endif /* AP_H */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index a7536d3..08121b6 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -31,6 +31,7 @@
#include "wps_supplicant.h"
#include "wps/wps.h"
#include "ibss_rsn.h"
+#include "ap.h"
extern struct wpa_driver_ops *wpa_drivers[];
@@ -150,18 +151,22 @@ static int wpa_supplicant_ctrl_iface_ft_ds(
static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
char *cmd)
{
- u8 bssid[ETH_ALEN];
+ u8 bssid[ETH_ALEN], *_bssid = bssid;
if (cmd == NULL || os_strcmp(cmd, "any") == 0)
- return wpas_wps_start_pbc(wpa_s, NULL);
-
- if (hwaddr_aton(cmd, bssid)) {
+ _bssid = NULL;
+ else if (hwaddr_aton(cmd, bssid)) {
wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
cmd);
return -1;
}
- return wpas_wps_start_pbc(wpa_s, bssid);
+#ifdef CONFIG_AP
+ if (wpa_s->ap_iface)
+ return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid);
+#endif /* CONFIG_AP */
+
+ return wpas_wps_start_pbc(wpa_s, _bssid);
}
@@ -185,6 +190,12 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
return -1;
}
+#ifdef CONFIG_AP
+ if (wpa_s->ap_iface)
+ return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
+ buf, buflen);
+#endif /* CONFIG_AP */
+
if (pin) {
ret = wpas_wps_start_pin(wpa_s, _bssid, pin);
if (ret < 0)
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 7804f7b..723e2ed 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -21,6 +21,7 @@
#include "common.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "eap_peer/eap.h"
+#include "eap_server/eap_methods.h"
#include "wpa.h"
#include "eloop.h"
#include "config.h"
@@ -2118,6 +2119,17 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
return NULL;
}
+#ifdef CONFIG_AP
+ ret = eap_server_register_methods();
+ if (ret) {
+ wpa_printf(MSG_ERROR, "Failed to register EAP server methods");
+ if (ret == -2)
+ wpa_printf(MSG_ERROR, "Two or more EAP methods used "
+ "the same EAP type.");
+ return NULL;
+ }
+#endif /* CONFIG_AP */
+
global = os_zalloc(sizeof(*global));
if (global == NULL)
return NULL;
@@ -2241,6 +2253,9 @@ void wpa_supplicant_deinit(struct wpa_global *global)
wpa_supplicant_dbus_ctrl_iface_deinit(global->dbus_ctrl_iface);
eap_peer_unregister_methods();
+#ifdef CONFIG_AP
+ eap_server_unregister_methods();
+#endif /* CONFIG_AP */
for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
if (!global->drv_priv[i])