]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP3: Push button Configurator in wpa_supplicant
authorJouni Malinen <quic_jouni@quicinc.com>
Fri, 22 Jul 2022 09:28:18 +0000 (12:28 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 22 Jul 2022 09:28:18 +0000 (12:28 +0300)
Extend DPP push button support in wpa_supplicant to allow the role of
the Configurator to be used. This provides similar functionality to the
way the DPP_PUSH_BUTTON command in hostapd worked when providing the
configuration parameters with that command (instead of building the
config object based on current AP configuration).

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/ap/hostapd.h
src/common/dpp.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/dpp_supplicant.c
wpa_supplicant/dpp_supplicant.h
wpa_supplicant/wpa_cli.c
wpa_supplicant/wpa_supplicant_i.h

index 33d4cb7840af37a8cd2795bab8d1e5d08f1765e0..c11cebc4ba2fef64a7031191d5ed91c0632db7a5 100644 (file)
@@ -43,13 +43,6 @@ struct mesh_conf;
 #define CTRL_IFACE_COOKIE_LEN 8
 #endif /* CONFIG_CTRL_IFACE_UDP */
 
-#define DPP_PB_INFO_COUNT 2
-
-struct dpp_pb_info {
-       u8 hash[SHA256_MAC_LEN];
-       struct os_reltime rx_time;
-};
-
 struct hostapd_iface;
 
 struct hapd_interfaces {
index 08febd94f2d7bc52cbb60896ce6b45d124d42aa2..b2129fccf0009d1d4bf48324fcb54517d23ed63d 100644 (file)
@@ -447,6 +447,13 @@ struct dpp_controller_config {
        bool (*tcp_msg_sent)(void *ctx, struct dpp_authentication *auth);
 };
 
+#define DPP_PB_INFO_COUNT 2
+
+struct dpp_pb_info {
+       u8 hash[SHA256_MAC_LEN];
+       struct os_reltime rx_time;
+};
+
 #ifdef CONFIG_TESTING_OPTIONS
 enum dpp_test_behavior {
        DPP_TEST_DISABLED = 0,
index 1c89e7d123509483ec9520aad4dd314d1135b1b0..7cccc1dd781c86421ec7e6342067dfaaad6b3d9b 100644 (file)
@@ -12455,7 +12455,10 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_DPP2 */
 #ifdef CONFIG_DPP3
        } else if (os_strcmp(buf, "DPP_PUSH_BUTTON") == 0) {
-               if (wpas_dpp_push_button(wpa_s) < 0)
+               if (wpas_dpp_push_button(wpa_s, NULL) < 0)
+                       reply_len = -1;
+       } else if (os_strncmp(buf, "DPP_PUSH_BUTTON ", 16) == 0) {
+               if (wpas_dpp_push_button(wpa_s, buf + 15) < 0)
                        reply_len = -1;
 #endif /* CONFIG_DPP3 */
 #endif /* CONFIG_DPP */
index 64eb5ea631b687be06efbff7a47ca880890c71e4..7901f01157c75081b1ffa30f26aa8084f646732d 100644 (file)
@@ -17,6 +17,7 @@
 #include "common/dpp.h"
 #include "common/gas.h"
 #include "common/gas_server.h"
+#include "crypto/random.h"
 #include "rsn_supp/wpa.h"
 #include "rsn_supp/pmksa_cache.h"
 #include "wpa_supplicant_i.h"
@@ -2032,6 +2033,42 @@ static void wpas_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
 }
 
 
+#ifdef CONFIG_DPP3
+
+static bool wpas_dpp_pb_active(struct wpa_supplicant *wpa_s)
+{
+       return (wpa_s->dpp_pb_time.sec || wpa_s->dpp_pb_time.usec) &&
+               wpa_s->dpp_pb_configurator;
+}
+
+
+static void wpas_dpp_remove_pb_hash(struct wpa_supplicant *wpa_s)
+{
+       int i;
+
+       if (!wpa_s->dpp_pb_bi)
+               return;
+       for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
+               struct dpp_pb_info *info = &wpa_s->dpp_pb[i];
+
+               if (info->rx_time.sec == 0 && info->rx_time.usec == 0)
+                       continue;
+               if (os_memcmp(info->hash, wpa_s->dpp_pb_resp_hash,
+                             SHA256_MAC_LEN) == 0) {
+                       /* Allow a new push button session to be established
+                        * immediately without the successfully completed
+                        * session triggering session overlap. */
+                       info->rx_time.sec = 0;
+                       info->rx_time.usec = 0;
+                       wpa_printf(MSG_DEBUG,
+                                  "DPP: Removed PB hash from session overlap detection due to successfully completed provisioning");
+               }
+       }
+}
+
+#endif /* CONFIG_DPP3 */
+
+
 static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src,
                                    const u8 *hdr, const u8 *buf, size_t len)
 {
@@ -2098,6 +2135,20 @@ static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src,
        dpp_auth_deinit(auth);
        wpa_s->dpp_auth = NULL;
        eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
+#ifdef CONFIG_DPP3
+       if (!wpa_s->dpp_pb_result_indicated && wpas_dpp_pb_active(wpa_s)) {
+               if (status == DPP_STATUS_OK)
+                       wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_RESULT
+                               "success");
+               else
+                       wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_RESULT
+                               "no-configuration-available");
+               wpa_s->dpp_pb_result_indicated = true;
+               if (status == DPP_STATUS_OK)
+                       wpas_dpp_remove_pb_hash(wpa_s);
+               wpas_dpp_push_button_stop(wpa_s);
+       }
+#endif /* CONFIG_DPP3 */
 }
 
 
