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