xref: /openbsd-src/sbin/iked/config.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: config.c,v 1.31 2014/05/06 14:10:53 markus Exp $	*/
2 
3 /*
4  * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
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 <getopt.h>
30 #include <signal.h>
31 #include <errno.h>
32 #include <err.h>
33 #include <pwd.h>
34 #include <event.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 u_int64_t
67 config_getspi(void)
68 {
69 	u_int64_t	 spi;
70 
71 	spi = ((u_int64_t)arc4random() << 32) | arc4random();
72 	if (spi == 0)
73 		return (config_getspi());
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 	if (kex->kex_dhgroup != NULL)
88 		group_free(kex->kex_dhgroup);
89 	ibuf_release(kex->kex_dhiexchange);
90 	ibuf_release(kex->kex_dhrexchange);
91 
92 	free(kex);
93 }
94 
95 void
96 config_free_sa(struct iked *env, struct iked_sa *sa)
97 {
98 	timer_del(env, &sa->sa_timer);
99 	timer_del(env, &sa->sa_rekey);
100 
101 	config_free_proposals(&sa->sa_proposals, 0);
102 	config_free_childsas(env, &sa->sa_childsas, NULL, NULL);
103 	sa_free_flows(env, &sa->sa_flows);
104 
105 	if (sa->sa_addrpool) {
106 		(void)RB_REMOVE(iked_addrpool, &env->sc_addrpool, sa);
107 		free(sa->sa_addrpool);
108 	}
109 
110 	if (sa->sa_policy) {
111 		(void)RB_REMOVE(iked_sapeers, &sa->sa_policy->pol_sapeers, sa);
112 		policy_unref(env, sa->sa_policy);
113 	}
114 
115 	ikev2_msg_flushqueue(env, &sa->sa_requests);
116 	ikev2_msg_flushqueue(env, &sa->sa_responses);
117 
118 	ibuf_release(sa->sa_inonce);
119 	ibuf_release(sa->sa_rnonce);
120 
121 	if (sa->sa_dhgroup != NULL)
122 		group_free(sa->sa_dhgroup);
123 	ibuf_release(sa->sa_dhiexchange);
124 	ibuf_release(sa->sa_dhrexchange);
125 
126 	hash_free(sa->sa_prf);
127 	hash_free(sa->sa_integr);
128 	cipher_free(sa->sa_encr);
129 
130 	ibuf_release(sa->sa_key_d);
131 	ibuf_release(sa->sa_key_iauth);
132 	ibuf_release(sa->sa_key_rauth);
133 	ibuf_release(sa->sa_key_iencr);
134 	ibuf_release(sa->sa_key_rencr);
135 	ibuf_release(sa->sa_key_iprf);
136 	ibuf_release(sa->sa_key_rprf);
137 
138 	ibuf_release(sa->sa_1stmsg);
139 	ibuf_release(sa->sa_2ndmsg);
140 
141 	ibuf_release(sa->sa_iid.id_buf);
142 	ibuf_release(sa->sa_rid.id_buf);
143 	ibuf_release(sa->sa_icert.id_buf);
144 	ibuf_release(sa->sa_rcert.id_buf);
145 
146 	ibuf_release(sa->sa_eap.id_buf);
147 	if (sa->sa_eapid != NULL)
148 		free(sa->sa_eapid);
149 	ibuf_release(sa->sa_eapmsk);
150 
151 	free(sa);
152 }
153 
154 struct iked_policy *
155 config_new_policy(struct iked *env)
156 {
157 	struct iked_policy	*pol;
158 
159 	if ((pol = calloc(1, sizeof(*pol))) == NULL)
160 		return (NULL);
161 
162 	TAILQ_INIT(&pol->pol_proposals);
163 	RB_INIT(&pol->pol_sapeers);
164 
165 	return (pol);
166 }
167 
168 void
169 config_free_policy(struct iked *env, struct iked_policy *pol)
170 {
171 	struct iked_sa		*sa;
172 
173 	if (pol->pol_flags & IKED_POLICY_REFCNT)
174 		goto remove;
175 
176 	TAILQ_REMOVE(&env->sc_policies, pol, pol_entry);
177 
178 	RB_FOREACH(sa, iked_sapeers, &pol->pol_sapeers) {
179 		/* Remove from the policy tree, but keep for existing SAs */
180 		if (sa->sa_policy == pol)
181 			policy_ref(env, pol);
182 	}
183 
184 	if (pol->pol_refcnt)
185 		return;
186 
187  remove:
188 	config_free_proposals(&pol->pol_proposals, 0);
189 	config_free_flows(env, &pol->pol_flows);
190 	free(pol);
191 }
192 
193 struct iked_proposal *
194 config_add_proposal(struct iked_proposals *head, u_int id, u_int proto)
195 {
196 	struct iked_proposal	*pp;
197 
198 	TAILQ_FOREACH(pp, head, prop_entry) {
199 		if (pp->prop_protoid == proto &&
200 		    pp->prop_id == id)
201 			return (pp);
202 	}
203 
204 	if ((pp = calloc(1, sizeof(*pp))) == NULL)
205 		return (NULL);
206 
207 	pp->prop_protoid = proto;
208 	pp->prop_id = id;
209 
210 	TAILQ_INSERT_TAIL(head, pp, prop_entry);
211 
212 	return (pp);
213 }
214 
215 void
216 config_free_proposals(struct iked_proposals *head, u_int proto)
217 {
218 	struct iked_proposal	*prop, *next;
219 
220 	for (prop = TAILQ_FIRST(head); prop != NULL; prop = next) {
221 		next = TAILQ_NEXT(prop, prop_entry);
222 
223 		/* Free any proposal or only selected SA proto */
224 		if (proto != 0 && prop->prop_protoid != proto)
225 			continue;
226 
227 		log_debug("%s: free %p", __func__, prop);
228 
229 		TAILQ_REMOVE(head, prop, prop_entry);
230 		if (prop->prop_nxforms)
231 			free(prop->prop_xforms);
232 		free(prop);
233 	}
234 }
235 
236 void
237 config_free_flows(struct iked *env, struct iked_flows *head)
238 {
239 	struct iked_flow	*flow, *next;
240 
241 	for (flow = RB_MIN(iked_flows, head); flow != NULL; flow = next) {
242 		next = RB_NEXT(iked_flows, head, flow);
243 		log_debug("%s: free %p", __func__, flow);
244 		RB_REMOVE(iked_flows, head, flow);
245 		flow_free(flow);
246 	}
247 }
248 
249 void
250 config_free_childsas(struct iked *env, struct iked_childsas *head,
251     struct iked_spi *peerspi, struct iked_spi *localspi)
252 {
253 	struct iked_childsa	*csa, *nextcsa;
254 
255 	if (localspi != NULL)
256 		bzero(localspi, sizeof(*localspi));
257 
258 	for (csa = TAILQ_FIRST(head); csa != NULL; csa = nextcsa) {
259 		nextcsa = TAILQ_NEXT(csa, csa_entry);
260 
261 		if (peerspi != NULL) {
262 			/* Only delete matching peer SPIs */
263 			if (peerspi->spi != csa->csa_peerspi)
264 				continue;
265 
266 			/* Store assigned local SPI */
267 			if (localspi != NULL && localspi->spi == 0)
268 				memcpy(localspi, &csa->csa_spi,
269 				    sizeof(*localspi));
270 		}
271 		log_debug("%s: free %p", __func__, csa);
272 
273 		TAILQ_REMOVE(head, csa, csa_entry);
274 		if (csa->csa_loaded) {
275 			RB_REMOVE(iked_activesas, &env->sc_activesas, csa);
276 			(void)pfkey_sa_delete(env->sc_pfkey, csa);
277 		}
278 		childsa_free(csa);
279 	}
280 }
281 
282 struct iked_transform *
283 config_add_transform(struct iked_proposal *prop, u_int type,
284     u_int id, u_int length, u_int keylength)
285 {
286 	struct iked_transform	*xform;
287 	struct iked_constmap	*map = NULL;
288 	int			 score = 1;
289 	u_int			 i;
290 
291 	switch (type) {
292 	case IKEV2_XFORMTYPE_ENCR:
293 		map = ikev2_xformencr_map;
294 		break;
295 	case IKEV2_XFORMTYPE_PRF:
296 		map = ikev2_xformprf_map;
297 		break;
298 	case IKEV2_XFORMTYPE_INTEGR:
299 		map = ikev2_xformauth_map;
300 		break;
301 	case IKEV2_XFORMTYPE_DH:
302 		map = ikev2_xformdh_map;
303 		break;
304 	case IKEV2_XFORMTYPE_ESN:
305 		map = ikev2_xformesn_map;
306 		break;
307 	default:
308 		log_debug("%s: invalid transform type %d", __func__, type);
309 		return (NULL);
310 	}
311 
312 	for (i = 0; i < prop->prop_nxforms; i++) {
313 		xform = prop->prop_xforms + i;
314 		if (xform->xform_type == type &&
315 		    xform->xform_id == id &&
316 		    xform->xform_length == length)
317 			return (xform);
318 	}
319 
320 	for (i = 0; i < prop->prop_nxforms; i++) {
321 		xform = prop->prop_xforms + i;
322 		if (xform->xform_type == type) {
323 			switch (type) {
324 			case IKEV2_XFORMTYPE_ENCR:
325 			case IKEV2_XFORMTYPE_INTEGR:
326 				score += 3;
327 				break;
328 			case IKEV2_XFORMTYPE_DH:
329 				score += 2;
330 				break;
331 			default:
332 				score += 1;
333 				break;
334 			}
335 		}
336 	}
337 
338 	if ((xform = realloc(prop->prop_xforms,
339 	    (prop->prop_nxforms + 1) * sizeof(*xform))) == NULL) {
340 		return (NULL);
341 	}
342 
343 	prop->prop_xforms = xform;
344 	xform = prop->prop_xforms + prop->prop_nxforms++;
345 	bzero(xform, sizeof(*xform));
346 
347 	xform->xform_type = type;
348 	xform->xform_id = id;
349 	xform->xform_length = length;
350 	xform->xform_keylength = keylength;
351 	xform->xform_score = score;
352 	xform->xform_map = map;
353 
354 	return (xform);
355 }
356 
357 struct iked_transform *
358 config_findtransform(struct iked_proposals *props, u_int8_t type,
359     u_int proto)
360 {
361 	struct iked_proposal	*prop;
362 	struct iked_transform	*xform;
363 	u_int			 i;
364 
365 	/* Search of the first transform with the desired type */
366 	TAILQ_FOREACH(prop, props, prop_entry) {
367 		/* Find any proposal or only selected SA proto */
368 		if (proto != 0 && prop->prop_protoid != proto)
369 			continue;
370 		for (i = 0; i < prop->prop_nxforms; i++) {
371 			xform = prop->prop_xforms + i;
372 			if (xform->xform_type == type)
373 				return (xform);
374 		}
375 	}
376 
377 	return (NULL);
378 }
379 
380 struct iked_user *
381 config_new_user(struct iked *env, struct iked_user *new)
382 {
383 	struct iked_user	*usr, *old;
384 
385 	if ((usr = calloc(1, sizeof(*usr))) == NULL)
386 		return (NULL);
387 
388 	memcpy(usr, new, sizeof(*usr));
389 
390 	if ((old = RB_INSERT(iked_users, &env->sc_users, usr)) != NULL) {
391 		/* Update the password of an existing user*/
392 		memcpy(old, new, sizeof(*old));
393 
394 		log_debug("%s: updating user %s", __func__, usr->usr_name);
395 		free(usr);
396 
397 		return (old);
398 	}
399 
400 	log_debug("%s: inserting new user %s", __func__, usr->usr_name);
401 	return (usr);
402 }
403 
404 /*
405  * Inter-process communication of configuration items.
406  */
407 
408 int
409 config_setcoupled(struct iked *env, u_int couple)
410 {
411 	u_int	 type;
412 
413 	type = couple ? IMSG_CTL_COUPLE : IMSG_CTL_DECOUPLE;
414 	proc_compose_imsg(&env->sc_ps, PROC_IKEV1, -1, type, -1, NULL, 0);
415 	proc_compose_imsg(&env->sc_ps, PROC_IKEV2, -1, type, -1, NULL, 0);
416 
417 	return (0);
418 }
419 
420 int
421 config_getcoupled(struct iked *env, u_int type)
422 {
423 	return (pfkey_couple(env->sc_pfkey, &env->sc_sas,
424 	    type == IMSG_CTL_COUPLE ? 1 : 0));
425 }
426 
427 int
428 config_setmode(struct iked *env, u_int passive)
429 {
430 	u_int	 type;
431 
432 	type = passive ? IMSG_CTL_PASSIVE : IMSG_CTL_ACTIVE;
433 	proc_compose_imsg(&env->sc_ps, PROC_IKEV1, -1, type, -1, NULL, 0);
434 	proc_compose_imsg(&env->sc_ps, PROC_IKEV2, -1, type, -1, NULL, 0);
435 
436 	return (0);
437 }
438 
439 int
440 config_getmode(struct iked *env, u_int type)
441 {
442 	u_int8_t	 old;
443 	u_char		*mode[] = { "active", "passive" };
444 
445 	old = env->sc_passive ? 1 : 0;
446 	env->sc_passive = type == IMSG_CTL_PASSIVE ? 1 : 0;
447 
448 	if (old == env->sc_passive)
449 		return (0);
450 
451 	log_debug("%s: mode %s -> %s", __func__,
452 	    mode[old], mode[env->sc_passive]);
453 
454 	return (0);
455 }
456 
457 int
458 config_setreset(struct iked *env, u_int mode, enum privsep_procid id)
459 {
460 	proc_compose_imsg(&env->sc_ps, id, -1,
461 	    IMSG_CTL_RESET, -1, &mode, sizeof(mode));
462 	return (0);
463 }
464 
465 int
466 config_getreset(struct iked *env, struct imsg *imsg)
467 {
468 	struct iked_policy	*pol, *nextpol;
469 	struct iked_sa		*sa, *nextsa;
470 	struct iked_user	*usr, *nextusr;
471 	u_int			 mode;
472 
473 	IMSG_SIZE_CHECK(imsg, &mode);
474 	memcpy(&mode, imsg->data, sizeof(mode));
475 
476 	if (mode == RESET_ALL || mode == RESET_POLICY) {
477 		log_debug("%s: flushing policies", __func__);
478 		for (pol = TAILQ_FIRST(&env->sc_policies);
479 		    pol != NULL; pol = nextpol) {
480 			nextpol = TAILQ_NEXT(pol, pol_entry);
481 			config_free_policy(env, pol);
482 		}
483 	}
484 
485 	if (mode == RESET_ALL || mode == RESET_SA) {
486 		log_debug("%s: flushing SAs", __func__);
487 		for (sa = RB_MIN(iked_sas, &env->sc_sas);
488 		    sa != NULL; sa = nextsa) {
489 			nextsa = RB_NEXT(iked_sas, &env->sc_sas, sa);
490 			RB_REMOVE(iked_sas, &env->sc_sas, sa);
491 			config_free_sa(env, sa);
492 		}
493 	}
494 
495 	if (mode == RESET_ALL || mode == RESET_USER) {
496 		log_debug("%s: flushing users", __func__);
497 		for (usr = RB_MIN(iked_users, &env->sc_users);
498 		    usr != NULL; usr = nextusr) {
499 			nextusr = RB_NEXT(iked_users, &env->sc_users, usr);
500 			RB_REMOVE(iked_users, &env->sc_users, usr);
501 			free(usr);
502 		}
503 	}
504 
505 	return (0);
506 }
507 
508 int
509 config_setsocket(struct iked *env, struct sockaddr_storage *ss,
510     in_port_t port, enum privsep_procid id)
511 {
512 	int	 s;
513 
514 	if ((s = udp_bind((struct sockaddr *)ss, port)) == -1)
515 		return (-1);
516 	proc_compose_imsg(&env->sc_ps, id, -1,
517 	    IMSG_UDP_SOCKET, s, ss, sizeof(*ss));
518 	return (0);
519 }
520 
521 int
522 config_getsocket(struct iked *env, struct imsg *imsg,
523     void (*cb)(int, short, void *))
524 {
525 	struct iked_socket	*sock, **sptr, **nptr;
526 
527 	log_debug("%s: received socket fd %d", __func__, imsg->fd);
528 
529 	if ((sock = calloc(1, sizeof(*sock))) == NULL)
530 		fatal("config_getsocket: calloc");
531 
532 	IMSG_SIZE_CHECK(imsg, &sock->sock_addr);
533 
534 	memcpy(&sock->sock_addr, imsg->data, sizeof(sock->sock_addr));
535 	sock->sock_fd = imsg->fd;
536 	sock->sock_env = env;
537 
538 	switch (sock->sock_addr.ss_family) {
539 	case AF_INET:
540 		sptr = &env->sc_sock4[0];
541 		nptr = &env->sc_sock4[1];
542 		break;
543 	case AF_INET6:
544 		sptr = &env->sc_sock6[0];
545 		nptr = &env->sc_sock6[1];
546 		break;
547 	default:
548 		fatal("config_getsocket: socket af");
549 		/* NOTREACHED */
550 	}
551 	if (*sptr == NULL)
552 		*sptr = sock;
553 	if (*nptr == NULL &&
554 	    socket_getport((struct sockaddr *)&sock->sock_addr) ==
555 	    IKED_NATT_PORT)
556 		*nptr = sock;
557 
558 	event_set(&sock->sock_ev, sock->sock_fd,
559 	    EV_READ|EV_PERSIST, cb, sock);
560 	event_add(&sock->sock_ev, NULL);
561 
562 	return (0);
563 }
564 
565 int
566 config_setpfkey(struct iked *env, enum privsep_procid id)
567 {
568 	int	 s;
569 
570 	if ((s = pfkey_socket()) == -1)
571 		return (-1);
572 	proc_compose_imsg(&env->sc_ps, id, -1,
573 	    IMSG_PFKEY_SOCKET, s, NULL, 0);
574 	return (0);
575 }
576 
577 int
578 config_getpfkey(struct iked *env, struct imsg *imsg)
579 {
580 	log_debug("%s: received pfkey fd %d", __func__, imsg->fd);
581 	pfkey_init(env, imsg->fd);
582 	return (0);
583 }
584 
585 int
586 config_setuser(struct iked *env, struct iked_user *usr, enum privsep_procid id)
587 {
588 	if (env->sc_opts & IKED_OPT_NOACTION) {
589 		print_user(usr);
590 		return (0);
591 	}
592 
593 	proc_compose_imsg(&env->sc_ps, id, -1,
594 	    IMSG_CFG_USER, -1, usr, sizeof(*usr));
595 	return (0);
596 }
597 
598 int
599 config_getuser(struct iked *env, struct imsg *imsg)
600 {
601 	struct iked_user	 usr;
602 
603 	IMSG_SIZE_CHECK(imsg, &usr);
604 	memcpy(&usr, imsg->data, sizeof(usr));
605 
606 	if (config_new_user(env, &usr) == NULL)
607 		return (-1);
608 
609 	print_user(&usr);
610 
611 	return (0);
612 }
613 
614 int
615 config_setpolicy(struct iked *env, struct iked_policy *pol,
616     enum privsep_procid id)
617 {
618 	struct iked_proposal	*prop;
619 	struct iked_flow	*flow;
620 	struct iked_transform	*xform;
621 	size_t			 size, iovcnt, j, c = 0;
622 	struct iovec		 iov[IOV_MAX];
623 
624 	iovcnt = 1;
625 	size = sizeof(*pol);
626 	TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) {
627 		size += (prop->prop_nxforms * sizeof(*xform)) +
628 		    (sizeof(*prop));
629 		iovcnt += prop->prop_nxforms + 1;
630 	}
631 
632 	iovcnt += pol->pol_nflows;
633 
634 	if (iovcnt > IOV_MAX) {
635 		log_warn("%s: too many proposals/flows", __func__);
636 		return (-1);
637 	}
638 
639 	iov[c].iov_base = pol;
640 	iov[c++].iov_len = sizeof(*pol);
641 
642 	TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) {
643 		iov[c].iov_base = prop;
644 		iov[c++].iov_len = sizeof(*prop);
645 
646 		for (j = 0; j < prop->prop_nxforms; j++) {
647 			xform = prop->prop_xforms + j;
648 
649 			iov[c].iov_base = xform;
650 			iov[c++].iov_len = sizeof(*xform);
651 		}
652 	}
653 
654 	RB_FOREACH(flow, iked_flows, &pol->pol_flows) {
655 		iov[c].iov_base = flow;
656 		iov[c++].iov_len = sizeof(*flow);
657 	}
658 
659 	if (env->sc_opts & IKED_OPT_NOACTION) {
660 		print_policy(pol);
661 		return (0);
662 	}
663 
664 	if (proc_composev_imsg(&env->sc_ps, id, -1,
665 	    IMSG_CFG_POLICY, -1, iov, iovcnt) == -1)
666 		return (-1);
667 
668 	return (0);
669 }
670 
671 int
672 config_getpolicy(struct iked *env, struct imsg *imsg)
673 {
674 	struct iked_policy	*pol;
675 	struct iked_proposal	 pp, *prop;
676 	struct iked_transform	 xf, *xform;
677 	struct iked_flow	*flow;
678 	off_t			 offset = 0;
679 	u_int			 i, j;
680 	u_int8_t		*buf = (u_int8_t *)imsg->data;
681 
682 	IMSG_SIZE_CHECK(imsg, pol);
683 	log_debug("%s: received policy", __func__);
684 
685 	if ((pol = config_new_policy(NULL)) == NULL)
686 		fatal("config_getpolicy: new policy");
687 
688 	memcpy(pol, buf, sizeof(*pol));
689 	offset += sizeof(*pol);
690 
691 	TAILQ_INIT(&pol->pol_proposals);
692 	RB_INIT(&pol->pol_flows);
693 
694 	for (i = 0; i < pol->pol_nproposals; i++) {
695 		memcpy(&pp, buf + offset, sizeof(pp));
696 		offset += sizeof(pp);
697 
698 		if ((prop = config_add_proposal(&pol->pol_proposals,
699 		    pp.prop_id, pp.prop_protoid)) == NULL)
700 			fatal("config_getpolicy: add proposal");
701 
702 		for (j = 0; j < pp.prop_nxforms; j++) {
703 			memcpy(&xf, buf + offset, sizeof(xf));
704 			offset += sizeof(xf);
705 
706 			if ((xform = config_add_transform(prop, xf.xform_type,
707 			    xf.xform_id, xf.xform_length,
708 			    xf.xform_keylength)) == NULL)
709 				fatal("config_getpolicy: add transform");
710 		}
711 	}
712 
713 	for (i = 0; i < pol->pol_nflows; i++) {
714 		if ((flow = calloc(1, sizeof(*flow))) == NULL)
715 			fatal("config_getpolicy: new flow");
716 
717 		memcpy(flow, buf + offset, sizeof(*flow));
718 		offset += sizeof(*flow);
719 
720 		if (RB_INSERT(iked_flows, &pol->pol_flows, flow))
721 			free(flow);
722 	}
723 
724 	TAILQ_INSERT_TAIL(&env->sc_policies, pol, pol_entry);
725 
726 	if (pol->pol_flags & IKED_POLICY_DEFAULT) {
727 		/* Only one default policy, just free/unref the old one */
728 		if (env->sc_defaultcon != NULL)
729 			config_free_policy(env, env->sc_defaultcon);
730 		env->sc_defaultcon = pol;
731 	}
732 
733 	print_policy(pol);
734 
735 	return (0);
736 }
737 
738 int
739 config_setcompile(struct iked *env, enum privsep_procid id)
740 {
741 	if (env->sc_opts & IKED_OPT_NOACTION)
742 		return (0);
743 
744 	proc_compose_imsg(&env->sc_ps, id, -1,
745 	    IMSG_COMPILE, -1, NULL, 0);
746 	return (0);
747 }
748 
749 int
750 config_getcompile(struct iked *env, struct imsg *imsg)
751 {
752 	/*
753 	 * Do any necessary steps after configuration, for now we
754 	 * only need to compile the skip steps.
755 	 */
756 	policy_calc_skip_steps(&env->sc_policies);
757 
758 	log_debug("%s: compilation done", __func__);
759 	return (0);
760 }
761 
762 int
763 config_setocsp(struct iked *env)
764 {
765 	if (env->sc_opts & IKED_OPT_NOACTION)
766 		return (0);
767 	proc_compose_imsg(&env->sc_ps, PROC_CERT, -1,
768 	    IMSG_OCSP_URL, -1, env->sc_ocsp_url,
769 	    env->sc_ocsp_url ? strlen(env->sc_ocsp_url) : 0);
770 
771 	return (0);
772 }
773 
774 int
775 config_getocsp(struct iked *env, struct imsg *imsg)
776 {
777 	if (env->sc_ocsp_url)
778 		free(env->sc_ocsp_url);
779 	if (IMSG_DATA_SIZE(imsg) > 0)
780 		env->sc_ocsp_url = get_string(imsg->data, IMSG_DATA_SIZE(imsg));
781 	else
782 		env->sc_ocsp_url = NULL;
783 	log_debug("%s: ocsp_url %s", __func__,
784 	    env->sc_ocsp_url ? env->sc_ocsp_url : "none");
785 	return (0);
786 }
787