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