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