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
|
||||
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
|
||||
media type "application/vnd.wfa.wsc", the NDEF message payload (with or
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
|
|
|
@ -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 wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
|
||||
int offset);
|
||||
struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
|
||||
int ndef);
|
||||
|
||||
#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(
|
||||
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) {
|
||||
if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8))
|
||||
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) {
|
||||
reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token(
|
||||
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"))
|
||||
|
||||
|
||||
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():
|
||||
wpas = wpas_connect()
|
||||
if (wpas == None):
|
||||
|
@ -169,6 +176,28 @@ def wps_tag_read(tag):
|
|||
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):
|
||||
print "Write WPS password token"
|
||||
data = wpas_get_password_token()
|
||||
|
@ -223,6 +252,10 @@ def main():
|
|||
clf = nfc.ContactlessFrontend()
|
||||
|
||||
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":
|
||||
wps_write_password_tag(clf)
|
||||
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,
|
||||
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,
|
||||
cli_cmd_flag_none,
|
||||
"[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,
|
||||
cli_cmd_flag_none,
|
||||
"<WPS|NDEF> = create password token" },
|
||||
|
|
|
@ -1830,6 +1830,17 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
|
|||
|
||||
#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)
|
||||
{
|
||||
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_in_progress(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);
|
||||
int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
||||
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
|
||||
|
|
Loading…
Reference in a new issue