/*
* hostapd / UNIX domain socket -based control interface
- * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
#endif /* CONFIG_WPS_OOB */
+#ifdef CONFIG_WPS_NFC
+static int hostapd_ctrl_iface_wps_nfc_tag_read(struct hostapd_data *hapd,
+ char *pos)
+{
+ size_t len;
+ struct wpabuf *buf;
+ int ret;
+
+ len = os_strlen(pos);
+ if (len & 0x01)
+ return -1;
+ len /= 2;
+
+ buf = wpabuf_alloc(len);
+ if (buf == NULL)
+ return -1;
+ if (hexstr2bin(pos, wpabuf_put(buf, len), len) < 0) {
+ wpabuf_free(buf);
+ return -1;
+ }
+
+ ret = hostapd_wps_nfc_tag_read(hapd, buf);
+ wpabuf_free(buf);
+
+ return ret;
+}
+#endif /* CONFIG_WPS_NFC */
+
+
static int hostapd_ctrl_iface_wps_ap_pin(struct hostapd_data *hapd, char *txt,
char *buf, size_t buflen)
{
} else if (os_strncmp(buf, "WPS_CONFIG ", 11) == 0) {
if (hostapd_ctrl_iface_wps_config(hapd, buf + 11) < 0)
reply_len = -1;
+#ifdef CONFIG_WPS_NFC
+ } else if (os_strncmp(buf, "WPS_NFC_TAG_READ ", 17) == 0) {
+ if (hostapd_ctrl_iface_wps_nfc_tag_read(hapd, buf + 17))
+ reply_len = -1;
+#endif /* CONFIG_WPS_NFC */
#endif /* CONFIG_WPS */
} else if (os_strncmp(buf, "ESS_DISASSOC ", 13) == 0) {
if (hostapd_ctrl_iface_ess_disassoc(hapd, buf + 13))
/*
* hostapd - command line interface for hostapd daemon
- * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
#ifdef CONFIG_WPS_OOB
" wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
#endif /* CONFIG_WPS_OOB */
+#ifdef CONFIG_WPS_NFC
+" wps_nfc_tag_read <hexdump> report read NFC tag with WPS data\n"
+#endif /* CONFIG_WPS_NFC */
" wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
" wps_config <SSID> <auth> <encr> <key> configure AP\n"
#endif /* CONFIG_WPS */
#endif /* CONFIG_WPS_OOB */
+#ifdef CONFIG_WPS_NFC
+static int hostapd_cli_cmd_wps_nfc_tag_read(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ int ret;
+ char *buf;
+ size_t buflen;
+
+ if (argc != 1) {
+ printf("Invalid 'wps_nfc_tag_read' command - one argument "
+ "is required.\n");
+ return -1;
+ }
+
+ buflen = 18 + os_strlen(argv[0]);
+ buf = os_malloc(buflen);
+ if (buf == NULL)
+ return -1;
+ os_snprintf(buf, buflen, "WPS_NFC_TAG_READ %s", argv[0]);
+
+ ret = wpa_ctrl_command(ctrl, buf);
+ os_free(buf);
+
+ return ret;
+}
+#endif /* CONFIG_WPS_NFC */
+
+
static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
#ifdef CONFIG_WPS_OOB
{ "wps_oob", hostapd_cli_cmd_wps_oob },
#endif /* CONFIG_WPS_OOB */
+#ifdef CONFIG_WPS_NFC
+ { "wps_nfc_tag_read", hostapd_cli_cmd_wps_nfc_tag_read },
+#endif /* CONFIG_WPS_NFC */
{ "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
{ "wps_config", hostapd_cli_cmd_wps_config },
#endif /* CONFIG_WPS */
/*
* hostapd / WPS integration
- * Copyright (c) 2008-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
#include "wps/wps.h"
#include "wps/wps_defs.h"
#include "wps/wps_dev_attr.h"
+#include "wps/wps_attr_parse.h"
#include "hostapd.h"
#include "ap_config.h"
#include "ap_drv_ops.h"
return wps_registrar_config_ap(hapd->wps->registrar, &cred);
}
+
+
+#ifdef CONFIG_WPS_NFC
+
+struct wps_nfc_password_token_data {
+ const u8 *oob_dev_pw;
+ size_t oob_dev_pw_len;
+ int added;
+};
+
+
+static int wps_add_nfc_password_token(struct hostapd_data *hapd, void *ctx)
+{
+ struct wps_nfc_password_token_data *data = ctx;
+ int ret;
+
+ if (hapd->wps == NULL)
+ return 0;
+ ret = wps_registrar_add_nfc_password_token(hapd->wps->registrar,
+ data->oob_dev_pw,
+ data->oob_dev_pw_len);
+ if (ret == 0)
+ data->added++;
+ return ret;
+}
+
+
+static int hostapd_wps_add_nfc_password_token(struct hostapd_data *hapd,
+ struct wps_parse_attr *attr)
+{
+ struct wps_nfc_password_token_data data;
+
+ data.oob_dev_pw = attr->oob_dev_password;
+ data.oob_dev_pw_len = attr->oob_dev_password_len;
+ data.added = 0;
+ if (hostapd_wps_for_each(hapd, wps_add_nfc_password_token, &data) < 0)
+ return -1;
+ return data.added ? 0 : -1;
+}
+
+
+static int hostapd_wps_nfc_tag_process(struct hostapd_data *hapd,
+ const struct wpabuf *wps)
+{
+ struct wps_parse_attr attr;
+
+ wpa_hexdump_buf(MSG_DEBUG, "WPS: Received NFC tag payload", wps);
+
+ if (wps_parse_msg(wps, &attr)) {
+ wpa_printf(MSG_DEBUG, "WPS: Ignore invalid data from NFC tag");
+ return -1;
+ }
+
+ if (attr.oob_dev_password)
+ return hostapd_wps_add_nfc_password_token(hapd, &attr);
+
+ wpa_printf(MSG_DEBUG, "WPS: Ignore unrecognized NFC tag");
+ return -1;
+}
+
+
+int hostapd_wps_nfc_tag_read(struct hostapd_data *hapd,
+ const struct wpabuf *data)
+{
+ const struct wpabuf *wps = data;
+ struct wpabuf *tmp = NULL;
+ int ret;
+
+ if (wpabuf_len(data) < 4)
+ return -1;
+
+ if (*wpabuf_head_u8(data) != 0x10) {
+ /* Assume this contains full NDEF record */
+ tmp = ndef_parse_wifi(data);
+ if (tmp == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS: Could not parse NDEF");
+ return -1;
+ }
+ wps = tmp;
+ }
+
+ ret = hostapd_wps_nfc_tag_process(hapd, wps);
+ wpabuf_free(tmp);
+ return ret;
+}
+
+#endif /* CONFIG_WPS_NFC */
/*
* hostapd / WPS integration
- * Copyright (c) 2008-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
void hostapd_wps_update_ie(struct hostapd_data *hapd);
int hostapd_wps_config_ap(struct hostapd_data *hapd, const char *ssid,
const char *auth, const char *encr, const char *key);
+int hostapd_wps_nfc_tag_read(struct hostapd_data *hapd,
+ const struct wpabuf *data);
#else /* CONFIG_WPS */
/*
* Wi-Fi Protected Setup
- * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
char *buf, size_t buflen);
int wps_registrar_config_ap(struct wps_registrar *reg,
struct wps_credential *cred);
+int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
+ const u8 *oob_dev_pw,
+ size_t oob_dev_pw_len);
int wps_build_credential_wrap(struct wpabuf *msg,
const struct wps_credential *cred);
/*
* Wi-Fi Protected Setup - Registrar
- * Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
return -1;
}
+
+
+#ifdef CONFIG_WPS_NFC
+int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
+ const u8 *oob_dev_pw,
+ size_t oob_dev_pw_len)
+{
+ const u8 *pos, *hash, *dev_pw;
+ u16 id;
+ size_t dev_pw_len;
+
+ if (oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
+ WPS_OOB_DEVICE_PASSWORD_MIN_LEN ||
+ oob_dev_pw_len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
+ WPS_OOB_DEVICE_PASSWORD_LEN)
+ return -1;
+
+ hash = oob_dev_pw;
+ pos = oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN;
+ id = WPA_GET_BE16(pos);
+ dev_pw = pos + 2;
+ dev_pw_len = oob_dev_pw + oob_dev_pw_len - dev_pw;
+
+ wpa_printf(MSG_DEBUG, "WPS: Add NFC Password Token for Password ID %u",
+ id);
+
+ wpa_hexdump(MSG_DEBUG, "WPS: Public Key Hash",
+ hash, WPS_OOB_PUBKEY_HASH_LEN);
+ wpa_hexdump_key(MSG_DEBUG, "WPS: Device Password", dev_pw, dev_pw_len);
+
+ reg->wps->oob_dev_pw_id = id;
+ wpabuf_free(reg->wps->oob_conf.pubkey_hash);
+ reg->wps->oob_conf.pubkey_hash = wpabuf_alloc_copy(
+ hash, WPS_OOB_PUBKEY_HASH_LEN);
+ if (reg->wps->oob_conf.pubkey_hash == NULL)
+ return -1;
+ return wps_registrar_add_pin(reg, NULL, NULL, dev_pw, dev_pw_len, 300);
+}
+#endif /* CONFIG_WPS_NFC */