WPS: Add support for config token generation with wpa_supplicant
When wpa_supplicant is controlling an AP mode interface, it can generate the NFC configuration token similarly to the way this is done in hostapd. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
23ffcaf172
commit
bbf41865c9
8 changed files with 112 additions and 0 deletions
|
@ -336,6 +336,16 @@ wps_nfc_dh_privkey, wps_nfc_dev_pw) or generated dynamically with
|
||||||
tokens during manufacturing (each station needs to have its own random
|
tokens during manufacturing (each station needs to have its own random
|
||||||
keys).
|
keys).
|
||||||
|
|
||||||
|
The "wps_nfc_config_token <WPS/NDEF>" command can be used to build an
|
||||||
|
NFC configuration token when wpa_supplicant is controlling an AP
|
||||||
|
interface (AP or P2P GO). The output value from this command is a
|
||||||
|
hexdump of the current AP configuration (WPS parameter requests this to
|
||||||
|
include only the WPS attributes; NDEF parameter requests additional NDEF
|
||||||
|
encapsulation to be included). This data needs to be written to an NFC
|
||||||
|
tag with an external program. Once written, the NFC configuration token
|
||||||
|
can be used to touch an NFC interface on a station to provision the
|
||||||
|
credentials needed to access the network.
|
||||||
|
|
||||||
If the station includes NFC interface and reads an NFC tag with a MIME
|
If the station includes NFC interface and reads an NFC tag with a MIME
|
||||||
media type "application/vnd.wfa.wsc", the NDEF message payload (with or
|
media type "application/vnd.wfa.wsc", the NDEF message payload (with or
|
||||||
without NDEF encapsulation) can be delivered to wpa_supplicant using the
|
without NDEF encapsulation) can be delivered to wpa_supplicant using the
|
||||||
|
|
|
@ -848,6 +848,18 @@ void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
|
||||||
hapd->conf->ap_pin = NULL;
|
hapd->conf->ap_pin = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
|
||||||
|
int ndef)
|
||||||
|
{
|
||||||
|
struct hostapd_data *hapd;
|
||||||
|
|
||||||
|
if (wpa_s->ap_iface == NULL)
|
||||||
|
return NULL;
|
||||||
|
hapd = wpa_s->ap_iface->bss[0];
|
||||||
|
return hostapd_wps_nfc_config_token(hapd, ndef);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,5 +52,7 @@ int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
|
||||||
void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s);
|
void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s);
|
||||||
void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
|
void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
|
||||||
int offset);
|
int offset);
|
||||||
|
struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
|
||||||
|
int ndef);
|
||||||
|
|
||||||
#endif /* AP_H */
|
#endif /* AP_H */
|
||||||
|
|
|
@ -778,6 +778,35 @@ static int wpa_supplicant_ctrl_iface_wps_nfc(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
|
||||||
|
struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
|
||||||
|
{
|
||||||
|
int ndef;
|
||||||
|
struct wpabuf *buf;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (os_strcmp(cmd, "WPS") == 0)
|
||||||
|
ndef = 0;
|
||||||
|
else if (os_strcmp(cmd, "NDEF") == 0)
|
||||||
|
ndef = 1;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
buf = wpas_wps_nfc_config_token(wpa_s, ndef);
|
||||||
|
if (buf == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
|
||||||
|
wpabuf_len(buf));
|
||||||
|
reply[res++] = '\n';
|
||||||
|
reply[res] = '\0';
|
||||||
|
|
||||||
|
wpabuf_free(buf);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_supplicant_ctrl_iface_wps_nfc_token(
|
static int wpa_supplicant_ctrl_iface_wps_nfc_token(
|
||||||
struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
|
struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
|
||||||
{
|
{
|
||||||
|
@ -4958,6 +4987,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
} else if (os_strncmp(buf, "WPS_NFC ", 8) == 0) {
|
} else if (os_strncmp(buf, "WPS_NFC ", 8) == 0) {
|
||||||
if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8))
|
if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8))
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
|
} else if (os_strncmp(buf, "WPS_NFC_CONFIG_TOKEN ", 21) == 0) {
|
||||||
|
reply_len = wpa_supplicant_ctrl_iface_wps_nfc_config_token(
|
||||||
|
wpa_s, buf + 21, reply, reply_size);
|
||||||
} else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) {
|
} else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) {
|
||||||
reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token(
|
reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token(
|
||||||
wpa_s, buf + 14, reply, reply_size);
|
wpa_s, buf + 14, reply, reply_size);
|
||||||
|
|
|
@ -54,6 +54,13 @@ def wpas_tag_read(message):
|
||||||
print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
|
print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
|
||||||
|
|
||||||
|
|
||||||
|
def wpas_get_config_token():
|
||||||
|
wpas = wpas_connect()
|
||||||
|
if (wpas == None):
|
||||||
|
return None
|
||||||
|
return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
|
||||||
|
|
||||||
|
|
||||||
def wpas_get_password_token():
|
def wpas_get_password_token():
|
||||||
wpas = wpas_connect()
|
wpas = wpas_connect()
|
||||||
if (wpas == None):
|
if (wpas == None):
|
||||||
|
@ -169,6 +176,28 @@ def wps_tag_read(tag):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def wps_write_config_tag(clf):
|
||||||
|
print "Write WPS config token"
|
||||||
|
data = wpas_get_config_token()
|
||||||
|
if (data == None):
|
||||||
|
print "Could not get WPS config token from wpa_supplicant"
|
||||||
|
return
|
||||||
|
|
||||||
|
print "Touch an NFC tag"
|
||||||
|
while True:
|
||||||
|
tag = clf.poll()
|
||||||
|
if tag == None:
|
||||||
|
time.sleep(0.1)
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
|
||||||
|
print "Tag found - writing"
|
||||||
|
tag.ndef.message = data
|
||||||
|
print "Done - remove tag"
|
||||||
|
while tag.is_present:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
def wps_write_password_tag(clf):
|
def wps_write_password_tag(clf):
|
||||||
print "Write WPS password token"
|
print "Write WPS password token"
|
||||||
data = wpas_get_password_token()
|
data = wpas_get_password_token()
|
||||||
|
@ -223,6 +252,10 @@ def main():
|
||||||
clf = nfc.ContactlessFrontend()
|
clf = nfc.ContactlessFrontend()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if len(sys.argv) > 1 and sys.argv[1] == "write-config":
|
||||||
|
wps_write_config_tag(clf)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
if len(sys.argv) > 1 and sys.argv[1] == "write-password":
|
if len(sys.argv) > 1 and sys.argv[1] == "write-password":
|
||||||
wps_write_password_tag(clf)
|
wps_write_password_tag(clf)
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
|
@ -744,6 +744,13 @@ static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
|
static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -2488,6 +2495,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
{ "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
|
{ "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"[BSSID] = start Wi-Fi Protected Setup: NFC" },
|
"[BSSID] = start Wi-Fi Protected Setup: NFC" },
|
||||||
|
{ "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
|
||||||
|
cli_cmd_flag_none,
|
||||||
|
"<WPS|NDEF> = build configuration token" },
|
||||||
{ "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
|
{ "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"<WPS|NDEF> = create password token" },
|
"<WPS|NDEF> = create password token" },
|
||||||
|
|
|
@ -1830,6 +1830,17 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_NFC
|
#ifdef CONFIG_WPS_NFC
|
||||||
|
|
||||||
|
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
|
||||||
|
int ndef)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_AP
|
||||||
|
if (wpa_s->ap_iface)
|
||||||
|
return wpas_ap_wps_nfc_config_token(wpa_s, ndef);
|
||||||
|
#endif /* CONFIG_AP */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef)
|
struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef)
|
||||||
{
|
{
|
||||||
if (wpa_s->conf->wps_nfc_pw_from_config) {
|
if (wpa_s->conf->wps_nfc_pw_from_config) {
|
||||||
|
|
|
@ -62,6 +62,8 @@ struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s,
|
||||||
int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s);
|
int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s);
|
||||||
int wpas_wps_in_progress(struct wpa_supplicant *wpa_s);
|
int wpas_wps_in_progress(struct wpa_supplicant *wpa_s);
|
||||||
void wpas_wps_update_config(struct wpa_supplicant *wpa_s);
|
void wpas_wps_update_config(struct wpa_supplicant *wpa_s);
|
||||||
|
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
|
||||||
|
int ndef);
|
||||||
struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef);
|
struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef);
|
||||||
int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
||||||
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
|
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
|
||||||
|
|
Loading…
Reference in a new issue