xref: /openbsd-src/sbin/iked/config.c (revision 25c4e8bd056e974b28f4a0ffd39d76c190a56013)
1 /*	$OpenBSD: config.c,v 1.86 2022/07/08 19:51:11 tobhe Exp $	*/
2 
3 /*
4  * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5  * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/queue.h>
21 #include <sys/socket.h>
22 #include <sys/uio.h>
23 
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <signal.h>
29 #include <errno.h>
30 #include <err.h>
31 #include <event.h>
32 
33 #include <openssl/evp.h>
34 #include <openssl/pem.h>
35 
36 #include "iked.h"
37 #include "ikev2.h"
38 
39 struct iked_sa *
40 config_new_sa(struct iked *env, int initiator)
41 {
42 	struct iked_sa	*sa;
43 
44 	if ((sa = calloc(1, sizeof(*sa))) == NULL)
45 		return (NULL);
46 
47 	TAILQ_INIT(&sa->sa_proposals);
48 	TAILQ_INIT(&sa->sa_childsas);
49 	TAILQ_INIT(&sa->sa_flows);
50 	TAILQ_INIT(&sa->sa_requests);
51 	TAILQ_INIT(&sa->sa_responses);
52 	sa->sa_hdr.sh_initiator = initiator;
53 	sa->sa_type = IKED_SATYPE_LOCAL;
54 
55 	if (initiator)
56 		sa->sa_hdr.sh_ispi = config_getspi();
57 	else
58 		sa->sa_hdr.sh_rspi = config_getspi();
59 
60 	gettimeofday(&sa->sa_timecreated, NULL);
61 	memcpy(&sa->sa_timeused, &sa->sa_timecreated, sizeof(sa->sa_timeused));
62 
63 	return (sa);
64 }
65 
66 uint64_t
67 config_getspi(void)
68 {
69 	uint64_t	 spi;
70 
71 	do {
72 		arc4random_buf(&spi, sizeof spi);
73 	} while (spi == 0);
74 
75 	return (spi);
76 }
77 
78 void
79 config_free_kex(struct iked_kex *kex)
80 {
81 	if (kex == NULL)
82 		return;
83 
84 	ibuf_release(kex->kex_inonce);
85 	ibuf_release(kex->kex_rnonce);
86 
87 	group_free(kex->kex_dhgroup);
88 	ibuf_release(kex->kex_dhiexchange);
89 	ibuf_release(kex->kex_dhrexchange);
90 
91 	free(kex);
92 }
93 
94 void
95 config_free_fragments(struct iked_frag *frag)
96 {
97 	size_t i;
98 
99 	if (frag && frag->frag_arr) {
100 		for (i = 0; i < frag->frag_total; i++) {
101 			if (frag->frag_arr[i] != NULL)
102 				free(frag->frag_arr[i]->frag_data);
103 			free(frag->frag_arr[i]);
104 		}
105 		free(frag->frag_arr);
106 		bzero(frag, sizeof(struct iked_frag));
107 	}
108 }
109 
110 void
111 config_free_sa(struct iked *env, struct iked_sa *sa)
112 {
113 	int i;
114 
115 	timer_del(env, &sa->sa_timer);
116 	timer_del(env, &sa->sa_keepalive);
117 	timer_del(env, &sa->sa_rekey);
118 
119 	config_free_fragments(&sa->sa_fragments);
120 	config_free_proposals(&sa->sa_proposals, 0);
121 	config_free_childsas(env, &sa->sa_childsas, NULL, NULL);
122 	sa_configure_iface(env, sa, 0);
123 	sa_free_flows(env, &sa->sa_flows);
124 
125 	if (sa->sa_addrpool) {
126 		(void)RB_REMOVE(iked_addrpool, &env->sc_addrpool, sa);
127 		free(sa->sa_addrpool);
128 	}
129 	if (sa->sa_addrpool6) {
130 		(void)RB_REMOVE(iked_addrpool6, &env->sc_addrpool6, sa);
131 		free(sa->sa_addrpool6);
132 	}
133 
134 	if (sa->sa_policy) {
135 		TAILQ_REMOVE(&sa->sa_policy->pol_sapeers, sa, sa_peer_entry);
136 		policy_unref(env, sa->sa_policy);
137 	}
138 
139 	ikev2_msg_flushqueue(env, &sa->sa_requests);
140 	ikev2_msg_flushqueue(env, &sa->sa_responses);
141 
142 	ibuf_release(sa->sa_inonce);
143 	ibuf_release(sa->sa_rnonce);
144 
145 	group_free(sa->sa_dhgroup);
146 	ibuf_release(sa->sa_dhiexchange);
147 	ibuf_release(sa->sa_dhrexchange);
148 
149 	ibuf_release(sa->sa_simult);
150 
151 	hash_free(sa->sa_prf);
152 	hash_free(sa->sa_integr);
153 	cipher_free(sa->sa_encr);
154 
155 	ibuf_release(sa->sa_key_d);
156 	ibuf_release(sa->sa_key_iauth);
157 	ibuf_release(sa->sa_key_rauth);
158 	ibuf_release(sa->sa_key_iencr);
159 	ibuf_release(sa->sa_key_rencr);
160 	ibuf_release(sa->sa_key_iprf);
161 	ibuf_release(sa->sa_key_rprf);
162 
163 	ibuf_release(sa->sa_1stmsg);
164 	ibuf_release(sa->sa_2ndmsg);
165 
166 	ibuf_release(sa->sa_iid.id_buf);
167 	ibuf_release(sa->sa_rid.id_buf);
168 	ibuf_release(sa->sa_icert.id_buf);
169 	ibuf_release(sa->sa_rcert.id_buf);
170 	for (i = 0; i < IKED_SCERT_MAX; i++)
171 		ibuf_release(sa->sa_scert[i].id_buf);
172 	ibuf_release(sa->sa_localauth.id_buf);
173 	ibuf_release(sa->sa_peerauth.id_buf);
174 
175 	ibuf_release(sa->sa_eap.id_buf);
176 	free(sa->sa_eapid);
177 	ibuf_release(sa->sa_eapmsk);
178 
179 	free(sa->sa_cp_addr);
180 	free(sa->sa_cp_addr6);
181 	free(sa->sa_cp_dns);
182 
183 	free(sa->sa_tag);
184 	free(sa);
185 }
186 
187 struct iked_policy *
188 config_new_policy(struct iked *env)
189 {
190 	struct iked_policy	*pol;
191 
192 	if ((pol = calloc(1, sizeof(*pol))) == NULL)
193 		return (NULL);
194 
195 	/* XXX caller does this again */
196 	TAILQ_INIT(&pol->pol_proposals);
197 	TAILQ_INIT(&pol->pol_sapeers);
198 	TAILQ_INIT(&pol->pol_tssrc);
199 	TAILQ_INIT(&pol->pol_tsdst);
200 	RB_INIT(&pol->pol_flows);
201 
202 	return (pol);
203 }
204 
205 void
206 config_free_policy(struct iked *env, struct iked_policy *pol)
207 {
208 	struct iked_sa		*sa;
209 	struct iked_ts	*tsi;
210 
211 	if (pol->pol_flags & IKED_POLICY_REFCNT)
212 		goto remove;
213 
214 	TAILQ_REMOVE(&env->sc_policies, pol, pol_entry);
215 
216 	TAILQ_FOREACH(sa, &pol->pol_sapeers, sa_peer_entry) {
217 		/* Remove from the policy list, but keep for existing SAs */
218 		if (sa->sa_policy == pol)
219 			policy_ref(env, pol);
220 		else
221 			log_warnx("%s: ERROR: sa_policy %p != pol %p",
222 			    __func__, sa->sa_policy, pol);
223 	}
224 
225 	if (pol->pol_refcnt)
226 		return;
227 
228  remove:
229 	while ((tsi = TAILQ_FIRST(&pol->pol_tssrc))) {
230 		TAILQ_REMOVE(&pol->pol_tssrc, tsi, ts_entry);
231 		free(tsi);
232 	}
233 	while ((tsi = TAILQ_FIRST(&pol->pol_tsdst))) {
234 		TAILQ_REMOVE(&pol->pol_tsdst, tsi, ts_entry);
235 		free(tsi);
236 	}
237 	config_free_proposals(&pol->pol_proposals, 0);
238 	config_free_flows(env, &pol->pol_flows);
239 	free(pol);
240 }
241 
242 struct iked_proposal *
243 config_add_proposal(struct iked_proposals *head, unsigned int id,
244     unsigned int proto)
245 {
246 	struct iked_proposal	*pp;
247 
248 	TAILQ_FOREACH(pp, head, prop_entry) {
249 		if (pp->prop_protoid == proto &&
250 		    pp->prop_id == id)
251 			return (pp);
252 	}
253 
254 	if ((pp = calloc(1, sizeof(*pp))) == NULL)
255 		return (NULL);
256 
257 	pp->prop_protoid = proto;
258 	pp->prop_id = id;
259 
260 	TAILQ_INSERT_TAIL(head, pp, prop_entry);
261 
262 	return (pp);
263 }
264 
265 void
266 config_free_proposal(struct iked_proposals *head, struct iked_proposal *prop)
267 {
268 	TAILQ_REMOVE(head, prop, prop_entry);
269 	if (prop->prop_nxforms)
270 		free(prop->prop_xforms);
271 	free(prop);
272 }
273 
274 void
275 config_free_proposals(struct iked_proposals *head, unsigned int proto)
276 {
277 	struct iked_proposal	*prop, *proptmp;
278 
279 	TAILQ_FOREACH_SAFE(prop, head, prop_entry, proptmp) {
280 		/* Free any proposal or only selected SA proto */
281 		if (proto != 0 && prop->prop_protoid != proto)
282 			continue;
283 
284 		log_debug("%s: free %p", __func__, prop);
285 
286 		config_free_proposal(head, prop);
287 	}
288 }
289 
290 void
291 config_free_flows(struct iked *env, struct iked_flows *head)
292 {
293 	struct iked_flow	*flow;
294 
295 	while ((flow = RB_MIN(iked_flows, head))) {
296 		log_debug("%s: free %p", __func__, flow);
297 		RB_REMOVE(iked_flows, head, flow);
298 		flow_free(flow);
299 	}
300 }
301 
302 void
303 config_free_childsas(struct iked *env, struct iked_childsas *head,
304     struct iked_spi *peerspi, struct iked_spi *localspi)
305 {
306 	struct iked_childsa	*csa, *csatmp, *ipcomp;
307 
308 	if (localspi != NULL)
309 		bzero(localspi, sizeof(*localspi));
310 
311 	TAILQ_FOREACH_SAFE(csa, head, csa_entry, csatmp) {
312 		if (peerspi != NULL) {
313 			/* Only delete matching peer SPIs */
314 			if (peerspi->spi != csa->csa_peerspi)
315 				continue;
316 
317 			/* Store assigned local SPI */
318 			if (localspi != NULL && localspi->spi == 0)
319 				memcpy(localspi, &csa->csa_spi,
320 				    sizeof(*localspi));
321 		}
322 		log_debug("%s: free %p", __func__, csa);
323 
324 		TAILQ_REMOVE(head, csa, csa_entry);
325 		if (csa->csa_loaded) {
326 			RB_REMOVE(iked_activesas, &env->sc_activesas, csa);
327 			(void)pfkey_sa_delete(env, csa);
328 		}
329 		if ((ipcomp = csa->csa_bundled) != NULL) {
330 			log_debug("%s: free IPCOMP %p", __func__, ipcomp);
331 			if (ipcomp->csa_loaded)
332 				(void)pfkey_sa_delete(env, ipcomp);
333 			childsa_free(ipcomp);
334 		}
335 		childsa_free(csa);
336 	}
337 }
338 
339 int
340 config_add_transform(struct iked_proposal *prop, unsigned int type,
341     unsigned int id, unsigned int length, unsigned int keylength)
342 {
343 	struct iked_transform	*xform;
344 	struct iked_constmap	*map = NULL;
345 	int			 score = 1;
346 	unsigned int		 i;
347 
348 	switch (type) {
349 	case IKEV2_XFORMTYPE_ENCR:
350 		map = ikev2_xformencr_map;
351 		break;
352 	case IKEV2_XFORMTYPE_PRF:
353 		map = ikev2_xformprf_map;
354 		break;
355 	case IKEV2_XFORMTYPE_INTEGR:
356 		map = ikev2_xformauth_map;
357 		break;
358 	case IKEV2_XFORMTYPE_DH:
359 		map = ikev2_xformdh_map;
360 		break;
361 	case IKEV2_XFORMTYPE_ESN:
362 		map = ikev2_xformesn_map;
363 		break;
364 	default:
365 		log_debug("%s: invalid transform type %d", __func__, type);
366 		return (-2);
367 	}
368 
369 	for (i = 0; i < prop->prop_nxforms; i++) {
370 		xform = prop->prop_xforms + i;
371 		if (xform->xform_type == type &&
372 		    xform->xform_id == id &&
373 		    xform->xform_length == length)
374 			return (0);
375 	}
376 
377 	for (i = 0; i < prop->prop_nxforms; i++) {
378 		xform = prop->prop_xforms + i;
379 		if (xform->xform_type == type) {
380 			switch (type) {
381 			case IKEV2_XFORMTYPE_ENCR:
382 			case IKEV2_XFORMTYPE_INTEGR:
383 				score += 3;
384 				break;
385 			case IKEV2_XFORMTYPE_DH:
386 				score += 2;
387 				break;
388 			default:
389 				score += 1;
390 				break;
391 			}
392 		}
393 	}
394 
395 	if ((xform = reallocarray(prop->prop_xforms,
396 	    prop->prop_nxforms + 1, sizeof(*xform))) == NULL) {
397 		return (-1);
398 	}
399 
400 	prop->prop_xforms = xform;
401 	xform = prop->prop_xforms + prop->prop_nxforms++;
402 	bzero(xform, sizeof(*xform));
403 
404 	xform->xform_type = type;
405 	xform->xform_id = id;
406 	xform->xform_length = length;
407 	xform->xform_keylength = keylength;
408 	xform->xform_score = score;
409 	xform->xform_map = map;
410 
411 	return (0);
412 }
413 
414 struct iked_transform *
415 config_findtransform_ext(struct iked_proposals *props, uint8_t type, int id,
416     unsigned int proto)
417 {
418 	struct iked_proposal	*prop;
419 	struct iked_transform	*xform;
420 	unsigned int		 i;
421 
422 	/* Search of the first transform with the desired type */
423 	TAILQ_FOREACH(prop, props, prop_entry) {
424 		/* Find any proposal or only selected SA proto */
425 		if (proto != 0 && prop->prop_protoid != proto)
426 			continue;
427 		for (i = 0; i < prop->prop_nxforms; i++) {
428 			xform = prop->prop_xforms + i;
429 			/* optional lookup of specific transform */
430 			if (id >= 0 && xform->xform_id != id)
431 				continue;
432 			if (xform->xform_type == type)
433 				return (xform);
434 		}
435 	}
436 
437 	return (NULL);
438 }
439 
440 struct iked_transform *
441 config_findtransform(struct iked_proposals *props, uint8_t type,
442     unsigned int proto)
443 {
444 	return config_findtransform_ext(props, type, -1, proto);
445 }
446 
447 struct iked_user *
448 config_new_user(struct iked *env, struct iked_user *new)
449 {
450 	struct iked_user	*usr, *old;
451 
452 	if ((usr = calloc(1, sizeof(*usr))) == NULL)
453 		return (NULL);
454 
455 	memcpy(usr, new, sizeof(*usr));
456 
457 	if ((old = RB_INSERT(iked_users, &env->sc_users, usr)) != NULL) {
458 		/* Update the password of an existing user*/
459 		memcpy(old->usr_pass, new->usr_pass, IKED_PASSWORD_SIZE);
460 
461 		log_debug("%s: updating user %s", __func__, usr->usr_name);
462 		freezero(usr, sizeof *usr);
463 
464 		return (old);
465 	}
466 
467 	log_debug("%s: inserting new user %s", __func__, usr->usr_name);
468 	return (usr);
469 }
470 
471 /*
472  * Inter-process communication of configuration items.
473  */
474 
475 int
476 config_setcoupled(struct iked *env, unsigned int couple)
477 {
478 	unsigned int	 type;
479 
480 	type = couple ? IMSG_CTL_COUPLE : IMSG_CTL_DECOUPLE;
481 	proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0);
482 
483 	return (0);
484 }
485 
486 int
487 config_getcoupled(struct iked *env, unsigned int type)
488 {
489 	return (pfkey_couple(env, &env->sc_sas,
490 	    type == IMSG_CTL_COUPLE ? 1 : 0));
491 }
492 
493 int
494 config_setmode(struct iked *env, unsigned int passive)
495 {
496 	unsigned int	 type;
497 
498 	type = passive ? IMSG_CTL_PASSIVE : IMSG_CTL_ACTIVE;
499 	proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0);
500 
501 	return (0);
502 }
503 
504 int
505 config_getmode(struct iked *env, unsigned int type)
506 {
507 	uint8_t		 old;
508 	unsigned char	*mode[] = { "active", "passive" };
509 
510 	old = env->sc_passive ? 1 : 0;
511 	env->sc_passive = type == IMSG_CTL_PASSIVE ? 1 : 0;
512 
513 	if (old == env->sc_passive)
514 		return (0);
515 
516 	log_debug("%s: mode %s -> %s", __func__,
517 	    mode[old], mode[env->sc_passive]);
518 
519 	return (0);
520 }
521 
522 int
523 config_setreset(struct iked *env, unsigned int mode, enum privsep_procid id)
524 {
525 	proc_compose(&env->sc_ps, id, IMSG_CTL_RESET, &mode, sizeof(mode));
526 	return (0);
527 }
528 
529 int
530 config_getreset(struct iked *env, struct imsg *imsg)
531 {
532 	unsigned int		 mode;
533 
534 	IMSG_SIZE_CHECK(imsg, &mode);
535 	memcpy(&mode, imsg->data, sizeof(mode));
536 
537 	return (config_doreset(env, mode));
538 }
539 
540 int
541 config_doreset(struct iked *env, unsigned int mode)
542 {
543 	struct iked_policy	*pol, *poltmp;
544 	struct iked_sa		*sa;
545 	struct iked_user	*usr;
546 
547 	if (mode == RESET_ALL || mode == RESET_POLICY) {
548 		log_debug("%s: flushing policies", __func__);
549 		TAILQ_FOREACH_SAFE(pol, &env->sc_policies, pol_entry, poltmp) {
550 			config_free_policy(env, pol);
551 		}
552 	}
553 
554 	if (mode == RESET_ALL || mode == RESET_SA) {
555 		log_debug("%s: flushing SAs", __func__);
556 		while ((sa = RB_MIN(iked_sas, &env->sc_sas))) {
557 			/* for RESET_SA we try send a DELETE */
558 			if (mode == RESET_ALL ||
559 			    ikev2_ike_sa_delete(env, sa) != 0) {
560 				RB_REMOVE(iked_sas, &env->sc_sas, sa);
561 				if (sa->sa_dstid_entry_valid)
562 					sa_dstid_remove(env, sa);
563 				config_free_sa(env, sa);
564 			}
565 		}
566 	}
567 
568 	if (mode == RESET_ALL || mode == RESET_USER) {
569 		log_debug("%s: flushing users", __func__);
570 		while ((usr = RB_MIN(iked_users, &env->sc_users))) {
571 			RB_REMOVE(iked_users, &env->sc_users, usr);
572 			free(usr);
573 		}
574 	}
575 
576 	return (0);
577 }
578 
579 /*
580  * The first call of this function sets the UDP socket for IKEv2.
581  * The second call is optional, setting the UDP socket used for NAT-T.
582  */
583 int
584 config_setsocket(struct iked *env, struct sockaddr_storage *ss,
585     in_port_t port, enum privsep_procid id)
586 {
587 	int	 s;
588 
589 	if ((s = udp_bind((struct sockaddr *)ss, port)) == -1)
590 		return (-1);
591 	proc_compose_imsg(&env->sc_ps, id, -1,
592 	    IMSG_UDP_SOCKET, -1, s, ss, sizeof(*ss));
593 	return (0);
594 }
595 
596 int
597 config_getsocket(struct iked *env, struct imsg *imsg,
598     void (*cb)(int, short, void *))
599 {
600 	struct iked_socket	*sock, **sock0 = NULL, **sock1 = NULL;
601 
602 	log_debug("%s: received socket fd %d", __func__, imsg->fd);
603 
604 	if ((sock = calloc(1, sizeof(*sock))) == NULL)
605 		fatal("config_getsocket: calloc");
606 
607 	IMSG_SIZE_CHECK(imsg, &sock->sock_addr);
608 
609 	memcpy(&sock->sock_addr, imsg->data, sizeof(sock->sock_addr));
610 	sock->sock_fd = imsg->fd;
611 	sock->sock_env = env;
612 
613 	switch (sock->sock_addr.ss_family) {
614 	case AF_INET:
615 		sock0 = &env->sc_sock4[0];
616 		sock1 = &env->sc_sock4[1];
617 		break;
618 	case AF_INET6:
619 		sock0 = &env->sc_sock6[0];
620 		sock1 = &env->sc_sock6[1];
621 		break;
622 	default:
623 		fatal("config_getsocket: socket af: %u",
624 		    sock->sock_addr.ss_family);
625 		/* NOTREACHED */
626 	}
627 	if (*sock0 == NULL)
628 		*sock0 = sock;
629 	else if (*sock1 == NULL)
630 		*sock1 = sock;
631 	else
632 		fatalx("%s: too many call", __func__);
633 
634 	event_set(&sock->sock_ev, sock->sock_fd,
635 	    EV_READ|EV_PERSIST, cb, sock);
636 	event_add(&sock->sock_ev, NULL);
637 
638 	return (0);
639 }
640 
641 int
642 config_setpfkey(struct iked *env)
643 {
644 	int	 s;
645 
646 	if ((s = pfkey_socket(env)) == -1)
647 		return (-1);
648 	proc_compose_imsg(&env->sc_ps, PROC_IKEV2, -1,
649 	    IMSG_PFKEY_SOCKET, -1, s, NULL, 0);
650 	return (0);
651 }
652 
653 int
654 config_getpfkey(struct iked *env, struct imsg *imsg)
655 {
656 	log_debug("%s: received pfkey fd %d", __func__, imsg->fd);
657 	pfkey_init(env, imsg->fd);
658 	return (0);
659 }
660 
661 int
662 config_setuser(struct iked *env, struct iked_user *usr, enum privsep_procid id)
663 {
664 	if (env->sc_opts & IKED_OPT_NOACTION) {
665 		print_user(usr);
666 		return (0);
667 	}
668 
669 	proc_compose(&env->sc_ps, id, IMSG_CFG_USER, usr, sizeof(*usr));
670 	return (0);
671 }
672 
673 int
674 config_getuser(struct iked *env, struct imsg *imsg)
675 {
676 	struct iked_user	 usr;
677 	int			 ret = -1;
678 
679 	IMSG_SIZE_CHECK(imsg, &usr);
680 	memcpy(&usr, imsg->data, sizeof(usr));
681 
682 	if (config_new_user(env, &usr) != NULL) {
683 		print_user(&usr);
684 		ret = 0;
685 	}
686 
687 	explicit_bzero(&usr, sizeof(usr));
688 	return (ret);
689 }
690 
691 int
692 config_setpolicy(struct iked *env, struct iked_policy *pol,
693     enum privsep_procid id)
694 {
695 	struct iked_proposal	*prop;
696 	struct iked_transform	*xform;
697 	size_t			 iovcnt, j, c = 0;
698 	struct iovec		 iov[IOV_MAX];
699 
700 	iovcnt = 1;
701 	TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) {
702 		iovcnt += prop->prop_nxforms + 1;
703 	}
704 
705 	if (iovcnt > IOV_MAX) {
706 		log_warn("%s: too many proposals", __func__);
707 		return (-1);
708 	}
709 
710 	iov[c].iov_base = pol;
711 	iov[c++].iov_len = sizeof(*pol);
712 
713 	TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) {
714 		iov[c].iov_base = prop;
715 		iov[c++].iov_len = sizeof(*prop);
716 
717 		for (j = 0; j < prop->prop_nxforms; j++) {
718 			xform = prop->prop_xforms + j;
719 
720 			iov[c].iov_base = xform;
721 			iov[c++].iov_len = sizeof(*xform);
722 		}
723 	}
724 
725 	print_policy(pol);
726 
727 	if (env->sc_opts & IKED_OPT_NOACTION)
728 		return (0);
729 
730 	if (proc_composev(&env->sc_ps, id, IMSG_CFG_POLICY, iov,
731 	    iovcnt) == -1) {
732 		log_debug("%s: proc_composev failed", __func__);
733 		return (-1);
734 	}
735 
736 	return (0);
737 }
738 
739 int
740 config_setflow(struct iked *env, struct iked_policy *pol,
741     enum privsep_procid id)
742 {
743 	struct iked_flow	*flow;
744 	struct iovec		 iov[2];
745 
746 	if (env->sc_opts & IKED_OPT_NOACTION)
747 		return (0);
748 
749 	RB_FOREACH(flow, iked_flows, &pol->pol_flows) {
750 		iov[0].iov_base = &pol->pol_id;
751 		iov[0].iov_len = sizeof(pol->pol_id);
752 		iov[1].iov_base = flow;
753 		iov[1].iov_len = sizeof(*flow);
754 
755 		if (proc_composev(&env->sc_ps, id, IMSG_CFG_FLOW,
756 		    iov, 2) == -1) {
757 			log_debug("%s: proc_composev failed", __func__);
758 			return (-1);
759 		}
760 	}
761 
762 	return (0);
763 }
764 
765 int
766 config_getpolicy(struct iked *env, struct imsg *imsg)
767 {
768 	struct iked_policy	*pol;
769 	struct iked_proposal	 pp, *prop;
770 	struct iked_transform	 xf;
771 	off_t			 offset = 0;
772 	unsigned int		 i, j;
773 	uint8_t			*buf = (uint8_t *)imsg->data;
774 
775 	IMSG_SIZE_CHECK(imsg, pol);
776 	log_debug("%s: received policy", __func__);
777 
778 	if ((pol = config_new_policy(NULL)) == NULL)
779 		fatal("config_getpolicy: new policy");
780 
781 	memcpy(pol, buf, sizeof(*pol));
782 	offset += sizeof(*pol);
783 
784 	TAILQ_INIT(&pol->pol_tssrc);
785 	TAILQ_INIT(&pol->pol_tsdst);
786 	TAILQ_INIT(&pol->pol_proposals);
787 	TAILQ_INIT(&pol->pol_sapeers);
788 	RB_INIT(&pol->pol_flows);
789 
790 	for (i = 0; i < pol->pol_nproposals; i++) {
791 		memcpy(&pp, buf + offset, sizeof(pp));
792 		offset += sizeof(pp);
793 
794 		if ((prop = config_add_proposal(&pol->pol_proposals,
795 		    pp.prop_id, pp.prop_protoid)) == NULL)
796 			fatal("config_getpolicy: add proposal");
797 
798 		for (j = 0; j < pp.prop_nxforms; j++) {
799 			memcpy(&xf, buf + offset, sizeof(xf));
800 			offset += sizeof(xf);
801 
802 			if (config_add_transform(prop, xf.xform_type,
803 			    xf.xform_id, xf.xform_length,
804 			    xf.xform_keylength) != 0)
805 				fatal("config_getpolicy: add transform");
806 		}
807 	}
808 
809 	/* Flows are sent separately */
810 	pol->pol_nflows = 0;
811 
812 	TAILQ_INSERT_TAIL(&env->sc_policies, pol, pol_entry);
813 
814 	if (pol->pol_flags & IKED_POLICY_DEFAULT) {
815 		/* Only one default policy, just free/unref the old one */
816 		if (env->sc_defaultcon != NULL)
817 			config_free_policy(env, env->sc_defaultcon);
818 		env->sc_defaultcon = pol;
819 	}
820 
821 	return (0);
822 }
823 
824 int
825 config_getflow(struct iked *env, struct imsg *imsg)
826 {
827 	struct iked_policy	*pol;
828 	struct iked_flow	*flow;
829 	off_t			 offset = 0;
830 	unsigned int		 id;
831 	uint8_t			*buf = (uint8_t *)imsg->data;
832 
833 	if (IMSG_DATA_SIZE(imsg) < sizeof(id))
834 		fatalx("bad length imsg received");
835 
836 	memcpy(&id, buf, sizeof(id));
837 	offset += sizeof(id);
838 
839 	TAILQ_FOREACH(pol, &env->sc_policies, pol_entry) {
840 		if (pol->pol_id == id)
841 			break;
842 	}
843 	if (pol == NULL) {
844 		log_warnx("%s: unknown policy %u", __func__, id);
845 		return (-1);
846 	}
847 
848 	if ((flow = calloc(1, sizeof(*flow))) == NULL)
849 		fatal("config_getpolicy: new flow");
850 
851 	memcpy(flow, buf + offset, sizeof(*flow));
852 
853 	if (RB_INSERT(iked_flows, &pol->pol_flows, flow)) {
854 		log_warnx("%s: received duplicate flow", __func__);
855 		free(flow);
856 		return (-1);
857 	}
858 	pol->pol_nflows++;
859 
860 	return (0);
861 }
862 
863 int
864 config_setcompile(struct iked *env, enum privsep_procid id)
865 {
866 	if (env->sc_opts & IKED_OPT_NOACTION)
867 		return (0);
868 
869 	proc_compose(&env->sc_ps, id, IMSG_COMPILE, NULL, 0);
870 	return (0);
871 }
872 
873 int
874 config_getcompile(struct iked *env)
875 {
876 	/*
877 	 * Do any necessary steps after configuration, for now we
878 	 * only need to compile the skip steps.
879 	 */
880 	policy_calc_skip_steps(&env->sc_policies);
881 
882 	log_debug("%s: compilation done", __func__);
883 	return (0);
884 }
885 
886 int
887 config_setstatic(struct iked *env)
888 {
889 	proc_compose(&env->sc_ps, PROC_IKEV2, IMSG_CTL_STATIC,
890 	    &env->sc_static, sizeof(env->sc_static));
891 	return (0);
892 }
893 
894 int
895 config_getstatic(struct iked *env, struct imsg *imsg)
896 {
897 	IMSG_SIZE_CHECK(imsg, &env->sc_static);
898 	memcpy(&env->sc_static, imsg->data, sizeof(env->sc_static));
899 
900 	log_debug("%s: dpd_check_interval %llu", __func__, env->sc_alive_timeout);
901 	log_debug("%s: %senforcesingleikesa", __func__,
902 	    env->sc_enforcesingleikesa ? "" : "no ");
903 	log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no ");
904 	log_debug("%s: %smobike", __func__, env->sc_mobike ? "" : "no ");
905 	log_debug("%s: nattport %u", __func__, env->sc_nattport);
906 	log_debug("%s: %sstickyaddress", __func__,
907 	    env->sc_stickyaddress ? "" : "no ");
908 
909 	ikev2_reset_alive_timer(env);
910 
911 	return (0);
912 }
913 
914 int
915 config_setocsp(struct iked *env)
916 {
917 	struct iovec		 iov[3];
918 	int			 iovcnt = 0;
919 
920 	if (env->sc_opts & IKED_OPT_NOACTION)
921 		return (0);
922 
923 	iov[0].iov_base = &env->sc_ocsp_tolerate;
924 	iov[0].iov_len = sizeof(env->sc_ocsp_tolerate);
925 	iovcnt++;
926 	iov[1].iov_base = &env->sc_ocsp_maxage;
927 	iov[1].iov_len = sizeof(env->sc_ocsp_maxage);
928 	iovcnt++;
929 	if (env->sc_ocsp_url) {
930 		iov[2].iov_base = env->sc_ocsp_url;
931 		iov[2].iov_len = strlen(env->sc_ocsp_url);
932 		iovcnt++;
933 	}
934 	return (proc_composev(&env->sc_ps, PROC_CERT, IMSG_OCSP_CFG,
935 	    iov, iovcnt));
936 }
937 
938 int
939 config_getocsp(struct iked *env, struct imsg *imsg)
940 {
941 	size_t			 have, need;
942 	u_int8_t		*ptr;
943 
944 	free(env->sc_ocsp_url);
945 	ptr = (u_int8_t *)imsg->data;
946 	have = IMSG_DATA_SIZE(imsg);
947 
948 	/* get tolerate */
949 	need = sizeof(env->sc_ocsp_tolerate);
950 	if (have < need)
951 		fatalx("bad 'tolerate' length imsg received");
952 	memcpy(&env->sc_ocsp_tolerate, ptr, need);
953 	ptr += need;
954 	have -= need;
955 
956 	/* get maxage */
957 	need = sizeof(env->sc_ocsp_maxage);
958 	if (have < need)
959 		fatalx("bad 'maxage' length imsg received");
960 	memcpy(&env->sc_ocsp_maxage, ptr, need);
961 	ptr += need;
962 	have -= need;
963 
964 	/* get url */
965 	if (have > 0)
966 		env->sc_ocsp_url = get_string(ptr, have);
967 	else
968 		env->sc_ocsp_url = NULL;
969 	log_debug("%s: ocsp_url %s tolerate %ld maxage %ld", __func__,
970 	    env->sc_ocsp_url ? env->sc_ocsp_url : "none",
971 	    env->sc_ocsp_tolerate, env->sc_ocsp_maxage);
972 	return (0);
973 }
974 
975 int
976 config_setcertpartialchain(struct iked *env)
977 {
978 	unsigned int boolval;
979 
980 	boolval = env->sc_cert_partial_chain;
981 	proc_compose(&env->sc_ps, PROC_CERT, IMSG_CERT_PARTIAL_CHAIN,
982 	    &boolval, sizeof(boolval));
983 	return (0);
984 }
985 
986 int
987 config_getcertpartialchain(struct iked *env, struct imsg *imsg)
988 {
989 	unsigned int boolval;
990 
991 	IMSG_SIZE_CHECK(imsg, &boolval);
992 	memcpy(&boolval, imsg->data, sizeof(boolval));
993 	env->sc_cert_partial_chain = boolval;
994 	return (0);
995 }
996 
997 int
998 config_setkeys(struct iked *env)
999 {
1000 	FILE			*fp = NULL;
1001 	EVP_PKEY		*key = NULL;
1002 	struct iked_id		 privkey;
1003 	struct iked_id		 pubkey;
1004 	struct iovec		 iov[2];
1005 	int			 ret = -1;
1006 
1007 	memset(&privkey, 0, sizeof(privkey));
1008 	memset(&pubkey, 0, sizeof(pubkey));
1009 
1010 	/* Read private key */
1011 	if ((fp = fopen(IKED_PRIVKEY, "r")) == NULL) {
1012 		log_warn("%s: failed to open private key", __func__);
1013 		goto done;
1014 	}
1015 
1016 	if ((key = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) {
1017 		log_warnx("%s: failed to read private key", __func__);
1018 		goto done;
1019 	}
1020 
1021 	if (ca_privkey_serialize(key, &privkey) != 0) {
1022 		log_warnx("%s: failed to serialize private key", __func__);
1023 		goto done;
1024 	}
1025 	if (ca_pubkey_serialize(key, &pubkey) != 0) {
1026 		log_warnx("%s: failed to serialize public key", __func__);
1027 		goto done;
1028 	}
1029 
1030 	iov[0].iov_base = &privkey;
1031 	iov[0].iov_len = sizeof(privkey);
1032 	iov[1].iov_base = ibuf_data(privkey.id_buf);
1033 	iov[1].iov_len = ibuf_length(privkey.id_buf);
1034 
1035 	if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PRIVKEY, iov, 2) == -1) {
1036 		log_warnx("%s: failed to send private key", __func__);
1037 		goto done;
1038 	}
1039 
1040 	iov[0].iov_base = &pubkey;
1041 	iov[0].iov_len = sizeof(pubkey);
1042 	iov[1].iov_base = ibuf_data(pubkey.id_buf);
1043 	iov[1].iov_len = ibuf_length(pubkey.id_buf);
1044 
1045 	if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PUBKEY, iov, 2) == -1) {
1046 		log_warnx("%s: failed to send public key", __func__);
1047 		goto done;
1048 	}
1049 
1050 	ret = 0;
1051  done:
1052 	if (fp != NULL)
1053 		fclose(fp);
1054 
1055 	ibuf_release(pubkey.id_buf);
1056 	ibuf_release(privkey.id_buf);
1057 	EVP_PKEY_free(key);
1058 
1059 	return (ret);
1060 }
1061 
1062 int
1063 config_getkey(struct iked *env, struct imsg *imsg)
1064 {
1065 	size_t		 len;
1066 	struct iked_id	 id;
1067 
1068 	len = IMSG_DATA_SIZE(imsg);
1069 	if (len <= sizeof(id))
1070 		fatalx("%s: invalid key message", __func__);
1071 
1072 	memcpy(&id, imsg->data, sizeof(id));
1073 	if ((id.id_buf = ibuf_new((uint8_t *)imsg->data + sizeof(id),
1074 	    len - sizeof(id))) == NULL)
1075 		fatalx("%s: failed to get key", __func__);
1076 
1077 	explicit_bzero(imsg->data, len);
1078 	ca_getkey(&env->sc_ps, &id, imsg->hdr.type);
1079 
1080 	return (0);
1081 }
1082