@@ -3083,7 +3134,7 @@ wpas_dpp_pkex_finish(struct wpa_supplicant *wpa_s, const u8 *peer,
        wpa_s->dpp_pkex = NULL;
 
 #ifdef CONFIG_DPP3
-       if (wpa_s->dpp_pb_bi &&
+       if (wpa_s->dpp_pb_bi && !wpa_s->dpp_pb_configurator &&
            os_memcmp(bi->pubkey_hash_chirp, wpa_s->dpp_pb_init_hash,
                      SHA256_MAC_LEN) != 0) {
                char id[20];
@@ -3185,6 +3236,28 @@ wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant *wpa_s, const u8 *src,
        if (!bi)
                return;
 
+#ifdef CONFIG_DPP3
+       if (wpa_s->dpp_pb_bi && wpa_s->dpp_pb_configurator &&
+           os_memcmp(bi->pubkey_hash_chirp, wpa_s->dpp_pb_resp_hash,
+                     SHA256_MAC_LEN) != 0) {
+               char id[20];
+
+               wpa_printf(MSG_INFO,
+                          "DPP: Peer bootstrap key from PKEX does not match PB announcement hash");
+               wpa_hexdump(MSG_DEBUG,
+                           "DPP: Peer provided bootstrap key hash(chirp) from PB PKEX",
+                           bi->pubkey_hash_chirp, SHA256_MAC_LEN);
+               wpa_hexdump(MSG_DEBUG,
+                           "DPP: Peer provided bootstrap key hash(chirp) from PB announcement",
+                           wpa_s->dpp_pb_resp_hash, SHA256_MAC_LEN);
+
+               os_snprintf(id, sizeof(id), "%u", bi->id);
+               dpp_bootstrap_remove(wpa_s->dpp, id);
+               wpas_dpp_push_button_stop(wpa_s);
+               return;
+       }
+#endif /* CONFIG_DPP3 */
+
        os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
                    bi->id,
                    wpa_s->dpp_pkex_auth_cmd ? wpa_s->dpp_pkex_auth_cmd : "");
@@ -3202,6 +3275,220 @@ wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant *wpa_s, const u8 *src,
 
 #ifdef CONFIG_DPP3
 
+static void wpas_dpp_pb_pkex_init(struct wpa_supplicant *wpa_s,
+                                 unsigned int freq, const u8 *src,
+                                 const u8 *r_hash)
+{
+       struct dpp_pkex *pkex;
+       struct wpabuf *msg;
+       unsigned int wait_time;
+
+       if (wpa_s->dpp_pkex) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: Sending previously generated PKEX Exchange Request to "
+                          MACSTR, MAC2STR(src));
+               msg = wpa_s->dpp_pkex->exchange_req;
+               wait_time = wpa_s->max_remain_on_chan;
+               if (wait_time > 2000)
+                       wait_time = 2000;
+               offchannel_send_action(wpa_s, freq, src,
+                                      wpa_s->own_addr, broadcast,
+                                      wpabuf_head(msg), wpabuf_len(msg),
+                                      wait_time, wpas_dpp_tx_pkex_status, 0);
+               return;
+       }
+
+       wpa_printf(MSG_DEBUG, "DPP: Initiate PKEX for push button with "
+                  MACSTR, MAC2STR(src));
+
+       if (!wpa_s->dpp_pb_cmd) {
+               wpa_printf(MSG_INFO,
+                          "DPP: No configuration to provision as push button Configurator");
+               wpas_dpp_push_button_stop(wpa_s);
+               return;
+       }
+
+       wpa_s->dpp_pkex_bi = wpa_s->dpp_pb_bi;
+       os_memcpy(wpa_s->dpp_pb_resp_hash, r_hash, SHA256_MAC_LEN);
+
+       pkex = dpp_pkex_init(wpa_s, wpa_s->dpp_pkex_bi, wpa_s->own_addr,
+                            "PBPKEX", (const char *) wpa_s->dpp_pb_c_nonce,
+                            wpa_s->dpp_pb_bi->curve->nonce_len,
+                            true);
+       if (!pkex) {
+               wpas_dpp_push_button_stop(wpa_s);
+               return;
+       }
+       pkex->freq = freq;
+
+       wpa_s->dpp_pkex = pkex;
+       msg = wpa_s->dpp_pkex->exchange_req;
+       wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
+               " freq=%u type=%d", MAC2STR(src), freq,
+               DPP_PA_PKEX_EXCHANGE_REQ);
+       wait_time = wpa_s->max_remain_on_chan;
+       if (wait_time > 2000)
+               wait_time = 2000;
+       offchannel_send_action(wpa_s, pkex->freq, src,
+                              wpa_s->own_addr, broadcast,
+                              wpabuf_head(msg), wpabuf_len(msg),
+                              wait_time, wpas_dpp_tx_pkex_status, 0);
+       pkex->exch_req_wait_time = 2000;
+       pkex->exch_req_tries = 1;
+
+       /* Use the externally provided configuration */
+       os_free(wpa_s->dpp_pkex_auth_cmd);
+       wpa_s->dpp_pkex_auth_cmd = os_strdup(wpa_s->dpp_pb_cmd);
+       if (!wpa_s->dpp_pkex_auth_cmd)
+               wpas_dpp_push_button_stop(wpa_s);
+}
+
+
+static void
+wpas_dpp_rx_pb_presence_announcement(struct wpa_supplicant *wpa_s,
+                                    const u8 *src, const u8 *hdr,
+                                    const u8 *buf, size_t len,
+                                    unsigned int freq)
+{
+       const u8 *r_hash;
+       u16 r_hash_len;
+       unsigned int i;
+       bool found = false;
+       struct dpp_pb_info *info, *tmp;
+       struct os_reltime now, age;
+       struct wpabuf *msg;
+
+       os_get_reltime(&now);
+       wpa_printf(MSG_DEBUG, "DPP: Push Button Presence Announcement from "
+                  MACSTR, MAC2STR(src));
+
+       r_hash = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
+                             &r_hash_len);
+       if (!r_hash || r_hash_len != SHA256_MAC_LEN) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute");
+               return;
+       }
+       wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
+                   r_hash, r_hash_len);
+
+       for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
+               info = &wpa_s->dpp_pb[i];
+               if ((info->rx_time.sec == 0 && info->rx_time.usec == 0) ||
+                   os_memcmp(r_hash, info->hash, SHA256_MAC_LEN) != 0)
+                       continue;
+               wpa_printf(MSG_DEBUG,
+                          "DPP: Active push button Enrollee already known");
+               found = true;
+               info->rx_time = now;
+       }
+
+       if (!found) {
+               for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
+                       tmp = &wpa_s->dpp_pb[i];
+                       if (tmp->rx_time.sec == 0 && tmp->rx_time.usec == 0)
+                               continue;
+
+                       if (os_reltime_expired(&now, &tmp->rx_time, 120)) {
+                               wpa_hexdump(MSG_DEBUG,
+                                           "DPP: Push button Enrollee hash expired",
+                                           tmp->hash, SHA256_MAC_LEN);
+                               tmp->rx_time.sec = 0;
+                               tmp->rx_time.usec = 0;
+                               continue;
+                       }
+
+                       wpa_hexdump(MSG_DEBUG,
+                                   "DPP: Push button session overlap with hash",
+                                   tmp->hash, SHA256_MAC_LEN);
+                       if (!wpa_s->dpp_pb_result_indicated &&
+                           wpas_dpp_pb_active(wpa_s)) {
+                               wpa_msg(wpa_s, MSG_INFO,
+                                       DPP_EVENT_PB_RESULT "session-overlap");
+                               wpa_s->dpp_pb_result_indicated = true;
+                       }
+                       wpas_dpp_push_button_stop(wpa_s);
+                       return;
+               }
+
+               /* Replace the oldest entry */
+               info = &wpa_s->dpp_pb[0];
+               for (i = 1; i < DPP_PB_INFO_COUNT; i++) {
+                       tmp = &wpa_s->dpp_pb[i];
+                       if (os_reltime_before(&tmp->rx_time, &info->rx_time))
+                               info = tmp;
+               }
+               wpa_printf(MSG_DEBUG, "DPP: New active push button Enrollee");
+               os_memcpy(info->hash, r_hash, SHA256_MAC_LEN);
+               info->rx_time = now;
+       }
+
+       if (!wpas_dpp_pb_active(wpa_s)) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: Discard message since own push button has not been pressed");
+               return;
+       }
+
+       if (wpa_s->dpp_pb_announce_time.sec == 0 &&
+           wpa_s->dpp_pb_announce_time.usec == 0) {
+               /* Start a wait before allowing PKEX to be initiated */
+               wpa_s->dpp_pb_announce_time = now;
+       }
+
+       if (!wpa_s->dpp_pb_bi) {
+               int res;
+
+               res = dpp_bootstrap_gen(wpa_s->dpp, "type=pkex");
+               if (res < 0)
+                       return;
+               wpa_s->dpp_pb_bi = dpp_bootstrap_get_id(wpa_s->dpp, res);
+               if (!wpa_s->dpp_pb_bi)
+                       return;
+
+               if (random_get_bytes(wpa_s->dpp_pb_c_nonce,
+                                    wpa_s->dpp_pb_bi->curve->nonce_len)) {
+                       wpa_printf(MSG_ERROR,
+                                  "DPP: Failed to generate C-nonce");
+                       wpas_dpp_push_button_stop(wpa_s);
+                       return;
+               }
+       }
+
+       /* Skip the response if one was sent within last 50 ms since the
+        * Enrollee is going to send out at least three announcement messages.
+        */
+       os_reltime_sub(&now, &wpa_s->dpp_pb_last_resp, &age);
+       if (age.sec == 0 && age.usec < 50000) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: Skip Push Button Presence Announcement Response frame immediately after having sent one");
+               return;
+       }
+
+       msg = dpp_build_pb_announcement_resp(
+               wpa_s->dpp_pb_bi, r_hash, wpa_s->dpp_pb_c_nonce,
+               wpa_s->dpp_pb_bi->curve->nonce_len);
+       if (!msg) {
+               wpas_dpp_push_button_stop(wpa_s);
+               return;
+       }
+
+       wpa_printf(MSG_DEBUG,
+                  "DPP: Send Push Button Presence Announcement Response to "
+                  MACSTR, MAC2STR(src));
+       wpa_s->dpp_pb_last_resp = now;
+
+       wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
+               MAC2STR(src), freq, DPP_PA_PB_PRESENCE_ANNOUNCEMENT_RESP);
+       offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr, broadcast,
+                              wpabuf_head(msg), wpabuf_len(msg),
+                              0, NULL, 0);
+       wpabuf_free(msg);
+
+       if (os_reltime_expired(&now, &wpa_s->dpp_pb_announce_time, 15))
+               wpas_dpp_pb_pkex_init(wpa_s, freq, src, r_hash);
+}
+
+
 static void
 wpas_dpp_rx_pb_presence_announcement_resp(struct wpa_supplicant *wpa_s,
                                          const u8 *src, const u8 *hdr,
@@ -3212,9 +3499,10 @@ wpas_dpp_rx_pb_presence_announcement_resp(struct wpa_supplicant *wpa_s,
        u16 i_hash_len, r_hash_len, c_nonce_len;
        bool overlap = false;
 
-       if (!wpa_s->dpp_pb_announcement || !wpa_s->dpp_pb_bi) {
+       if (!wpa_s->dpp_pb_announcement || !wpa_s->dpp_pb_bi ||
+           wpa_s->dpp_pb_configurator) {
                wpa_printf(MSG_INFO,
-                          "DPP: Not in active push button mode - discard Push Button Presence Announcement Response from "
+                          "DPP: Not in active push button Enrollee mode - discard Push Button Presence Announcement Response from "
                           MACSTR, MAC2STR(src));
                return;
        }
@@ -3672,6 +3960,10 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
                break;
 #endif /* CONFIG_DPP2 */
 #ifdef CONFIG_DPP3
+       case DPP_PA_PB_PRESENCE_ANNOUNCEMENT:
+               wpas_dpp_rx_pb_presence_announcement(wpa_s, src, hdr,
+                                                    buf, len, freq);
+               break;
        case DPP_PA_PB_PRESENCE_ANNOUNCEMENT_RESP:
                wpas_dpp_rx_pb_presence_announcement_resp(wpa_s, src, hdr,
                                                          buf, len, freq);
@@ -3888,6 +4180,20 @@ wpas_dpp_gas_status_handler(void *ctx, struct wpabuf *resp, int ok)
        dpp_auth_deinit(wpa_s->dpp_auth);
        wpa_s->dpp_auth = NULL;
        wpabuf_free(resp);
+#ifdef CONFIG_DPP3
+       if (!wpa_s->dpp_pb_result_indicated && wpas_dpp_pb_active(wpa_s)) {
+               if (ok)
+                       wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_RESULT
+                               "success");
+               else
+                       wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_RESULT
+                               "could-not-connect");
+               wpa_s->dpp_pb_result_indicated = true;
+               if (ok)
+                       wpas_dpp_remove_pb_hash(wpa_s);
+               wpas_dpp_push_button_stop(wpa_s);
+       }
+#endif /* CONFIG_DPP3 */
 }
 
 
