1 /*
2  * DPP over TCP
3  * Copyright (c) 2019-2020, The Linux Foundation
4  * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
5  *
6  * This software may be distributed under the terms of the BSD license.
7  * See README for more details.
8  */
9 
10 #include "utils/includes.h"
11 #include <fcntl.h>
12 
13 #include "utils/common.h"
14 #include "utils/ip_addr.h"
15 #include "utils/eloop.h"
16 #include "common/ieee802_11_common.h"
17 #include "common/wpa_ctrl.h"
18 #include "dpp.h"
19 #include "dpp_i.h"
20 
21 #ifdef CONFIG_DPP2
22 
23 struct dpp_connection {
24           struct dl_list list;
25           struct dpp_controller *ctrl;
26           struct dpp_relay_controller *relay;
27           struct dpp_global *global;
28           struct dpp_pkex *pkex;
29           struct dpp_authentication *auth;
30           void *msg_ctx;
31           void *cb_ctx;
32           int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
33           int (*pkex_done)(void *ctx, void *conn, struct dpp_bootstrap_info *bi);
34           bool (*tcp_msg_sent)(void *ctx, struct dpp_authentication *auth);
35           int sock;
36           u8 mac_addr[ETH_ALEN];
37           unsigned int freq;
38           u8 msg_len[4];
39           size_t msg_len_octets;
40           struct wpabuf *msg;
41           struct wpabuf *msg_out;
42           size_t msg_out_pos;
43           unsigned int read_eloop:1;
44           unsigned int write_eloop:1;
45           unsigned int on_tcp_tx_complete_gas_done:1;
46           unsigned int on_tcp_tx_complete_remove:1;
47           unsigned int on_tcp_tx_complete_auth_ok:1;
48           unsigned int gas_comeback_in_progress:1;
49           u8 gas_dialog_token;
50           char *name;
51           char *mud_url;
52           char *extra_conf_req_name;
53           char *extra_conf_req_value;
54           enum dpp_netrole netrole;
55 };
56 
57 /* Remote Controller */
58 struct dpp_relay_controller {
59           struct dl_list list;
60           struct dpp_global *global;
61           u8 pkhash[SHA256_MAC_LEN];
62           struct hostapd_ip_addr ipaddr;
63           void *msg_ctx;
64           void *cb_ctx;
65           void (*tx)(void *ctx, const u8 *addr, unsigned int freq, const u8 *msg,
66                        size_t len);
67           void (*gas_resp_tx)(void *ctx, const u8 *addr, u8 dialog_token,
68                                   int prot, struct wpabuf *buf);
69           struct dl_list conn; /* struct dpp_connection */
70 };
71 
72 /* Local Controller */
73 struct dpp_controller {
74           struct dpp_global *global;
75           u8 allowed_roles;
76           int qr_mutual;
77           int sock;
78           struct dl_list conn; /* struct dpp_connection */
79           char *configurator_params;
80           enum dpp_netrole netrole;
81           struct dpp_bootstrap_info *pkex_bi;
82           char *pkex_code;
83           char *pkex_identifier;
84           void *msg_ctx;
85           void *cb_ctx;
86           int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
87           bool (*tcp_msg_sent)(void *ctx, struct dpp_authentication *auth);
88 };
89 
90 static void dpp_controller_rx(int sd, void *eloop_ctx, void *sock_ctx);
91 static void dpp_conn_tx_ready(int sock, void *eloop_ctx, void *sock_ctx);
92 static void dpp_controller_auth_success(struct dpp_connection *conn,
93                                                   int initiator);
94 static void dpp_tcp_build_csr(void *eloop_ctx, void *timeout_ctx);
95 #ifdef CONFIG_DPP3
96 static void dpp_tcp_build_new_key(void *eloop_ctx, void *timeout_ctx);
97 #endif /* CONFIG_DPP3 */
98 static void dpp_tcp_gas_query_comeback(void *eloop_ctx, void *timeout_ctx);
99 static void dpp_relay_conn_timeout(void *eloop_ctx, void *timeout_ctx);
100 
101 
dpp_connection_free(struct dpp_connection * conn)102 static void dpp_connection_free(struct dpp_connection *conn)
103 {
104           if (conn->sock >= 0) {
105                     wpa_printf(MSG_DEBUG, "DPP: Close Controller socket %d",
106                                  conn->sock);
107                     eloop_unregister_sock(conn->sock, EVENT_TYPE_READ);
108                     eloop_unregister_sock(conn->sock, EVENT_TYPE_WRITE);
109                     close(conn->sock);
110           }
111           eloop_cancel_timeout(dpp_controller_conn_status_result_wait_timeout,
112                                    conn, NULL);
113           eloop_cancel_timeout(dpp_tcp_build_csr, conn, NULL);
114           eloop_cancel_timeout(dpp_tcp_gas_query_comeback, conn, NULL);
115           eloop_cancel_timeout(dpp_relay_conn_timeout, conn, NULL);
116 #ifdef CONFIG_DPP3
117           eloop_cancel_timeout(dpp_tcp_build_new_key, conn, NULL);
118 #endif /* CONFIG_DPP3 */
119           wpabuf_free(conn->msg);
120           wpabuf_free(conn->msg_out);
121           dpp_auth_deinit(conn->auth);
122           dpp_pkex_free(conn->pkex);
123           os_free(conn->name);
124           os_free(conn->mud_url);
125           os_free(conn->extra_conf_req_name);
126           os_free(conn->extra_conf_req_value);
127           os_free(conn);
128 }
129 
130 
dpp_connection_remove(struct dpp_connection * conn)131 static void dpp_connection_remove(struct dpp_connection *conn)
132 {
133           dl_list_del(&conn->list);
134           dpp_connection_free(conn);
135 }
136 
137 
dpp_relay_add_controller(struct dpp_global * dpp,struct dpp_relay_config * config)138 int dpp_relay_add_controller(struct dpp_global *dpp,
139                                    struct dpp_relay_config *config)
140 {
141           struct dpp_relay_controller *ctrl;
142           char txt[100];
143 
144           if (!dpp)
145                     return -1;
146 
147           ctrl = os_zalloc(sizeof(*ctrl));
148           if (!ctrl)
149                     return -1;
150           dl_list_init(&ctrl->conn);
151           ctrl->global = dpp;
152           os_memcpy(&ctrl->ipaddr, config->ipaddr, sizeof(*config->ipaddr));
153           os_memcpy(ctrl->pkhash, config->pkhash, SHA256_MAC_LEN);
154           ctrl->msg_ctx = config->msg_ctx;
155           ctrl->cb_ctx = config->cb_ctx;
156           ctrl->tx = config->tx;
157           ctrl->gas_resp_tx = config->gas_resp_tx;
158           wpa_printf(MSG_DEBUG, "DPP: Add Relay connection to Controller %s",
159                        hostapd_ip_txt(&ctrl->ipaddr, txt, sizeof(txt)));
160           dl_list_add(&dpp->controllers, &ctrl->list);
161           return 0;
162 }
163 
164 
165 static struct dpp_relay_controller *
dpp_relay_controller_get(struct dpp_global * dpp,const u8 * pkhash)166 dpp_relay_controller_get(struct dpp_global *dpp, const u8 *pkhash)
167 {
168           struct dpp_relay_controller *ctrl;
169 
170           if (!dpp)
171                     return NULL;
172 
173           dl_list_for_each(ctrl, &dpp->controllers, struct dpp_relay_controller,
174                                list) {
175                     if (os_memcmp(pkhash, ctrl->pkhash, SHA256_MAC_LEN) == 0)
176                               return ctrl;
177           }
178 
179           return NULL;
180 }
181 
182 
183 static struct dpp_relay_controller *
dpp_relay_controller_get_ctx(struct dpp_global * dpp,void * cb_ctx)184 dpp_relay_controller_get_ctx(struct dpp_global *dpp, void *cb_ctx)
185 {
186           struct dpp_relay_controller *ctrl;
187 
188           if (!dpp)
189                     return NULL;
190 
191           dl_list_for_each(ctrl, &dpp->controllers, struct dpp_relay_controller,
192                                list) {
193                     if (cb_ctx == ctrl->cb_ctx)
194                               return ctrl;
195           }
196 
197           return NULL;
198 }
199 
200 
201 static struct dpp_relay_controller *
dpp_relay_controller_get_addr(struct dpp_global * dpp,const struct sockaddr_in * addr)202 dpp_relay_controller_get_addr(struct dpp_global *dpp,
203                                     const struct sockaddr_in *addr)
204 {
205           struct dpp_relay_controller *ctrl;
206 
207           if (!dpp)
208                     return NULL;
209 
210           dl_list_for_each(ctrl, &dpp->controllers, struct dpp_relay_controller,
211                                list) {
212                     if (ctrl->ipaddr.af == AF_INET &&
213                         addr->sin_addr.s_addr == ctrl->ipaddr.u.v4.s_addr)
214                               return ctrl;
215           }
216 
217           if (dpp->tmp_controller &&
218               dpp->tmp_controller->ipaddr.af == AF_INET &&
219               addr->sin_addr.s_addr == dpp->tmp_controller->ipaddr.u.v4.s_addr)
220                     return dpp->tmp_controller;
221 
222           return NULL;
223 }
224 
225 
dpp_controller_gas_done(struct dpp_connection * conn)226 static void dpp_controller_gas_done(struct dpp_connection *conn)
227 {
228           struct dpp_authentication *auth = conn->auth;
229 
230           if (auth->waiting_csr) {
231                     wpa_printf(MSG_DEBUG, "DPP: Waiting for CSR");
232                     conn->on_tcp_tx_complete_gas_done = 0;
233                     return;
234           }
235 
236 #ifdef CONFIG_DPP3
237           if (auth->waiting_new_key) {
238                     wpa_printf(MSG_DEBUG, "DPP: Waiting for a new key");
239                     conn->on_tcp_tx_complete_gas_done = 0;
240                     return;
241           }
242 #endif /* CONFIG_DPP3 */
243 
244           if (auth->peer_version >= 2 &&
245               auth->conf_resp_status == DPP_STATUS_OK) {
246                     wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
247                     auth->waiting_conf_result = 1;
248                     return;
249           }
250 
251           wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT "conf_status=%d",
252                     auth->conf_resp_status);
253           dpp_connection_remove(conn);
254 }
255 
256 
dpp_tcp_send(struct dpp_connection * conn)257 static int dpp_tcp_send(struct dpp_connection *conn)
258 {
259           int res;
260 
261           if (!conn->msg_out) {
262                     eloop_unregister_sock(conn->sock, EVENT_TYPE_WRITE);
263                     conn->write_eloop = 0;
264                     return -1;
265           }
266           res = send(conn->sock,
267                        wpabuf_head_u8(conn->msg_out) + conn->msg_out_pos,
268                        wpabuf_len(conn->msg_out) - conn->msg_out_pos, 0);
269           if (res < 0) {
270                     wpa_printf(MSG_DEBUG, "DPP: Failed to send buffer: %s",
271                                  strerror(errno));
272                     dpp_connection_remove(conn);
273                     return -1;
274           }
275 
276           conn->msg_out_pos += res;
277           if (wpabuf_len(conn->msg_out) > conn->msg_out_pos) {
278                     wpa_printf(MSG_DEBUG,
279                                  "DPP: %u/%u bytes of message sent to Controller",
280                                  (unsigned int) conn->msg_out_pos,
281                                  (unsigned int) wpabuf_len(conn->msg_out));
282                     if (!conn->write_eloop &&
283                         eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
284                                                   dpp_conn_tx_ready, conn, NULL) == 0)
285                               conn->write_eloop = 1;
286                     return 1;
287           }
288 
289           wpa_printf(MSG_DEBUG, "DPP: Full message sent over TCP");
290           wpabuf_free(conn->msg_out);
291           conn->msg_out = NULL;
292           conn->msg_out_pos = 0;
293           eloop_unregister_sock(conn->sock, EVENT_TYPE_WRITE);
294           conn->write_eloop = 0;
295           if (!conn->read_eloop &&
296               eloop_register_sock(conn->sock, EVENT_TYPE_READ,
297                                         dpp_controller_rx, conn, NULL) == 0)
298                     conn->read_eloop = 1;
299           if (conn->on_tcp_tx_complete_remove) {
300                     if (conn->auth && conn->auth->connect_on_tx_status &&
301                         conn->tcp_msg_sent &&
302                         conn->tcp_msg_sent(conn->cb_ctx, conn->auth))
303                               return 0;
304                     dpp_connection_remove(conn);
305           } else if (conn->auth && (conn->ctrl || conn->auth->configurator) &&
306                        conn->on_tcp_tx_complete_gas_done) {
307                     dpp_controller_gas_done(conn);
308           } else if (conn->on_tcp_tx_complete_auth_ok) {
309                     conn->on_tcp_tx_complete_auth_ok = 0;
310                     dpp_controller_auth_success(conn, 1);
311           }
312 
313           return 0;
314 }
315 
316 
dpp_tcp_send_msg(struct dpp_connection * conn,const struct wpabuf * msg)317 static int dpp_tcp_send_msg(struct dpp_connection *conn,
318                                   const struct wpabuf *msg)
319 {
320           wpabuf_free(conn->msg_out);
321           conn->msg_out_pos = 0;
322           conn->msg_out = wpabuf_alloc(4 + wpabuf_len(msg) - 1);
323           if (!conn->msg_out)
324                     return -1;
325           wpabuf_put_be32(conn->msg_out, wpabuf_len(msg) - 1);
326           wpabuf_put_data(conn->msg_out, wpabuf_head_u8(msg) + 1,
327                               wpabuf_len(msg) - 1);
328 
329           if (dpp_tcp_send(conn) == 1) {
330                     if (!conn->write_eloop) {
331                               if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
332                                                             dpp_conn_tx_ready,
333                                                             conn, NULL) < 0)
334                                         return -1;
335                               conn->write_eloop = 1;
336                     }
337           }
338 
339           return 0;
340 }
341 
342 
dpp_controller_start_gas_client(struct dpp_connection * conn)343 static void dpp_controller_start_gas_client(struct dpp_connection *conn)
344 {
345           struct dpp_authentication *auth = conn->auth;
346           struct wpabuf *buf;
347           const char *dpp_name;
348 
349           dpp_name = conn->name ? conn->name : "Test";
350           buf = dpp_build_conf_req_helper(auth, dpp_name, conn->netrole,
351                                                   conn->mud_url, NULL,
352                                                   conn->extra_conf_req_name,
353                                                   conn->extra_conf_req_value);
354           if (!buf) {
355                     wpa_printf(MSG_DEBUG,
356                                  "DPP: No configuration request data available");
357                     return;
358           }
359 
360           dpp_tcp_send_msg(conn, buf);
361           wpabuf_free(buf);
362 }
363 
364 
dpp_controller_auth_success(struct dpp_connection * conn,int initiator)365 static void dpp_controller_auth_success(struct dpp_connection *conn,
366                                                   int initiator)
367 {
368           struct dpp_authentication *auth = conn->auth;
369 
370           if (!auth)
371                     return;
372 
373           wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
374           dpp_notify_auth_success(auth, initiator);
375 #ifdef CONFIG_TESTING_OPTIONS
376           if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
377                     wpa_printf(MSG_INFO,
378                                  "DPP: TESTING - stop at Authentication Confirm");
379                     if (auth->configurator) {
380                               /* Prevent GAS response */
381                               auth->auth_success = 0;
382                     }
383                     return;
384           }
385 #endif /* CONFIG_TESTING_OPTIONS */
386 
387           if (!auth->configurator)
388                     dpp_controller_start_gas_client(conn);
389 }
390 
391 
dpp_conn_tx_ready(int sock,void * eloop_ctx,void * sock_ctx)392 static void dpp_conn_tx_ready(int sock, void *eloop_ctx, void *sock_ctx)
393 {
394           struct dpp_connection *conn = eloop_ctx;
395 
396           wpa_printf(MSG_DEBUG, "DPP: TCP socket %d ready for TX", sock);
397           dpp_tcp_send(conn);
398 }
399 
400 
dpp_ipaddr_to_sockaddr(struct sockaddr * addr,socklen_t * addrlen,const struct hostapd_ip_addr * ipaddr,int port)401 static int dpp_ipaddr_to_sockaddr(struct sockaddr *addr, socklen_t *addrlen,
402                                           const struct hostapd_ip_addr *ipaddr,
403                                           int port)
404 {
405           struct sockaddr_in *dst;
406 #ifdef CONFIG_IPV6
407           struct sockaddr_in6 *dst6;
408 #endif /* CONFIG_IPV6 */
409 
410           switch (ipaddr->af) {
411           case AF_INET:
412                     dst = (struct sockaddr_in *) addr;
413                     os_memset(dst, 0, sizeof(*dst));
414                     dst->sin_family = AF_INET;
415                     dst->sin_addr.s_addr = ipaddr->u.v4.s_addr;
416                     dst->sin_port = htons(port);
417                     *addrlen = sizeof(*dst);
418                     break;
419 #ifdef CONFIG_IPV6
420           case AF_INET6:
421                     dst6 = (struct sockaddr_in6 *) addr;
422                     os_memset(dst6, 0, sizeof(*dst6));
423                     dst6->sin6_family = AF_INET6;
424                     os_memcpy(&dst6->sin6_addr, &ipaddr->u.v6,
425                                 sizeof(struct in6_addr));
426                     dst6->sin6_port = htons(port);
427                     *addrlen = sizeof(*dst6);
428                     break;
429 #endif /* CONFIG_IPV6 */
430           default:
431                     return -1;
432           }
433 
434           return 0;
435 }
436 
437 
dpp_relay_conn_timeout(void * eloop_ctx,void * timeout_ctx)438 static void dpp_relay_conn_timeout(void *eloop_ctx, void *timeout_ctx)
439 {
440           struct dpp_connection *conn = eloop_ctx;
441 
442           wpa_printf(MSG_DEBUG,
443                        "DPP: Timeout while waiting for relayed connection to complete");
444           dpp_connection_remove(conn);
445 }
446 
447 
448 static struct dpp_connection *
dpp_relay_new_conn(struct dpp_relay_controller * ctrl,const u8 * src,unsigned int freq)449 dpp_relay_new_conn(struct dpp_relay_controller *ctrl, const u8 *src,
450                        unsigned int freq)
451 {
452           struct dpp_connection *conn;
453           struct sockaddr_storage addr;
454           socklen_t addrlen;
455           char txt[100];
456 
457           if (dl_list_len(&ctrl->conn) >= 15) {
458                     wpa_printf(MSG_DEBUG,
459                                  "DPP: Too many ongoing Relay connections to the Controller - cannot start a new one");
460                     return NULL;
461           }
462 
463           if (dpp_ipaddr_to_sockaddr((struct sockaddr *) &addr, &addrlen,
464                                            &ctrl->ipaddr, DPP_TCP_PORT) < 0)
465                     return NULL;
466 
467           conn = os_zalloc(sizeof(*conn));
468           if (!conn)
469                     return NULL;
470 
471           conn->global = ctrl->global;
472           conn->relay = ctrl;
473           conn->msg_ctx = ctrl->msg_ctx;
474           conn->cb_ctx = ctrl->global->cb_ctx;
475           os_memcpy(conn->mac_addr, src, ETH_ALEN);
476           conn->freq = freq;
477 
478           conn->sock = socket(AF_INET, SOCK_STREAM, 0);
479           if (conn->sock < 0)
480                     goto fail;
481           wpa_printf(MSG_DEBUG, "DPP: TCP relay socket %d connection to %s",
482                        conn->sock, hostapd_ip_txt(&ctrl->ipaddr, txt, sizeof(txt)));
483 
484           if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
485                     wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
486                                  strerror(errno));
487                     goto fail;
488           }
489 
490           if (connect(conn->sock, (struct sockaddr *) &addr, addrlen) < 0) {
491                     if (errno != EINPROGRESS) {
492                               wpa_printf(MSG_DEBUG, "DPP: Failed to connect: %s",
493                                            strerror(errno));
494                               goto fail;
495                     }
496 
497                     /*
498                      * Continue connecting in the background; eloop will call us
499                      * once the connection is ready (or failed).
500                      */
501           }
502 
503           if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
504                                         dpp_conn_tx_ready, conn, NULL) < 0)
505                     goto fail;
506           conn->write_eloop = 1;
507 
508           eloop_cancel_timeout(dpp_relay_conn_timeout, conn, NULL);
509           eloop_register_timeout(20, 0, dpp_relay_conn_timeout, conn, NULL);
510 
511           dl_list_add(&ctrl->conn, &conn->list);
512           return conn;
513 fail:
514           dpp_connection_free(conn);
515           return NULL;
516 }
517 
518 
dpp_tcp_encaps(const u8 * hdr,const u8 * buf,size_t len)519 static struct wpabuf * dpp_tcp_encaps(const u8 *hdr, const u8 *buf, size_t len)
520 {
521           struct wpabuf *msg;
522 
523           msg = wpabuf_alloc(4 + 1 + DPP_HDR_LEN + len);
524           if (!msg)
525                     return NULL;
526           wpabuf_put_be32(msg, 1 + DPP_HDR_LEN + len);
527           wpabuf_put_u8(msg, WLAN_PA_VENDOR_SPECIFIC);
528           wpabuf_put_data(msg, hdr, DPP_HDR_LEN);
529           wpabuf_put_data(msg, buf, len);
530           wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", msg);
531           return msg;
532 }
533 
534 
dpp_relay_tx(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)535 static int dpp_relay_tx(struct dpp_connection *conn, const u8 *hdr,
536                               const u8 *buf, size_t len)
537 {
538           u8 type = hdr[DPP_HDR_LEN - 1];
539 
540           wpa_printf(MSG_DEBUG,
541                        "DPP: Continue already established Relay/Controller connection for this session");
542           wpabuf_free(conn->msg_out);
543           conn->msg_out_pos = 0;
544           conn->msg_out = dpp_tcp_encaps(hdr, buf, len);
545           if (!conn->msg_out) {
546                     dpp_connection_remove(conn);
547                     return -1;
548           }
549 
550           /* TODO: for proto ver 1, need to do remove connection based on GAS Resp
551            * TX status */
552           if (type == DPP_PA_CONFIGURATION_RESULT)
553                     conn->on_tcp_tx_complete_remove = 1;
554           dpp_tcp_send(conn);
555           return 0;
556 }
557 
558 
559 static struct dpp_connection *
dpp_relay_match_ctrl(struct dpp_relay_controller * ctrl,const u8 * src,unsigned int freq,u8 type)560 dpp_relay_match_ctrl(struct dpp_relay_controller *ctrl, const u8 *src,
561                          unsigned int freq, u8 type)
562 {
563           struct dpp_connection *conn;
564 
565           dl_list_for_each(conn, &ctrl->conn, struct dpp_connection, list) {
566                     if (ether_addr_equal(src, conn->mac_addr))
567                               return conn;
568                     if ((type == DPP_PA_PKEX_EXCHANGE_RESP ||
569                          type == DPP_PA_AUTHENTICATION_RESP) &&
570                         conn->freq == 0 &&
571                         is_broadcast_ether_addr(conn->mac_addr)) {
572                               wpa_printf(MSG_DEBUG,
573                                            "DPP: Associate this peer to the new Controller initiated connection");
574                               os_memcpy(conn->mac_addr, src, ETH_ALEN);
575                               conn->freq = freq;
576                               return conn;
577                     }
578           }
579 
580           return NULL;
581 }
582 
583 
dpp_relay_rx_action(struct dpp_global * dpp,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq,const u8 * i_bootstrap,const u8 * r_bootstrap,void * cb_ctx)584 int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr,
585                               const u8 *buf, size_t len, unsigned int freq,
586                               const u8 *i_bootstrap, const u8 *r_bootstrap,
587                               void *cb_ctx)
588 {
589           struct dpp_relay_controller *ctrl;
590           struct dpp_connection *conn;
591           u8 type = hdr[DPP_HDR_LEN - 1];
592 
593           /* Check if there is an already started session for this peer and if so,
594            * continue that session (send this over TCP) and return 0.
595            */
596           if (type != DPP_PA_PEER_DISCOVERY_REQ &&
597               type != DPP_PA_PEER_DISCOVERY_RESP &&
598               type != DPP_PA_PRESENCE_ANNOUNCEMENT &&
599               type != DPP_PA_RECONFIG_ANNOUNCEMENT) {
600                     dl_list_for_each(ctrl, &dpp->controllers,
601                                          struct dpp_relay_controller, list) {
602                               conn = dpp_relay_match_ctrl(ctrl, src, freq, type);
603                               if (conn)
604                                         return dpp_relay_tx(conn, hdr, buf, len);
605                     }
606 
607                     if (dpp->tmp_controller) {
608                               conn = dpp_relay_match_ctrl(dpp->tmp_controller, src,
609                                                                 freq, type);
610                               if (conn)
611                                         return dpp_relay_tx(conn, hdr, buf, len);
612                     }
613           }
614 
615           if (type == DPP_PA_PRESENCE_ANNOUNCEMENT ||
616               type == DPP_PA_RECONFIG_ANNOUNCEMENT) {
617                     /* TODO: Could send this to all configured Controllers. For now,
618                      * only the first Controller is supported. */
619                     ctrl = dpp_relay_controller_get_ctx(dpp, cb_ctx);
620           } else if (type == DPP_PA_PKEX_EXCHANGE_REQ) {
621                     ctrl = dpp_relay_controller_get_ctx(dpp, cb_ctx);
622           } else {
623                     if (!r_bootstrap)
624                               return -1;
625                     ctrl = dpp_relay_controller_get(dpp, r_bootstrap);
626           }
627           if (!ctrl)
628                     return -1;
629 
630           if (type == DPP_PA_PRESENCE_ANNOUNCEMENT ||
631               type == DPP_PA_RECONFIG_ANNOUNCEMENT) {
632                     conn = dpp_relay_match_ctrl(ctrl, src, freq, type);
633                     if (conn &&
634                         (!conn->auth || conn->auth->waiting_auth_resp)) {
635                               wpa_printf(MSG_DEBUG,
636                                            "DPP: Use existing TCP connection to Controller since no Auth Resp seen on it yet");
637                               return dpp_relay_tx(conn, hdr, buf, len);
638                     }
639           }
640 
641           wpa_printf(MSG_DEBUG,
642                        "DPP: Authentication Request for a configured Controller");
643           conn = dpp_relay_new_conn(ctrl, src, freq);
644           if (!conn)
645                     return -1;
646 
647           conn->msg_out = dpp_tcp_encaps(hdr, buf, len);
648           if (!conn->msg_out) {
649                     dpp_connection_remove(conn);
650                     return -1;
651           }
652           /* Message will be sent in dpp_conn_tx_ready() */
653 
654           return 0;
655 }
656 
657 
658 static struct dpp_connection *
dpp_relay_find_conn(struct dpp_relay_controller * ctrl,const u8 * src)659 dpp_relay_find_conn(struct dpp_relay_controller *ctrl, const u8 *src)
660 {
661           struct dpp_connection *conn;
662 
663           dl_list_for_each(conn, &ctrl->conn, struct dpp_connection, list) {
664                     if (ether_addr_equal(src, conn->mac_addr))
665                               return conn;
666           }
667 
668           return NULL;
669 }
670 
671 
dpp_relay_rx_gas_req(struct dpp_global * dpp,const u8 * src,const u8 * data,size_t data_len)672 int dpp_relay_rx_gas_req(struct dpp_global *dpp, const u8 *src, const u8 *data,
673                                size_t data_len)
674 {
675           struct dpp_relay_controller *ctrl;
676           struct dpp_connection *conn = NULL;
677           struct wpabuf *msg;
678 
679           /* Check if there is a successfully completed authentication for this
680            * and if so, continue that session (send this over TCP) and return 0.
681            */
682           dl_list_for_each(ctrl, &dpp->controllers,
683                                struct dpp_relay_controller, list) {
684                     conn = dpp_relay_find_conn(ctrl, src);
685                     if (conn)
686                               break;
687           }
688 
689           if (!conn && dpp->tmp_controller)
690                     conn = dpp_relay_find_conn(dpp->tmp_controller, src);
691 
692           if (!conn)
693                     return -1;
694 
695           msg = wpabuf_alloc(4 + 1 + data_len);
696           if (!msg)
697                     return -1;
698           wpabuf_put_be32(msg, 1 + data_len);
699           wpabuf_put_u8(msg, WLAN_PA_GAS_INITIAL_REQ);
700           wpabuf_put_data(msg, data, data_len);
701           wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", msg);
702 
703           wpabuf_free(conn->msg_out);
704           conn->msg_out_pos = 0;
705           conn->msg_out = msg;
706           dpp_tcp_send(conn);
707           return 0;
708 }
709 
710 
dpp_relay_controller_available(struct dpp_global * dpp)711 bool dpp_relay_controller_available(struct dpp_global *dpp)
712 {
713           return dpp && dl_list_len(&dpp->controllers) > 0;
714 }
715 
716 
dpp_controller_free(struct dpp_controller * ctrl)717 static void dpp_controller_free(struct dpp_controller *ctrl)
718 {
719           struct dpp_connection *conn, *tmp;
720 
721           if (!ctrl)
722                     return;
723 
724           dl_list_for_each_safe(conn, tmp, &ctrl->conn, struct dpp_connection,
725                                     list)
726                     dpp_connection_remove(conn);
727 
728           if (ctrl->sock >= 0) {
729                     close(ctrl->sock);
730                     eloop_unregister_sock(ctrl->sock, EVENT_TYPE_READ);
731           }
732           os_free(ctrl->configurator_params);
733           os_free(ctrl->pkex_code);
734           os_free(ctrl->pkex_identifier);
735           os_free(ctrl);
736 }
737 
738 
dpp_controller_rx_auth_req(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)739 static int dpp_controller_rx_auth_req(struct dpp_connection *conn,
740                                               const u8 *hdr, const u8 *buf, size_t len)
741 {
742           const u8 *r_bootstrap, *i_bootstrap;
743           u16 r_bootstrap_len, i_bootstrap_len;
744           struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
745 
746           if (!conn->ctrl)
747                     return 0;
748 
749           wpa_printf(MSG_DEBUG, "DPP: Authentication Request");
750 
751           r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
752                                            &r_bootstrap_len);
753           if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
754                     wpa_printf(MSG_INFO,
755                                  "Missing or invalid required Responder Bootstrapping Key Hash attribute");
756                     return -1;
757           }
758           wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
759                         r_bootstrap, r_bootstrap_len);
760 
761           i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
762                                            &i_bootstrap_len);
763           if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
764                     wpa_printf(MSG_INFO,
765                                  "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
766                     return -1;
767           }
768           wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
769                         i_bootstrap, i_bootstrap_len);
770 
771           /* Try to find own and peer bootstrapping key matches based on the
772            * received hash values */
773           dpp_bootstrap_find_pair(conn->ctrl->global, i_bootstrap, r_bootstrap,
774                                         &own_bi, &peer_bi);
775           if (!own_bi) {
776                     wpa_printf(MSG_INFO,
777                               "No matching own bootstrapping key found - ignore message");
778                     return -1;
779           }
780 
781           if (conn->auth) {
782                     wpa_printf(MSG_INFO,
783                                  "Already in DPP authentication exchange - ignore new one");
784                     return 0;
785           }
786 
787           conn->auth = dpp_auth_req_rx(conn->ctrl->global, conn->msg_ctx,
788                                              conn->ctrl->allowed_roles,
789                                              conn->ctrl->qr_mutual,
790                                              peer_bi, own_bi, -1, hdr, buf, len);
791           if (!conn->auth) {
792                     wpa_printf(MSG_DEBUG, "DPP: No response generated");
793                     return -1;
794           }
795 
796           if (dpp_set_configurator(conn->auth,
797                                          conn->ctrl->configurator_params) < 0)
798                     return -1;
799 
800           return dpp_tcp_send_msg(conn, conn->auth->resp_msg);
801 }
802 
803 
dpp_controller_rx_auth_resp(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)804 static int dpp_controller_rx_auth_resp(struct dpp_connection *conn,
805                                                const u8 *hdr, const u8 *buf, size_t len)
806 {
807           struct dpp_authentication *auth = conn->auth;
808           struct wpabuf *msg;
809           int res;
810 
811           if (!auth)
812                     return -1;
813 
814           wpa_printf(MSG_DEBUG, "DPP: Authentication Response");
815 
816           msg = dpp_auth_resp_rx(auth, hdr, buf, len);
817           if (!msg) {
818                     if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
819                               wpa_printf(MSG_DEBUG,
820                                            "DPP: Start wait for full response");
821                               return 0;
822                     }
823                     wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
824                     return -1;
825           }
826 
827           conn->on_tcp_tx_complete_auth_ok = 1;
828           res = dpp_tcp_send_msg(conn, msg);
829           wpabuf_free(msg);
830           return res;
831 }
832 
833 
dpp_controller_rx_auth_conf(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)834 static int dpp_controller_rx_auth_conf(struct dpp_connection *conn,
835                                                const u8 *hdr, const u8 *buf, size_t len)
836 {
837           struct dpp_authentication *auth = conn->auth;
838 
839           wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation");
840 
841           if (!auth) {
842                     wpa_printf(MSG_DEBUG,
843                                  "DPP: No DPP Authentication in progress - drop");
844                     return -1;
845           }
846 
847           if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
848                     wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
849                     return -1;
850           }
851 
852           dpp_controller_auth_success(conn, 0);
853           return 0;
854 }
855 
856 
dpp_controller_conn_status_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)857 void dpp_controller_conn_status_result_wait_timeout(void *eloop_ctx,
858                                                                 void *timeout_ctx)
859 {
860           struct dpp_connection *conn = eloop_ctx;
861 
862           if (!conn->auth->waiting_conf_result)
863                     return;
864 
865           wpa_printf(MSG_DEBUG,
866                        "DPP: Timeout while waiting for Connection Status Result");
867           wpa_msg(conn->msg_ctx, MSG_INFO,
868                     DPP_EVENT_CONN_STATUS_RESULT "timeout");
869           dpp_connection_remove(conn);
870 }
871 
872 
dpp_controller_rx_conf_result(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)873 static int dpp_controller_rx_conf_result(struct dpp_connection *conn,
874                                                    const u8 *hdr, const u8 *buf,
875                                                    size_t len)
876 {
877           struct dpp_authentication *auth = conn->auth;
878           enum dpp_status_error status;
879           void *msg_ctx = conn->msg_ctx;
880 
881           if (!conn->ctrl && (!auth || !auth->configurator))
882                     return 0;
883 
884           wpa_printf(MSG_DEBUG, "DPP: Configuration Result");
885 
886           if (!auth || !auth->waiting_conf_result) {
887                     wpa_printf(MSG_DEBUG,
888                                  "DPP: No DPP Configuration waiting for result - drop");
889                     return -1;
890           }
891 
892           status = dpp_conf_result_rx(auth, hdr, buf, len);
893           if (status == DPP_STATUS_OK && auth->send_conn_status) {
894                     wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
895                               "wait_conn_status=1 conf_resp_status=%d",
896                               auth->conf_resp_status);
897                     wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
898                     auth->waiting_conn_status_result = 1;
899                     eloop_cancel_timeout(
900                               dpp_controller_conn_status_result_wait_timeout,
901                               conn, NULL);
902                     eloop_register_timeout(
903                               16, 0, dpp_controller_conn_status_result_wait_timeout,
904                               conn, NULL);
905                     return 0;
906           }
907           if (status == DPP_STATUS_OK)
908                     wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
909                               "conf_resp_status=%d", auth->conf_resp_status);
910           else
911                     wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
912           return -1; /* to remove the completed connection */
913 }
914 
915 
dpp_controller_rx_conn_status_result(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)916 static int dpp_controller_rx_conn_status_result(struct dpp_connection *conn,
917                                                             const u8 *hdr, const u8 *buf,
918                                                             size_t len)
919 {
920           struct dpp_authentication *auth = conn->auth;
921           enum dpp_status_error status;
922           u8 ssid[SSID_MAX_LEN];
923           size_t ssid_len = 0;
924           char *channel_list = NULL;
925 
926           if (!conn->ctrl)
927                     return 0;
928 
929           wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
930 
931           if (!auth || !auth->waiting_conn_status_result) {
932                     wpa_printf(MSG_DEBUG,
933                                  "DPP: No DPP Configuration waiting for connection status result - drop");
934                     return -1;
935           }
936 
937           status = dpp_conn_status_result_rx(auth, hdr, buf, len,
938                                                      ssid, &ssid_len, &channel_list);
939           wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
940                     "result=%d ssid=%s channel_list=%s",
941                     status, wpa_ssid_txt(ssid, ssid_len),
942                     channel_list ? channel_list : "N/A");
943           os_free(channel_list);
944           return -1; /* to remove the completed connection */
945 }
946 
947 
dpp_controller_rx_presence_announcement(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)948 static int dpp_controller_rx_presence_announcement(struct dpp_connection *conn,
949                                                                const u8 *hdr, const u8 *buf,
950                                                                size_t len)
951 {
952           const u8 *r_bootstrap;
953           u16 r_bootstrap_len;
954           struct dpp_bootstrap_info *peer_bi;
955           struct dpp_authentication *auth;
956           struct dpp_global *dpp = conn->ctrl->global;
957 
958           wpa_printf(MSG_DEBUG, "DPP: Presence Announcement");
959 
960           r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
961                                            &r_bootstrap_len);
962           if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
963                     wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
964                               "Missing or invalid required Responder Bootstrapping Key Hash attribute");
965                     return -1;
966           }
967           wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
968                         r_bootstrap, r_bootstrap_len);
969           peer_bi = dpp_bootstrap_find_chirp(dpp, r_bootstrap);
970           if (!peer_bi) {
971                     wpa_printf(MSG_DEBUG,
972                                  "DPP: No matching bootstrapping information found");
973                     return -1;
974           }
975 
976           if (conn->auth) {
977                     wpa_printf(MSG_DEBUG,
978                                  "DPP: Ignore Presence Announcement during ongoing Authentication");
979                     return 0;
980           }
981 
982           auth = dpp_auth_init(dpp, conn->msg_ctx, peer_bi, NULL,
983                                    DPP_CAPAB_CONFIGURATOR, -1, NULL, 0);
984           if (!auth)
985                     return -1;
986           if (dpp_set_configurator(auth, conn->ctrl->configurator_params) < 0) {
987                     dpp_auth_deinit(auth);
988                     return -1;
989           }
990 
991           conn->auth = auth;
992           return dpp_tcp_send_msg(conn, conn->auth->req_msg);
993 }
994 
995 
dpp_controller_rx_reconfig_announcement(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)996 static int dpp_controller_rx_reconfig_announcement(struct dpp_connection *conn,
997                                                                const u8 *hdr, const u8 *buf,
998                                                                size_t len)
999 {
1000           const u8 *csign_hash, *fcgroup, *a_nonce, *e_id;
1001           u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len;
1002           struct dpp_configurator *conf;
1003           struct dpp_global *dpp = conn->ctrl->global;
1004           struct dpp_authentication *auth;
1005           u16 group;
1006 
1007           if (conn->auth) {
1008                     wpa_printf(MSG_DEBUG,
1009                                  "DPP: Ignore Reconfig Announcement during ongoing Authentication");
1010                     return -1;
1011           }
1012 
1013           wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement");
1014 
1015           csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
1016                                           &csign_hash_len);
1017           if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
1018                     wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1019                               "Missing or invalid required Configurator C-sign key Hash attribute");
1020                     return -1;
1021           }
1022           wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
1023                         csign_hash, csign_hash_len);
1024           conf = dpp_configurator_find_kid(dpp, csign_hash);
1025           if (!conf) {
1026                     wpa_printf(MSG_DEBUG,
1027                                  "DPP: No matching Configurator information found");
1028                     return -1;
1029           }
1030 
1031           fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
1032                                      &fcgroup_len);
1033           if (!fcgroup || fcgroup_len != 2) {
1034                     wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1035                               "Missing or invalid required Finite Cyclic Group attribute");
1036                     return -1;
1037           }
1038           group = WPA_GET_LE16(fcgroup);
1039           wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group);
1040 
1041           a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len);
1042           e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len);
1043 
1044           auth = dpp_reconfig_init(dpp, conn->msg_ctx, conf, 0, group,
1045                                          a_nonce, a_nonce_len, e_id, e_id_len);
1046           if (!auth)
1047                     return -1;
1048           if (dpp_set_configurator(auth, conn->ctrl->configurator_params) < 0) {
1049                     dpp_auth_deinit(auth);
1050                     return -1;
1051           }
1052 
1053           conn->auth = auth;
1054           return dpp_tcp_send_msg(conn, auth->reconfig_req_msg);
1055 }
1056 
1057 
dpp_controller_rx_reconfig_auth_resp(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1058 static int dpp_controller_rx_reconfig_auth_resp(struct dpp_connection *conn,
1059                                                             const u8 *hdr, const u8 *buf,
1060                                                             size_t len)
1061 {
1062           struct dpp_authentication *auth = conn->auth;
1063           struct wpabuf *conf;
1064           int res;
1065 
1066           wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response");
1067 
1068           if (!auth || !auth->reconfig || !auth->configurator) {
1069                     wpa_printf(MSG_DEBUG,
1070                                  "DPP: No DPP Reconfig Authentication in progress - drop");
1071                     return -1;
1072           }
1073 
1074           conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
1075           if (!conf)
1076                     return -1;
1077 
1078           res = dpp_tcp_send_msg(conn, conf);
1079           wpabuf_free(conf);
1080           return res;
1081 }
1082 
1083 
dpp_controller_rx_pkex_exchange_req(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1084 static int dpp_controller_rx_pkex_exchange_req(struct dpp_connection *conn,
1085                                                          const u8 *hdr, const u8 *buf,
1086                                                          size_t len)
1087 {
1088           struct dpp_controller *ctrl = conn->ctrl;
1089 
1090           if (!ctrl)
1091                     return 0;
1092 
1093           wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request");
1094 
1095           /* TODO: Support multiple PKEX codes by iterating over all the enabled
1096            * values here */
1097 
1098           if (!ctrl->pkex_code || !ctrl->pkex_bi) {
1099                     wpa_printf(MSG_DEBUG,
1100                                  "DPP: No PKEX code configured - ignore request");
1101                     return 0;
1102           }
1103 
1104           if (conn->pkex || conn->auth) {
1105                     wpa_printf(MSG_DEBUG,
1106                                  "DPP: Already in PKEX/Authentication session - ignore new PKEX request");
1107                     return 0;
1108           }
1109 
1110           conn->pkex = dpp_pkex_rx_exchange_req(conn->msg_ctx, ctrl->pkex_bi,
1111                                                         NULL, NULL,
1112                                                         ctrl->pkex_identifier,
1113                                                         ctrl->pkex_code,
1114                                                         os_strlen(ctrl->pkex_code),
1115                                                         buf, len, true);
1116           if (!conn->pkex) {
1117                     wpa_printf(MSG_DEBUG,
1118                                  "DPP: Failed to process the request");
1119                     return -1;
1120           }
1121 
1122           return dpp_tcp_send_msg(conn, conn->pkex->exchange_resp);
1123 }
1124 
1125 
dpp_controller_rx_pkex_exchange_resp(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1126 static int dpp_controller_rx_pkex_exchange_resp(struct dpp_connection *conn,
1127                                                             const u8 *hdr, const u8 *buf,
1128                                                             size_t len)
1129 {
1130           struct dpp_pkex *pkex = conn->pkex;
1131           struct wpabuf *msg;
1132           int res;
1133 
1134           wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response");
1135 
1136           if (!pkex || !pkex->initiator || pkex->exchange_done) {
1137                     wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1138                     return 0;
1139           }
1140 
1141           msg = dpp_pkex_rx_exchange_resp(pkex, NULL, buf, len);
1142           if (!msg) {
1143                     wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1144                     return -1;
1145           }
1146 
1147           wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request");
1148           res = dpp_tcp_send_msg(conn, msg);
1149           wpabuf_free(msg);
1150           return res;
1151 }
1152 
1153 
dpp_controller_rx_pkex_commit_reveal_req(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1154 static int dpp_controller_rx_pkex_commit_reveal_req(struct dpp_connection *conn,
1155                                                                 const u8 *hdr,
1156                                                                 const u8 *buf, size_t len)
1157 {
1158           struct dpp_pkex *pkex = conn->pkex;
1159           struct wpabuf *msg;
1160           int res;
1161           struct dpp_bootstrap_info *bi;
1162 
1163           wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request");
1164 
1165           if (!pkex || pkex->initiator || !pkex->exchange_done) {
1166                     wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1167                     return 0;
1168           }
1169 
1170           msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
1171           if (!msg) {
1172                     wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
1173                     return -1;
1174           }
1175 
1176           wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response");
1177           res = dpp_tcp_send_msg(conn, msg);
1178           wpabuf_free(msg);
1179           if (res < 0)
1180                     return res;
1181           bi = dpp_pkex_finish(conn->global, pkex, NULL, 0);
1182           if (!bi)
1183                     return -1;
1184           conn->pkex = NULL;
1185           return 0;
1186 }
1187 
1188 
1189 static int
dpp_controller_rx_pkex_commit_reveal_resp(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1190 dpp_controller_rx_pkex_commit_reveal_resp(struct dpp_connection *conn,
1191                                                     const u8 *hdr,
1192                                                     const u8 *buf, size_t len)
1193 {
1194           struct dpp_pkex *pkex = conn->pkex;
1195           int res;
1196           struct dpp_bootstrap_info *bi;
1197 
1198           wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response");
1199 
1200           if (!pkex || !pkex->initiator || !pkex->exchange_done) {
1201                     wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1202                     return 0;
1203           }
1204 
1205           res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
1206           if (res < 0) {
1207                     wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1208                     return res;
1209           }
1210 
1211           bi = dpp_pkex_finish(conn->global, pkex, NULL, 0);
1212           if (!bi)
1213                     return -1;
1214           conn->pkex = NULL;
1215 
1216           if (!conn->pkex_done)
1217                     return -1;
1218           return conn->pkex_done(conn->cb_ctx, conn, bi);
1219 }
1220 
1221 
dpp_controller_rx_action(struct dpp_connection * conn,const u8 * msg,size_t len)1222 static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg,
1223                                             size_t len)
1224 {
1225           const u8 *pos, *end;
1226           u8 type;
1227 
1228           wpa_printf(MSG_DEBUG, "DPP: Received DPP Action frame over TCP");
1229           pos = msg;
1230           end = msg + len;
1231 
1232           if (end - pos < DPP_HDR_LEN ||
1233               WPA_GET_BE24(pos) != OUI_WFA ||
1234               pos[3] != DPP_OUI_TYPE) {
1235                     wpa_printf(MSG_DEBUG, "DPP: Unrecognized header");
1236                     return -1;
1237           }
1238 
1239           if (pos[4] != 1) {
1240                     wpa_printf(MSG_DEBUG, "DPP: Unsupported Crypto Suite %u",
1241                                  pos[4]);
1242                     return -1;
1243           }
1244           type = pos[5];
1245           wpa_printf(MSG_DEBUG, "DPP: Received message type %u", type);
1246           pos += DPP_HDR_LEN;
1247 
1248           wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes",
1249                         pos, end - pos);
1250           if (dpp_check_attrs(pos, end - pos) < 0)
1251                     return -1;
1252 
1253           if (conn->relay) {
1254                     wpa_printf(MSG_DEBUG, "DPP: Relay - send over WLAN");
1255                     conn->relay->tx(conn->relay->cb_ctx, conn->mac_addr,
1256                                         conn->freq, msg, len);
1257                     return 0;
1258           }
1259 
1260           switch (type) {
1261           case DPP_PA_AUTHENTICATION_REQ:
1262                     return dpp_controller_rx_auth_req(conn, msg, pos, end - pos);
1263           case DPP_PA_AUTHENTICATION_RESP:
1264                     return dpp_controller_rx_auth_resp(conn, msg, pos, end - pos);
1265           case DPP_PA_AUTHENTICATION_CONF:
1266                     return dpp_controller_rx_auth_conf(conn, msg, pos, end - pos);
1267           case DPP_PA_CONFIGURATION_RESULT:
1268                     return dpp_controller_rx_conf_result(conn, msg, pos, end - pos);
1269           case DPP_PA_CONNECTION_STATUS_RESULT:
1270                     return dpp_controller_rx_conn_status_result(conn, msg, pos,
1271                                                                           end - pos);
1272           case DPP_PA_PRESENCE_ANNOUNCEMENT:
1273                     return dpp_controller_rx_presence_announcement(conn, msg, pos,
1274                                                                              end - pos);
1275           case DPP_PA_RECONFIG_ANNOUNCEMENT:
1276                     return dpp_controller_rx_reconfig_announcement(conn, msg, pos,
1277                                                                              end - pos);
1278           case DPP_PA_RECONFIG_AUTH_RESP:
1279                     return dpp_controller_rx_reconfig_auth_resp(conn, msg, pos,
1280                                                                           end - pos);
1281           case DPP_PA_PKEX_V1_EXCHANGE_REQ:
1282                     wpa_printf(MSG_DEBUG,
1283                                  "DPP: Ignore PKEXv1 Exchange Request - not supported over TCP");
1284                     return -1;
1285           case DPP_PA_PKEX_EXCHANGE_REQ:
1286                     return dpp_controller_rx_pkex_exchange_req(conn, msg, pos,
1287                                                                          end - pos);
1288           case DPP_PA_PKEX_EXCHANGE_RESP:
1289                     return dpp_controller_rx_pkex_exchange_resp(conn, msg, pos,
1290                                                                           end - pos);
1291           case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
1292                     return dpp_controller_rx_pkex_commit_reveal_req(conn, msg, pos,
1293                                                                                 end - pos);
1294           case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
1295                     return dpp_controller_rx_pkex_commit_reveal_resp(conn, msg, pos,
1296                                                                                  end - pos);
1297           default:
1298                     /* TODO: missing messages types */
1299                     wpa_printf(MSG_DEBUG,
1300                                  "DPP: Unsupported frame subtype %d", type);
1301                     return -1;
1302           }
1303 }
1304 
1305 
dpp_tcp_send_comeback_delay(struct dpp_connection * conn,u8 action)1306 static int dpp_tcp_send_comeback_delay(struct dpp_connection *conn, u8 action)
1307 {
1308           struct wpabuf *buf;
1309           size_t len = 18;
1310 
1311           if (action == WLAN_PA_GAS_COMEBACK_RESP)
1312                     len++;
1313 
1314           buf = wpabuf_alloc(4 + len);
1315           if (!buf)
1316                     return -1;
1317 
1318           wpabuf_put_be32(buf, len);
1319 
1320           wpabuf_put_u8(buf, action);
1321           wpabuf_put_u8(buf, conn->gas_dialog_token);
1322           wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
1323           if (action == WLAN_PA_GAS_COMEBACK_RESP)
1324                     wpabuf_put_u8(buf, 0);
1325           wpabuf_put_le16(buf, 500); /* GAS Comeback Delay */
1326 
1327           dpp_write_adv_proto(buf);
1328           wpabuf_put_le16(buf, 0); /* Query Response Length */
1329 
1330           /* Send Config Response over TCP */
1331           wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", buf);
1332           wpabuf_free(conn->msg_out);
1333           conn->msg_out_pos = 0;
1334           conn->msg_out = buf;
1335           dpp_tcp_send(conn);
1336           return 0;
1337 }
1338 
1339 
dpp_tcp_send_gas_resp(struct dpp_connection * conn,u8 action,struct wpabuf * resp)1340 static int dpp_tcp_send_gas_resp(struct dpp_connection *conn, u8 action,
1341                                          struct wpabuf *resp)
1342 {
1343           struct wpabuf *buf;
1344           size_t len;
1345 
1346           if (!resp)
1347                     return -1;
1348 
1349           len = 18 + wpabuf_len(resp);
1350           if (action == WLAN_PA_GAS_COMEBACK_RESP)
1351                     len++;
1352 
1353           buf = wpabuf_alloc(4 + len);
1354           if (!buf) {
1355                     wpabuf_free(resp);
1356                     return -1;
1357           }
1358 
1359           wpabuf_put_be32(buf, len);
1360 
1361           wpabuf_put_u8(buf, action);
1362           wpabuf_put_u8(buf, conn->gas_dialog_token);
1363           wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
1364           if (action == WLAN_PA_GAS_COMEBACK_RESP)
1365                     wpabuf_put_u8(buf, 0);
1366           wpabuf_put_le16(buf, 0); /* GAS Comeback Delay */
1367 
1368           dpp_write_adv_proto(buf);
1369           dpp_write_gas_query(buf, resp);
1370           wpabuf_free(resp);
1371 
1372           /* Send Config Response over TCP; GAS fragmentation is taken care of by
1373            * the Relay */
1374           wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", buf);
1375           wpabuf_free(conn->msg_out);
1376           conn->msg_out_pos = 0;
1377           conn->msg_out = buf;
1378           conn->on_tcp_tx_complete_gas_done = 1;
1379           dpp_tcp_send(conn);
1380           return 0;
1381 }
1382 
1383 
dpp_controller_rx_gas_req(struct dpp_connection * conn,const u8 * msg,size_t len)1384 static int dpp_controller_rx_gas_req(struct dpp_connection *conn, const u8 *msg,
1385                                              size_t len)
1386 {
1387           const u8 *pos, *end, *next;
1388           const u8 *adv_proto;
1389           u16 slen;
1390           struct wpabuf *resp;
1391           struct dpp_authentication *auth = conn->auth;
1392 
1393           if (len < 1 + 2)
1394                     return -1;
1395 
1396           wpa_printf(MSG_DEBUG,
1397                        "DPP: Received DPP Configuration Request over TCP");
1398 
1399           if (!auth || (!conn->ctrl && !auth->configurator) ||
1400               (!auth->auth_success && !auth->reconfig_success)) {
1401                     wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1402                     return -1;
1403           }
1404 
1405           wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX);
1406 
1407           pos = msg;
1408           end = msg + len;
1409 
1410           conn->gas_dialog_token = *pos++;
1411           adv_proto = pos++;
1412           slen = *pos++;
1413           if (*adv_proto != WLAN_EID_ADV_PROTO ||
1414               slen > end - pos || slen < 2)
1415                     return -1;
1416 
1417           next = pos + slen;
1418           pos++; /* skip QueryRespLenLimit and PAME-BI */
1419 
1420           if (slen != 8 || *pos != WLAN_EID_VENDOR_SPECIFIC ||
1421               pos[1] != 5 || WPA_GET_BE24(&pos[2]) != OUI_WFA ||
1422               pos[5] != DPP_OUI_TYPE || pos[6] != 0x01)
1423                     return -1;
1424 
1425           pos = next;
1426           /* Query Request */
1427           if (end - pos < 2)
1428                     return -1;
1429           slen = WPA_GET_LE16(pos);
1430           pos += 2;
1431           if (slen > end - pos)
1432                     return -1;
1433 
1434           resp = dpp_conf_req_rx(auth, pos, slen);
1435           if (!resp && auth->waiting_cert) {
1436                     wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
1437                     conn->gas_comeback_in_progress = 1;
1438                     return dpp_tcp_send_comeback_delay(conn,
1439                                                                WLAN_PA_GAS_INITIAL_RESP);
1440           }
1441 
1442           if (!resp && auth->waiting_config && auth->peer_bi) {
1443                     char *buf = NULL, *name = "";
1444                     char band[200], *b_pos, *b_end;
1445                     int i, res, *opclass = auth->e_band_support;
1446                     char *mud_url = "N/A";
1447 
1448                     wpa_printf(MSG_DEBUG, "DPP: Configuration not yet ready");
1449                     if (auth->e_name) {
1450                               size_t e_len = os_strlen(auth->e_name);
1451 
1452                               buf = os_malloc(e_len * 4 + 1);
1453                               if (buf) {
1454                                         printf_encode(buf, len * 4 + 1,
1455                                                         (const u8 *) auth->e_name, e_len);
1456                                         name = buf;
1457                               }
1458                     }
1459                     band[0] = '\0';
1460                     b_pos = band;
1461                     b_end = band + sizeof(band);
1462                     for (i = 0; opclass && opclass[i]; i++) {
1463                               res = os_snprintf(b_pos, b_end - b_pos, "%s%d",
1464                                                     b_pos == band ? "" : ",", opclass[i]);
1465                               if (os_snprintf_error(b_end - b_pos, res)) {
1466                                         *b_pos = '\0';
1467                                         break;
1468                               }
1469                               b_pos += res;
1470                     }
1471                     if (auth->e_mud_url) {
1472                               size_t e_len = os_strlen(auth->e_mud_url);
1473 
1474                               if (!has_ctrl_char((const u8 *) auth->e_mud_url, e_len))
1475                                         mud_url = auth->e_mud_url;
1476                     }
1477                     wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_CONF_NEEDED
1478                               "peer=%d net_role=%s name=\"%s\" opclass=%s mud_url=%s",
1479                               auth->peer_bi->id, dpp_netrole_str(auth->e_netrole),
1480                               name, band, mud_url);
1481                     os_free(buf);
1482 
1483                     conn->gas_comeback_in_progress = 1;
1484                     return dpp_tcp_send_comeback_delay(conn,
1485                                                                WLAN_PA_GAS_INITIAL_RESP);
1486           }
1487 
1488           return dpp_tcp_send_gas_resp(conn, WLAN_PA_GAS_INITIAL_RESP, resp);
1489 }
1490 
1491 
dpp_controller_rx_gas_comeback_req(struct dpp_connection * conn,const u8 * msg,size_t len)1492 static int dpp_controller_rx_gas_comeback_req(struct dpp_connection *conn,
1493                                                         const u8 *msg, size_t len)
1494 {
1495           u8 dialog_token;
1496           struct dpp_authentication *auth = conn->auth;
1497           struct wpabuf *resp;
1498 
1499           if (len < 1)
1500                     return -1;
1501 
1502           wpa_printf(MSG_DEBUG,
1503                        "DPP: Received DPP Configuration Request over TCP (comeback)");
1504 
1505           if (!auth || (!conn->ctrl && !auth->configurator) ||
1506               (!auth->auth_success && !auth->reconfig_success) ||
1507               !conn->gas_comeback_in_progress) {
1508                     wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1509                     return -1;
1510           }
1511 
1512           dialog_token = msg[0];
1513           if (dialog_token != conn->gas_dialog_token) {
1514                     wpa_printf(MSG_DEBUG, "DPP: Dialog token mismatch (%u != %u)",
1515                                  dialog_token, conn->gas_dialog_token);
1516                     return -1;
1517           }
1518 
1519           if (!auth->conf_resp_tcp) {
1520                     wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
1521                     return dpp_tcp_send_comeback_delay(conn,
1522                                                                WLAN_PA_GAS_COMEBACK_RESP);
1523           }
1524 
1525           wpa_printf(MSG_DEBUG,
1526                        "DPP: Configuration response is ready to be sent out");
1527           resp = auth->conf_resp_tcp;
1528           auth->conf_resp_tcp = NULL;
1529           return dpp_tcp_send_gas_resp(conn, WLAN_PA_GAS_COMEBACK_RESP, resp);
1530 }
1531 
1532 
dpp_tcp_build_csr(void * eloop_ctx,void * timeout_ctx)1533 static void dpp_tcp_build_csr(void *eloop_ctx, void *timeout_ctx)
1534 {
1535           struct dpp_connection *conn = eloop_ctx;
1536           struct dpp_authentication *auth = conn->auth;
1537 
1538           if (!auth || !auth->csrattrs)
1539                     return;
1540 
1541           wpa_printf(MSG_DEBUG, "DPP: Build CSR");
1542           wpabuf_free(auth->csr);
1543           /* TODO: Additional information needed for CSR based on csrAttrs */
1544           auth->csr = dpp_build_csr(auth, conn->name ? conn->name : "Test");
1545           if (!auth->csr) {
1546                     dpp_connection_remove(conn);
1547                     return;
1548           }
1549 
1550           dpp_controller_start_gas_client(conn);
1551 }
1552 
1553 
1554 #ifdef CONFIG_DPP3
dpp_tcp_build_new_key(void * eloop_ctx,void * timeout_ctx)1555 static void dpp_tcp_build_new_key(void *eloop_ctx, void *timeout_ctx)
1556 {
1557           struct dpp_connection *conn = eloop_ctx;
1558           struct dpp_authentication *auth = conn->auth;
1559 
1560           if (!auth || !auth->waiting_new_key)
1561                     return;
1562 
1563           wpa_printf(MSG_DEBUG, "DPP: Build config request with a new key");
1564           dpp_controller_start_gas_client(conn);
1565 }
1566 #endif /* CONFIG_DPP3 */
1567 
1568 
dpp_tcp_rx_gas_resp(struct dpp_connection * conn,struct wpabuf * resp)1569 static int dpp_tcp_rx_gas_resp(struct dpp_connection *conn, struct wpabuf *resp)
1570 {
1571           struct dpp_authentication *auth = conn->auth;
1572           int res;
1573           struct wpabuf *msg;
1574           enum dpp_status_error status;
1575 
1576           wpa_printf(MSG_DEBUG,
1577                        "DPP: Configuration Response for local stack from TCP");
1578 
1579           if (auth)
1580                     res = dpp_conf_resp_rx(auth, resp);
1581           else
1582                     res = -1;
1583           wpabuf_free(resp);
1584           if (res == -2) {
1585                     wpa_printf(MSG_DEBUG, "DPP: CSR needed");
1586                     eloop_register_timeout(0, 0, dpp_tcp_build_csr, conn, NULL);
1587                     return 0;
1588           }
1589 #ifdef CONFIG_DPP3
1590           if (res == -3) {
1591                     wpa_printf(MSG_DEBUG, "DPP: New protocol key needed");
1592                     eloop_register_timeout(0, 0, dpp_tcp_build_new_key, conn,
1593                                                NULL);
1594                     return 0;
1595           }
1596 #endif /* CONFIG_DPP3 */
1597           if (res < 0) {
1598                     wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
1599                     return -1;
1600           }
1601 
1602           if (conn->process_conf_obj)
1603                     res = conn->process_conf_obj(conn->cb_ctx, auth);
1604           else
1605                     res = 0;
1606 
1607           if (auth->peer_version < 2 || auth->conf_resp_status != DPP_STATUS_OK)
1608                     return -1;
1609 
1610           wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
1611           status = res < 0 ? DPP_STATUS_CONFIG_REJECTED : DPP_STATUS_OK;
1612           msg = dpp_build_conf_result(auth, status);
1613           if (!msg)
1614                     return -1;
1615 
1616           conn->on_tcp_tx_complete_remove = 1;
1617           res = dpp_tcp_send_msg(conn, msg);
1618           wpabuf_free(msg);
1619 
1620           /* This exchange will be terminated in the TX status handler */
1621 
1622           return res;
1623 }
1624 
1625 
dpp_tcp_gas_query_comeback(void * eloop_ctx,void * timeout_ctx)1626 static void dpp_tcp_gas_query_comeback(void *eloop_ctx, void *timeout_ctx)
1627 {
1628           struct dpp_connection *conn = eloop_ctx;
1629           struct dpp_authentication *auth = conn->auth;
1630           struct wpabuf *msg;
1631 
1632           if (!auth)
1633                     return;
1634 
1635           wpa_printf(MSG_DEBUG, "DPP: Send GAS Comeback Request");
1636           msg = wpabuf_alloc(4 + 2);
1637           if (!msg)
1638                     return;
1639           wpabuf_put_be32(msg, 2);
1640           wpabuf_put_u8(msg, WLAN_PA_GAS_COMEBACK_REQ);
1641           wpabuf_put_u8(msg, conn->gas_dialog_token);
1642           wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", msg);
1643 
1644           wpabuf_free(conn->msg_out);
1645           conn->msg_out_pos = 0;
1646           conn->msg_out = msg;
1647           dpp_tcp_send(conn);
1648 }
1649 
1650 
dpp_rx_gas_resp(struct dpp_connection * conn,const u8 * msg,size_t len,bool comeback)1651 static int dpp_rx_gas_resp(struct dpp_connection *conn, const u8 *msg,
1652                                  size_t len, bool comeback)
1653 {
1654           struct wpabuf *buf;
1655           u8 dialog_token;
1656           const u8 *pos, *end, *next, *adv_proto;
1657           u16 status, slen, comeback_delay;
1658 
1659           if (len < (size_t) (5 + 2 + (comeback ? 1 : 0)))
1660                     return -1;
1661 
1662           wpa_printf(MSG_DEBUG,
1663                        "DPP: Received DPP Configuration Response over TCP");
1664 
1665           pos = msg;
1666           end = msg + len;
1667 
1668           dialog_token = *pos++;
1669           status = WPA_GET_LE16(pos);
1670           if (status != WLAN_STATUS_SUCCESS) {
1671                     wpa_printf(MSG_DEBUG, "DPP: Unexpected Status Code %u", status);
1672                     return -1;
1673           }
1674           pos += 2;
1675           if (comeback)
1676                     pos++; /* ignore Fragment ID */
1677           comeback_delay = WPA_GET_LE16(pos);
1678           pos += 2;
1679 
1680           adv_proto = pos++;
1681           slen = *pos++;
1682           if (*adv_proto != WLAN_EID_ADV_PROTO ||
1683               slen > end - pos || slen < 2)
1684                     return -1;
1685 
1686           next = pos + slen;
1687           pos++; /* skip QueryRespLenLimit and PAME-BI */
1688 
1689           if (slen != 8 || *pos != WLAN_EID_VENDOR_SPECIFIC ||
1690               pos[1] != 5 || WPA_GET_BE24(&pos[2]) != OUI_WFA ||
1691               pos[5] != DPP_OUI_TYPE || pos[6] != 0x01)
1692                     return -1;
1693 
1694           pos = next;
1695           /* Query Response */
1696           if (end - pos < 2)
1697                     return -1;
1698           slen = WPA_GET_LE16(pos);
1699           pos += 2;
1700           if (slen > end - pos)
1701                     return -1;
1702 
1703           if (comeback_delay) {
1704                     unsigned int secs, usecs;
1705 
1706                     conn->gas_dialog_token = dialog_token;
1707                     secs = (comeback_delay * 1024) / 1000000;
1708                     usecs = comeback_delay * 1024 - secs * 1000000;
1709                     wpa_printf(MSG_DEBUG, "DPP: Comeback delay: %u",
1710                                  comeback_delay);
1711                     eloop_cancel_timeout(dpp_tcp_gas_query_comeback, conn, NULL);
1712                     eloop_register_timeout(secs, usecs, dpp_tcp_gas_query_comeback,
1713                                                conn, NULL);
1714                     return 0;
1715           }
1716 
1717           buf = wpabuf_alloc(slen);
1718           if (!buf)
1719                     return -1;
1720           wpabuf_put_data(buf, pos, slen);
1721 
1722           if (!conn->relay &&
1723               (!conn->ctrl || (conn->ctrl->allowed_roles & DPP_CAPAB_ENROLLEE)))
1724                     return dpp_tcp_rx_gas_resp(conn, buf);
1725 
1726           if (!conn->relay) {
1727                     wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1728                     wpabuf_free(buf);
1729                     return -1;
1730           }
1731           wpa_printf(MSG_DEBUG, "DPP: Relay - send over WLAN");
1732           conn->relay->gas_resp_tx(conn->relay->cb_ctx, conn->mac_addr,
1733                                          dialog_token, 0, buf);
1734 
1735           return 0;
1736 }
1737 
1738 
dpp_controller_rx(int sd,void * eloop_ctx,void * sock_ctx)1739 static void dpp_controller_rx(int sd, void *eloop_ctx, void *sock_ctx)
1740 {
1741           struct dpp_connection *conn = eloop_ctx;
1742           int res;
1743           const u8 *pos;
1744 
1745           wpa_printf(MSG_DEBUG, "DPP: TCP data available for reading (sock %d)",
1746                        sd);
1747 
1748           if (conn->msg_len_octets < 4) {
1749                     u32 msglen;
1750 
1751                     res = recv(sd, &conn->msg_len[conn->msg_len_octets],
1752                                  4 - conn->msg_len_octets, 0);
1753                     if (res < 0) {
1754                               wpa_printf(MSG_DEBUG, "DPP: recv failed: %s",
1755                                            strerror(errno));
1756                               dpp_connection_remove(conn);
1757                               return;
1758                     }
1759                     if (res == 0) {
1760                               wpa_printf(MSG_DEBUG,
1761                                            "DPP: No more data available over TCP");
1762                               dpp_connection_remove(conn);
1763                               return;
1764                     }
1765                     wpa_printf(MSG_DEBUG,
1766                                  "DPP: Received %d/%d octet(s) of message length field",
1767                                  res, (int) (4 - conn->msg_len_octets));
1768                     conn->msg_len_octets += res;
1769 
1770                     if (conn->msg_len_octets < 4) {
1771                               wpa_printf(MSG_DEBUG,
1772                                            "DPP: Need %d more octets of message length field",
1773                                            (int) (4 - conn->msg_len_octets));
1774                               return;
1775                     }
1776 
1777                     msglen = WPA_GET_BE32(conn->msg_len);
1778                     wpa_printf(MSG_DEBUG, "DPP: Message length: %u", msglen);
1779                     if (msglen > 65535) {
1780                               wpa_printf(MSG_INFO, "DPP: Unexpectedly long message");
1781                               dpp_connection_remove(conn);
1782                               return;
1783                     }
1784 
1785                     wpabuf_free(conn->msg);
1786                     conn->msg = wpabuf_alloc(msglen);
1787           }
1788 
1789           if (!conn->msg) {
1790                     wpa_printf(MSG_DEBUG,
1791                                  "DPP: No buffer available for receiving the message");
1792                     dpp_connection_remove(conn);
1793                     return;
1794           }
1795 
1796           wpa_printf(MSG_DEBUG, "DPP: Need %u more octets of message payload",
1797                        (unsigned int) wpabuf_tailroom(conn->msg));
1798 
1799           res = recv(sd, wpabuf_put(conn->msg, 0), wpabuf_tailroom(conn->msg), 0);
1800           if (res < 0) {
1801                     wpa_printf(MSG_DEBUG, "DPP: recv failed: %s", strerror(errno));
1802                     dpp_connection_remove(conn);
1803                     return;
1804           }
1805           if (res == 0) {
1806                     wpa_printf(MSG_DEBUG, "DPP: No more data available over TCP");
1807                     dpp_connection_remove(conn);
1808                     return;
1809           }
1810           wpa_printf(MSG_DEBUG, "DPP: Received %d octets", res);
1811           wpabuf_put(conn->msg, res);
1812 
1813           if (wpabuf_tailroom(conn->msg) > 0) {
1814                     wpa_printf(MSG_DEBUG,
1815                                  "DPP: Need %u more octets of message payload",
1816                                  (unsigned int) wpabuf_tailroom(conn->msg));
1817                     return;
1818           }
1819 
1820           conn->msg_len_octets = 0;
1821           wpa_hexdump_buf(MSG_DEBUG, "DPP: Received TCP message", conn->msg);
1822           if (wpabuf_len(conn->msg) < 1) {
1823                     dpp_connection_remove(conn);
1824                     return;
1825           }
1826 
1827           pos = wpabuf_head(conn->msg);
1828           switch (*pos) {
1829           case WLAN_PA_VENDOR_SPECIFIC:
1830                     if (dpp_controller_rx_action(conn, pos + 1,
1831                                                        wpabuf_len(conn->msg) - 1) < 0)
1832                               dpp_connection_remove(conn);
1833                     break;
1834           case WLAN_PA_GAS_INITIAL_REQ:
1835                     if (dpp_controller_rx_gas_req(conn, pos + 1,
1836                                                         wpabuf_len(conn->msg) - 1) < 0)
1837                               dpp_connection_remove(conn);
1838                     break;
1839           case WLAN_PA_GAS_INITIAL_RESP:
1840           case WLAN_PA_GAS_COMEBACK_RESP:
1841                     if (dpp_rx_gas_resp(conn, pos + 1,
1842                                             wpabuf_len(conn->msg) - 1,
1843                                             *pos == WLAN_PA_GAS_COMEBACK_RESP) < 0)
1844                               dpp_connection_remove(conn);
1845                     break;
1846           case WLAN_PA_GAS_COMEBACK_REQ:
1847                     if (dpp_controller_rx_gas_comeback_req(
1848                                   conn, pos + 1, wpabuf_len(conn->msg) - 1) < 0)
1849                               dpp_connection_remove(conn);
1850                     break;
1851           default:
1852                     wpa_printf(MSG_DEBUG, "DPP: Ignore unsupported message type %u",
1853                                  *pos);
1854                     break;
1855           }
1856 }
1857 
1858 
dpp_controller_tcp_cb(int sd,void * eloop_ctx,void * sock_ctx)1859 static void dpp_controller_tcp_cb(int sd, void *eloop_ctx, void *sock_ctx)
1860 {
1861           struct dpp_controller *ctrl = eloop_ctx;
1862           struct sockaddr_in addr;
1863           socklen_t addr_len = sizeof(addr);
1864           int fd;
1865           struct dpp_connection *conn;
1866 
1867           wpa_printf(MSG_DEBUG, "DPP: New TCP connection");
1868 
1869           fd = accept(ctrl->sock, (struct sockaddr *) &addr, &addr_len);
1870           if (fd < 0) {
1871                     wpa_printf(MSG_DEBUG,
1872                                  "DPP: Failed to accept new connection: %s",
1873                                  strerror(errno));
1874                     return;
1875           }
1876           wpa_printf(MSG_DEBUG, "DPP: Connection from %s:%d",
1877                        inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
1878 
1879           conn = os_zalloc(sizeof(*conn));
1880           if (!conn)
1881                     goto fail;
1882 
1883           conn->global = ctrl->global;
1884           conn->ctrl = ctrl;
1885           conn->msg_ctx = ctrl->msg_ctx;
1886           conn->cb_ctx = ctrl->cb_ctx;
1887           conn->process_conf_obj = ctrl->process_conf_obj;
1888           conn->tcp_msg_sent = ctrl->tcp_msg_sent;
1889           conn->sock = fd;
1890           conn->netrole = ctrl->netrole;
1891 
1892           if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
1893                     wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
1894                                  strerror(errno));
1895                     goto fail;
1896           }
1897 
1898           if (eloop_register_sock(conn->sock, EVENT_TYPE_READ,
1899                                         dpp_controller_rx, conn, NULL) < 0)
1900                     goto fail;
1901           conn->read_eloop = 1;
1902 
1903           /* TODO: eloop timeout to expire connections that do not complete in
1904            * reasonable time */
1905           dl_list_add(&ctrl->conn, &conn->list);
1906           return;
1907 
1908 fail:
1909           close(fd);
1910           os_free(conn);
1911 }
1912 
1913 
dpp_tcp_pkex_init(struct dpp_global * dpp,struct dpp_pkex * pkex,const struct hostapd_ip_addr * addr,int port,void * msg_ctx,void * cb_ctx,int (* pkex_done)(void * ctx,void * conn,struct dpp_bootstrap_info * bi))1914 int dpp_tcp_pkex_init(struct dpp_global *dpp, struct dpp_pkex *pkex,
1915                           const struct hostapd_ip_addr *addr, int port,
1916                           void *msg_ctx, void *cb_ctx,
1917                           int (*pkex_done)(void *ctx, void *conn,
1918                                                struct dpp_bootstrap_info *bi))
1919 {
1920           struct dpp_connection *conn;
1921           struct sockaddr_storage saddr;
1922           socklen_t addrlen;
1923           const u8 *hdr, *pos, *end;
1924           char txt[100];
1925 
1926           wpa_printf(MSG_DEBUG, "DPP: Initialize TCP connection to %s port %d",
1927                        hostapd_ip_txt(addr, txt, sizeof(txt)), port);
1928           if (dpp_ipaddr_to_sockaddr((struct sockaddr *) &saddr, &addrlen,
1929                                            addr, port) < 0) {
1930                     dpp_pkex_free(pkex);
1931                     return -1;
1932           }
1933 
1934           conn = os_zalloc(sizeof(*conn));
1935           if (!conn) {
1936                     dpp_pkex_free(pkex);
1937                     return -1;
1938           }
1939 
1940           conn->msg_ctx = msg_ctx;
1941           conn->cb_ctx = cb_ctx;
1942           conn->pkex_done = pkex_done;
1943           conn->global = dpp;
1944           conn->pkex = pkex;
1945           conn->sock = socket(AF_INET, SOCK_STREAM, 0);
1946           if (conn->sock < 0)
1947                     goto fail;
1948 
1949           if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
1950                     wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
1951                                  strerror(errno));
1952                     goto fail;
1953           }
1954 
1955           if (connect(conn->sock, (struct sockaddr *) &saddr, addrlen) < 0) {
1956                     if (errno != EINPROGRESS) {
1957                               wpa_printf(MSG_DEBUG, "DPP: Failed to connect: %s",
1958                                            strerror(errno));
1959                               goto fail;
1960                     }
1961 
1962                     /*
1963                      * Continue connecting in the background; eloop will call us
1964                      * once the connection is ready (or failed).
1965                      */
1966           }
1967 
1968           if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
1969                                         dpp_conn_tx_ready, conn, NULL) < 0)
1970                     goto fail;
1971           conn->write_eloop = 1;
1972 
1973           hdr = wpabuf_head(pkex->exchange_req);
1974           end = hdr + wpabuf_len(pkex->exchange_req);
1975           hdr += 2; /* skip Category and Actiom */
1976           pos = hdr + DPP_HDR_LEN;
1977           conn->msg_out = dpp_tcp_encaps(hdr, pos, end - pos);
1978           if (!conn->msg_out)
1979                     goto fail;
1980           /* Message will be sent in dpp_conn_tx_ready() */
1981 
1982           /* TODO: eloop timeout to clear a connection if it does not complete
1983            * properly */
1984           dl_list_add(&dpp->tcp_init, &conn->list);
1985           return 0;
1986 fail:
1987           dpp_connection_free(conn);
1988           return -1;
1989 }
1990 
1991 
dpp_tcp_auth_start(struct dpp_connection * conn,struct dpp_authentication * auth)1992 static int dpp_tcp_auth_start(struct dpp_connection *conn,
1993                                     struct dpp_authentication *auth)
1994 {
1995           const u8 *hdr, *pos, *end;
1996 
1997           hdr = wpabuf_head(auth->req_msg);
1998           end = hdr + wpabuf_len(auth->req_msg);
1999           hdr += 2; /* skip Category and Actiom */
2000           pos = hdr + DPP_HDR_LEN;
2001           conn->msg_out = dpp_tcp_encaps(hdr, pos, end - pos);
2002           if (!conn->msg_out)
2003                     return -1;
2004           /* Message will be sent in dpp_conn_tx_ready() */
2005           return 0;
2006 }
2007 
2008 
dpp_tcp_init(struct dpp_global * dpp,struct dpp_authentication * auth,const struct hostapd_ip_addr * addr,int port,const char * name,enum dpp_netrole netrole,const char * mud_url,const char * extra_conf_req_name,const char * extra_conf_req_value,void * msg_ctx,void * cb_ctx,int (* process_conf_obj)(void * ctx,struct dpp_authentication * auth),bool (* tcp_msg_sent)(void * ctx,struct dpp_authentication * auth))2009 int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
2010                      const struct hostapd_ip_addr *addr, int port, const char *name,
2011                      enum dpp_netrole netrole, const char *mud_url,
2012                      const char *extra_conf_req_name,
2013                      const char *extra_conf_req_value,
2014                      void *msg_ctx, void *cb_ctx,
2015                      int (*process_conf_obj)(void *ctx,
2016                                                    struct dpp_authentication *auth),
2017                      bool (*tcp_msg_sent)(void *ctx,
2018                                               struct dpp_authentication *auth))
2019 {
2020           struct dpp_connection *conn;
2021           struct sockaddr_storage saddr;
2022           socklen_t addrlen;
2023           char txt[100];
2024 
2025           wpa_printf(MSG_DEBUG, "DPP: Initialize TCP connection to %s port %d",
2026                        hostapd_ip_txt(addr, txt, sizeof(txt)), port);
2027           if (dpp_ipaddr_to_sockaddr((struct sockaddr *) &saddr, &addrlen,
2028                                            addr, port) < 0) {
2029                     dpp_auth_deinit(auth);
2030                     return -1;
2031           }
2032 
2033           conn = os_zalloc(sizeof(*conn));
2034           if (!conn) {
2035                     dpp_auth_deinit(auth);
2036                     return -1;
2037           }
2038 
2039           conn->msg_ctx = msg_ctx;
2040           conn->cb_ctx = cb_ctx;
2041           conn->process_conf_obj = process_conf_obj;
2042           conn->tcp_msg_sent = tcp_msg_sent;
2043           conn->name = os_strdup(name ? name : "Test");
2044           if (mud_url)
2045                     conn->mud_url = os_strdup(mud_url);
2046           if (extra_conf_req_name)
2047                     conn->extra_conf_req_name = os_strdup(extra_conf_req_name);
2048           if (extra_conf_req_value)
2049                     conn->extra_conf_req_value = os_strdup(extra_conf_req_value);
2050           conn->netrole = netrole;
2051           conn->global = dpp;
2052           conn->auth = auth;
2053           conn->sock = socket(AF_INET, SOCK_STREAM, 0);
2054           if (conn->sock < 0)
2055                     goto fail;
2056 
2057           if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
2058                     wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
2059                                  strerror(errno));
2060                     goto fail;
2061           }
2062 
2063           if (connect(conn->sock, (struct sockaddr *) &saddr, addrlen) < 0) {
2064                     if (errno != EINPROGRESS) {
2065                               wpa_printf(MSG_DEBUG, "DPP: Failed to connect: %s",
2066                                            strerror(errno));
2067                               goto fail;
2068                     }
2069 
2070                     /*
2071                      * Continue connecting in the background; eloop will call us
2072                      * once the connection is ready (or failed).
2073                      */
2074           }
2075 
2076           if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
2077                                         dpp_conn_tx_ready, conn, NULL) < 0)
2078                     goto fail;
2079           conn->write_eloop = 1;
2080 
2081           if (dpp_tcp_auth_start(conn, auth) < 0)
2082                     goto fail;
2083 
2084           /* TODO: eloop timeout to clear a connection if it does not complete
2085            * properly */
2086           dl_list_add(&dpp->tcp_init, &conn->list);
2087           return 0;
2088 fail:
2089           dpp_connection_free(conn);
2090           return -1;
2091 }
2092 
2093 
dpp_tcp_auth(struct dpp_global * dpp,void * _conn,struct dpp_authentication * auth,const char * name,enum dpp_netrole netrole,const char * mud_url,const char * extra_conf_req_name,const char * extra_conf_req_value,int (* process_conf_obj)(void * ctx,struct dpp_authentication * auth),bool (* tcp_msg_sent)(void * ctx,struct dpp_authentication * auth))2094 int dpp_tcp_auth(struct dpp_global *dpp, void *_conn,
2095                      struct dpp_authentication *auth, const char *name,
2096                      enum dpp_netrole netrole, const char *mud_url,
2097                      const char *extra_conf_req_name,
2098                      const char *extra_conf_req_value,
2099                      int (*process_conf_obj)(void *ctx,
2100                                                    struct dpp_authentication *auth),
2101                      bool (*tcp_msg_sent)(void *ctx,
2102                                               struct dpp_authentication *auth))
2103 {
2104           struct dpp_connection *conn = _conn;
2105 
2106           /* Continue with Authentication exchange on an existing TCP connection.
2107            */
2108           conn->process_conf_obj = process_conf_obj;
2109           conn->tcp_msg_sent = tcp_msg_sent;
2110           os_free(conn->name);
2111           conn->name = os_strdup(name ? name : "Test");
2112           os_free(conn->mud_url);
2113           conn->mud_url = mud_url ? os_strdup(mud_url) : NULL;
2114           os_free(conn->extra_conf_req_name);
2115           conn->extra_conf_req_name = extra_conf_req_name ?
2116                     os_strdup(extra_conf_req_name) : NULL;
2117           conn->extra_conf_req_value = extra_conf_req_value ?
2118                     os_strdup(extra_conf_req_value) : NULL;
2119           conn->netrole = netrole;
2120           conn->auth = auth;
2121 
2122           if (dpp_tcp_auth_start(conn, auth) < 0)
2123                     return -1;
2124 
2125           dpp_conn_tx_ready(conn->sock, conn, NULL);
2126           return 0;
2127 }
2128 
2129 
dpp_controller_start(struct dpp_global * dpp,struct dpp_controller_config * config)2130 int dpp_controller_start(struct dpp_global *dpp,
2131                                struct dpp_controller_config *config)
2132 {
2133           struct dpp_controller *ctrl;
2134           int on = 1;
2135           struct sockaddr_in sin;
2136           int port;
2137 
2138           if (!dpp || dpp->controller)
2139                     return -1;
2140 
2141           ctrl = os_zalloc(sizeof(*ctrl));
2142           if (!ctrl)
2143                     return -1;
2144           ctrl->global = dpp;
2145           if (config->configurator_params)
2146                     ctrl->configurator_params =
2147                               os_strdup(config->configurator_params);
2148           dl_list_init(&ctrl->conn);
2149           ctrl->allowed_roles = config->allowed_roles;
2150           ctrl->qr_mutual = config->qr_mutual;
2151           ctrl->netrole = config->netrole;
2152           ctrl->msg_ctx = config->msg_ctx;
2153           ctrl->cb_ctx = config->cb_ctx;
2154           ctrl->process_conf_obj = config->process_conf_obj;
2155           ctrl->tcp_msg_sent = config->tcp_msg_sent;
2156 
2157           ctrl->sock = socket(AF_INET, SOCK_STREAM, 0);
2158           if (ctrl->sock < 0)
2159                     goto fail;
2160 
2161           if (setsockopt(ctrl->sock, SOL_SOCKET, SO_REUSEADDR,
2162                            &on, sizeof(on)) < 0) {
2163                     wpa_printf(MSG_DEBUG,
2164                                  "DPP: setsockopt(SO_REUSEADDR) failed: %s",
2165                                  strerror(errno));
2166                     /* try to continue anyway */
2167           }
2168 
2169           if (fcntl(ctrl->sock, F_SETFL, O_NONBLOCK) < 0) {
2170                     wpa_printf(MSG_INFO, "DPP: fnctl(O_NONBLOCK) failed: %s",
2171                                  strerror(errno));
2172                     goto fail;
2173           }
2174 
2175           /* TODO: IPv6 */
2176           os_memset(&sin, 0, sizeof(sin));
2177           sin.sin_family = AF_INET;
2178           sin.sin_addr.s_addr = INADDR_ANY;
2179           port = config->tcp_port ? config->tcp_port : DPP_TCP_PORT;
2180           sin.sin_port = htons(port);
2181           if (bind(ctrl->sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
2182                     wpa_printf(MSG_INFO,
2183                                  "DPP: Failed to bind Controller TCP port: %s",
2184                                  strerror(errno));
2185                     goto fail;
2186           }
2187           if (listen(ctrl->sock, 10 /* max backlog */) < 0 ||
2188               fcntl(ctrl->sock, F_SETFL, O_NONBLOCK) < 0 ||
2189               eloop_register_sock(ctrl->sock, EVENT_TYPE_READ,
2190                                         dpp_controller_tcp_cb, ctrl, NULL))
2191                     goto fail;
2192 
2193           dpp->controller = ctrl;
2194           wpa_printf(MSG_DEBUG, "DPP: Controller started on TCP port %d", port);
2195           return 0;
2196 fail:
2197           dpp_controller_free(ctrl);
2198           return -1;
2199 }
2200 
2201 
dpp_controller_set_params(struct dpp_global * dpp,const char * configurator_params)2202 int dpp_controller_set_params(struct dpp_global *dpp,
2203                                     const char *configurator_params)
2204 {
2205 
2206           if (!dpp || !dpp->controller)
2207                     return -1;
2208 
2209           if (configurator_params) {
2210                     char *val = os_strdup(configurator_params);
2211 
2212                     if (!val)
2213                               return -1;
2214                     os_free(dpp->controller->configurator_params);
2215                     dpp->controller->configurator_params = val;
2216           } else {
2217                     os_free(dpp->controller->configurator_params);
2218                     dpp->controller->configurator_params = NULL;
2219           }
2220 
2221           return 0;
2222 }
2223 
2224 
dpp_controller_stop(struct dpp_global * dpp)2225 void dpp_controller_stop(struct dpp_global *dpp)
2226 {
2227           if (dpp) {
2228                     dpp_controller_free(dpp->controller);
2229                     dpp->controller = NULL;
2230           }
2231 }
2232 
2233 
dpp_controller_stop_for_ctx(struct dpp_global * dpp,void * cb_ctx)2234 void dpp_controller_stop_for_ctx(struct dpp_global *dpp, void *cb_ctx)
2235 {
2236           if (dpp && dpp->controller && dpp->controller->cb_ctx == cb_ctx)
2237                     dpp_controller_stop(dpp);
2238 }
2239 
2240 
dpp_tcp_peer_id_match(struct dpp_authentication * auth,unsigned int id)2241 static bool dpp_tcp_peer_id_match(struct dpp_authentication *auth,
2242                                           unsigned int id)
2243 {
2244           return auth &&
2245                     ((auth->peer_bi && auth->peer_bi->id == id) ||
2246                      (auth->tmp_peer_bi && auth->tmp_peer_bi->id == id));
2247 }
2248 
2249 
dpp_tcp_get_auth(struct dpp_global * dpp,unsigned int id)2250 static struct dpp_authentication * dpp_tcp_get_auth(struct dpp_global *dpp,
2251                                                                 unsigned int id)
2252 {
2253           struct dpp_connection *conn;
2254 
2255           dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
2256                     if (dpp_tcp_peer_id_match(conn->auth, id))
2257                               return conn->auth;
2258           }
2259 
2260           return NULL;
2261 }
2262 
2263 
dpp_controller_get_auth(struct dpp_global * dpp,unsigned int id)2264 struct dpp_authentication * dpp_controller_get_auth(struct dpp_global *dpp,
2265                                                                 unsigned int id)
2266 {
2267           struct dpp_controller *ctrl = dpp->controller;
2268           struct dpp_connection *conn;
2269 
2270           if (!ctrl)
2271                     return dpp_tcp_get_auth(dpp, id);
2272 
2273           dl_list_for_each(conn, &ctrl->conn, struct dpp_connection, list) {
2274                     if (dpp_tcp_peer_id_match(conn->auth, id))
2275                               return conn->auth;
2276           }
2277 
2278           return dpp_tcp_get_auth(dpp, id);
2279 }
2280 
2281 
dpp_controller_new_qr_code(struct dpp_global * dpp,struct dpp_bootstrap_info * bi)2282 void dpp_controller_new_qr_code(struct dpp_global *dpp,
2283                                         struct dpp_bootstrap_info *bi)
2284 {
2285           struct dpp_controller *ctrl = dpp->controller;
2286           struct dpp_connection *conn;
2287 
2288           if (!ctrl)
2289                     return;
2290 
2291           dl_list_for_each(conn, &ctrl->conn, struct dpp_connection, list) {
2292                     struct dpp_authentication *auth = conn->auth;
2293 
2294                     if (!auth->response_pending ||
2295                         dpp_notify_new_qr_code(auth, bi) != 1)
2296                               continue;
2297                     wpa_printf(MSG_DEBUG,
2298                                  "DPP: Sending out pending authentication response");
2299                     dpp_tcp_send_msg(conn, conn->auth->resp_msg);
2300           }
2301 }
2302 
2303 
dpp_controller_pkex_add(struct dpp_global * dpp,struct dpp_bootstrap_info * bi,const char * code,const char * identifier)2304 void dpp_controller_pkex_add(struct dpp_global *dpp,
2305                                    struct dpp_bootstrap_info *bi,
2306                                    const char *code, const char *identifier)
2307 {
2308           struct dpp_controller *ctrl = dpp->controller;
2309 
2310           if (!ctrl)
2311                     return;
2312 
2313           ctrl->pkex_bi = bi;
2314           os_free(ctrl->pkex_code);
2315           ctrl->pkex_code = code ? os_strdup(code) : NULL;
2316           os_free(ctrl->pkex_identifier);
2317           ctrl->pkex_identifier = identifier ? os_strdup(identifier) : NULL;
2318 }
2319 
2320 
dpp_controller_is_own_pkex_req(struct dpp_global * dpp,const u8 * buf,size_t len)2321 bool dpp_controller_is_own_pkex_req(struct dpp_global *dpp,
2322                                             const u8 *buf, size_t len)
2323 {
2324           struct dpp_connection *conn;
2325           const u8 *attr_key = NULL;
2326           u16 attr_key_len = 0;
2327 
2328           dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
2329                     if (!conn->pkex || !conn->pkex->enc_key)
2330                               continue;
2331 
2332                     if (!attr_key) {
2333                               attr_key = dpp_get_attr(buf, len,
2334                                                             DPP_ATTR_ENCRYPTED_KEY,
2335                                                             &attr_key_len);
2336                               if (!attr_key)
2337                                         return false;
2338                     }
2339 
2340                     if (attr_key_len == wpabuf_len(conn->pkex->enc_key) &&
2341                         os_memcmp(attr_key, wpabuf_head(conn->pkex->enc_key),
2342                                     attr_key_len) == 0)
2343                               return true;
2344           }
2345 
2346           return false;
2347 }
2348 
2349 
dpp_tcp_init_flush(struct dpp_global * dpp)2350 void dpp_tcp_init_flush(struct dpp_global *dpp)
2351 {
2352           struct dpp_connection *conn, *tmp;
2353 
2354           dl_list_for_each_safe(conn, tmp, &dpp->tcp_init, struct dpp_connection,
2355                                     list)
2356                     dpp_connection_remove(conn);
2357 }
2358 
2359 
dpp_relay_controller_free(struct dpp_relay_controller * ctrl)2360 static void dpp_relay_controller_free(struct dpp_relay_controller *ctrl)
2361 {
2362           struct dpp_connection *conn, *tmp;
2363           char txt[100];
2364 
2365           wpa_printf(MSG_DEBUG, "DPP: Remove Relay connection to Controller %s",
2366                        hostapd_ip_txt(&ctrl->ipaddr, txt, sizeof(txt)));
2367 
2368           dl_list_for_each_safe(conn, tmp, &ctrl->conn, struct dpp_connection,
2369                                     list)
2370                     dpp_connection_remove(conn);
2371           os_free(ctrl);
2372 }
2373 
2374 
dpp_relay_flush_controllers(struct dpp_global * dpp)2375 void dpp_relay_flush_controllers(struct dpp_global *dpp)
2376 {
2377           struct dpp_relay_controller *ctrl, *tmp;
2378 
2379           if (!dpp)
2380                     return;
2381 
2382           dl_list_for_each_safe(ctrl, tmp, &dpp->controllers,
2383                                     struct dpp_relay_controller, list) {
2384                     dl_list_del(&ctrl->list);
2385                     dpp_relay_controller_free(ctrl);
2386           }
2387 
2388           if (dpp->tmp_controller) {
2389                     dpp_relay_controller_free(dpp->tmp_controller);
2390                     dpp->tmp_controller = NULL;
2391           }
2392 }
2393 
2394 
dpp_relay_remove_controller(struct dpp_global * dpp,const struct hostapd_ip_addr * addr)2395 void dpp_relay_remove_controller(struct dpp_global *dpp,
2396                                          const struct hostapd_ip_addr *addr)
2397 {
2398           struct dpp_relay_controller *ctrl;
2399 
2400           if (!dpp)
2401                     return;
2402 
2403           dl_list_for_each(ctrl, &dpp->controllers, struct dpp_relay_controller,
2404                                list) {
2405                     if (hostapd_ip_equal(&ctrl->ipaddr, addr)) {
2406                               dl_list_del(&ctrl->list);
2407                               dpp_relay_controller_free(ctrl);
2408                               return;
2409                     }
2410           }
2411 
2412           if (dpp->tmp_controller &&
2413               hostapd_ip_equal(&dpp->tmp_controller->ipaddr, addr)) {
2414                     dpp_relay_controller_free(dpp->tmp_controller);
2415                     dpp->tmp_controller = NULL;
2416           }
2417 }
2418 
2419 
dpp_relay_tcp_cb(int sd,void * eloop_ctx,void * sock_ctx)2420 static void dpp_relay_tcp_cb(int sd, void *eloop_ctx, void *sock_ctx)
2421 {
2422           struct dpp_global *dpp = eloop_ctx;
2423           struct sockaddr_in addr;
2424           socklen_t addr_len = sizeof(addr);
2425           int fd;
2426           struct dpp_relay_controller *ctrl;
2427           struct dpp_connection *conn = NULL;
2428 
2429           wpa_printf(MSG_DEBUG, "DPP: New TCP connection (Relay)");
2430 
2431           fd = accept(dpp->relay_sock, (struct sockaddr *) &addr, &addr_len);
2432           if (fd < 0) {
2433                     wpa_printf(MSG_DEBUG,
2434                                  "DPP: Failed to accept new connection: %s",
2435                                  strerror(errno));
2436                     return;
2437           }
2438           wpa_printf(MSG_DEBUG, "DPP: Connection from %s:%d",
2439                        inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
2440 
2441           ctrl = dpp_relay_controller_get_addr(dpp, &addr);
2442           if (!ctrl && dpp->tmp_controller &&
2443               dl_list_len(&dpp->tmp_controller->conn)) {
2444                     char txt[100];
2445 
2446                     wpa_printf(MSG_DEBUG,
2447                                  "DPP: Remove a temporaty Controller entry for %s",
2448                                  hostapd_ip_txt(&dpp->tmp_controller->ipaddr,
2449                                                     txt, sizeof(txt)));
2450                     dpp_relay_controller_free(dpp->tmp_controller);
2451                     dpp->tmp_controller = NULL;
2452           }
2453           if (!ctrl && !dpp->tmp_controller) {
2454                     wpa_printf(MSG_DEBUG, "DPP: Add a temporary Controller entry");
2455                     ctrl = os_zalloc(sizeof(*ctrl));
2456                     if (!ctrl)
2457                               goto fail;
2458                     dl_list_init(&ctrl->conn);
2459                     ctrl->global = dpp;
2460                     ctrl->ipaddr.af = AF_INET;
2461                     ctrl->ipaddr.u.v4.s_addr = addr.sin_addr.s_addr;
2462                     ctrl->msg_ctx = dpp->relay_msg_ctx;
2463                     ctrl->cb_ctx = dpp->relay_cb_ctx;
2464                     ctrl->tx = dpp->relay_tx;
2465                     ctrl->gas_resp_tx = dpp->relay_gas_resp_tx;
2466                     dpp->tmp_controller = ctrl;
2467           }
2468           if (!ctrl) {
2469                     wpa_printf(MSG_DEBUG,
2470                                  "DPP: No Controller found for that address");
2471                     goto fail;
2472           }
2473 
2474           if (dl_list_len(&ctrl->conn) >= 15) {
2475                     wpa_printf(MSG_DEBUG,
2476                                  "DPP: Too many ongoing Relay connections to the Controller - cannot start a new one");
2477                     goto fail;
2478           }
2479 
2480           conn = os_zalloc(sizeof(*conn));
2481           if (!conn)
2482                     goto fail;
2483 
2484           conn->global = ctrl->global;
2485           conn->relay = ctrl;
2486           conn->msg_ctx = ctrl->msg_ctx;
2487           conn->cb_ctx = ctrl->global->cb_ctx;
2488           os_memset(conn->mac_addr, 0xff, ETH_ALEN);
2489           conn->sock = fd;
2490 
2491           if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
2492                     wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
2493                                  strerror(errno));
2494                     goto fail;
2495           }
2496 
2497           if (eloop_register_sock(conn->sock, EVENT_TYPE_READ,
2498                                         dpp_controller_rx, conn, NULL) < 0)
2499                     goto fail;
2500           conn->read_eloop = 1;
2501 
2502           /* TODO: eloop timeout to expire connections that do not complete in
2503            * reasonable time */
2504           dl_list_add(&ctrl->conn, &conn->list);
2505           return;
2506 
2507 fail:
2508           close(fd);
2509           os_free(conn);
2510 }
2511 
2512 
dpp_relay_listen(struct dpp_global * dpp,int port,struct dpp_relay_config * config)2513 int dpp_relay_listen(struct dpp_global *dpp, int port,
2514                          struct dpp_relay_config *config)
2515 {
2516           int s;
2517           int on = 1;
2518           struct sockaddr_in sin;
2519 
2520           if (dpp->relay_sock >= 0) {
2521                     wpa_printf(MSG_INFO, "DPP: %s(%d) - relay port already opened",
2522                                  __func__, port);
2523                     return -1;
2524           }
2525 
2526           s = socket(AF_INET, SOCK_STREAM, 0);
2527           if (s < 0) {
2528                     wpa_printf(MSG_INFO,
2529                                  "DPP: socket(SOCK_STREAM) failed: %s",
2530                                  strerror(errno));
2531                     return -1;
2532           }
2533 
2534           if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2535                     wpa_printf(MSG_DEBUG,
2536                                  "DPP: setsockopt(SO_REUSEADDR) failed: %s",
2537                                  strerror(errno));
2538                     /* try to continue anyway */
2539           }
2540 
2541           if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) {
2542                     wpa_printf(MSG_INFO, "DPP: fnctl(O_NONBLOCK) failed: %s",
2543                                  strerror(errno));
2544                     close(s);
2545                     return -1;
2546           }
2547 
2548           /* TODO: IPv6 */
2549           os_memset(&sin, 0, sizeof(sin));
2550           sin.sin_family = AF_INET;
2551           sin.sin_addr.s_addr = INADDR_ANY;
2552           sin.sin_port = htons(port);
2553           if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
2554                     wpa_printf(MSG_INFO,
2555                                  "DPP: Failed to bind Relay TCP port: %s",
2556                                  strerror(errno));
2557                     close(s);
2558                     return -1;
2559           }
2560           if (listen(s, 10 /* max backlog */) < 0 ||
2561               fcntl(s, F_SETFL, O_NONBLOCK) < 0 ||
2562               eloop_register_sock(s, EVENT_TYPE_READ, dpp_relay_tcp_cb, dpp,
2563                                         NULL)) {
2564                     close(s);
2565                     return -1;
2566           }
2567 
2568           dpp->relay_sock = s;
2569           dpp->relay_msg_ctx = config->msg_ctx;
2570           dpp->relay_cb_ctx = config->cb_ctx;
2571           dpp->relay_tx = config->tx;
2572           dpp->relay_gas_resp_tx = config->gas_resp_tx;
2573           wpa_printf(MSG_DEBUG, "DPP: Relay started on TCP port %d", port);
2574           return 0;
2575 }
2576 
2577 
dpp_relay_stop_listen(struct dpp_global * dpp)2578 void dpp_relay_stop_listen(struct dpp_global *dpp)
2579 {
2580           if (!dpp || dpp->relay_sock < 0)
2581                     return;
2582           eloop_unregister_sock(dpp->relay_sock, EVENT_TYPE_READ);
2583           close(dpp->relay_sock);
2584           dpp->relay_sock = -1;
2585 }
2586 
2587 
dpp_tcp_conn_status_requested(struct dpp_global * dpp)2588 bool dpp_tcp_conn_status_requested(struct dpp_global *dpp)
2589 {
2590           struct dpp_connection *conn;
2591 
2592           if (!dpp)
2593                     return false;
2594 
2595           dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
2596                     if (conn->auth && conn->auth->conn_status_requested)
2597                               return true;
2598           }
2599 
2600           return false;
2601 }
2602 
2603 
dpp_tcp_send_conn_status_msg(struct dpp_global * dpp,struct dpp_connection * conn,enum dpp_status_error result,const u8 * ssid,size_t ssid_len,const char * channel_list)2604 static void dpp_tcp_send_conn_status_msg(struct dpp_global *dpp,
2605                                                    struct dpp_connection *conn,
2606                                                    enum dpp_status_error result,
2607                                                    const u8 *ssid, size_t ssid_len,
2608                                                    const char *channel_list)
2609 {
2610           struct dpp_authentication *auth = conn->auth;
2611           int res;
2612           struct wpabuf *msg;
2613           struct dpp_connection *c;
2614 
2615           auth->conn_status_requested = 0;
2616 
2617           msg = dpp_build_conn_status_result(auth, result, ssid, ssid_len,
2618                                                      channel_list);
2619           if (!msg) {
2620                     dpp_connection_remove(conn);
2621                     return;
2622           }
2623 
2624           res = dpp_tcp_send_msg(conn, msg);
2625           wpabuf_free(msg);
2626 
2627           if (res < 0) {
2628                     dpp_connection_remove(conn);
2629                     return;
2630           }
2631 
2632           /* conn might have been removed during the dpp_tcp_send_msg() call, so
2633            * need to check that it is still present before modifying it. */
2634           dl_list_for_each(c, &dpp->tcp_init, struct dpp_connection, list) {
2635                     if (conn == c) {
2636                               /* This exchange will be terminated in the TX status
2637                                * handler */
2638                               conn->on_tcp_tx_complete_remove = 1;
2639                               break;
2640                     }
2641           }
2642 }
2643 
2644 
dpp_tcp_send_conn_status(struct dpp_global * dpp,enum dpp_status_error result,const u8 * ssid,size_t ssid_len,const char * channel_list)2645 void dpp_tcp_send_conn_status(struct dpp_global *dpp,
2646                                     enum dpp_status_error result,
2647                                     const u8 *ssid, size_t ssid_len,
2648                                     const char *channel_list)
2649 {
2650           struct dpp_connection *conn;
2651 
2652           dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
2653                     if (conn->auth && conn->auth->conn_status_requested) {
2654                               dpp_tcp_send_conn_status_msg(dpp, conn, result, ssid,
2655                                                                  ssid_len, channel_list);
2656                               break;
2657                     }
2658           }
2659 }
2660 
2661 #endif /* CONFIG_DPP2 */
2662