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