@@ -5170,7 +5476,37 @@ static void wpas_dpp_pb_next(void *eloop_ctx, void *timeout_ctx)
 }
 
 
-int wpas_dpp_push_button(struct wpa_supplicant *wpa_s)
+static void wpas_dpp_push_button_expire(void *eloop_ctx, void *timeout_ctx)
+{
+       struct wpa_supplicant *wpa_s = eloop_ctx;
+
+       wpa_printf(MSG_DEBUG,
+                  "DPP: Active push button Configurator mode expired");
+       wpas_dpp_push_button_stop(wpa_s);
+}
+
+
+static int wpas_dpp_push_button_configurator(struct wpa_supplicant *wpa_s,
+                                            const char *cmd)
+{
+       wpa_s->dpp_pb_configurator = true;
+       wpa_s->dpp_pb_announce_time.sec = 0;
+       wpa_s->dpp_pb_announce_time.usec = 0;
+       str_clear_free(wpa_s->dpp_pb_cmd);
+       wpa_s->dpp_pb_cmd = NULL;
+       if (cmd) {
+               wpa_s->dpp_pb_cmd = os_strdup(cmd);
+               if (!wpa_s->dpp_pb_cmd)
+                       return -1;
+       }
+       eloop_register_timeout(100, 0, wpas_dpp_push_button_expire,
+                              wpa_s, NULL);
+
+       return 0;
+}
+
+
+int wpas_dpp_push_button(struct wpa_supplicant *wpa_s, const char *cmd)
 {
        int res;
 
@@ -5182,6 +5518,13 @@ int wpas_dpp_push_button(struct wpa_supplicant *wpa_s)
 
        os_get_reltime(&wpa_s->dpp_pb_time);
 
+       if (cmd &&
+           (os_strstr(cmd, " role=configurator") ||
+            os_strstr(cmd, " conf=")))
+               return wpas_dpp_push_button_configurator(wpa_s, cmd);
+
+       wpa_s->dpp_pb_configurator = false;
+
        if (wpas_dpp_pb_channels(wpa_s) < 0)
                return -1;
        wpa_s->dpp_pb_freq_idx = 0;
@@ -5219,16 +5562,36 @@ void wpas_dpp_push_button_stop(struct wpa_supplicant *wpa_s)
                os_snprintf(id, sizeof(id), "%u", wpa_s->dpp_pb_bi->id);
                dpp_bootstrap_remove(wpa_s->dpp, id);
                wpa_s->dpp_pb_bi = NULL;
-               if (!wpa_s->dpp_pb_result_indicated)
+               if (!wpa_s->dpp_pb_result_indicated) {
                        wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_RESULT "failed");
+                       wpa_s->dpp_pb_result_indicated = true;
+               }
        }
 
        wpa_s->dpp_pb_resp_freq = 0;
        wpa_s->dpp_pb_stop_iter = 0;
        wpa_s->dpp_pb_discovery_done = false;
