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, anonymize_ip(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_only_for_cb(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 wpa_printf(MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
944 "result=%d ssid=%s channel_list=%s",
945 status, anonymize_ssid(wpa_ssid_txt(ssid, ssid_len)),
946 channel_list ? channel_list : "N/A");
947 os_free(channel_list);
948 return -1; /* to remove the completed connection */
949 }
950
951
dpp_controller_rx_presence_announcement(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)952 static int dpp_controller_rx_presence_announcement(struct dpp_connection *conn,
953 const u8 *hdr, const u8 *buf,
954 size_t len)
955 {
956 const u8 *r_bootstrap;
957 u16 r_bootstrap_len;
958 struct dpp_bootstrap_info *peer_bi;
959 struct dpp_authentication *auth;
960 struct dpp_global *dpp = conn->ctrl->global;
961
962 wpa_printf(MSG_DEBUG, "DPP: Presence Announcement");
963
964 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
965 &r_bootstrap_len);
966 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
967 wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
968 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
969 return -1;
970 }
971 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
972 r_bootstrap, r_bootstrap_len);
973 peer_bi = dpp_bootstrap_find_chirp(dpp, r_bootstrap);
974 if (!peer_bi) {
975 wpa_printf(MSG_DEBUG,
976 "DPP: No matching bootstrapping information found");
977 return -1;
978 }
979
980 if (conn->auth) {
981 wpa_printf(MSG_DEBUG,
982 "DPP: Ignore Presence Announcement during ongoing Authentication");
983 return 0;
984 }
985
986 auth = dpp_auth_init(dpp, conn->msg_ctx, peer_bi, NULL,
987 DPP_CAPAB_CONFIGURATOR, -1, NULL, 0);
988 if (!auth)
989 return -1;
990 if (dpp_set_configurator(auth, conn->ctrl->configurator_params) < 0) {
991 dpp_auth_deinit(auth);
992 return -1;
993 }
994
995 conn->auth = auth;
996 return dpp_tcp_send_msg(conn, conn->auth->req_msg);
997 }
998
999
dpp_controller_rx_reconfig_announcement(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1000 static int dpp_controller_rx_reconfig_announcement(struct dpp_connection *conn,
1001 const u8 *hdr, const u8 *buf,
1002 size_t len)
1003 {
1004 const u8 *csign_hash, *fcgroup, *a_nonce, *e_id;
1005 u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len;
1006 struct dpp_configurator *conf;
1007 struct dpp_global *dpp = conn->ctrl->global;
1008 struct dpp_authentication *auth;
1009 u16 group;
1010
1011 if (conn->auth) {
1012 wpa_printf(MSG_DEBUG,
1013 "DPP: Ignore Reconfig Announcement during ongoing Authentication");
1014 return -1;
1015 }
1016
1017 wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement");
1018
1019 csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
1020 &csign_hash_len);
1021 if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
1022 wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1023 "Missing or invalid required Configurator C-sign key Hash attribute");
1024 return -1;
1025 }
1026 wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
1027 csign_hash, csign_hash_len);
1028 conf = dpp_configurator_find_kid(dpp, csign_hash);
1029 if (!conf) {
1030 wpa_printf(MSG_DEBUG,
1031 "DPP: No matching Configurator information found");
1032 return -1;
1033 }
1034
1035 fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
1036 &fcgroup_len);
1037 if (!fcgroup || fcgroup_len != 2) {
1038 wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1039 "Missing or invalid required Finite Cyclic Group attribute");
1040 return -1;
1041 }
1042 group = WPA_GET_LE16(fcgroup);
1043 wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group);
1044
1045 a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len);
1046 e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len);
1047
1048 auth = dpp_reconfig_init(dpp, conn->msg_ctx, conf, 0, group,
1049 a_nonce, a_nonce_len, e_id, e_id_len);
1050 if (!auth)
1051 return -1;
1052 if (dpp_set_configurator(auth, conn->ctrl->configurator_params) < 0) {
1053 dpp_auth_deinit(auth);
1054 return -1;
1055 }
1056
1057 conn->auth = auth;
1058 return dpp_tcp_send_msg(conn, auth->reconfig_req_msg);
1059 }
1060
1061
dpp_controller_rx_reconfig_auth_resp(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1062 static int dpp_controller_rx_reconfig_auth_resp(struct dpp_connection *conn,
1063 const u8 *hdr, const u8 *buf,
1064 size_t len)
1065 {
1066 struct dpp_authentication *auth = conn->auth;
1067 struct wpabuf *conf;
1068 int res;
1069
1070 wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response");
1071
1072 if (!auth || !auth->reconfig || !auth->configurator) {
1073 wpa_printf(MSG_DEBUG,
1074 "DPP: No DPP Reconfig Authentication in progress - drop");
1075 return -1;
1076 }
1077
1078 conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
1079 if (!conf)
1080 return -1;
1081
1082 res = dpp_tcp_send_msg(conn, conf);
1083 wpabuf_free(conf);
1084 return res;
1085 }
1086
1087
dpp_controller_rx_pkex_exchange_req(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1088 static int dpp_controller_rx_pkex_exchange_req(struct dpp_connection *conn,
1089 const u8 *hdr, const u8 *buf,
1090 size_t len)
1091 {
1092 struct dpp_controller *ctrl = conn->ctrl;
1093
1094 if (!ctrl)
1095 return 0;
1096
1097 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request");
1098
1099 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1100 * values here */
1101
1102 if (!ctrl->pkex_code || !ctrl->pkex_bi) {
1103 wpa_printf(MSG_DEBUG,
1104 "DPP: No PKEX code configured - ignore request");
1105 return 0;
1106 }
1107
1108 if (conn->pkex || conn->auth) {
1109 wpa_printf(MSG_DEBUG,
1110 "DPP: Already in PKEX/Authentication session - ignore new PKEX request");
1111 return 0;
1112 }
1113
1114 conn->pkex = dpp_pkex_rx_exchange_req(conn->msg_ctx, ctrl->pkex_bi,
1115 NULL, NULL,
1116 ctrl->pkex_identifier,
1117 ctrl->pkex_code,
1118 os_strlen(ctrl->pkex_code),
1119 buf, len, true);
1120 if (!conn->pkex) {
1121 wpa_printf(MSG_DEBUG,
1122 "DPP: Failed to process the request");
1123 return -1;
1124 }
1125
1126 return dpp_tcp_send_msg(conn, conn->pkex->exchange_resp);
1127 }
1128
1129
dpp_controller_rx_pkex_exchange_resp(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1130 static int dpp_controller_rx_pkex_exchange_resp(struct dpp_connection *conn,
1131 const u8 *hdr, const u8 *buf,
1132 size_t len)
1133 {
1134 struct dpp_pkex *pkex = conn->pkex;
1135 struct wpabuf *msg;
1136 int res;
1137
1138 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response");
1139
1140 if (!pkex || !pkex->initiator || pkex->exchange_done) {
1141 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1142 return 0;
1143 }
1144
1145 msg = dpp_pkex_rx_exchange_resp(pkex, NULL, buf, len);
1146 if (!msg) {
1147 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1148 return -1;
1149 }
1150
1151 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request");
1152 res = dpp_tcp_send_msg(conn, msg);
1153 wpabuf_free(msg);
1154 return res;
1155 }
1156
1157
dpp_controller_rx_pkex_commit_reveal_req(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1158 static int dpp_controller_rx_pkex_commit_reveal_req(struct dpp_connection *conn,
1159 const u8 *hdr,
1160 const u8 *buf, size_t len)
1161 {
1162 struct dpp_pkex *pkex = conn->pkex;
1163 struct wpabuf *msg;
1164 int res;
1165 struct dpp_bootstrap_info *bi;
1166
1167 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request");
1168
1169 if (!pkex || pkex->initiator || !pkex->exchange_done) {
1170 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1171 return 0;
1172 }
1173
1174 msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
1175 if (!msg) {
1176 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
1177 return -1;
1178 }
1179
1180 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response");
1181 res = dpp_tcp_send_msg(conn, msg);
1182 wpabuf_free(msg);
1183 if (res < 0)
1184 return res;
1185 bi = dpp_pkex_finish(conn->global, pkex, NULL, 0);
1186 if (!bi)
1187 return -1;
1188 conn->pkex = NULL;
1189 return 0;
1190 }
1191
1192
1193 static int
dpp_controller_rx_pkex_commit_reveal_resp(struct dpp_connection * conn,const u8 * hdr,const u8 * buf,size_t len)1194 dpp_controller_rx_pkex_commit_reveal_resp(struct dpp_connection *conn,
1195 const u8 *hdr,
1196 const u8 *buf, size_t len)
1197 {
1198 struct dpp_pkex *pkex = conn->pkex;
1199 int res;
1200 struct dpp_bootstrap_info *bi;
1201
1202 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response");
1203
1204 if (!pkex || !pkex->initiator || !pkex->exchange_done) {
1205 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1206 return 0;
1207 }
1208
1209 res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
1210 if (res < 0) {
1211 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1212 return res;
1213 }
1214
1215 bi = dpp_pkex_finish(conn->global, pkex, NULL, 0);
1216 if (!bi)
1217 return -1;
1218 conn->pkex = NULL;
1219
1220 if (!conn->pkex_done)
1221 return -1;
1222 return conn->pkex_done(conn->cb_ctx, conn, bi);
1223 }
1224
1225
dpp_controller_rx_action(struct dpp_connection * conn,const u8 * msg,size_t len)1226 static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg,
1227 size_t len)
1228 {
1229 const u8 *pos, *end;
1230 u8 type;
1231
1232 wpa_printf(MSG_DEBUG, "DPP: Received DPP Action frame over TCP");
1233 pos = msg;
1234 end = msg + len;
1235
1236 if (end - pos < DPP_HDR_LEN ||
1237 WPA_GET_BE24(pos) != OUI_WFA ||
1238 pos[3] != DPP_OUI_TYPE) {
1239 wpa_printf(MSG_DEBUG, "DPP: Unrecognized header");
1240 return -1;
1241 }
1242
1243 if (pos[4] != 1) {
1244 wpa_printf(MSG_DEBUG, "DPP: Unsupported Crypto Suite %u",
1245 pos[4]);
1246 return -1;
1247 }
1248 type = pos[5];
1249 wpa_printf(MSG_DEBUG, "DPP: Received message type %u", type);
1250 pos += DPP_HDR_LEN;
1251
1252 wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes",
1253 pos, end - pos);
1254 if (dpp_check_attrs(pos, end - pos) < 0)
1255 return -1;
1256
1257 if (conn->relay) {
1258 wpa_printf(MSG_DEBUG, "DPP: Relay - send over WLAN");
1259 conn->relay->tx(conn->relay->cb_ctx, conn->mac_addr,
1260 conn->freq, msg, len);
1261 return 0;
1262 }
1263
1264 switch (type) {
1265 case DPP_PA_AUTHENTICATION_REQ:
1266 return dpp_controller_rx_auth_req(conn, msg, pos, end - pos);
1267 case DPP_PA_AUTHENTICATION_RESP:
1268 return dpp_controller_rx_auth_resp(conn, msg, pos, end - pos);
1269 case DPP_PA_AUTHENTICATION_CONF:
1270 return dpp_controller_rx_auth_conf(conn, msg, pos, end - pos);
1271 case DPP_PA_CONFIGURATION_RESULT:
1272 return dpp_controller_rx_conf_result(conn, msg, pos, end - pos);
1273 case DPP_PA_CONNECTION_STATUS_RESULT:
1274 return dpp_controller_rx_conn_status_result(conn, msg, pos,
1275 end - pos);
1276 case DPP_PA_PRESENCE_ANNOUNCEMENT:
1277 return dpp_controller_rx_presence_announcement(conn, msg, pos,
1278 end - pos);
1279 case DPP_PA_RECONFIG_ANNOUNCEMENT:
1280 return dpp_controller_rx_reconfig_announcement(conn, msg, pos,
1281 end - pos);
1282 case DPP_PA_RECONFIG_AUTH_RESP:
1283 return dpp_controller_rx_reconfig_auth_resp(conn, msg, pos,
1284 end - pos);
1285 case DPP_PA_PKEX_V1_EXCHANGE_REQ:
1286 wpa_printf(MSG_DEBUG,
1287 "DPP: Ignore PKEXv1 Exchange Request - not supported over TCP");
1288 return -1;
1289 case DPP_PA_PKEX_EXCHANGE_REQ:
1290 return dpp_controller_rx_pkex_exchange_req(conn, msg, pos,
1291 end - pos);
1292 case DPP_PA_PKEX_EXCHANGE_RESP:
1293 return dpp_controller_rx_pkex_exchange_resp(conn, msg, pos,
1294 end - pos);
1295 case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
1296 return dpp_controller_rx_pkex_commit_reveal_req(conn, msg, pos,
1297 end - pos);
1298 case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
1299 return dpp_controller_rx_pkex_commit_reveal_resp(conn, msg, pos,
1300 end - pos);
1301 default:
1302 /* TODO: missing messages types */
1303 wpa_printf(MSG_DEBUG,
1304 "DPP: Unsupported frame subtype %d", type);
1305 return -1;
1306 }
1307 }
1308
1309
dpp_tcp_send_comeback_delay(struct dpp_connection * conn,u8 action)1310 static int dpp_tcp_send_comeback_delay(struct dpp_connection *conn, u8 action)
1311 {
1312 struct wpabuf *buf;
1313 size_t len = 18;
1314
1315 if (action == WLAN_PA_GAS_COMEBACK_RESP)
1316 len++;
1317
1318 buf = wpabuf_alloc(4 + len);
1319 if (!buf)
1320 return -1;
1321
1322 wpabuf_put_be32(buf, len);
1323
1324 wpabuf_put_u8(buf, action);
1325 wpabuf_put_u8(buf, conn->gas_dialog_token);
1326 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
1327 if (action == WLAN_PA_GAS_COMEBACK_RESP)
1328 wpabuf_put_u8(buf, 0);
1329 wpabuf_put_le16(buf, 500); /* GAS Comeback Delay */
1330
1331 dpp_write_adv_proto(buf);
1332 wpabuf_put_le16(buf, 0); /* Query Response Length */
1333
1334 /* Send Config Response over TCP */
1335 wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", buf);
1336 wpabuf_free(conn->msg_out);
1337 conn->msg_out_pos = 0;
1338 conn->msg_out = buf;
1339 dpp_tcp_send(conn);
1340 return 0;
1341 }
1342
1343
dpp_tcp_send_gas_resp(struct dpp_connection * conn,u8 action,struct wpabuf * resp)1344 static int dpp_tcp_send_gas_resp(struct dpp_connection *conn, u8 action,
1345 struct wpabuf *resp)
1346 {
1347 struct wpabuf *buf;
1348 size_t len;
1349
1350 if (!resp)
1351 return -1;
1352
1353 len = 18 + wpabuf_len(resp);
1354 if (action == WLAN_PA_GAS_COMEBACK_RESP)
1355 len++;
1356
1357 buf = wpabuf_alloc(4 + len);
1358 if (!buf) {
1359 wpabuf_free(resp);
1360 return -1;
1361 }
1362
1363 wpabuf_put_be32(buf, len);
1364
1365 wpabuf_put_u8(buf, action);
1366 wpabuf_put_u8(buf, conn->gas_dialog_token);
1367 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
1368 if (action == WLAN_PA_GAS_COMEBACK_RESP)
1369 wpabuf_put_u8(buf, 0);
1370 wpabuf_put_le16(buf, 0); /* GAS Comeback Delay */
1371
1372 dpp_write_adv_proto(buf);
1373 dpp_write_gas_query(buf, resp);
1374 wpabuf_free(resp);
1375
1376 /* Send Config Response over TCP; GAS fragmentation is taken care of by
1377 * the Relay */
1378 wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", buf);
1379 wpabuf_free(conn->msg_out);
1380 conn->msg_out_pos = 0;
1381 conn->msg_out = buf;
1382 conn->on_tcp_tx_complete_gas_done = 1;
1383 dpp_tcp_send(conn);
1384 return 0;
1385 }
1386
1387
dpp_controller_rx_gas_req(struct dpp_connection * conn,const u8 * msg,size_t len)1388 static int dpp_controller_rx_gas_req(struct dpp_connection *conn, const u8 *msg,
1389 size_t len)
1390 {
1391 const u8 *pos, *end, *next;
1392 const u8 *adv_proto;
1393 u16 slen;
1394 struct wpabuf *resp;
1395 struct dpp_authentication *auth = conn->auth;
1396
1397 if (len < 1 + 2)
1398 return -1;
1399
1400 wpa_printf(MSG_DEBUG,
1401 "DPP: Received DPP Configuration Request over TCP");
1402
1403 if (!auth || (!conn->ctrl && !auth->configurator) ||
1404 (!auth->auth_success && !auth->reconfig_success)) {
1405 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1406 return -1;
1407 }
1408
1409 wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX);
1410
1411 pos = msg;
1412 end = msg + len;
1413
1414 conn->gas_dialog_token = *pos++;
1415 adv_proto = pos++;
1416 slen = *pos++;
1417 if (*adv_proto != WLAN_EID_ADV_PROTO ||
1418 slen > end - pos || slen < 2)
1419 return -1;
1420
1421 next = pos + slen;
1422 pos++; /* skip QueryRespLenLimit and PAME-BI */
1423
1424 if (slen != 8 || *pos != WLAN_EID_VENDOR_SPECIFIC ||
1425 pos[1] != 5 || WPA_GET_BE24(&pos[2]) != OUI_WFA ||
1426 pos[5] != DPP_OUI_TYPE || pos[6] != 0x01)
1427 return -1;
1428
1429 pos = next;
1430 /* Query Request */
1431 if (end - pos < 2)
1432 return -1;
1433 slen = WPA_GET_LE16(pos);
1434 pos += 2;
1435 if (slen > end - pos)
1436 return -1;
1437
1438 resp = dpp_conf_req_rx(auth, pos, slen);
1439 if (!resp && auth->waiting_cert) {
1440 wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
1441 conn->gas_comeback_in_progress = 1;
1442 return dpp_tcp_send_comeback_delay(conn,
1443 WLAN_PA_GAS_INITIAL_RESP);
1444 }
1445
1446 if (!resp && auth->waiting_config && auth->peer_bi) {
1447 char *buf = NULL, *name = "";
1448 char band[200], *b_pos, *b_end;
1449 int i, res, *opclass = auth->e_band_support;
1450 char *mud_url = "N/A";
1451
1452 wpa_printf(MSG_DEBUG, "DPP: Configuration not yet ready");
1453 if (auth->e_name) {
1454 size_t e_len = os_strlen(auth->e_name);
1455
1456 buf = os_malloc(e_len * 4 + 1);
1457 if (buf) {
1458 printf_encode(buf, len * 4 + 1,
1459 (const u8 *) auth->e_name, e_len);
1460 name = buf;
1461 }
1462 }
1463 band[0] = '\0';
1464 b_pos = band;
1465 b_end = band + sizeof(band);
1466 for (i = 0; opclass && opclass[i]; i++) {
1467 res = os_snprintf(b_pos, b_end - b_pos, "%s%d",
1468 b_pos == band ? "" : ",", opclass[i]);
1469 if (os_snprintf_error(b_end - b_pos, res)) {
1470 *b_pos = '\0';
1471 break;
1472 }
1473 b_pos += res;
1474 }
1475 if (auth->e_mud_url) {
1476 size_t e_len = os_strlen(auth->e_mud_url);
1477
1478 if (!has_ctrl_char((const u8 *) auth->e_mud_url, e_len))
1479 mud_url = auth->e_mud_url;
1480 }
1481 wpa_msg(conn->msg_ctx, MSG_INFO, DPP_EVENT_CONF_NEEDED
1482 "peer=%d net_role=%s name=\"%s\" opclass=%s mud_url=%s",
1483 auth->peer_bi->id, dpp_netrole_str(auth->e_netrole),
1484 name, band, mud_url);
1485 os_free(buf);
1486
1487 conn->gas_comeback_in_progress = 1;
1488 return dpp_tcp_send_comeback_delay(conn,
1489 WLAN_PA_GAS_INITIAL_RESP);
1490 }
1491
1492 return dpp_tcp_send_gas_resp(conn, WLAN_PA_GAS_INITIAL_RESP, resp);
1493 }
1494
1495
dpp_controller_rx_gas_comeback_req(struct dpp_connection * conn,const u8 * msg,size_t len)1496 static int dpp_controller_rx_gas_comeback_req(struct dpp_connection *conn,
1497 const u8 *msg, size_t len)
1498 {
1499 u8 dialog_token;
1500 struct dpp_authentication *auth = conn->auth;
1501 struct wpabuf *resp;
1502
1503 if (len < 1)
1504 return -1;
1505
1506 wpa_printf(MSG_DEBUG,
1507 "DPP: Received DPP Configuration Request over TCP (comeback)");
1508
1509 if (!auth || (!conn->ctrl && !auth->configurator) ||
1510 (!auth->auth_success && !auth->reconfig_success) ||
1511 !conn->gas_comeback_in_progress) {
1512 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1513 return -1;
1514 }
1515
1516 dialog_token = msg[0];
1517 if (dialog_token != conn->gas_dialog_token) {
1518 wpa_printf(MSG_DEBUG, "DPP: Dialog token mismatch (%u != %u)",
1519 dialog_token, conn->gas_dialog_token);
1520 return -1;
1521 }
1522
1523 if (!auth->conf_resp_tcp) {
1524 wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
1525 return dpp_tcp_send_comeback_delay(conn,
1526 WLAN_PA_GAS_COMEBACK_RESP);
1527 }
1528
1529 wpa_printf(MSG_DEBUG,
1530 "DPP: Configuration response is ready to be sent out");
1531 resp = auth->conf_resp_tcp;
1532 auth->conf_resp_tcp = NULL;
1533 return dpp_tcp_send_gas_resp(conn, WLAN_PA_GAS_COMEBACK_RESP, resp);
1534 }
1535
1536
dpp_tcp_build_csr(void * eloop_ctx,void * timeout_ctx)1537 static void dpp_tcp_build_csr(void *eloop_ctx, void *timeout_ctx)
1538 {
1539 struct dpp_connection *conn = eloop_ctx;
1540 struct dpp_authentication *auth = conn->auth;
1541
1542 if (!auth || !auth->csrattrs)
1543 return;
1544
1545 wpa_printf(MSG_DEBUG, "DPP: Build CSR");
1546 wpabuf_free(auth->csr);
1547 /* TODO: Additional information needed for CSR based on csrAttrs */
1548 auth->csr = dpp_build_csr(auth, conn->name ? conn->name : "Test");
1549 if (!auth->csr) {
1550 dpp_connection_remove(conn);
1551 return;
1552 }
1553
1554 dpp_controller_start_gas_client(conn);
1555 }
1556
1557
1558 #ifdef CONFIG_DPP3
dpp_tcp_build_new_key(void * eloop_ctx,void * timeout_ctx)1559 static void dpp_tcp_build_new_key(void *eloop_ctx, void *timeout_ctx)
1560 {
1561 struct dpp_connection *conn = eloop_ctx;
1562 struct dpp_authentication *auth = conn->auth;
1563
1564 if (!auth || !auth->waiting_new_key)
1565 return;
1566
1567 wpa_printf(MSG_DEBUG, "DPP: Build config request with a new key");
1568 dpp_controller_start_gas_client(conn);
1569 }
1570 #endif /* CONFIG_DPP3 */
1571
1572
dpp_tcp_rx_gas_resp(struct dpp_connection * conn,struct wpabuf * resp)1573 static int dpp_tcp_rx_gas_resp(struct dpp_connection *conn, struct wpabuf *resp)
1574 {
1575 struct dpp_authentication *auth = conn->auth;
1576 int res;
1577 struct wpabuf *msg;
1578 enum dpp_status_error status;
1579
1580 wpa_printf(MSG_DEBUG,
1581 "DPP: Configuration Response for local stack from TCP");
1582
1583 if (auth)
1584 res = dpp_conf_resp_rx(auth, resp);
1585 else
1586 res = -1;
1587 wpabuf_free(resp);
1588 if (res == -2) {
1589 wpa_printf(MSG_DEBUG, "DPP: CSR needed");
1590 eloop_register_timeout(0, 0, dpp_tcp_build_csr, conn, NULL);
1591 return 0;
1592 }
1593 #ifdef CONFIG_DPP3
1594 if (res == -3) {
1595 wpa_printf(MSG_DEBUG, "DPP: New protocol key needed");
1596 eloop_register_timeout(0, 0, dpp_tcp_build_new_key, conn,
1597 NULL);
1598 return 0;
1599 }
1600 #endif /* CONFIG_DPP3 */
1601 if (res < 0) {
1602 wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
1603 return -1;
1604 }
1605
1606 if (conn->process_conf_obj)
1607 res = conn->process_conf_obj(conn->cb_ctx, auth);
1608 else
1609 res = 0;
1610
1611 if (auth->peer_version < 2 || auth->conf_resp_status != DPP_STATUS_OK)
1612 return -1;
1613
1614 wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
1615 status = res < 0 ? DPP_STATUS_CONFIG_REJECTED : DPP_STATUS_OK;
1616 msg = dpp_build_conf_result(auth, status);
1617 if (!msg)
1618 return -1;
1619
1620 conn->on_tcp_tx_complete_remove = 1;
1621 res = dpp_tcp_send_msg(conn, msg);
1622 wpabuf_free(msg);
1623
1624 /* This exchange will be terminated in the TX status handler */
1625
1626 return res;
1627 }
1628
1629
dpp_tcp_gas_query_comeback(void * eloop_ctx,void * timeout_ctx)1630 static void dpp_tcp_gas_query_comeback(void *eloop_ctx, void *timeout_ctx)
1631 {
1632 struct dpp_connection *conn = eloop_ctx;
1633 struct dpp_authentication *auth = conn->auth;
1634 struct wpabuf *msg;
1635
1636 if (!auth)
1637 return;
1638
1639 wpa_printf(MSG_DEBUG, "DPP: Send GAS Comeback Request");
1640 msg = wpabuf_alloc(4 + 2);
1641 if (!msg)
1642 return;
1643 wpabuf_put_be32(msg, 2);
1644 wpabuf_put_u8(msg, WLAN_PA_GAS_COMEBACK_REQ);
1645 wpabuf_put_u8(msg, conn->gas_dialog_token);
1646 wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", msg);
1647
1648 wpabuf_free(conn->msg_out);
1649 conn->msg_out_pos = 0;
1650 conn->msg_out = msg;
1651 dpp_tcp_send(conn);
1652 }
1653
1654
dpp_rx_gas_resp(struct dpp_connection * conn,const u8 * msg,size_t len,bool comeback)1655 static int dpp_rx_gas_resp(struct dpp_connection *conn, const u8 *msg,
1656 size_t len, bool comeback)
1657 {
1658 struct wpabuf *buf;
1659 u8 dialog_token;
1660 const u8 *pos, *end, *next, *adv_proto;
1661 u16 status, slen, comeback_delay;
1662
1663 if (len < (size_t) (5 + 2 + (comeback ? 1 : 0)))
1664 return -1;
1665
1666 wpa_printf(MSG_DEBUG,
1667 "DPP: Received DPP Configuration Response over TCP");
1668
1669 pos = msg;
1670 end = msg + len;
1671
1672 dialog_token = *pos++;
1673 status = WPA_GET_LE16(pos);
1674 if (status != WLAN_STATUS_SUCCESS) {
1675 wpa_printf(MSG_DEBUG, "DPP: Unexpected Status Code %u", status);
1676 return -1;
1677 }
1678 pos += 2;
1679 if (comeback)
1680 pos++; /* ignore Fragment ID */
1681 comeback_delay = WPA_GET_LE16(pos);
1682 pos += 2;
1683
1684 adv_proto = pos++;
1685 slen = *pos++;
1686 if (*adv_proto != WLAN_EID_ADV_PROTO ||
1687 slen > end - pos || slen < 2)
1688 return -1;
1689
1690 next = pos + slen;
1691 pos++; /* skip QueryRespLenLimit and PAME-BI */
1692
1693 if (slen != 8 || *pos != WLAN_EID_VENDOR_SPECIFIC ||
1694 pos[1] != 5 || WPA_GET_BE24(&pos[2]) != OUI_WFA ||
1695 pos[5] != DPP_OUI_TYPE || pos[6] != 0x01)
1696 return -1;
1697
1698 pos = next;
1699 /* Query Response */
1700 if (end - pos < 2)
1701 return -1;
1702 slen = WPA_GET_LE16(pos);
1703 pos += 2;
1704 if (slen > end - pos)
1705 return -1;
1706
1707 if (comeback_delay) {
1708 unsigned int secs, usecs;
1709
1710 conn->gas_dialog_token = dialog_token;
1711 secs = (comeback_delay * 1024) / 1000000;
1712 usecs = comeback_delay * 1024 - secs * 1000000;
1713 wpa_printf(MSG_DEBUG, "DPP: Comeback delay: %u",
1714 comeback_delay);
1715 eloop_cancel_timeout(dpp_tcp_gas_query_comeback, conn, NULL);
1716 eloop_register_timeout(secs, usecs, dpp_tcp_gas_query_comeback,
1717 conn, NULL);
1718 return 0;
1719 }
1720
1721 buf = wpabuf_alloc(slen);
1722 if (!buf)
1723 return -1;
1724 wpabuf_put_data(buf, pos, slen);
1725
1726 if (!conn->relay &&
1727 (!conn->ctrl || (conn->ctrl->allowed_roles & DPP_CAPAB_ENROLLEE)))
1728 return dpp_tcp_rx_gas_resp(conn, buf);
1729
1730 if (!conn->relay) {
1731 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1732 wpabuf_free(buf);
1733 return -1;
1734 }
1735 wpa_printf(MSG_DEBUG, "DPP: Relay - send over WLAN");
1736 conn->relay->gas_resp_tx(conn->relay->cb_ctx, conn->mac_addr,
1737 dialog_token, 0, buf);
1738
1739 return 0;
1740 }
1741
1742
dpp_controller_rx(int sd,void * eloop_ctx,void * sock_ctx)1743 static void dpp_controller_rx(int sd, void *eloop_ctx, void *sock_ctx)
1744 {
1745 struct dpp_connection *conn = eloop_ctx;
1746 int res;
1747 const u8 *pos;
1748
1749 wpa_printf(MSG_DEBUG, "DPP: TCP data available for reading (sock %d)",
1750 sd);
1751
1752 if (conn->msg_len_octets < 4) {
1753 u32 msglen;
1754
1755 res = recv(sd, &conn->msg_len[conn->msg_len_octets],
1756 4 - conn->msg_len_octets, 0);
1757 if (res < 0) {
1758 wpa_printf(MSG_DEBUG, "DPP: recv failed: %s",
1759 strerror(errno));
1760 dpp_connection_remove(conn);
1761 return;
1762 }
1763 if (res == 0) {
1764 wpa_printf(MSG_DEBUG,
1765 "DPP: No more data available over TCP");
1766 dpp_connection_remove(conn);
1767 return;
1768 }
1769 wpa_printf(MSG_DEBUG,
1770 "DPP: Received %d/%d octet(s) of message length field",
1771 res, (int) (4 - conn->msg_len_octets));
1772 conn->msg_len_octets += res;
1773
1774 if (conn->msg_len_octets < 4) {
1775 wpa_printf(MSG_DEBUG,
1776 "DPP: Need %d more octets of message length field",
1777 (int) (4 - conn->msg_len_octets));
1778 return;
1779 }
1780
1781 msglen = WPA_GET_BE32(conn->msg_len);
1782 wpa_printf(MSG_DEBUG, "DPP: Message length: %u", msglen);
1783 if (msglen > 65535) {
1784 wpa_printf(MSG_INFO, "DPP: Unexpectedly long message");
1785 dpp_connection_remove(conn);
1786 return;
1787 }
1788
1789 wpabuf_free(conn->msg);
1790 conn->msg = wpabuf_alloc(msglen);
1791 }
1792
1793 if (!conn->msg) {
1794 wpa_printf(MSG_DEBUG,
1795 "DPP: No buffer available for receiving the message");
1796 dpp_connection_remove(conn);
1797 return;
1798 }
1799
1800 wpa_printf(MSG_DEBUG, "DPP: Need %u more octets of message payload",
1801 (unsigned int) wpabuf_tailroom(conn->msg));
1802
1803 res = recv(sd, wpabuf_put(conn->msg, 0), wpabuf_tailroom(conn->msg), 0);
1804 if (res < 0) {
1805 wpa_printf(MSG_DEBUG, "DPP: recv failed: %s", strerror(errno));
1806 dpp_connection_remove(conn);
1807 return;
1808 }
1809 if (res == 0) {
1810 wpa_printf(MSG_DEBUG, "DPP: No more data available over TCP");
1811 dpp_connection_remove(conn);
1812 return;
1813 }
1814 wpa_printf(MSG_DEBUG, "DPP: Received %d octets", res);
1815 wpabuf_put(conn->msg, res);
1816
1817 if (wpabuf_tailroom(conn->msg) > 0) {
1818 wpa_printf(MSG_DEBUG,
1819 "DPP: Need %u more octets of message payload",
1820 (unsigned int) wpabuf_tailroom(conn->msg));
1821 return;
1822 }
1823
1824 conn->msg_len_octets = 0;
1825 wpa_hexdump_buf(MSG_DEBUG, "DPP: Received TCP message", conn->msg);
1826 if (wpabuf_len(conn->msg) < 1) {
1827 dpp_connection_remove(conn);
1828 return;
1829 }
1830
1831 pos = wpabuf_head(conn->msg);
1832 switch (*pos) {
1833 case WLAN_PA_VENDOR_SPECIFIC:
1834 if (dpp_controller_rx_action(conn, pos + 1,
1835 wpabuf_len(conn->msg) - 1) < 0)
1836 dpp_connection_remove(conn);
1837 break;
1838 case WLAN_PA_GAS_INITIAL_REQ:
1839 if (dpp_controller_rx_gas_req(conn, pos + 1,
1840 wpabuf_len(conn->msg) - 1) < 0)
1841 dpp_connection_remove(conn);
1842 break;
1843 case WLAN_PA_GAS_INITIAL_RESP:
1844 case WLAN_PA_GAS_COMEBACK_RESP:
1845 if (dpp_rx_gas_resp(conn, pos + 1,
1846 wpabuf_len(conn->msg) - 1,
1847 *pos == WLAN_PA_GAS_COMEBACK_RESP) < 0)
1848 dpp_connection_remove(conn);
1849 break;
1850 case WLAN_PA_GAS_COMEBACK_REQ:
1851 if (dpp_controller_rx_gas_comeback_req(
1852 conn, pos + 1, wpabuf_len(conn->msg) - 1) < 0)
1853 dpp_connection_remove(conn);
1854 break;
1855 default:
1856 wpa_printf(MSG_DEBUG, "DPP: Ignore unsupported message type %u",
1857 *pos);
1858 break;
1859 }
1860 }
1861
1862
dpp_controller_tcp_cb(int sd,void * eloop_ctx,void * sock_ctx)1863 static void dpp_controller_tcp_cb(int sd, void *eloop_ctx, void *sock_ctx)
1864 {
1865 struct dpp_controller *ctrl = eloop_ctx;
1866 struct sockaddr_in addr;
1867 socklen_t addr_len = sizeof(addr);
1868 int fd;
1869 struct dpp_connection *conn;
1870
1871 wpa_printf(MSG_DEBUG, "DPP: New TCP connection");
1872
1873 fd = accept(ctrl->sock, (struct sockaddr *) &addr, &addr_len);
1874 if (fd < 0) {
1875 wpa_printf(MSG_DEBUG,
1876 "DPP: Failed to accept new connection: %s",
1877 strerror(errno));
1878 return;
1879 }
1880 wpa_printf(MSG_DEBUG, "DPP: Connection from %s:%d",
1881 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
1882
1883 conn = os_zalloc(sizeof(*conn));
1884 if (!conn)
1885 goto fail;
1886
1887 conn->global = ctrl->global;
1888 conn->ctrl = ctrl;
1889 conn->msg_ctx = ctrl->msg_ctx;
1890 conn->cb_ctx = ctrl->cb_ctx;
1891 conn->process_conf_obj = ctrl->process_conf_obj;
1892 conn->tcp_msg_sent = ctrl->tcp_msg_sent;
1893 conn->sock = fd;
1894 conn->netrole = ctrl->netrole;
1895
1896 if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
1897 wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
1898 strerror(errno));
1899 goto fail;
1900 }
1901
1902 if (eloop_register_sock(conn->sock, EVENT_TYPE_READ,
1903 dpp_controller_rx, conn, NULL) < 0)
1904 goto fail;
1905 conn->read_eloop = 1;
1906
1907 /* TODO: eloop timeout to expire connections that do not complete in
1908 * reasonable time */
1909 dl_list_add(&ctrl->conn, &conn->list);
1910 return;
1911
1912 fail:
1913 close(fd);
1914 os_free(conn);
1915 }
1916
1917
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))1918 int dpp_tcp_pkex_init(struct dpp_global *dpp, struct dpp_pkex *pkex,
1919 const struct hostapd_ip_addr *addr, int port,
1920 void *msg_ctx, void *cb_ctx,
1921 int (*pkex_done)(void *ctx, void *conn,
1922 struct dpp_bootstrap_info *bi))
1923 {
1924 struct dpp_connection *conn;
1925 struct sockaddr_storage saddr;
1926 socklen_t addrlen;
1927 const u8 *hdr, *pos, *end;
1928 char txt[100];
1929
1930 wpa_printf(MSG_DEBUG, "DPP: Initialize TCP connection to %s port %d",
1931 anonymize_ip(hostapd_ip_txt(addr, txt, sizeof(txt))), port);
1932 if (dpp_ipaddr_to_sockaddr((struct sockaddr *) &saddr, &addrlen,
1933 addr, port) < 0) {
1934 dpp_pkex_free(pkex);
1935 return -1;
1936 }
1937
1938 conn = os_zalloc(sizeof(*conn));
1939 if (!conn) {
1940 dpp_pkex_free(pkex);
1941 return -1;
1942 }
1943
1944 conn->msg_ctx = msg_ctx;
1945 conn->cb_ctx = cb_ctx;
1946 conn->pkex_done = pkex_done;
1947 conn->global = dpp;
1948 conn->pkex = pkex;
1949 conn->sock = socket(AF_INET, SOCK_STREAM, 0);
1950 if (conn->sock < 0)
1951 goto fail;
1952
1953 if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
1954 wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
1955 strerror(errno));
1956 goto fail;
1957 }
1958
1959 if (connect(conn->sock, (struct sockaddr *) &saddr, addrlen) < 0) {
1960 if (errno != EINPROGRESS) {
1961 wpa_printf(MSG_DEBUG, "DPP: Failed to connect: %s",
1962 strerror(errno));
1963 goto fail;
1964 }
1965
1966 /*
1967 * Continue connecting in the background; eloop will call us
1968 * once the connection is ready (or failed).
1969 */
1970 }
1971
1972 if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
1973 dpp_conn_tx_ready, conn, NULL) < 0)
1974 goto fail;
1975 conn->write_eloop = 1;
1976
1977 hdr = wpabuf_head(pkex->exchange_req);
1978 end = hdr + wpabuf_len(pkex->exchange_req);
1979 hdr += 2; /* skip Category and Actiom */
1980 pos = hdr + DPP_HDR_LEN;
1981 conn->msg_out = dpp_tcp_encaps(hdr, pos, end - pos);
1982 if (!conn->msg_out)
1983 goto fail;
1984 /* Message will be sent in dpp_conn_tx_ready() */
1985
1986 /* TODO: eloop timeout to clear a connection if it does not complete
1987 * properly */
1988 dl_list_add(&dpp->tcp_init, &conn->list);
1989 return 0;
1990 fail:
1991 dpp_connection_free(conn);
1992 return -1;
1993 }
1994
1995
dpp_tcp_auth_start(struct dpp_connection * conn,struct dpp_authentication * auth)1996 static int dpp_tcp_auth_start(struct dpp_connection *conn,
1997 struct dpp_authentication *auth)
1998 {
1999 const u8 *hdr, *pos, *end;
2000
2001 hdr = wpabuf_head(auth->req_msg);
2002 end = hdr + wpabuf_len(auth->req_msg);
2003 hdr += 2; /* skip Category and Actiom */
2004 pos = hdr + DPP_HDR_LEN;
2005 conn->msg_out = dpp_tcp_encaps(hdr, pos, end - pos);
2006 if (!conn->msg_out)
2007 return -1;
2008 /* Message will be sent in dpp_conn_tx_ready() */
2009 return 0;
2010 }
2011
2012
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))2013 int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
2014 const struct hostapd_ip_addr *addr, int port, const char *name,
2015 enum dpp_netrole netrole, const char *mud_url,
2016 const char *extra_conf_req_name,
2017 const char *extra_conf_req_value,
2018 void *msg_ctx, void *cb_ctx,
2019 int (*process_conf_obj)(void *ctx,
2020 struct dpp_authentication *auth),
2021 bool (*tcp_msg_sent)(void *ctx,
2022 struct dpp_authentication *auth))
2023 {
2024 struct dpp_connection *conn;
2025 struct sockaddr_storage saddr;
2026 socklen_t addrlen;
2027 char txt[100];
2028
2029 wpa_printf(MSG_DEBUG, "DPP: Initialize TCP connection to %s port %d",
2030 anonymize_ip(hostapd_ip_txt(addr, txt, sizeof(txt))), port);
2031 if (dpp_ipaddr_to_sockaddr((struct sockaddr *) &saddr, &addrlen,
2032 addr, port) < 0) {
2033 dpp_auth_deinit(auth);
2034 return -1;
2035 }
2036
2037 conn = os_zalloc(sizeof(*conn));
2038 if (!conn) {
2039 dpp_auth_deinit(auth);
2040 return -1;
2041 }
2042
2043 conn->msg_ctx = msg_ctx;
2044 conn->cb_ctx = cb_ctx;
2045 conn->process_conf_obj = process_conf_obj;
2046 conn->tcp_msg_sent = tcp_msg_sent;
2047 conn->name = os_strdup(name ? name : "Test");
2048 if (mud_url)
2049 conn->mud_url = os_strdup(mud_url);
2050 if (extra_conf_req_name)
2051 conn->extra_conf_req_name = os_strdup(extra_conf_req_name);
2052 if (extra_conf_req_value)
2053 conn->extra_conf_req_value = os_strdup(extra_conf_req_value);
2054 conn->netrole = netrole;
2055 conn->global = dpp;
2056 conn->auth = auth;
2057 conn->sock = socket(AF_INET, SOCK_STREAM, 0);
2058 if (conn->sock < 0)
2059 goto fail;
2060
2061 if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
2062 wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
2063 strerror(errno));
2064 goto fail;
2065 }
2066
2067 if (connect(conn->sock, (struct sockaddr *) &saddr, addrlen) < 0) {
2068 if (errno != EINPROGRESS) {
2069 wpa_printf(MSG_DEBUG, "DPP: Failed to connect: %s",
2070 strerror(errno));
2071 goto fail;
2072 }
2073
2074 /*
2075 * Continue connecting in the background; eloop will call us
2076 * once the connection is ready (or failed).
2077 */
2078 }
2079
2080 if (eloop_register_sock(conn->sock, EVENT_TYPE_WRITE,
2081 dpp_conn_tx_ready, conn, NULL) < 0)
2082 goto fail;
2083 conn->write_eloop = 1;
2084
2085 if (dpp_tcp_auth_start(conn, auth) < 0)
2086 goto fail;
2087
2088 /* TODO: eloop timeout to clear a connection if it does not complete
2089 * properly */
2090 dl_list_add(&dpp->tcp_init, &conn->list);
2091 return 0;
2092 fail:
2093 dpp_connection_free(conn);
2094 return -1;
2095 }
2096
2097
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))2098 int dpp_tcp_auth(struct dpp_global *dpp, void *_conn,
2099 struct dpp_authentication *auth, const char *name,
2100 enum dpp_netrole netrole, const char *mud_url,
2101 const char *extra_conf_req_name,
2102 const char *extra_conf_req_value,
2103 int (*process_conf_obj)(void *ctx,
2104 struct dpp_authentication *auth),
2105 bool (*tcp_msg_sent)(void *ctx,
2106 struct dpp_authentication *auth))
2107 {
2108 struct dpp_connection *conn = _conn;
2109
2110 /* Continue with Authentication exchange on an existing TCP connection.
2111 */
2112 conn->process_conf_obj = process_conf_obj;
2113 conn->tcp_msg_sent = tcp_msg_sent;
2114 os_free(conn->name);
2115 conn->name = os_strdup(name ? name : "Test");
2116 os_free(conn->mud_url);
2117 conn->mud_url = mud_url ? os_strdup(mud_url) : NULL;
2118 os_free(conn->extra_conf_req_name);
2119 conn->extra_conf_req_name = extra_conf_req_name ?
2120 os_strdup(extra_conf_req_name) : NULL;
2121 conn->extra_conf_req_value = extra_conf_req_value ?
2122 os_strdup(extra_conf_req_value) : NULL;
2123 conn->netrole = netrole;
2124 conn->auth = auth;
2125
2126 if (dpp_tcp_auth_start(conn, auth) < 0)
2127 return -1;
2128
2129 dpp_conn_tx_ready(conn->sock, conn, NULL);
2130 return 0;
2131 }
2132
2133
dpp_controller_start(struct dpp_global * dpp,struct dpp_controller_config * config)2134 int dpp_controller_start(struct dpp_global *dpp,
2135 struct dpp_controller_config *config)
2136 {
2137 struct dpp_controller *ctrl;
2138 int on = 1;
2139 struct sockaddr_in sin;
2140 int port;
2141
2142 if (!dpp || dpp->controller)
2143 return -1;
2144
2145 ctrl = os_zalloc(sizeof(*ctrl));
2146 if (!ctrl)
2147 return -1;
2148 ctrl->global = dpp;
2149 if (config->configurator_params)
2150 ctrl->configurator_params =
2151 os_strdup(config->configurator_params);
2152 dl_list_init(&ctrl->conn);
2153 ctrl->allowed_roles = config->allowed_roles;
2154 ctrl->qr_mutual = config->qr_mutual;
2155 ctrl->netrole = config->netrole;
2156 ctrl->msg_ctx = config->msg_ctx;
2157 ctrl->cb_ctx = config->cb_ctx;
2158 ctrl->process_conf_obj = config->process_conf_obj;
2159 ctrl->tcp_msg_sent = config->tcp_msg_sent;
2160
2161 ctrl->sock = socket(AF_INET, SOCK_STREAM, 0);
2162 if (ctrl->sock < 0)
2163 goto fail;
2164
2165 if (setsockopt(ctrl->sock, SOL_SOCKET, SO_REUSEADDR,
2166 &on, sizeof(on)) < 0) {
2167 wpa_printf(MSG_DEBUG,
2168 "DPP: setsockopt(SO_REUSEADDR) failed: %s",
2169 strerror(errno));
2170 /* try to continue anyway */
2171 }
2172
2173 if (fcntl(ctrl->sock, F_SETFL, O_NONBLOCK) < 0) {
2174 wpa_printf(MSG_INFO, "DPP: fnctl(O_NONBLOCK) failed: %s",
2175 strerror(errno));
2176 goto fail;
2177 }
2178
2179 /* TODO: IPv6 */
2180 os_memset(&sin, 0, sizeof(sin));
2181 sin.sin_family = AF_INET;
2182 sin.sin_addr.s_addr = INADDR_ANY;
2183 port = config->tcp_port ? config->tcp_port : DPP_TCP_PORT;
2184 sin.sin_port = htons(port);
2185 if (bind(ctrl->sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
2186 wpa_printf(MSG_INFO,
2187 "DPP: Failed to bind Controller TCP port: %s",
2188 strerror(errno));
2189 goto fail;
2190 }
2191 if (listen(ctrl->sock, 10 /* max backlog */) < 0 ||
2192 fcntl(ctrl->sock, F_SETFL, O_NONBLOCK) < 0 ||
2193 eloop_register_sock(ctrl->sock, EVENT_TYPE_READ,
2194 dpp_controller_tcp_cb, ctrl, NULL))
2195 goto fail;
2196
2197 dpp->controller = ctrl;
2198 wpa_printf(MSG_DEBUG, "DPP: Controller started on TCP port %d", port);
2199 return 0;
2200 fail:
2201 dpp_controller_free(ctrl);
2202 return -1;
2203 }
2204
2205
dpp_controller_set_params(struct dpp_global * dpp,const char * configurator_params)2206 int dpp_controller_set_params(struct dpp_global *dpp,
2207 const char *configurator_params)
2208 {
2209
2210 if (!dpp || !dpp->controller)
2211 return -1;
2212
2213 if (configurator_params) {
2214 char *val = os_strdup(configurator_params);
2215
2216 if (!val)
2217 return -1;
2218 os_free(dpp->controller->configurator_params);
2219 dpp->controller->configurator_params = val;
2220 } else {
2221 os_free(dpp->controller->configurator_params);
2222 dpp->controller->configurator_params = NULL;
2223 }
2224
2225 return 0;
2226 }
2227
2228
dpp_controller_stop(struct dpp_global * dpp)2229 void dpp_controller_stop(struct dpp_global *dpp)
2230 {
2231 if (dpp) {
2232 dpp_controller_free(dpp->controller);
2233 dpp->controller = NULL;
2234 }
2235 }
2236
2237
dpp_controller_stop_for_ctx(struct dpp_global * dpp,void * cb_ctx)2238 void dpp_controller_stop_for_ctx(struct dpp_global *dpp, void *cb_ctx)
2239 {
2240 if (dpp && dpp->controller && dpp->controller->cb_ctx == cb_ctx)
2241 dpp_controller_stop(dpp);
2242 }
2243
2244
dpp_tcp_peer_id_match(struct dpp_authentication * auth,unsigned int id)2245 static bool dpp_tcp_peer_id_match(struct dpp_authentication *auth,
2246 unsigned int id)
2247 {
2248 return auth &&
2249 ((auth->peer_bi && auth->peer_bi->id == id) ||
2250 (auth->tmp_peer_bi && auth->tmp_peer_bi->id == id));
2251 }
2252
2253
dpp_tcp_get_auth(struct dpp_global * dpp,unsigned int id)2254 static struct dpp_authentication * dpp_tcp_get_auth(struct dpp_global *dpp,
2255 unsigned int id)
2256 {
2257 struct dpp_connection *conn;
2258
2259 dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
2260 if (dpp_tcp_peer_id_match(conn->auth, id))
2261 return conn->auth;
2262 }
2263
2264 return NULL;
2265 }
2266
2267
dpp_controller_get_auth(struct dpp_global * dpp,unsigned int id)2268 struct dpp_authentication * dpp_controller_get_auth(struct dpp_global *dpp,
2269 unsigned int id)
2270 {
2271 struct dpp_controller *ctrl = dpp->controller;
2272 struct dpp_connection *conn;
2273
2274 if (!ctrl)
2275 return dpp_tcp_get_auth(dpp, id);
2276
2277 dl_list_for_each(conn, &ctrl->conn, struct dpp_connection, list) {
2278 if (dpp_tcp_peer_id_match(conn->auth, id))
2279 return conn->auth;
2280 }
2281
2282 return dpp_tcp_get_auth(dpp, id);
2283 }
2284
2285
dpp_controller_new_qr_code(struct dpp_global * dpp,struct dpp_bootstrap_info * bi)2286 void dpp_controller_new_qr_code(struct dpp_global *dpp,
2287 struct dpp_bootstrap_info *bi)
2288 {
2289 struct dpp_controller *ctrl = dpp->controller;
2290 struct dpp_connection *conn;
2291
2292 if (!ctrl)
2293 return;
2294
2295 dl_list_for_each(conn, &ctrl->conn, struct dpp_connection, list) {
2296 struct dpp_authentication *auth = conn->auth;
2297
2298 if (!auth->response_pending ||
2299 dpp_notify_new_qr_code(auth, bi) != 1)
2300 continue;
2301 wpa_printf(MSG_DEBUG,
2302 "DPP: Sending out pending authentication response");
2303 dpp_tcp_send_msg(conn, conn->auth->resp_msg);
2304 }
2305 }
2306
2307
dpp_controller_pkex_add(struct dpp_global * dpp,struct dpp_bootstrap_info * bi,const char * code,const char * identifier)2308 void dpp_controller_pkex_add(struct dpp_global *dpp,
2309 struct dpp_bootstrap_info *bi,
2310 const char *code, const char *identifier)
2311 {
2312 struct dpp_controller *ctrl = dpp->controller;
2313
2314 if (!ctrl)
2315 return;
2316
2317 ctrl->pkex_bi = bi;
2318 os_free(ctrl->pkex_code);
2319 ctrl->pkex_code = code ? os_strdup(code) : NULL;
2320 os_free(ctrl->pkex_identifier);
2321 ctrl->pkex_identifier = identifier ? os_strdup(identifier) : NULL;
2322 }
2323
2324
dpp_controller_is_own_pkex_req(struct dpp_global * dpp,const u8 * buf,size_t len)2325 bool dpp_controller_is_own_pkex_req(struct dpp_global *dpp,
2326 const u8 *buf, size_t len)
2327 {
2328 struct dpp_connection *conn;
2329 const u8 *attr_key = NULL;
2330 u16 attr_key_len = 0;
2331
2332 dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
2333 if (!conn->pkex || !conn->pkex->enc_key)
2334 continue;
2335
2336 if (!attr_key) {
2337 attr_key = dpp_get_attr(buf, len,
2338 DPP_ATTR_ENCRYPTED_KEY,
2339 &attr_key_len);
2340 if (!attr_key)
2341 return false;
2342 }
2343
2344 if (attr_key_len == wpabuf_len(conn->pkex->enc_key) &&
2345 os_memcmp(attr_key, wpabuf_head(conn->pkex->enc_key),
2346 attr_key_len) == 0)
2347 return true;
2348 }
2349
2350 return false;
2351 }
2352
2353
dpp_tcp_init_flush(struct dpp_global * dpp)2354 void dpp_tcp_init_flush(struct dpp_global *dpp)
2355 {
2356 struct dpp_connection *conn, *tmp;
2357
2358 dl_list_for_each_safe(conn, tmp, &dpp->tcp_init, struct dpp_connection,
2359 list)
2360 dpp_connection_remove(conn);
2361 }
2362
2363
dpp_relay_controller_free(struct dpp_relay_controller * ctrl)2364 static void dpp_relay_controller_free(struct dpp_relay_controller *ctrl)
2365 {
2366 struct dpp_connection *conn, *tmp;
2367 char txt[100];
2368
2369 wpa_printf(MSG_DEBUG, "DPP: Remove Relay connection to Controller %s",
2370 hostapd_ip_txt(&ctrl->ipaddr, txt, sizeof(txt)));
2371
2372 dl_list_for_each_safe(conn, tmp, &ctrl->conn, struct dpp_connection,
2373 list)
2374 dpp_connection_remove(conn);
2375 os_free(ctrl);
2376 }
2377
2378
dpp_relay_flush_controllers(struct dpp_global * dpp)2379 void dpp_relay_flush_controllers(struct dpp_global *dpp)
2380 {
2381 struct dpp_relay_controller *ctrl, *tmp;
2382
2383 if (!dpp)
2384 return;
2385
2386 dl_list_for_each_safe(ctrl, tmp, &dpp->controllers,
2387 struct dpp_relay_controller, list) {
2388 dl_list_del(&ctrl->list);
2389 dpp_relay_controller_free(ctrl);
2390 }
2391
2392 if (dpp->tmp_controller) {
2393 dpp_relay_controller_free(dpp->tmp_controller);
2394 dpp->tmp_controller = NULL;
2395 }
2396 }
2397
2398
dpp_relay_remove_controller(struct dpp_global * dpp,const struct hostapd_ip_addr * addr)2399 void dpp_relay_remove_controller(struct dpp_global *dpp,
2400 const struct hostapd_ip_addr *addr)
2401 {
2402 struct dpp_relay_controller *ctrl;
2403
2404 if (!dpp)
2405 return;
2406
2407 dl_list_for_each(ctrl, &dpp->controllers, struct dpp_relay_controller,
2408 list) {
2409 if (hostapd_ip_equal(&ctrl->ipaddr, addr)) {
2410 dl_list_del(&ctrl->list);
2411 dpp_relay_controller_free(ctrl);
2412 return;
2413 }
2414 }
2415
2416 if (dpp->tmp_controller &&
2417 hostapd_ip_equal(&dpp->tmp_controller->ipaddr, addr)) {
2418 dpp_relay_controller_free(dpp->tmp_controller);
2419 dpp->tmp_controller = NULL;
2420 }
2421 }
2422
2423
dpp_relay_tcp_cb(int sd,void * eloop_ctx,void * sock_ctx)2424 static void dpp_relay_tcp_cb(int sd, void *eloop_ctx, void *sock_ctx)
2425 {
2426 struct dpp_global *dpp = eloop_ctx;
2427 struct sockaddr_in addr;
2428 socklen_t addr_len = sizeof(addr);
2429 int fd;
2430 struct dpp_relay_controller *ctrl;
2431 struct dpp_connection *conn = NULL;
2432
2433 wpa_printf(MSG_DEBUG, "DPP: New TCP connection (Relay)");
2434
2435 fd = accept(dpp->relay_sock, (struct sockaddr *) &addr, &addr_len);
2436 if (fd < 0) {
2437 wpa_printf(MSG_DEBUG,
2438 "DPP: Failed to accept new connection: %s",
2439 strerror(errno));
2440 return;
2441 }
2442 wpa_printf(MSG_DEBUG, "DPP: Connection from %s:%d",
2443 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
2444
2445 ctrl = dpp_relay_controller_get_addr(dpp, &addr);
2446 if (!ctrl && dpp->tmp_controller &&
2447 dl_list_len(&dpp->tmp_controller->conn)) {
2448 char txt[100];
2449
2450 wpa_printf(MSG_DEBUG,
2451 "DPP: Remove a temporaty Controller entry for %s",
2452 hostapd_ip_txt(&dpp->tmp_controller->ipaddr,
2453 txt, sizeof(txt)));
2454 dpp_relay_controller_free(dpp->tmp_controller);
2455 dpp->tmp_controller = NULL;
2456 }
2457 if (!ctrl && !dpp->tmp_controller) {
2458 wpa_printf(MSG_DEBUG, "DPP: Add a temporary Controller entry");
2459 ctrl = os_zalloc(sizeof(*ctrl));
2460 if (!ctrl)
2461 goto fail;
2462 dl_list_init(&ctrl->conn);
2463 ctrl->global = dpp;
2464 ctrl->ipaddr.af = AF_INET;
2465 ctrl->ipaddr.u.v4.s_addr = addr.sin_addr.s_addr;
2466 ctrl->msg_ctx = dpp->relay_msg_ctx;
2467 ctrl->cb_ctx = dpp->relay_cb_ctx;
2468 ctrl->tx = dpp->relay_tx;
2469 ctrl->gas_resp_tx = dpp->relay_gas_resp_tx;
2470 dpp->tmp_controller = ctrl;
2471 }
2472 if (!ctrl) {
2473 wpa_printf(MSG_DEBUG,
2474 "DPP: No Controller found for that address");
2475 goto fail;
2476 }
2477
2478 if (dl_list_len(&ctrl->conn) >= 15) {
2479 wpa_printf(MSG_DEBUG,
2480 "DPP: Too many ongoing Relay connections to the Controller - cannot start a new one");
2481 goto fail;
2482 }
2483
2484 conn = os_zalloc(sizeof(*conn));
2485 if (!conn)
2486 goto fail;
2487
2488 conn->global = ctrl->global;
2489 conn->relay = ctrl;
2490 conn->msg_ctx = ctrl->msg_ctx;
2491 conn->cb_ctx = ctrl->global->cb_ctx;
2492 os_memset(conn->mac_addr, 0xff, ETH_ALEN);
2493 conn->sock = fd;
2494
2495 if (fcntl(conn->sock, F_SETFL, O_NONBLOCK) != 0) {
2496 wpa_printf(MSG_DEBUG, "DPP: fnctl(O_NONBLOCK) failed: %s",
2497 strerror(errno));
2498 goto fail;
2499 }
2500
2501 if (eloop_register_sock(conn->sock, EVENT_TYPE_READ,
2502 dpp_controller_rx, conn, NULL) < 0)
2503 goto fail;
2504 conn->read_eloop = 1;
2505
2506 /* TODO: eloop timeout to expire connections that do not complete in
2507 * reasonable time */
2508 dl_list_add(&ctrl->conn, &conn->list);
2509 return;
2510
2511 fail:
2512 close(fd);
2513 os_free(conn);
2514 }
2515
2516
dpp_relay_listen(struct dpp_global * dpp,int port,struct dpp_relay_config * config)2517 int dpp_relay_listen(struct dpp_global *dpp, int port,
2518 struct dpp_relay_config *config)
2519 {
2520 int s;
2521 int on = 1;
2522 struct sockaddr_in sin;
2523
2524 if (dpp->relay_sock >= 0) {
2525 wpa_printf(MSG_INFO, "DPP: %s(%d) - relay port already opened",
2526 __func__, port);
2527 return -1;
2528 }
2529
2530 s = socket(AF_INET, SOCK_STREAM, 0);
2531 if (s < 0) {
2532 wpa_printf(MSG_INFO,
2533 "DPP: socket(SOCK_STREAM) failed: %s",
2534 strerror(errno));
2535 return -1;
2536 }
2537
2538 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2539 wpa_printf(MSG_DEBUG,
2540 "DPP: setsockopt(SO_REUSEADDR) failed: %s",
2541 strerror(errno));
2542 /* try to continue anyway */
2543 }
2544
2545 if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) {
2546 wpa_printf(MSG_INFO, "DPP: fnctl(O_NONBLOCK) failed: %s",
2547 strerror(errno));
2548 close(s);
2549 return -1;
2550 }
2551
2552 /* TODO: IPv6 */
2553 os_memset(&sin, 0, sizeof(sin));
2554 sin.sin_family = AF_INET;
2555 sin.sin_addr.s_addr = INADDR_ANY;
2556 sin.sin_port = htons(port);
2557 if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
2558 wpa_printf(MSG_INFO,
2559 "DPP: Failed to bind Relay TCP port: %s",
2560 strerror(errno));
2561 close(s);
2562 return -1;
2563 }
2564 if (listen(s, 10 /* max backlog */) < 0 ||
2565 fcntl(s, F_SETFL, O_NONBLOCK) < 0 ||
2566 eloop_register_sock(s, EVENT_TYPE_READ, dpp_relay_tcp_cb, dpp,
2567 NULL)) {
2568 close(s);
2569 return -1;
2570 }
2571
2572 dpp->relay_sock = s;
2573 dpp->relay_msg_ctx = config->msg_ctx;
2574 dpp->relay_cb_ctx = config->cb_ctx;
2575 dpp->relay_tx = config->tx;
2576 dpp->relay_gas_resp_tx = config->gas_resp_tx;
2577 wpa_printf(MSG_DEBUG, "DPP: Relay started on TCP port %d", port);
2578 return 0;
2579 }
2580
2581
dpp_relay_stop_listen(struct dpp_global * dpp)2582 void dpp_relay_stop_listen(struct dpp_global *dpp)
2583 {
2584 if (!dpp || dpp->relay_sock < 0)
2585 return;
2586 eloop_unregister_sock(dpp->relay_sock, EVENT_TYPE_READ);
2587 close(dpp->relay_sock);
2588 dpp->relay_sock = -1;
2589 }
2590
2591
dpp_tcp_conn_status_requested(struct dpp_global * dpp)2592 bool dpp_tcp_conn_status_requested(struct dpp_global *dpp)
2593 {
2594 struct dpp_connection *conn;
2595
2596 if (!dpp)
2597 return false;
2598
2599 dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
2600 if (conn->auth && conn->auth->conn_status_requested)
2601 return true;
2602 }
2603
2604 return false;
2605 }
2606
2607
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)2608 static void dpp_tcp_send_conn_status_msg(struct dpp_global *dpp,
2609 struct dpp_connection *conn,
2610 enum dpp_status_error result,
2611 const u8 *ssid, size_t ssid_len,
2612 const char *channel_list)
2613 {
2614 struct dpp_authentication *auth = conn->auth;
2615 int res;
2616 struct wpabuf *msg;
2617 struct dpp_connection *c;
2618
2619 auth->conn_status_requested = 0;
2620
2621 msg = dpp_build_conn_status_result(auth, result, ssid, ssid_len,
2622 channel_list);
2623 if (!msg) {
2624 dpp_connection_remove(conn);
2625 return;
2626 }
2627
2628 res = dpp_tcp_send_msg(conn, msg);
2629 wpabuf_free(msg);
2630
2631 if (res < 0) {
2632 dpp_connection_remove(conn);
2633 return;
2634 }
2635
2636 /* conn might have been removed during the dpp_tcp_send_msg() call, so
2637 * need to check that it is still present before modifying it. */
2638 dl_list_for_each(c, &dpp->tcp_init, struct dpp_connection, list) {
2639 if (conn == c) {
2640 /* This exchange will be terminated in the TX status
2641 * handler */
2642 conn->on_tcp_tx_complete_remove = 1;
2643 break;
2644 }
2645 }
2646 }
2647
2648
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)2649 void dpp_tcp_send_conn_status(struct dpp_global *dpp,
2650 enum dpp_status_error result,
2651 const u8 *ssid, size_t ssid_len,
2652 const char *channel_list)
2653 {
2654 struct dpp_connection *conn;
2655
2656 dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
2657 if (conn->auth && conn->auth->conn_status_requested) {
2658 dpp_tcp_send_conn_status_msg(dpp, conn, result, ssid,
2659 ssid_len, channel_list);
2660 break;
2661 }
2662 }
2663 }
2664
2665 #endif /* CONFIG_DPP2 */
2666