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