OSDN Git Service

Accumulative patch from commit f8361e3d681e55efead2aac79fedf4b232d533fb
authorDmitry Shmidt <dimitrysh@google.com>
Wed, 27 Feb 2013 20:56:00 +0000 (12:56 -0800)
committerDmitry Shmidt <dimitrysh@google.com>
Wed, 27 Feb 2013 20:56:00 +0000 (12:56 -0800)
TDLS: Pass peer's VHT Capability information during sta_add
WPS: Clear sent_carrier to avoid errors in python script
WPS: Fix OOB Device Password use in PSK1,PSK1 derivation
WPS: Add AP mode NFC connection handover with wpa_supplicant/nfcpy
WPS NFC: Add connection handover support for ER
WPS: Add wps-er-config command for writing config token from ER

Change-Id: I8934dcffb9f66bd3a2f840b78d72c9dd6cecf61d
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
14 files changed:
hostapd/wps-ap-nfc.py
src/ap/wps_hostapd.c
src/eap_peer/eap_wsc.c
src/rsn_supp/tdls.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_i.h
src/rsn_supp/wpa_ie.c
src/rsn_supp/wpa_ie.h
src/wps/wps_registrar.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/examples/wps-nfc.py
wpa_supplicant/wpas_glue.c
wpa_supplicant/wps_supplicant.c
wpa_supplicant/wps_supplicant.h

index 32a0214..6ad0b43 100755 (executable)
@@ -120,6 +120,7 @@ def wps_handover_resp(peer):
     print "Trying to handle WPS handover"
 
     srv = HandoverServer()
+    srv.sent_carrier = None
 
     nfc.llcp.activate(peer);
 
