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