xref: /openbsd-src/sbin/iked/config.c (revision 4e1ee0786f11cc571bd0be17d38e46f635c719fc)
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 
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 uint64_t
67 config_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 
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 	group_free(kex->kex_dhgroup);
88 	ibuf_release(kex->kex_dhiexchange);
89 	ibuf_release(kex->kex_dhrexchange);
90 
91 	free(kex);
92 }
93 
94 void
95 config_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 
110 void
111 config_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 
183 struct iked_policy *
184 config_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 
201 void
202 config_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 
238 struct iked_proposal *
239 config_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 
261 void
262 config_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 
270 void
271 config_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 
286 void
287 config_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 
298 void
299 config_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 
335 int
336 config_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 
410 struct iked_transform *
411 config_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 
436 struct iked_transform *
437 config_findtransform(struct iked_proposals *props, uint8_t type,
438     unsigned int proto)
439 {
440 	return config_findtransform_ext(props, type, -1, proto);
441 }
442 
443 struct iked_user *
444 config_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 
471 int
472 config_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 
482 int
483 config_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 
489 int
490 config_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 
500 int
501 config_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 
518 int
519 config_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 
525 int
526 config_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 
536 int
537 config_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  */
579 int
580 config_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 
592 int
593 config_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 
637 int
638 config_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 
649 int
650 config_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 
657 int
658 config_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 
669 int
670 config_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 
687 int
688 config_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 
735 int
736 config_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 
761 int
762 config_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 
820 int
821 config_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 
859 int
860 config_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 
869 int
870 config_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 
882 int
883 config_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 
890 int
891 config_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 
908 int
909 config_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 
932 int
933 config_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 
969 int
970 config_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 
980 int
981 config_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 
991 int
992 config_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 
1056 int
1057 config_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