aboutsummaryrefslogtreecommitdiffstats
path: root/hostapd
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2010-09-23 17:30:52 (GMT)
committerJouni Malinen <j@w1.fi>2010-09-23 17:30:52 (GMT)
commit3981cb3cb81641813b1f51292032f2225ccdd70b (patch)
treebf6e7f50a8fcddc8b7e16ccc1fe4923464f51b68 /hostapd
parentfa37511fa7e9d6a8f4fdaa8ec2df4af71bac7941 (diff)
downloadhostap-3981cb3cb81641813b1f51292032f2225ccdd70b.zip
hostap-3981cb3cb81641813b1f51292032f2225ccdd70b.tar.gz
hostap-3981cb3cb81641813b1f51292032f2225ccdd70b.tar.bz2
WPS: Add wps_check_pin command for processing PIN from user input
UIs can use this command to process a PIN entered by a user and to validate the checksum digit (if present).
Diffstat (limited to 'hostapd')
-rw-r--r--hostapd/README-WPS7
-rw-r--r--hostapd/ctrl_iface.c49
-rw-r--r--hostapd/hostapd_cli.c28
3 files changed, 84 insertions, 0 deletions
diff --git a/hostapd/README-WPS b/hostapd/README-WPS
index 64561d0..63b62a5 100644
--- a/hostapd/README-WPS
+++ b/hostapd/README-WPS
@@ -120,6 +120,13 @@ pushbutton event (for PBC) to allow a new WPS Enrollee to join the
network. hostapd uses the control interface as an input channel for
these events.
+The PIN value used in the commands must be processed by an UI to
+remove non-digit characters and potentially, to verify the checksum
+digit. "hostapd_cli wps_check_pin <PIN>" can be used to do such
+processing. It returns FAIL if the PIN is invalid, or FAIL-CHECKSUM if
+the checksum digit is incorrect, or the processed PIN (non-digit
+characters removed) if the PIN is valid.
+
When a client device (WPS Enrollee) connects to hostapd (WPS
Registrar) in order to start PIN mode negotiation for WPS, an
identifier (Enrollee UUID) is sent. hostapd will need to be configured
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index bd25e1c..7f628f1 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -35,6 +35,7 @@
#include "ap/wps_hostapd.h"
#include "ap/ctrl_iface_ap.h"
#include "wps/wps_defs.h"
+#include "wps/wps.h"
#include "ctrl_iface.h"
@@ -369,6 +370,51 @@ static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
}
+static int hostapd_ctrl_iface_wps_check_pin(
+ struct hostapd_data *hapd, char *cmd, char *buf, size_t buflen)
+{
+ char pin[9];
+ size_t len;
+ char *pos;
+ int ret;
+
+ wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
+ (u8 *) cmd, os_strlen(cmd));
+ for (pos = cmd, len = 0; *pos != '\0'; pos++) {
+ if (*pos < '0' || *pos > '9')
+ continue;
+ pin[len++] = *pos;
+ if (len == 9) {
+ wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
+ return -1;
+ }
+ }
+ if (len != 4 && len != 8) {
+ wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
+ return -1;
+ }
+ pin[len] = '\0';
+
+ if (len == 8) {
+ unsigned int pin_val;
+ pin_val = atoi(pin);
+ if (!wps_pin_valid(pin_val)) {
+ wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
+ ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
+ if (ret < 0 || (size_t) ret >= buflen)
+ return -1;
+ return ret;
+ }
+ }
+
+ ret = os_snprintf(buf, buflen, "%s", pin);
+ if (ret < 0 || (size_t) ret >= buflen)
+ return -1;
+
+ return ret;
+}
+
+
#ifdef CONFIG_WPS_OOB
static int hostapd_ctrl_iface_wps_oob(struct hostapd_data *hapd, char *txt)
{
@@ -589,6 +635,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
} else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
if (hostapd_ctrl_iface_wps_pin(hapd, buf + 8))
reply_len = -1;
+ } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
+ reply_len = hostapd_ctrl_iface_wps_check_pin(
+ hapd, buf + 14, reply, reply_size);
} else if (os_strcmp(buf, "WPS_PBC") == 0) {
if (hostapd_wps_button_pushed(hapd))
reply_len = -1;
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index e80de48..5ca793b 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -90,6 +90,7 @@ static const char *commands_help =
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WPS
" wps_pin <uuid> <pin> [timeout] [addr] add WPS Enrollee PIN\n"
+" wps_check_pin <PIN> verify PIN checksum\n"
" wps_pbc indicate button pushed to initiate PBC\n"
#ifdef CONFIG_WPS_OOB
" wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
@@ -370,6 +371,32 @@ static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
}
+static int hostapd_cli_cmd_wps_check_pin(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char cmd[256];
+ int res;
+
+ if (argc != 1 && argc != 2) {
+ printf("Invalid WPS_CHECK_PIN command: needs one argument:\n"
+ "- PIN to be verified\n");
+ return -1;
+ }
+
+ if (argc == 2)
+ res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s %s",
+ argv[0], argv[1]);
+ else
+ res = os_snprintf(cmd, sizeof(cmd), "WPS_CHECK_PIN %s",
+ argv[0]);
+ if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+ printf("Too long WPS_CHECK_PIN command.\n");
+ return -1;
+ }
+ return wpa_ctrl_command(ctrl, cmd);
+}
+
+
static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
@@ -608,6 +635,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WPS
{ "wps_pin", hostapd_cli_cmd_wps_pin },
+ { "wps_check_pin", hostapd_cli_cmd_wps_check_pin },
{ "wps_pbc", hostapd_cli_cmd_wps_pbc },
#ifdef CONFIG_WPS_OOB
{ "wps_oob", hostapd_cli_cmd_wps_oob },