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