index dfe77ad..e017972 100644 (file)
@@ -1612,6 +1612,7 @@ struct wpabuf * hostapd_wps_nfc_token_gen(struct hostapd_data *hapd, int ndef)
 int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd)
 {
        struct wps_context *wps = hapd->wps;
+       struct wpabuf *pw;
 
        if (wps == NULL)
                return -1;
@@ -1626,7 +1627,16 @@ int hostapd_wps_nfc_token_enable(struct hostapd_data *hapd)
        wps->ap_nfc_dev_pw_id = hapd->conf->wps_nfc_dev_pw_id;
        wps->ap_nfc_dh_pubkey = wpabuf_dup(hapd->conf->wps_nfc_dh_pubkey);
        wps->ap_nfc_dh_privkey = wpabuf_dup(hapd->conf->wps_nfc_dh_privkey);
-       wps->ap_nfc_dev_pw = wpabuf_dup(hapd->conf->wps_nfc_dev_pw);
+       pw = hapd->conf->wps_nfc_dev_pw;
+       wps->ap_nfc_dev_pw = wpabuf_alloc(
+               wpabuf_len(pw) * 2 + 1);
+       if (wps->ap_nfc_dev_pw) {
+               wpa_snprintf_hex_uppercase(
+                       (char *) wpabuf_put(wps->ap_nfc_dev_pw,
+                                           wpabuf_len(pw) * 2),
+                       wpabuf_len(pw) * 2 + 1,
+                       wpabuf_head(pw), wpabuf_len(pw));
+       }
 
        if (!wps->ap_nfc_dh_pubkey || !wps->ap_nfc_dh_privkey ||
            !wps->ap_nfc_dev_pw) {
index f358156..81ad0ce 100644 (file)
@@ -137,7 +137,6 @@ static void * eap_wsc_init(struct eap_sm *sm)
        struct wps_context *wps;
        struct wps_credential new_ap_settings;
        int res;
-       u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN];
        int nfc = 0;
 
        wps = sm->wps;
@@ -186,14 +185,6 @@ static void * eap_wsc_init(struct eap_sm *sm)
                while (*pos != '\0' && *pos != ' ')
                        pos++;
                cfg.pin_len = pos - (const char *) cfg.pin;
-               if (cfg.pin_len >= WPS_OOB_DEVICE_PASSWORD_MIN_LEN * 2 &&
-                   cfg.pin_len <= WPS_OOB_DEVICE_PASSWORD_LEN * 2 &&
-                   hexstr2bin((const char *) cfg.pin, dev_pw,
-                              cfg.pin_len / 2) == 0) {
-                       /* Convert OOB Device Password to binary */
-                       cfg.pin = dev_pw;
-                       cfg.pin_len /= 2;
-               }
                if (cfg.pin_len == 6 &&
                    os_strncmp((const char *) cfg.pin, "nfc-pw", 6) == 0) {
                        cfg.pin = NULL;
index 09adc19..09abdbb 100644 (file)
@@ -122,6 +122,7 @@ struct wpa_tdls_peer {
        size_t supp_rates_len;
 
        struct ieee80211_ht_capabilities *ht_capabilities;
+       struct ieee80211_vht_capabilities *vht_capabilities;
 
        u8 qos_info;
 
@@ -620,6 +621,8 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
        peer->sm_tmr.buf = NULL;
        os_free(peer->ht_capabilities);
        peer->ht_capabilities = NULL;
+       os_free(peer->vht_capabilities);
+       peer->vht_capabilities = NULL;
        os_free(peer->ext_capab);
        peer->ext_capab = NULL;
        peer->rsnie_i_len = peer->rsnie_p_len = 0;
@@ -1370,6 +1373,34 @@ static int copy_peer_ht_capab(const struct wpa_eapol_ie_parse *kde,
 }
 
 
+static int copy_peer_vht_capab(const struct wpa_eapol_ie_parse *kde,
+                             struct wpa_tdls_peer *peer)
+{
+       if (!kde->vht_capabilities ||
+           kde->vht_capabilities_len <
+           sizeof(struct ieee80211_vht_capabilities) ) {
+               wpa_printf(MSG_DEBUG, "TDLS: No supported vht capabilities "
+                          "received");
+               return 0;
+       }
+
+       if (!peer->vht_capabilities) {
+               peer->vht_capabilities =
+                        os_zalloc(sizeof(struct ieee80211_vht_capabilities));
+               if (peer->vht_capabilities == NULL)
+                        return -1;
+       }
+
+       os_memcpy(peer->vht_capabilities, kde->vht_capabilities,
+                  sizeof(struct ieee80211_vht_capabilities));
+       wpa_hexdump(MSG_DEBUG, "TDLS: Peer VHT capabilities",
+                   (u8 *) peer->vht_capabilities,
+                   sizeof(struct ieee80211_vht_capabilities));
+
+       return 0;
+}
+
+
 static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde,
                               struct wpa_tdls_peer *peer)
 {
@@ -1466,6 +1497,9 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
        if (copy_peer_ht_capab(&kde, peer) < 0)
                goto error;
 
+       if (copy_peer_vht_capab(&kde, peer) < 0)
+               goto error;
+
        if (copy_peer_ext_capab(&kde, peer) < 0)
                goto error;
 
@@ -1694,7 +1728,7 @@ skip_rsn:
 
 skip_rsn_check:
        /* add the peer to the driver as a "setup in progress" peer */
-       wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0,
+       wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0,
                                NULL, 0);
 
        wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
@@ -1738,8 +1772,9 @@ static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
        /* add supported rates, capabilities, and qos_info to the TDLS peer */
        wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
                                peer->supp_rates, peer->supp_rates_len,
-                               peer->ht_capabilities, peer->qos_info,
-                               peer->ext_capab, peer->ext_capab_len);
+                               peer->ht_capabilities, peer->vht_capabilities,
+                               peer->qos_info, peer->ext_capab,
+                               peer->ext_capab_len);
 
        wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
 }
@@ -1838,6 +1873,9 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
        if (copy_peer_ht_capab(&kde, peer) < 0)
                goto error;
 
+       if (copy_peer_vht_capab(&kde, peer) < 0)
+               goto error;
+
        if (copy_peer_ext_capab(&kde, peer) < 0)
                goto error;
 
