WPS: Add support for NFC out-of-band mechanism
The new file wps_nfc.c and ndef.c implements NFC device independent operation, wps_nfc_pn531.c implements NFC device dependent operation. This patch is only for the following use case: - Enrollee = wpa_supplicant - Registrar = hostapd internal Registrar Following NFC methods can be used: - Enrollee PIN with NFC - Registrar PIN with NFC - unencrypted credential with NFC Encrypted credentials are not supported. Enrollee side operation: Registrar side operation: Example configuration. CONFIG_WPS=y CONFIG_WPS_NFC=y CONFIG_WPS_NFC_PN531=y I used NFC device "NXP PN531". The NFC device access method is confidential, so I used outer library. Please download below files from https://www.saice-wpsnfc.bz/index.php [WPS NFC Library] WpsNfcLibrary/WpsNfc.h WpsNfcLibrary/WpsNfcType.h WpsNfcLibrary/WpsNfcVersion.h WpsNfcLibrary/linux/libnfc_mapping_pn53x.dll WpsNfcLibrary/linux/wpsnfc.dll [NFC Reader/Writer Kernel Driver] NFCKernelDriver-1.0.3/linux/kobj/sonyrw.ko <WiFi test> The hostapd/wpa_supplicant with this patch passed below tests on "Wi-Fi WPS Test Plan Version 1.6". 4.2.5 Add device using NFC Method with password token (I used SONY STA instead of NXP STA.) 4.2.6 Add device using NFC Method with configuration token 5.1.9 Add to AP using NFC Method with password token through internal registrar (I used SONY AP instead of NXP AP.) 5.1.10 Add to AP using NFC Method with configuration token through internal registrar
This commit is contained in:
parent
7cc1b6c900
commit
e1ee6b600b
19 changed files with 523 additions and 25 deletions
|
@ -324,6 +324,21 @@ OBJS += ../src/wps/wps_ufd.o
|
||||||
NEED_WPS_OOB=y
|
NEED_WPS_OOB=y
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_WPS_NFC
|
||||||
|
CFLAGS += -DCONFIG_WPS_NFC
|
||||||
|
OBJS += ../src/wps/ndef.o
|
||||||
|
OBJS += ../src/wps/wps_nfc.o
|
||||||
|
NEED_WPS_OOB=y
|
||||||
|
ifdef CONFIG_WPS_NFC_PN531
|
||||||
|
PN531_PATH = /usr/local/src/nfc
|
||||||
|
CFLAGS += -DCONFIG_WPS_NFC_PN531
|
||||||
|
CFLAGS += -I${PN531_PATH}/inc
|
||||||
|
OBJS += ../src/wps/wps_nfc_pn531.o
|
||||||
|
LIBS += ${PN531_PATH}/lib/wpsnfc.dll
|
||||||
|
LIBS += ${PN531_PATH}/lib/libnfc_mapping_pn53x.dll
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef NEED_WPS_OOB
|
ifdef NEED_WPS_OOB
|
||||||
CFLAGS += -DCONFIG_WPS_OOB
|
CFLAGS += -DCONFIG_WPS_OOB
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -257,7 +257,7 @@ static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
|
||||||
#ifdef CONFIG_WPS_OOB
|
#ifdef CONFIG_WPS_OOB
|
||||||
static int hostapd_ctrl_iface_wps_oob(struct hostapd_data *hapd, char *txt)
|
static int hostapd_ctrl_iface_wps_oob(struct hostapd_data *hapd, char *txt)
|
||||||
{
|
{
|
||||||
char *path, *method;
|
char *path, *method, *name;
|
||||||
|
|
||||||
path = os_strchr(txt, ' ');
|
path = os_strchr(txt, ' ');
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
|
@ -269,7 +269,11 @@ static int hostapd_ctrl_iface_wps_oob(struct hostapd_data *hapd, char *txt)
|
||||||
return -1;
|
return -1;
|
||||||
*method++ = '\0';
|
*method++ = '\0';
|
||||||
|
|
||||||
return hostapd_wps_start_oob(hapd, txt, path, method);
|
name = os_strchr(method, ' ');
|
||||||
|
if (name != NULL)
|
||||||
|
*name++ = '\0';
|
||||||
|
|
||||||
|
return hostapd_wps_start_oob(hapd, txt, path, method, name);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_WPS_OOB */
|
#endif /* CONFIG_WPS_OOB */
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
|
|
@ -287,17 +287,24 @@ static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
|
||||||
char cmd[256];
|
char cmd[256];
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3 && argc != 4) {
|
||||||
printf("Invalid WPS_OOB command: need three arguments:\n"
|
printf("Invalid WPS_OOB command: need three or four "
|
||||||
"- OOB_DEV_TYPE: use 'ufd'\n"
|
"arguments:\n"
|
||||||
"- OOB_PATH: path of OOB device like '/mnt'\n"
|
"- DEV_TYPE: use 'ufd' or 'nfc'\n"
|
||||||
"- OOB_METHOD: OOB method 'pin-e' or 'pin-r', "
|
"- PATH: path of OOB device like '/mnt'\n"
|
||||||
"'cred'\n");
|
"- METHOD: OOB method 'pin-e' or 'pin-r', "
|
||||||
|
"'cred'\n"
|
||||||
|
"- DEV_NAME: (only for NFC) device name like "
|
||||||
|
"'pn531'\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
|
if (argc == 3)
|
||||||
argv[0], argv[1], argv[2]);
|
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2]);
|
||||||
|
else
|
||||||
|
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2], argv[3]);
|
||||||
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||||
printf("Too long WPS_OOB command.\n");
|
printf("Too long WPS_OOB command.\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -706,7 +706,7 @@ int hostapd_wps_button_pushed(struct hostapd_data *hapd)
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_OOB
|
#ifdef CONFIG_WPS_OOB
|
||||||
int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type,
|
int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type,
|
||||||
char *path, char *method)
|
char *path, char *method, char *name)
|
||||||
{
|
{
|
||||||
struct wps_context *wps = hapd->wps;
|
struct wps_context *wps = hapd->wps;
|
||||||
struct oob_device_data *oob_dev;
|
struct oob_device_data *oob_dev;
|
||||||
|
@ -715,6 +715,7 @@ int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type,
|
||||||
if (oob_dev == NULL)
|
if (oob_dev == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
oob_dev->device_path = path;
|
oob_dev->device_path = path;
|
||||||
|
oob_dev->device_name = name;
|
||||||
wps->oob_conf.oob_method = wps_get_oob_method(method);
|
wps->oob_conf.oob_method = wps_get_oob_method(method);
|
||||||
|
|
||||||
if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) {
|
if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid,
|
||||||
const char *pin);
|
const char *pin);
|
||||||
int hostapd_wps_button_pushed(struct hostapd_data *hapd);
|
int hostapd_wps_button_pushed(struct hostapd_data *hapd);
|
||||||
int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type,
|
int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type,
|
||||||
char *path, char *method);
|
char *path, char *method, char *name);
|
||||||
void hostapd_wps_probe_req_rx(struct hostapd_data *hapd, const u8 *addr,
|
void hostapd_wps_probe_req_rx(struct hostapd_data *hapd, const u8 *addr,
|
||||||
const u8 *ie, size_t ie_len);
|
const u8 *ie, size_t ie_len);
|
||||||
|
|
||||||
|
|
174
src/wps/ndef.c
Normal file
174
src/wps/ndef.c
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
* NDEF(NFC Data Exchange Format) routines for Wi-Fi Protected Setup
|
||||||
|
* Reference is "NFCForum-TS-NDEF_1.0 2006-07-24".
|
||||||
|
* Copyright (c) 2009, Masashi Honma <honma@ictec.co.jp>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Alternatively, this software may be distributed under the terms of BSD
|
||||||
|
* license.
|
||||||
|
*
|
||||||
|
* See README and COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "wps/wps.h"
|
||||||
|
|
||||||
|
#define FLAG_MESSAGE_BEGIN (1 << 7)
|
||||||
|
#define FLAG_MESSAGE_END (1 << 6)
|
||||||
|
#define FLAG_CHUNK (1 << 5)
|
||||||
|
#define FLAG_SHORT_RECORD (1 << 4)
|
||||||
|
#define FLAG_ID_LENGTH_PRESENT (1 << 3)
|
||||||
|
#define FLAG_TNF_RFC2046 (0x02)
|
||||||
|
|
||||||
|
struct ndef_record {
|
||||||
|
u8 *type;
|
||||||
|
u8 *id;
|
||||||
|
u8 *payload;
|
||||||
|
u8 type_length;
|
||||||
|
u8 id_length;
|
||||||
|
u32 payload_length;
|
||||||
|
u32 total_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
static char wifi_handover_type[] = "application/vnd.wfa.wsc";
|
||||||
|
|
||||||
|
static int ndef_parse_record(u8 *data, u32 size, struct ndef_record *record)
|
||||||
|
{
|
||||||
|
u8 *pos = data + 1;
|
||||||
|
|
||||||
|
if (size < 2)
|
||||||
|
return -1;
|
||||||
|
record->type_length = *pos++;
|
||||||
|
if (data[0] & FLAG_SHORT_RECORD) {
|
||||||
|
if (size < 3)
|
||||||
|
return -1;
|
||||||
|
record->payload_length = *pos++;
|
||||||
|
} else {
|
||||||
|
if (size < 6)
|
||||||
|
return -1;
|
||||||
|
record->payload_length = ntohl(*(u32 *)pos);
|
||||||
|
pos += sizeof(u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data[0] & FLAG_ID_LENGTH_PRESENT) {
|
||||||
|
if ((int) size < pos - data + 1)
|
||||||
|
return -1;
|
||||||
|
record->id_length = *pos++;
|
||||||
|
} else
|
||||||
|
record->id_length = 0;
|
||||||
|
|
||||||
|
record->type = record->type_length == 0 ? NULL : pos;
|
||||||
|
pos += record->type_length;
|
||||||
|
|
||||||
|
record->id = record->id_length == 0 ? NULL : pos;
|
||||||
|
pos += record->id_length;
|
||||||
|
|
||||||
|
record->payload = record->payload_length == 0 ? NULL : pos;
|
||||||
|
pos += record->payload_length;
|
||||||
|
|
||||||
|
record->total_length = pos - data;
|
||||||
|
if (record->total_length > size)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct wpabuf * ndef_parse_records(struct wpabuf *buf,
|
||||||
|
int (*filter)(struct ndef_record *))
|
||||||
|
{
|
||||||
|
struct ndef_record record;
|
||||||
|
int len = wpabuf_len(buf);
|
||||||
|
u8 *data = wpabuf_mhead(buf);
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
if (ndef_parse_record(data, len, &record) < 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "NDEF : Failed to parse");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (filter == NULL || filter(&record))
|
||||||
|
return wpabuf_alloc_copy(record.payload,
|
||||||
|
record.payload_length);
|
||||||
|
data += record.total_length;
|
||||||
|
len -= record.total_length;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_ERROR, "NDEF : Record not found");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct wpabuf * ndef_build_record(u8 flags, void *type,
|
||||||
|
u8 type_length, void *id,
|
||||||
|
u8 id_length, void *payload,
|
||||||
|
u32 payload_length)
|
||||||
|
{
|
||||||
|
struct wpabuf *record;
|
||||||
|
size_t total_len;
|
||||||
|
int short_record;
|
||||||
|
u8 local_flag;
|
||||||
|
|
||||||
|
short_record = payload_length < 256 ? 1 : 0;
|
||||||
|
|
||||||
|
total_len = 2; /* flag + type length */
|
||||||
|
/* payload length */
|
||||||
|
total_len += short_record ? sizeof(u8) : sizeof(u32);
|
||||||
|
if (id_length > 0)
|
||||||
|
total_len += 1;
|
||||||
|
total_len += type_length + id_length + payload_length;
|
||||||
|
record = wpabuf_alloc(total_len);
|
||||||
|
if (record == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "NDEF : Failed to allocate "
|
||||||
|
"record for build");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
local_flag = flags;
|
||||||
|
if (id_length > 0)
|
||||||
|
local_flag |= FLAG_ID_LENGTH_PRESENT;
|
||||||
|
if (short_record)
|
||||||
|
local_flag |= FLAG_SHORT_RECORD;
|
||||||
|
wpabuf_put_u8(record, local_flag);
|
||||||
|
|
||||||
|
wpabuf_put_u8(record, type_length);
|
||||||
|
|
||||||
|
if (short_record)
|
||||||
|
wpabuf_put_u8(record, payload_length);
|
||||||
|
else
|
||||||
|
wpabuf_put_be32(record, payload_length);
|
||||||
|
|
||||||
|
if (id_length > 0)
|
||||||
|
wpabuf_put_u8(record, id_length);
|
||||||
|
wpabuf_put_data(record, type, type_length);
|
||||||
|
wpabuf_put_data(record, id, id_length);
|
||||||
|
wpabuf_put_data(record, payload, payload_length);
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wifi_filter(struct ndef_record *record)
|
||||||
|
{
|
||||||
|
if (record->type_length != os_strlen(wifi_handover_type))
|
||||||
|
return 0;
|
||||||
|
if (os_memcmp(record->type, wifi_handover_type,
|
||||||
|
os_strlen(wifi_handover_type)) != 0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct wpabuf * ndef_parse_wifi(struct wpabuf *buf)
|
||||||
|
{
|
||||||
|
return ndef_parse_records(buf, wifi_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct wpabuf * ndef_build_wifi(struct wpabuf *buf)
|
||||||
|
{
|
||||||
|
return ndef_build_record(FLAG_MESSAGE_BEGIN | FLAG_MESSAGE_END |
|
||||||
|
FLAG_TNF_RFC2046, wifi_handover_type,
|
||||||
|
os_strlen(wifi_handover_type), NULL, 0,
|
||||||
|
wpabuf_mhead(buf), wpabuf_len(buf));
|
||||||
|
}
|
|
@ -305,6 +305,9 @@ struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
|
||||||
#ifdef CONFIG_WPS_UFD
|
#ifdef CONFIG_WPS_UFD
|
||||||
methods |= WPS_CONFIG_USBA;
|
methods |= WPS_CONFIG_USBA;
|
||||||
#endif /* CONFIG_WPS_UFD */
|
#endif /* CONFIG_WPS_UFD */
|
||||||
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
methods |= WPS_CONFIG_NFC_INTERFACE;
|
||||||
|
#endif /* CONFIG_WPS_NFC */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wps_build_version(ie) ||
|
if (wps_build_version(ie) ||
|
||||||
|
|
|
@ -526,6 +526,7 @@ struct wps_context {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct oob_device_data {
|
struct oob_device_data {
|
||||||
|
char *device_name;
|
||||||
char *device_path;
|
char *device_path;
|
||||||
void * (*init_func)(struct wps_context *, struct oob_device_data *,
|
void * (*init_func)(struct wps_context *, struct oob_device_data *,
|
||||||
int);
|
int);
|
||||||
|
@ -534,6 +535,13 @@ struct oob_device_data {
|
||||||
void (*deinit_func)(void *);
|
void (*deinit_func)(void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct oob_nfc_device_data {
|
||||||
|
int (*init_func)(char *);
|
||||||
|
void * (*read_func)(size_t *);
|
||||||
|
int (*write_func)(void *, size_t);
|
||||||
|
void (*deinit_func)(void);
|
||||||
|
};
|
||||||
|
|
||||||
struct wps_registrar *
|
struct wps_registrar *
|
||||||
wps_registrar_init(struct wps_context *wps,
|
wps_registrar_init(struct wps_context *wps,
|
||||||
const struct wps_registrar_config *cfg);
|
const struct wps_registrar_config *cfg);
|
||||||
|
@ -555,6 +563,7 @@ unsigned int wps_generate_pin(void);
|
||||||
void wps_free_pending_msgs(struct upnp_pending_message *msgs);
|
void wps_free_pending_msgs(struct upnp_pending_message *msgs);
|
||||||
|
|
||||||
struct oob_device_data * wps_get_oob_device(char *device_type);
|
struct oob_device_data * wps_get_oob_device(char *device_type);
|
||||||
|
struct oob_nfc_device_data * wps_get_oob_nfc_device(char *device_name);
|
||||||
int wps_get_oob_method(char *method);
|
int wps_get_oob_method(char *method);
|
||||||
int wps_process_oob(struct wps_context *wps, struct oob_device_data *oob_dev,
|
int wps_process_oob(struct wps_context *wps, struct oob_device_data *oob_dev,
|
||||||
int registrar);
|
int registrar);
|
||||||
|
|
|
@ -525,11 +525,30 @@ struct oob_device_data * wps_get_oob_device(char *device_type)
|
||||||
if (os_strstr(device_type, "ufd") != NULL)
|
if (os_strstr(device_type, "ufd") != NULL)
|
||||||
return &oob_ufd_device_data;
|
return &oob_ufd_device_data;
|
||||||
#endif /* CONFIG_WPS_UFD */
|
#endif /* CONFIG_WPS_UFD */
|
||||||
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
if (os_strstr(device_type, "nfc") != NULL)
|
||||||
|
return &oob_nfc_device_data;
|
||||||
|
#endif /* CONFIG_WPS_NFC */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
struct oob_nfc_device_data * wps_get_oob_nfc_device(char *device_name)
|
||||||
|
{
|
||||||
|
if (device_name == NULL)
|
||||||
|
return NULL;
|
||||||
|
#ifdef CONFIG_WPS_NFC_PN531
|
||||||
|
if (os_strstr(device_name, "pn531") != NULL)
|
||||||
|
return &oob_nfc_pn531_device_data;
|
||||||
|
#endif /* CONFIG_WPS_NFC_PN531 */
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_WPS_NFC */
|
||||||
|
|
||||||
|
|
||||||
int wps_get_oob_method(char *method)
|
int wps_get_oob_method(char *method)
|
||||||
{
|
{
|
||||||
if (os_strstr(method, "pin-e") != NULL)
|
if (os_strstr(method, "pin-e") != NULL)
|
||||||
|
|
|
@ -135,6 +135,9 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
|
||||||
#ifdef CONFIG_WPS_UFD
|
#ifdef CONFIG_WPS_UFD
|
||||||
methods |= WPS_CONFIG_USBA;
|
methods |= WPS_CONFIG_USBA;
|
||||||
#endif /* CONFIG_WPS_UFD */
|
#endif /* CONFIG_WPS_UFD */
|
||||||
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
methods |= WPS_CONFIG_NFC_INTERFACE;
|
||||||
|
#endif /* CONFIG_WPS_NFC */
|
||||||
if (wps->pbc)
|
if (wps->pbc)
|
||||||
methods |= WPS_CONFIG_PUSHBUTTON;
|
methods |= WPS_CONFIG_PUSHBUTTON;
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,8 @@ void wps_success_event(struct wps_context *wps);
|
||||||
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part);
|
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part);
|
||||||
|
|
||||||
extern struct oob_device_data oob_ufd_device_data;
|
extern struct oob_device_data oob_ufd_device_data;
|
||||||
|
extern struct oob_device_data oob_nfc_device_data;
|
||||||
|
extern struct oob_nfc_device_data oob_nfc_pn531_device_data;
|
||||||
|
|
||||||
/* wps_attr_parse.c */
|
/* wps_attr_parse.c */
|
||||||
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
|
int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
|
||||||
|
@ -244,6 +246,9 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
|
||||||
const struct wpabuf *msg);
|
const struct wpabuf *msg);
|
||||||
int wps_build_cred(struct wps_data *wps, struct wpabuf *msg);
|
int wps_build_cred(struct wps_data *wps, struct wpabuf *msg);
|
||||||
|
|
||||||
|
/* ndef.c */
|
||||||
|
struct wpabuf * ndef_parse_wifi(struct wpabuf *buf);
|
||||||
|
struct wpabuf * ndef_build_wifi(struct wpabuf *buf);
|
||||||
|
|
||||||
static inline int wps_version_supported(const u8 *version)
|
static inline int wps_version_supported(const u8 *version)
|
||||||
{
|
{
|
||||||
|
|
117
src/wps/wps_nfc.c
Normal file
117
src/wps/wps_nfc.c
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* NFC routines for Wi-Fi Protected Setup
|
||||||
|
* Copyright (c) 2009, Masashi Honma <honma@ictec.co.jp>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Alternatively, this software may be distributed under the terms of BSD
|
||||||
|
* license.
|
||||||
|
*
|
||||||
|
* See README and COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include "wps/wps.h"
|
||||||
|
#include "wps_i.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct wps_nfc_data {
|
||||||
|
struct oob_nfc_device_data *oob_nfc_dev;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void * init_nfc(struct wps_context *wps,
|
||||||
|
struct oob_device_data *oob_dev, int registrar)
|
||||||
|
{
|
||||||
|
struct oob_nfc_device_data *oob_nfc_dev;
|
||||||
|
struct wps_nfc_data *data;
|
||||||
|
|
||||||
|
oob_nfc_dev = wps_get_oob_nfc_device(oob_dev->device_name);
|
||||||
|
if (oob_nfc_dev == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (NFC): Unknown NFC device (%s)",
|
||||||
|
oob_dev->device_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oob_nfc_dev->init_func(oob_dev->device_path) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
data = os_zalloc(sizeof(*data));
|
||||||
|
if (data == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (NFC): Failed to allocate "
|
||||||
|
"nfc data area");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
data->oob_nfc_dev = oob_nfc_dev;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct wpabuf * read_nfc(void *priv)
|
||||||
|
{
|
||||||
|
struct wps_nfc_data *data = priv;
|
||||||
|
struct wpabuf *wifi, *buf;
|
||||||
|
char *raw_data;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
raw_data = data->oob_nfc_dev->read_func(&len);
|
||||||
|
if (raw_data == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
wifi = wpabuf_alloc_copy(raw_data, len);
|
||||||
|
os_free(raw_data);
|
||||||
|
if (wifi == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (NFC): Failed to allocate "
|
||||||
|
"nfc read area");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = ndef_parse_wifi(wifi);
|
||||||
|
wpabuf_free(wifi);
|
||||||
|
if (buf == NULL)
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (NFC): Failed to unwrap");
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int write_nfc(void *priv, struct wpabuf *buf)
|
||||||
|
{
|
||||||
|
struct wps_nfc_data *data = priv;
|
||||||
|
struct wpabuf *wifi;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
wifi = ndef_build_wifi(buf);
|
||||||
|
if (wifi == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (NFC): Failed to wrap");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = data->oob_nfc_dev->write_func(wpabuf_mhead(wifi),
|
||||||
|
wpabuf_len(wifi));
|
||||||
|
wpabuf_free(wifi);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void deinit_nfc(void *priv)
|
||||||
|
{
|
||||||
|
struct wps_nfc_data *data = priv;
|
||||||
|
|
||||||
|
data->oob_nfc_dev->deinit_func();
|
||||||
|
|
||||||
|
os_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct oob_device_data oob_nfc_device_data = {
|
||||||
|
.device_name = NULL,
|
||||||
|
.device_path = NULL,
|
||||||
|
.init_func = init_nfc,
|
||||||
|
.read_func = read_nfc,
|
||||||
|
.write_func = write_nfc,
|
||||||
|
.deinit_func = deinit_nfc,
|
||||||
|
};
|
113
src/wps/wps_nfc_pn531.c
Normal file
113
src/wps/wps_nfc_pn531.c
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* NFC PN531 routines for Wi-Fi Protected Setup
|
||||||
|
* Copyright (c) 2009, Masashi Honma <honma@ictec.co.jp>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Alternatively, this software may be distributed under the terms of BSD
|
||||||
|
* license.
|
||||||
|
*
|
||||||
|
* See README and COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include "wps/wps.h"
|
||||||
|
#include "wps_i.h"
|
||||||
|
|
||||||
|
#include "WpsNfcType.h"
|
||||||
|
#include "WpsNfc.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int init_nfc_pn531(char *path)
|
||||||
|
{
|
||||||
|
u32 ret;
|
||||||
|
|
||||||
|
ret = WpsNfcInit();
|
||||||
|
if (ret != WPS_NFCLIB_ERR_SUCCESS) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (PN531): Failed to initialize "
|
||||||
|
"NFC Library: 0x%08x", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = WpsNfcOpenDevice((int8 *) path);
|
||||||
|
if (ret != WPS_NFCLIB_ERR_SUCCESS) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (PN531): Failed to open "
|
||||||
|
"NFC Device(%s): 0x%08x", path, ret);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = WpsNfcTokenDiscovery();
|
||||||
|
if (ret != WPS_NFCLIB_ERR_SUCCESS) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (PN531): Failed to discover "
|
||||||
|
"token: 0x%08x", ret);
|
||||||
|
WpsNfcCloseDevice();
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
WpsNfcDeinit();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void * read_nfc_pn531(size_t *size)
|
||||||
|
{
|
||||||
|
uint32 len;
|
||||||
|
u32 ret;
|
||||||
|
int8 *data;
|
||||||
|
|
||||||
|
ret = WpsNfcRawReadToken(&data, &len);
|
||||||
|
if (ret != WPS_NFCLIB_ERR_SUCCESS) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (PN531): Failed to read: 0x%08x",
|
||||||
|
ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = len;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int write_nfc_pn531(void *data, size_t len)
|
||||||
|
{
|
||||||
|
u32 ret;
|
||||||
|
|
||||||
|
ret = WpsNfcRawWriteToken(data, len);
|
||||||
|
if (ret != WPS_NFCLIB_ERR_SUCCESS) {
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (PN531): Failed to write: 0x%08x",
|
||||||
|
ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void deinit_nfc_pn531(void)
|
||||||
|
{
|
||||||
|
u32 ret;
|
||||||
|
|
||||||
|
ret = WpsNfcCloseDevice();
|
||||||
|
if (ret != WPS_NFCLIB_ERR_SUCCESS)
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (PN531): Failed to close "
|
||||||
|
"NFC Device: 0x%08x", ret);
|
||||||
|
|
||||||
|
ret = WpsNfcDeinit();
|
||||||
|
if (ret != WPS_NFCLIB_ERR_SUCCESS)
|
||||||
|
wpa_printf(MSG_ERROR, "WPS (PN531): Failed to deinitialize "
|
||||||
|
"NFC Library: 0x%08x", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct oob_nfc_device_data oob_nfc_pn531_device_data = {
|
||||||
|
.init_func = init_nfc_pn531,
|
||||||
|
.read_func = read_nfc_pn531,
|
||||||
|
.write_func = write_nfc_pn531,
|
||||||
|
.deinit_func = deinit_nfc_pn531,
|
||||||
|
};
|
|
@ -225,6 +225,7 @@ static void deinit_ufd(void *priv)
|
||||||
|
|
||||||
|
|
||||||
struct oob_device_data oob_ufd_device_data = {
|
struct oob_device_data oob_ufd_device_data = {
|
||||||
|
.device_name = NULL,
|
||||||
.device_path = NULL,
|
.device_path = NULL,
|
||||||
.init_func = init_ufd,
|
.init_func = init_ufd,
|
||||||
.read_func = read_ufd,
|
.read_func = read_ufd,
|
||||||
|
|
|
@ -534,6 +534,21 @@ OBJS += ../src/wps/wps_ufd.o
|
||||||
NEED_WPS_OOB=y
|
NEED_WPS_OOB=y
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_WPS_NFC
|
||||||
|
CFLAGS += -DCONFIG_WPS_NFC
|
||||||
|
OBJS += ../src/wps/ndef.o
|
||||||
|
OBJS += ../src/wps/wps_nfc.o
|
||||||
|
NEED_WPS_OOB=y
|
||||||
|
ifdef CONFIG_WPS_NFC_PN531
|
||||||
|
PN531_PATH = /usr/local/src/nfc
|
||||||
|
CFLAGS += -DCONFIG_WPS_NFC_PN531
|
||||||
|
CFLAGS += -I${PN531_PATH}/inc
|
||||||
|
OBJS += ../src/wps/wps_nfc_pn531.o
|
||||||
|
LIBS += ${PN531_PATH}/lib/wpsnfc.dll
|
||||||
|
LIBS += ${PN531_PATH}/lib/libnfc_mapping_pn53x.dll
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef NEED_WPS_OOB
|
ifdef NEED_WPS_OOB
|
||||||
CFLAGS += -DCONFIG_WPS_OOB
|
CFLAGS += -DCONFIG_WPS_OOB
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -208,7 +208,7 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
|
||||||
static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
|
static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
|
||||||
char *cmd)
|
char *cmd)
|
||||||
{
|
{
|
||||||
char *path, *method;
|
char *path, *method, *name;
|
||||||
|
|
||||||
path = os_strchr(cmd, ' ');
|
path = os_strchr(cmd, ' ');
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
|
@ -220,7 +220,11 @@ static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
|
||||||
return -1;
|
return -1;
|
||||||
*method++ = '\0';
|
*method++ = '\0';
|
||||||
|
|
||||||
return wpas_wps_start_oob(wpa_s, cmd, path, method);
|
name = os_strchr(method, ' ');
|
||||||
|
if (name != NULL)
|
||||||
|
*name++ = '\0';
|
||||||
|
|
||||||
|
return wpas_wps_start_oob(wpa_s, cmd, path, method, name);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_WPS_OOB */
|
#endif /* CONFIG_WPS_OOB */
|
||||||
|
|
||||||
|
|
|
@ -452,17 +452,24 @@ static int wpa_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
char cmd[256];
|
char cmd[256];
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3 && argc != 4) {
|
||||||
printf("Invalid WPS_OOB command: need three arguments:\n"
|
printf("Invalid WPS_OOB command: need three or four "
|
||||||
"- OOB_DEV_TYPE: use 'ufd'\n"
|
"arguments:\n"
|
||||||
"- OOB_PATH: path of OOB device like '/mnt'\n"
|
"- DEV_TYPE: use 'ufd' or 'nfc'\n"
|
||||||
"- OOB_METHOD: OOB method 'pin-e' or 'pin-r', "
|
"- PATH: path of OOB device like '/mnt'\n"
|
||||||
"'cred'\n");
|
"- METHOD: OOB method 'pin-e' or 'pin-r', "
|
||||||
|
"'cred'\n"
|
||||||
|
"- DEV_NAME: (only for NFC) device name like "
|
||||||
|
"'pn531'\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
|
if (argc == 3)
|
||||||
argv[0], argv[1], argv[2]);
|
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2]);
|
||||||
|
else
|
||||||
|
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2], argv[3]);
|
||||||
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||||
printf("Too long WPS_OOB command.\n");
|
printf("Too long WPS_OOB command.\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1287,7 +1294,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
#ifdef CONFIG_WPS_OOB
|
#ifdef CONFIG_WPS_OOB
|
||||||
{ "wps_oob", wpa_cli_cmd_wps_oob,
|
{ "wps_oob", wpa_cli_cmd_wps_oob,
|
||||||
cli_cmd_flag_sensitive,
|
cli_cmd_flag_sensitive,
|
||||||
"<OOB_DEV_TYPE> <OOB_PATH> <OOB_METHOD> = start WPS OOB" },
|
"<DEV_TYPE> <PATH> <METHOD> [DEV_NAME] = start WPS OOB" },
|
||||||
#endif /* CONFIG_WPS_OOB */
|
#endif /* CONFIG_WPS_OOB */
|
||||||
{ "wps_reg", wpa_cli_cmd_wps_reg,
|
{ "wps_reg", wpa_cli_cmd_wps_reg,
|
||||||
cli_cmd_flag_sensitive,
|
cli_cmd_flag_sensitive,
|
||||||
|
|
|
@ -563,7 +563,7 @@ int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_OOB
|
#ifdef CONFIG_WPS_OOB
|
||||||
int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
|
int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
|
||||||
char *path, char *method)
|
char *path, char *method, char *name)
|
||||||
{
|
{
|
||||||
struct wps_context *wps = wpa_s->wps;
|
struct wps_context *wps = wpa_s->wps;
|
||||||
struct oob_device_data *oob_dev;
|
struct oob_device_data *oob_dev;
|
||||||
|
@ -572,6 +572,7 @@ int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
|
||||||
if (oob_dev == NULL)
|
if (oob_dev == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
oob_dev->device_path = path;
|
oob_dev->device_path = path;
|
||||||
|
oob_dev->device_name = name;
|
||||||
wps->oob_conf.oob_method = wps_get_oob_method(method);
|
wps->oob_conf.oob_method = wps_get_oob_method(method);
|
||||||
|
|
||||||
if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E) {
|
if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
||||||
int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
const char *pin);
|
const char *pin);
|
||||||
int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
|
int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
|
||||||
char *path, char *method);
|
char *path, char *method, char *name);
|
||||||
int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
const char *pin);
|
const char *pin);
|
||||||
int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
|
int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
|
||||||
|
|
Loading…
Reference in a new issue