aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hostapd/ctrl_iface.c20
-rw-r--r--hostapd/hostapd_cli.c26
-rw-r--r--hostapd/wps_hostapd.c12
-rw-r--r--hostapd/wps_hostapd.h2
-rw-r--r--src/wps/wps.h2
-rw-r--r--src/wps/wps_registrar.c98
6 files changed, 151 insertions, 9 deletions
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index e2df04f..6452952 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -1,6 +1,6 @@
/*
* hostapd / UNIX domain socket -based control interface
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -29,6 +29,7 @@
#include "ctrl_iface.h"
#include "sta_info.h"
#include "accounting.h"
+#include "wps_hostapd.h"
struct wpa_ctrl_dst {
@@ -218,6 +219,18 @@ static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
}
+#ifdef CONFIG_WPS
+static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
+{
+ char *pin = os_strchr(txt, ' ');
+ if (pin == NULL)
+ return -1;
+ *pin++ = '\0';
+ return hostapd_wps_add_pin(hapd, txt, pin);
+}
+#endif /* CONFIG_WPS */
+
+
static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
void *sock_ctx)
{
@@ -301,6 +314,11 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
} else if (os_strncmp(buf, "NEW_STA ", 8) == 0) {
if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))
reply_len = -1;
+#ifdef CONFIG_WPS
+ } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
+ if (hostapd_ctrl_iface_wps_pin(hapd, buf + 8))
+ reply_len = -1;
+#endif /* CONFIG_WPS */
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16;
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index ca68352..bd85513 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -1,6 +1,6 @@
/*
* hostapd - command line interface for hostapd daemon
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -22,7 +22,7 @@
static const char *hostapd_cli_version =
"hostapd_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> and contributors";
static const char *hostapd_cli_license =
@@ -83,6 +83,9 @@ static const char *commands_help =
" sta <addr> get MIB variables for one station\n"
" all_sta get MIB variables for all stations\n"
" new_sta <addr> add a new station\n"
+#ifdef CONFIG_WPS
+" wps_pin <uuid> <pin> add WPS Enrollee PIN (Device Password)\n"
+#endif /* CONFIG_WPS */
" help show this usage help\n"
" interface [ifname] show interfaces/select interface\n"
" level <debug level> change debug level\n"
@@ -230,6 +233,22 @@ static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
}
+#ifdef CONFIG_WPS
+static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char buf[64];
+ if (argc != 2) {
+ printf("Invalid 'wps_pin' command - exactly two arguments, "
+ "UUID and PIN, are required.\n");
+ return -1;
+ }
+ snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
+ return wpa_ctrl_command(ctrl, buf);
+}
+#endif /* CONFIG_WPS */
+
+
static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
char *addr, size_t addr_len)
{
@@ -378,6 +397,9 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
{ "sta", hostapd_cli_cmd_sta },
{ "all_sta", hostapd_cli_cmd_all_sta },
{ "new_sta", hostapd_cli_cmd_new_sta },
+#ifdef CONFIG_WPS
+ { "wps_pin", hostapd_cli_cmd_wps_pin },
+#endif /* CONFIG_WPS */
{ "help", hostapd_cli_cmd_help },
{ "interface", hostapd_cli_cmd_interface },
{ "level", hostapd_cli_cmd_level },
diff --git a/hostapd/wps_hostapd.c b/hostapd/wps_hostapd.c
index 5d6b2a9..9c64ffa 100644
--- a/hostapd/wps_hostapd.c
+++ b/hostapd/wps_hostapd.c
@@ -15,6 +15,7 @@
#include "includes.h"
#include "hostapd.h"
+#include "uuid.h"
#include "wps/wps.h"
#include "wps/wps_defs.h"
#include "wps_hostapd.h"
@@ -148,3 +149,14 @@ void hostapd_deinit_wps(struct hostapd_data *hapd)
{
wps_registrar_deinit(hapd->wps_registrar);
}
+
+
+int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid,
+ const char *pin)
+{
+ u8 u[UUID_LEN];
+ if (uuid_str2bin(uuid, u))
+ return -1;
+ return wps_registrar_add_pin(hapd->wps_registrar, u,
+ (const u8 *) pin, os_strlen(pin));
+}
diff --git a/hostapd/wps_hostapd.h b/hostapd/wps_hostapd.h
index 02d8a70..6497c75 100644
--- a/hostapd/wps_hostapd.h
+++ b/hostapd/wps_hostapd.h
@@ -20,6 +20,8 @@
int hostapd_init_wps(struct hostapd_data *hapd,
struct hostapd_bss_config *conf);
void hostapd_deinit_wps(struct hostapd_data *hapd);
+int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid,
+ const char *pin);
#else /* CONFIG_WPS */
diff --git a/src/wps/wps.h b/src/wps/wps.h
index dbde71f..c4459b5 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -66,5 +66,7 @@ struct wps_registrar_config {
struct wps_registrar *
wps_registrar_init(const struct wps_registrar_config *cfg);
void wps_registrar_deinit(struct wps_registrar *reg);
+int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
+ const u8 *pin, size_t pin_len);
#endif /* WPS_H */
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index 30b78b3..c2104ad 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -19,6 +19,34 @@
#include "wps_i.h"
+struct wps_uuid_pin {
+ struct wps_uuid_pin *next;
+ u8 uuid[WPS_UUID_LEN];
+ u8 *pin;
+ size_t pin_len;
+};
+
+
+static void wps_free_pin(struct wps_uuid_pin *pin)
+{
+ os_free(pin->pin);
+ os_free(pin);
+}
+
+
+static void wps_free_pins(struct wps_uuid_pin *pins)
+{
+ struct wps_uuid_pin *pin, *prev;
+
+ pin = pins;
+ while (pin) {
+ prev = pin;
+ pin = pin->next;
+ wps_free_pin(prev);
+ }
+}
+
+
struct wps_registrar {
int wps_state;
u8 uuid[WPS_UUID_LEN];
@@ -32,6 +60,8 @@ struct wps_registrar {
int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
size_t psk_len);
void *cb_ctx;
+
+ struct wps_uuid_pin *pins;
};
@@ -78,10 +108,57 @@ void wps_registrar_deinit(struct wps_registrar *reg)
if (reg == NULL)
return;
os_free(reg->network_key);
+ wps_free_pins(reg->pins);
os_free(reg);
}
+int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
+ const u8 *pin, size_t pin_len)
+{
+ struct wps_uuid_pin *p;
+
+ p = os_zalloc(sizeof(*p));
+ if (p == NULL)
+ return -1;
+ os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
+ p->pin = os_malloc(pin_len);
+ if (p->pin == NULL) {
+ os_free(p);
+ return -1;
+ }
+ os_memcpy(p->pin, pin, pin_len);
+ p->pin_len = pin_len;
+
+ p->next = reg->pins;
+ reg->pins = p;
+
+ wpa_printf(MSG_DEBUG, "WPS: A new PIN configured");
+ wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
+ wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
+
+ return 0;
+}
+
+
+static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
+ const u8 *uuid, size_t *pin_len)
+{
+ struct wps_uuid_pin *pin;
+
+ pin = reg->pins;
+ while (pin) {
+ if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
+ *pin_len = pin->pin_len;
+ return pin->pin;
+ }
+ pin = pin->next;
+ }
+
+ return NULL;
+}
+
+
static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
const u8 *psk, size_t psk_len)
{
@@ -94,17 +171,26 @@ static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
static int wps_get_dev_password(struct wps_data *wps)
{
+ const u8 *pin;
+ size_t pin_len;
+
os_free(wps->dev_password);
wps->dev_password = NULL;
- /* TODO: callback to request Device Password */
- if (1) {
- wps->dev_password = (u8 *) os_strdup("12345670");
- wps->dev_password_len = 8;
- return 0;
+ pin = wps_registrar_get_pin(wps->registrar, wps->uuid_e, &pin_len);
+ if (pin == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
+ "the Enrollee");
+ return -1;
}
- return -1;
+ wps->dev_password = os_malloc(pin_len);
+ if (wps->dev_password == NULL)
+ return -1;
+ os_memcpy(wps->dev_password, pin, pin_len);
+ wps->dev_password_len = pin_len;
+
+ return 0;
}