From e47588279af1af78ccdc88cf93df83003c01061b Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 11 Feb 2013 18:43:46 +0200 Subject: [PATCH] WPS: Report NFC connection handover completion differently Instead of reporting only one connection handover message, report completion of NFC connection handover with carrier record from both the request and select messages. Signed-hostap: Jouni Malinen --- hostapd/ctrl_iface.c | 16 +++++++ hostapd/wps-ap-nfc.py | 13 ++++-- wpa_supplicant/ctrl_iface.c | 74 ++++++++++++++++++++++++++++++ wpa_supplicant/examples/wps-nfc.py | 10 ++-- wpa_supplicant/wpa_cli.c | 11 +++++ wpa_supplicant/wps_supplicant.c | 11 +++++ wpa_supplicant/wps_supplicant.h | 3 ++ 7 files changed, 131 insertions(+), 7 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index d4b3af362..f20721b8a 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -392,6 +392,19 @@ static int hostapd_ctrl_iface_nfc_get_handover_sel(struct hostapd_data *hapd, return res; } + +static int hostapd_ctrl_iface_nfc_report_handover(struct hostapd_data *hapd, + char *cmd) +{ + /* + * Since NFC connection handover provided full WPS Credential, there is + * no need for additional operations within hostapd. Just report this in + * debug log. + */ + wpa_printf(MSG_DEBUG, "NFC: Connection handover reported: %s", cmd); + return 0; +} + #endif /* CONFIG_WPS_NFC */ @@ -956,6 +969,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx, } else if (os_strncmp(buf, "NFC_GET_HANDOVER_SEL ", 21) == 0) { reply_len = hostapd_ctrl_iface_nfc_get_handover_sel( hapd, buf + 21, reply, reply_size); + } else if (os_strncmp(buf, "NFC_REPORT_HANDOVER ", 20) == 0) { + if (hostapd_ctrl_iface_nfc_report_handover(hapd, buf + 20)) + reply_len = -1; #endif /* CONFIG_WPS_NFC */ #endif /* CONFIG_WPS */ #ifdef CONFIG_WNM diff --git a/hostapd/wps-ap-nfc.py b/hostapd/wps-ap-nfc.py index 61fa677b6..32a021451 100755 --- a/hostapd/wps-ap-nfc.py +++ b/hostapd/wps-ap-nfc.py @@ -73,11 +73,13 @@ def wpas_get_handover_sel(): return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip().decode("hex") -def wpas_put_handover_sel(message): +def wpas_report_handover(req, sel): wpas = wpas_connect() if (wpas == None): - return - print wpas.request("NFC_RX_HANDOVER_SEL " + str(message).encode("hex")) + return None + return wpas.request("NFC_REPORT_HANDOVER RESP WPS " + + str(req).encode("hex") + " " + + str(sel).encode("hex")) class HandoverServer(nfc.handover.HandoverServer): @@ -94,12 +96,14 @@ class HandoverServer(nfc.handover.HandoverServer): print "Remote carrier type: " + carrier.type if carrier.type == "application/vnd.wfa.wsc": print "WPS carrier type match - add WPS carrier record" + self.received_carrier = carrier.record data = wpas_get_handover_sel() if data is None: print "Could not get handover select carrier record from hostapd" continue print "Handover select carrier record from hostapd:" print data.encode("hex") + self.sent_carrier = data message = nfc.ndef.Message(data); sel.add_carrier(message[0], "active", message[1:]) @@ -131,6 +135,9 @@ def wps_handover_resp(peer): nfc.llcp.shutdown() return + if srv.sent_carrier: + wpas_report_handover(srv.received_carrier, srv.sent_carrier) + print "Remove peer" nfc.llcp.shutdown() print "Done with handover" diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 1a709c884..de6c450e2 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -977,6 +977,76 @@ static int wpas_ctrl_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s, return ret; } + +static int wpas_ctrl_nfc_report_handover(struct wpa_supplicant *wpa_s, + char *cmd) +{ + size_t len; + struct wpabuf *req, *sel; + int ret; + char *pos, *role, *type, *pos2; + + role = cmd; + pos = os_strchr(role, ' '); + if (pos == NULL) + return -1; + *pos++ = '\0'; + + type = pos; + pos = os_strchr(type, ' '); + if (pos == NULL) + return -1; + *pos++ = '\0'; + + pos2 = os_strchr(pos, ' '); + if (pos2 == NULL) + return -1; + *pos2++ = '\0'; + + len = os_strlen(pos); + if (len & 0x01) + return -1; + len /= 2; + + req = wpabuf_alloc(len); + if (req == NULL) + return -1; + if (hexstr2bin(pos, wpabuf_put(req, len), len) < 0) { + wpabuf_free(req); + return -1; + } + + len = os_strlen(pos2); + if (len & 0x01) { + wpabuf_free(req); + return -1; + } + len /= 2; + + sel = wpabuf_alloc(len); + if (sel == NULL) { + wpabuf_free(req); + return -1; + } + if (hexstr2bin(pos2, wpabuf_put(sel, len), len) < 0) { + wpabuf_free(req); + wpabuf_free(sel); + return -1; + } + + if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "WPS") == 0) { + ret = wpas_wps_nfc_report_handover(wpa_s, req, sel); + } else { + wpa_printf(MSG_DEBUG, "NFC: Unsupported connection handover " + "reported: role=%s type=%s", role, type); + ret = -1; + } + wpabuf_free(req); + wpabuf_free(sel); + + return ret; +} + #endif /* CONFIG_WPS_NFC */ @@ -4771,6 +4841,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || os_strncmp(buf, "SET_NETWORK ", 12) == 0 || os_strncmp(buf, "WPS_NFC_TAG_READ", 16) == 0 || + os_strncmp(buf, "NFC_REPORT_HANDOVER", 19) == 0 || os_strncmp(buf, "NFC_RX_HANDOVER_SEL", 19) == 0) { wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", (const u8 *) buf, os_strlen(buf)); @@ -4906,6 +4977,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "NFC_RX_HANDOVER_SEL ", 20) == 0) { if (wpas_ctrl_nfc_rx_handover_sel(wpa_s, buf + 20)) reply_len = -1; + } else if (os_strncmp(buf, "NFC_REPORT_HANDOVER ", 20) == 0) { + if (wpas_ctrl_nfc_report_handover(wpa_s, buf + 20)) + reply_len = -1; #endif /* CONFIG_WPS_NFC */ } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) { if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8)) diff --git a/wpa_supplicant/examples/wps-nfc.py b/wpa_supplicant/examples/wps-nfc.py index c328a90f8..f1b29accc 100755 --- a/wpa_supplicant/examples/wps-nfc.py +++ b/wpa_supplicant/examples/wps-nfc.py @@ -61,11 +61,13 @@ def wpas_get_handover_req(): return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex") -def wpas_put_handover_sel(message): +def wpas_report_handover(req, sel): wpas = wpas_connect() if (wpas == None): - return - print wpas.request("NFC_RX_HANDOVER_SEL " + str(message).encode("hex")) + return None + return wpas.request("NFC_REPORT_HANDOVER INIT WPS " + + str(req).encode("hex") + " " + + str(sel).encode("hex")) def wps_handover_init(peer): @@ -131,7 +133,7 @@ def wps_handover_init(peer): print "Remote carrier type: " + carrier.type if carrier.type == "application/vnd.wfa.wsc": print "WPS carrier type match - send to wpa_supplicant" - wpas_put_handover_sel(carrier.record) + wpas_report_handover(data, carrier.record) wifi = nfc.ndef.WifiConfigRecord(carrier.record) print wifi.pretty() diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 1a764bb96..3034e1538 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -842,6 +842,13 @@ static int wpa_cli_cmd_nfc_rx_handover_sel(struct wpa_ctrl *ctrl, int argc, return ret; } + +static int wpa_cli_cmd_nfc_report_handover(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "NFC_REPORT_HANDOVER", 4, argc, argv); +} + #endif /* CONFIG_WPS_NFC */ @@ -2499,6 +2506,10 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { { "nfc_rx_handover_sel", wpa_cli_cmd_nfc_rx_handover_sel, NULL, cli_cmd_flag_none, " = report received NFC handover select" }, + { "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL, + cli_cmd_flag_none, + " = report completed " + "NFC handover" }, #endif /* CONFIG_WPS_NFC */ { "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss, cli_cmd_flag_sensitive, diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index ff14260b6..3fd8274b5 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -2017,6 +2017,17 @@ int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s, return ret; } + +int wpas_wps_nfc_report_handover(struct wpa_supplicant *wpa_s, + const struct wpabuf *req, + const struct wpabuf *sel) +{ + wpa_printf(MSG_DEBUG, "NFC: WPS connection handover reported"); + wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in request", req); + wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in select", sel); + return wpas_wps_nfc_rx_handover_sel(wpa_s, sel); +} + #endif /* CONFIG_WPS_NFC */ diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h index b3e69ed2d..465e6f227 100644 --- a/wpa_supplicant/wps_supplicant.h +++ b/wpa_supplicant/wps_supplicant.h @@ -72,6 +72,9 @@ int wpas_wps_nfc_rx_handover_req(struct wpa_supplicant *wpa_s, const struct wpabuf *data); int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s, const struct wpabuf *data); +int wpas_wps_nfc_report_handover(struct wpa_supplicant *wpa_s, + const struct wpabuf *req, + const struct wpabuf *sel); void wpas_wps_update_ap_info(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res); void wpas_wps_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *bssid);