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