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