-       wpa_s->dpp_pb_result_indicated = false;
+       os_free(wpa_s->dpp_pb_cmd);
+       wpa_s->dpp_pb_cmd = NULL;
 
        eloop_cancel_timeout(wpas_dpp_pb_next, wpa_s, NULL);
+       eloop_cancel_timeout(wpas_dpp_push_button_expire, wpa_s, NULL);
+       if (wpas_dpp_pb_active(wpa_s)) {
+               wpa_printf(MSG_DEBUG, "DPP: Stop active push button mode");
+               if (!wpa_s->dpp_pb_result_indicated)
+                       wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_RESULT "failed");
+       }
+       wpa_s->dpp_pb_time.sec = 0;
+       wpa_s->dpp_pb_time.usec = 0;
+       dpp_pkex_free(wpa_s->dpp_pkex);
+       wpa_s->dpp_pkex = NULL;
+       os_free(wpa_s->dpp_pkex_auth_cmd);
+       wpa_s->dpp_pkex_auth_cmd = NULL;
+
+       wpa_s->dpp_pb_result_indicated = false;
+
+       str_clear_free(wpa_s->dpp_pb_cmd);
+       wpa_s->dpp_pb_cmd = NULL;
 }
 
 #endif /* CONFIG_DPP3 */
index f9ccc602887aee2f8bf9cd73a80f1109e47ca46e..e2bdd9d40e5f07549f49a6d0e8f42dc53653de70 100644 (file)
@@ -44,7 +44,7 @@ void wpas_dpp_chirp_stop(struct wpa_supplicant *wpa_s);
 int wpas_dpp_reconfig(struct wpa_supplicant *wpa_s, const char *cmd);
 int wpas_dpp_ca_set(struct wpa_supplicant *wpa_s, const char *cmd);
 int wpas_dpp_conf_set(struct wpa_supplicant *wpa_s, const char *cmd);
