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