@@ -2146,7 +2184,7 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
        peer->initiator = 1;
 
        /* add the peer to the driver as a "setup in progress" peer */
-       wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0,
+       wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0,
                                NULL, 0);
 
        if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
index 6679dda..dbb493e 100644 (file)
@@ -60,6 +60,7 @@ struct wpa_sm_ctx {
                                u16 capability, const u8 *supp_rates,
                                size_t supp_rates_len,
                                const struct ieee80211_ht_capabilities *ht_capab,
+                               const struct ieee80211_vht_capabilities *vht_capab,
                                u8 qosinfo, const u8 *ext_capab,
                                size_t ext_capab_len);
 #endif /* CONFIG_TDLS */
index 5dae5de..877e6de 100644 (file)
@@ -285,14 +285,15 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
                        u16 capability, const u8 *supp_rates,
                        size_t supp_rates_len,
                        const struct ieee80211_ht_capabilities *ht_capab,
+                       const struct ieee80211_vht_capabilities *vht_capab,
                        u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
 {
        if (sm->ctx->tdls_peer_addset)
                return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
                                                 capability, supp_rates,
                                                 supp_rates_len, ht_capab,
-                                                qosinfo, ext_capab,
-                                                ext_capab_len);
+                                                vht_capab, qosinfo,
+                                                ext_capab, ext_capab_len);
        return -1;
 }
 #endif /* CONFIG_TDLS */
index 252737f..652197f 100644 (file)
@@ -430,6 +430,9 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
                } else if (*pos == WLAN_EID_HT_CAP) {
                        ie->ht_capabilities = pos + 2;
                        ie->ht_capabilities_len = pos[1];
+               } else if (*pos == WLAN_EID_VHT_CAP) {
+                       ie->vht_capabilities = pos + 2;
+                       ie->vht_capabilities_len = pos[1];
                } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
                        ie->qosinfo = pos[2];
                } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
index b212711..82a5c08 100644 (file)
@@ -51,6 +51,8 @@ struct wpa_eapol_ie_parse {
        size_t ext_supp_rates_len;
        const u8 *ht_capabilities;
        size_t ht_capabilities_len;
+       const u8 *vht_capabilities;
+       size_t vht_capabilities_len;
        u8 qosinfo;
 };
 
index f01e3b3..86ef022 100644 (file)
@@ -32,7 +32,7 @@ struct wps_nfc_pw_token {
        struct dl_list list;
        u8 pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN];
        u16 pw_id;
-       u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN];
+       u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN * 2 + 1];
        size_t dev_pw_len;
 };
 
@@ -3503,8 +3503,10 @@ int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,
 
        os_memcpy(token->pubkey_hash, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
        token->pw_id = pw_id;
-       os_memcpy(token->dev_pw, dev_pw, dev_pw_len);
-       token->dev_pw_len = dev_pw_len;
+       wpa_snprintf_hex_uppercase((char *) token->dev_pw,
+                                  sizeof(token->dev_pw),
+                                  dev_pw, dev_pw_len);
+       token->dev_pw_len = dev_pw_len * 2;
 
        dl_list_add(&reg->nfc_pw_tokens, &token->list);
 
index dbe9153..940cd74 100644 (file)
@@ -910,12 +910,12 @@ static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s,
 
 static int wpas_ctrl_nfc_get_handover_sel_wps(struct wpa_supplicant *wpa_s,
                                              char *reply, size_t max_len,
-                                             int ndef, int cr)
+                                             int ndef, int cr, char *uuid)
 {
        struct wpabuf *buf;
        int res;
 
-       buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr);
+       buf = wpas_wps_nfc_handover_sel(wpa_s, ndef, cr, uuid);
        if (buf == NULL)
                return -1;
 