-int wpas_dpp_push_button(struct wpa_supplicant *wpa_s);
+int wpas_dpp_push_button(struct wpa_supplicant *wpa_s, const char *cmd);
 void wpas_dpp_push_button_stop(struct wpa_supplicant *wpa_s);
 
 #endif /* DPP_SUPPLICANT_H */
index ff39b5d12f5b5b5ef85acb193f845dbbe6d7a889..aa0f70589cfbc4107615c12c91986eb96b360c6b 100644 (file)
@@ -3165,7 +3165,7 @@ static int wpa_cli_cmd_dpp_stop_chirp(struct wpa_ctrl *ctrl, int argc,
 static int wpa_cli_cmd_dpp_push_button(struct wpa_ctrl *ctrl, int argc,
                                       char *argv[])
 {
-       return wpa_ctrl_command(ctrl, "DPP_PUSH_BUTTON");
+       return wpa_cli_cmd(ctrl, "DPP_PUSH_BUTTON", 0, argc, argv);
 }
 #endif /* CONFIG_DPP3 */
 #endif /* CONFIG_DPP */
index e98a34b409f315b62ef31f5b3962067f49a766e3..5f9bbe32df2de3cc8415de48490ecd0af340e4fb 100644 (file)
@@ -1496,6 +1496,7 @@ struct wpa_supplicant {
 #endif /* CONFIG_DPP2 */
 #ifdef CONFIG_DPP3
        struct os_reltime dpp_pb_time;
+       bool dpp_pb_configurator;
        int *dpp_pb_freqs;
        unsigned int dpp_pb_freq_idx;
        unsigned int dpp_pb_announce_count;
@@ -1508,6 +1509,11 @@ struct wpa_supplicant {
        u8 dpp_pb_c_nonce[DPP_MAX_NONCE_LEN];
        size_t dpp_pb_c_nonce_len;
        bool dpp_pb_result_indicated;
+       struct os_reltime dpp_pb_announce_time;
+       struct dpp_pb_info dpp_pb[DPP_PB_INFO_COUNT];
+       u8 dpp_pb_resp_hash[SHA256_MAC_LEN];
+       struct os_reltime dpp_pb_last_resp;
+       char *dpp_pb_cmd;
 #endif /* CONFIG_DPP3 */
 #ifdef CONFIG_TESTING_OPTIONS
        char *dpp_config_obj_override;