@@ -934,7 +934,7 @@ static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
                                          char *cmd, char *reply,
                                          size_t max_len)
 {
-       char *pos;
+       char *pos, *pos2;
        int ndef;
 
        pos = os_strchr(cmd, ' ');
@@ -949,10 +949,13 @@ static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
        else
                return -1;
 
+       pos2 = os_strchr(pos, ' ');
+       if (pos2)
+               *pos2++ = '\0';
        if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
                return wpas_ctrl_nfc_get_handover_sel_wps(
                        wpa_s, reply, max_len, ndef,
-                       os_strcmp(pos, "WPS-CR") == 0);
+                       os_strcmp(pos, "WPS-CR") == 0, pos2);
        }
 
        return -1;
index 14acc5b..9a6da5f 100755 (executable)
@@ -61,6 +61,13 @@ def wpas_get_config_token():
     return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
 
 
+def wpas_get_er_config_token(uuid):
+    wpas = wpas_connect()
+    if (wpas == None):
+        return None
+    return wpas.request("WPS_ER_NFC_CONFIG_TOKEN NDEF " + uuid).rstrip().decode("hex")
+
+
 def wpas_get_password_token():
     wpas = wpas_connect()
     if (wpas == None):
@@ -75,15 +82,91 @@ def wpas_get_handover_req():
     return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex")
 
 
-def wpas_report_handover(req, sel):
+def wpas_get_handover_sel(uuid):
     wpas = wpas_connect()
     if (wpas == None):
         return None
-    return wpas.request("NFC_REPORT_HANDOVER INIT WPS " +
+    if uuid is None:
+        return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip().decode("hex")
+    return wpas.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR " + uuid).rstrip().decode("hex")
+
+
+def wpas_report_handover(req, sel, type):
+    wpas = wpas_connect()
+    if (wpas == None):
+        return None
+    return wpas.request("NFC_REPORT_HANDOVER " + type + " WPS " +
                         str(req).encode("hex") + " " +
                         str(sel).encode("hex"))
 
 
+class HandoverServer(nfc.handover.HandoverServer):
+    def __init__(self):
+        super(HandoverServer, self).__init__()
+
+    def process_request(self, request):
+        print "HandoverServer - request received"
+        print "Parsed handover request: " + request.pretty()
+
+        sel = nfc.ndef.HandoverSelectMessage(version="1.2")
+
+        for carrier in request.carriers:
+            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(self.uuid)
+                if data is None:
+                    print "Could not get handover select carrier record from wpa_supplicant"
+                    continue
+                print "Handover select carrier record from wpa_supplicant:"
+                print data.encode("hex")
+                self.sent_carrier = data
+
+                message = nfc.ndef.Message(data);
+                sel.add_carrier(message[0], "active", message[1:])
+
+        print "Handover select:"
+        print sel.pretty()
+        print str(sel).encode("hex")
+
+        print "Sending handover select"
+        return sel
+
+
+def wps_handover_resp(peer, uuid):
+    if uuid is None:
+        print "Trying to handle WPS handover"
+    else:
+        print "Trying to handle WPS handover with AP " + uuid
+
+    srv = HandoverServer()
+    srv.sent_carrier = None
+    srv.uuid = uuid
+
+    nfc.llcp.activate(peer);
+
+    try:
+        print "Trying handover";
+        srv.start()
+        print "Wait for disconnect"
+        while nfc.llcp.connected():
+            time.sleep(0.1)
+        print "Disconnected after handover"
+    except nfc.llcp.ConnectRefused:
+        print "Handover connection refused"
+        nfc.llcp.shutdown()
+        return
+
+    if srv.sent_carrier:
+        wpas_report_handover(srv.received_carrier, srv.sent_carrier, "RESP")
+
+    print "Remove peer"
+    nfc.llcp.shutdown()
+    print "Done with handover"
+    time.sleep(1)
+
+
 def wps_handover_init(peer):
     print "Trying to initiate WPS handover"
 
@@ -147,7 +230,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_report_handover(data, carrier.record)
+            wpas_report_handover(data, carrier.record, "INIT")
             wifi = nfc.ndef.WifiConfigRecord(carrier.record)
             print wifi.pretty()
 
@@ -198,6 +281,28 @@ def wps_write_config_tag(clf):
         time.sleep(0.1)
 
 
+def wps_write_er_config_tag(clf, uuid):
+    print "Write WPS ER config token"
+    data = wpas_get_er_config_token(uuid)
+    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()
@@ -252,10 +357,18 @@ def main():
     clf = nfc.ContactlessFrontend()
 
     try:
+        arg_uuid = None
+        if len(sys.argv) > 1:
+            arg_uuid = sys.argv[1]
+
         if len(sys.argv) > 1 and sys.argv[1] == "write-config":
             wps_write_config_tag(clf)
             raise SystemExit
 
+        if len(sys.argv) > 2 and sys.argv[1] == "write-er-config":
+            wps_write_er_config_tag(clf, sys.argv[2])
+            raise SystemExit
+
         if len(sys.argv) > 1 and sys.argv[1] == "write-password":
             wps_write_password_tag(clf)
             raise SystemExit
@@ -265,7 +378,12 @@ def main():
 
             tag = find_peer(clf)
             if isinstance(tag, nfc.DEP):
-                wps_handover_init(tag)
+                if arg_uuid is None:
+                    wps_handover_init(tag)
+                elif arg_uuid is "ap":
+                    wps_handover_resp(tag, None)
+                else:
+                    wps_handover_resp(tag, arg_uuid)
                 continue
 
             if tag.ndef:
index dfc3b76..7585b86 100644 (file)
@@ -554,6 +554,7 @@ static int wpa_supplicant_tdls_peer_addset(
        void *ctx, const u8 *peer, int add, u16 capability,
        const u8 *supp_rates, size_t supp_rates_len,
        const struct ieee80211_ht_capabilities *ht_capab,
+       const struct ieee80211_vht_capabilities *vht_capab,
        u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
 {
        struct wpa_supplicant *wpa_s = ctx;
@@ -574,6 +575,7 @@ static int wpa_supplicant_tdls_peer_addset(
                params.flags |= WPA_STA_WMM;
 
        params.ht_capabilities = ht_capab;
+       params.vht_capabilities = vht_capab;
        params.qosinfo = qosinfo;
        params.listen_interval = 0;
        params.supp_rates = supp_rates;
index c89479f..509a7c0 100644 (file)
@@ -2003,12 +2003,48 @@ struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s, int cr)
 }
 
 
+#ifdef CONFIG_WPS_NFC
+struct wpabuf * wpas_wps_er_nfc_handover_sel(struct wpa_supplicant *wpa_s,
+                                            int ndef, const char *uuid)
+{
+       struct wpabuf *ret;
+       u8 u[UUID_LEN];
+
+       if (!wpa_s->wps_er)
+               return NULL;
+
+       if (uuid == NULL || uuid_str2bin(uuid, u))
+               return NULL;
+
+       /*
+        * Handover Select carrier record for WPS uses the same format as
+        * configuration token.
+        */
+       ret = wps_er_nfc_config_token(wpa_s->wps_er, u);
+       if (ndef && ret) {
+               struct wpabuf *tmp;
+               tmp = ndef_build_wifi(ret);
+               wpabuf_free(ret);
+               if (tmp == NULL)
+                       return NULL;
+               ret = tmp;
+       }
+
+       return ret;
+}
+#endif /* CONFIG_WPS_NFC */
+
+
 struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
-                                         int ndef, int cr)
+                                         int ndef, int cr, const char *uuid)
 {
+       struct wpabuf *ret;
        if (!cr)
                return NULL;
-       return wpas_ap_wps_nfc_handover_sel(wpa_s, ndef);
+       ret = wpas_ap_wps_nfc_handover_sel(wpa_s, ndef);
+       if (ret)
+               return ret;
+       return wpas_wps_er_nfc_handover_sel(wpa_s, ndef, uuid);
 }
 
 
index 5bc5ffa..8bb9546 100644 (file)
@@ -70,7 +70,7 @@ int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
                          const struct wpabuf *data);
 struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s, int cr);
 struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
-                                         int ndef, int cr);
+                                         int ndef, int cr, const char *uuid);
 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,