xref: /openbsd/sbin/iked/config.c (revision 9ca241fc)
1 /*	$OpenBSD: config.c,v 1.99 2024/09/15 11:08:50 yasuoka 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 *
config_new_sa(struct iked * env,int initiator)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 	ikestat_inc(env, ikes_sa_created);
64 	return (sa);
65 }
66 
67 uint64_t
config_getspi(void)68 config_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 
79 void
config_free_kex(struct iked_kex * kex)80 config_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 
95 void
config_free_fragments(struct iked_frag * frag)96 config_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 
111 void
config_free_sa(struct iked * env,struct iked_sa * sa)112 config_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 	iked_radius_acct_stop(env, sa);
127 
128 	if (sa->sa_addrpool) {
129 		(void)RB_REMOVE(iked_addrpool, &env->sc_addrpool, sa);
130 		free(sa->sa_addrpool);
131 	}
132 	if (sa->sa_addrpool6) {
133 		(void)RB_REMOVE(iked_addrpool6, &env->sc_addrpool6, sa);
134 		free(sa->sa_addrpool6);
135 	}
136 
137 	if (sa->sa_policy) {
138 		TAILQ_REMOVE(&sa->sa_policy->pol_sapeers, sa, sa_peer_entry);
139 		policy_unref(env, sa->sa_policy);
140 	}
141 
142 	ikev2_msg_flushqueue(env, &sa->sa_requests);
143 	ikev2_msg_flushqueue(env, &sa->sa_responses);
144 
145 	ibuf_free(sa->sa_inonce);
146 	ibuf_free(sa->sa_rnonce);
147 
148 	group_free(sa->sa_dhgroup);
149 	ibuf_free(sa->sa_dhiexchange);
150 	ibuf_free(sa->sa_dhrexchange);
151 
152 	ibuf_free(sa->sa_simult);
153 
154 	hash_free(sa->sa_prf);
155 	hash_free(sa->sa_integr);
156 	cipher_free(sa->sa_encr);
157 
158 	ibuf_free(sa->sa_key_d);
159 	ibuf_free(sa->sa_key_iauth);
160 	ibuf_free(sa->sa_key_rauth);
161 	ibuf_free(sa->sa_key_iencr);
162 	ibuf_free(sa->sa_key_rencr);
163 	ibuf_free(sa->sa_key_iprf);
164 	ibuf_free(sa->sa_key_rprf);
165 
166 	ibuf_free(sa->sa_1stmsg);
167 	ibuf_free(sa->sa_2ndmsg);
168 
169 	ibuf_free(sa->sa_iid.id_buf);
170 	ibuf_free(sa->sa_rid.id_buf);
171 	ibuf_free(sa->sa_icert.id_buf);
172 	ibuf_free(sa->sa_rcert.id_buf);
173 	for (i = 0; i < IKED_SCERT_MAX; i++)
174 		ibuf_free(sa->sa_scert[i].id_buf);
175 	ibuf_free(sa->sa_localauth.id_buf);
176 	ibuf_free(sa->sa_peerauth.id_buf);
177 
178 	ibuf_free(sa->sa_eap.id_buf);
179 	free(sa->sa_eapid);
180 	ibuf_free(sa->sa_eapmsk);
181 	ibuf_free(sa->sa_eapclass);
182 
183 	free(sa->sa_cp_addr);
184 	free(sa->sa_cp_addr6);
185 	free(sa->sa_cp_dns);
186 
187 	free(sa->sa_tag);
188 
189 	if (sa->sa_state == IKEV2_STATE_ESTABLISHED)
190 		ikestat_dec(env, ikes_sa_established_current);
191 	ikestat_inc(env, ikes_sa_removed);
192 
193 	free(sa->sa_rad_addr);
194 	free(sa->sa_rad_addr6);
195 	iked_radius_request_free(env, sa->sa_radreq);
196 
197 	free(sa);
198 }
199 
200 struct iked_policy *
config_new_policy(struct iked * env)201 config_new_policy(struct iked *env)
202 {
203 	struct iked_policy	*pol;
204 
205 	if ((pol = calloc(1, sizeof(*pol))) == NULL)
206 		return (NULL);
207 
208 	/* XXX caller does this again */
209 	TAILQ_INIT(&pol->pol_proposals);
210 	TAILQ_INIT(&pol->pol_sapeers);
211 	TAILQ_INIT(&pol->pol_tssrc);
212 	TAILQ_INIT(&pol->pol_tsdst);
213 	RB_INIT(&pol->pol_flows);
214 
215 	return (pol);
216 }
217 
218 void
config_free_policy(struct iked * env,struct iked_policy * pol)219 config_free_policy(struct iked *env, struct iked_policy *pol)
220 {
221 	struct iked_sa		*sa;
222 	struct iked_ts	*tsi;
223 
224 	if (pol->pol_flags & IKED_POLICY_REFCNT)
225 		goto remove;
226 
227 	/*
228 	 * Remove policy from the sc_policies list, but increment
229 	 * refcount for every SA linked for the policy.
230 	 */
231 	pol->pol_flags |= IKED_POLICY_REFCNT;
232 
233 	TAILQ_REMOVE(&env->sc_policies, pol, pol_entry);
234 
235 	TAILQ_FOREACH(sa, &pol->pol_sapeers, sa_peer_entry) {
236 		if (sa->sa_policy == pol)
237 			policy_ref(env, pol);
238 		else
239 			log_warnx("%s: ERROR: sa_policy %p != pol %p",
240 			    __func__, sa->sa_policy, pol);
241 	}
242 
243 	if (pol->pol_refcnt)
244 		return;
245 
246  remove:
247 	while ((tsi = TAILQ_FIRST(&pol->pol_tssrc))) {
248 		TAILQ_REMOVE(&pol->pol_tssrc, tsi, ts_entry);
249 		free(tsi);
250 	}
251 	while ((tsi = TAILQ_FIRST(&pol->pol_tsdst))) {
252 		TAILQ_REMOVE(&pol->pol_tsdst, tsi, ts_entry);
253 		free(tsi);
254 	}
255 	config_free_proposals(&pol->pol_proposals, 0);
256 	config_free_flows(env, &pol->pol_flows);
257 	free(pol);
258 }
259 
260 struct iked_proposal *
config_add_proposal(struct iked_proposals * head,unsigned int id,unsigned int proto)261 config_add_proposal(struct iked_proposals *head, unsigned int id,
262     unsigned int proto)
263 {
264 	struct iked_proposal	*pp;
265 
266 	TAILQ_FOREACH(pp, head, prop_entry) {
267 		if (pp->prop_protoid == proto &&
268 		    pp->prop_id == id)
269 			return (pp);
270 	}
271 
272 	if ((pp = calloc(1, sizeof(*pp))) == NULL)
273 		return (NULL);
274 
275 	pp->prop_protoid = proto;
276 	pp->prop_id = id;
277 
278 	TAILQ_INSERT_TAIL(head, pp, prop_entry);
279 
280 	return (pp);
281 }
282 
283 void
config_free_proposal(struct iked_proposals * head,struct iked_proposal * prop)284 config_free_proposal(struct iked_proposals *head, struct iked_proposal *prop)
285 {
286 	TAILQ_REMOVE(head, prop, prop_entry);
287 	if (prop->prop_nxforms)
288 		free(prop->prop_xforms);
289 	free(prop);
290 }
291 
292 void
config_free_proposals(struct iked_proposals * head,unsigned int proto)293 config_free_proposals(struct iked_proposals *head, unsigned int proto)
294 {
295 	struct iked_proposal	*prop, *proptmp;
296 
297 	TAILQ_FOREACH_SAFE(prop, head, prop_entry, proptmp) {
298 		/* Free any proposal or only selected SA proto */
299 		if (proto != 0 && prop->prop_protoid != proto)
300 			continue;
301 
302 		log_debug("%s: free %p", __func__, prop);
303 
304 		config_free_proposal(head, prop);
305 	}
306 }
307 
308 void
config_free_flows(struct iked * env,struct iked_flows * head)309 config_free_flows(struct iked *env, struct iked_flows *head)
310 {
311 	struct iked_flow	*flow;
312 
313 	while ((flow = RB_MIN(iked_flows, head))) {
314 		log_debug("%s: free %p", __func__, flow);
315 		RB_REMOVE(iked_flows, head, flow);
316 		flow_free(flow);
317 	}
318 }
319 
320 void
config_free_childsas(struct iked * env,struct iked_childsas * head,struct iked_spi * peerspi,struct iked_spi * localspi)321 config_free_childsas(struct iked *env, struct iked_childsas *head,
322     struct iked_spi *peerspi, struct iked_spi *localspi)
323 {
324 	struct iked_childsa	*csa, *csatmp, *ipcomp;
325 
326 	if (localspi != NULL)
327 		bzero(localspi, sizeof(*localspi));
328 
329 	TAILQ_FOREACH_SAFE(csa, head, csa_entry, csatmp) {
330 		if (peerspi != NULL) {
331 			/* Only delete matching peer SPIs */
332 			if (peerspi->spi != csa->csa_peerspi)
333 				continue;
334 
335 			/* Store assigned local SPI */
336 			if (localspi != NULL && localspi->spi == 0)
337 				memcpy(localspi, &csa->csa_spi,
338 				    sizeof(*localspi));
339 		}
340 		log_debug("%s: free %p", __func__, csa);
341 
342 		TAILQ_REMOVE(head, csa, csa_entry);
343 		if (csa->csa_loaded) {
344 			RB_REMOVE(iked_activesas, &env->sc_activesas, csa);
345 			(void)pfkey_sa_delete(env, csa);
346 		}
347 		if ((ipcomp = csa->csa_bundled) != NULL) {
348 			log_debug("%s: free IPCOMP %p", __func__, ipcomp);
349 			if (ipcomp->csa_loaded)
350 				(void)pfkey_sa_delete(env, ipcomp);
351 			childsa_free(ipcomp);
352 		}
353 		childsa_free(csa);
354 		ikestat_inc(env, ikes_csa_removed);
355 	}
356 }
357 
358 int
config_add_transform(struct iked_proposal * prop,unsigned int type,unsigned int id,unsigned int length,unsigned int keylength)359 config_add_transform(struct iked_proposal *prop, unsigned int type,
360     unsigned int id, unsigned int length, unsigned int keylength)
361 {
362 	struct iked_transform	*xform;
363 	struct iked_constmap	*map = NULL;
364 	int			 score = 1;
365 	unsigned int		 i;
366 
367 	switch (type) {
368 	case IKEV2_XFORMTYPE_ENCR:
369 		map = ikev2_xformencr_map;
370 		break;
371 	case IKEV2_XFORMTYPE_PRF:
372 		map = ikev2_xformprf_map;
373 		break;
374 	case IKEV2_XFORMTYPE_INTEGR:
375 		map = ikev2_xformauth_map;
376 		break;
377 	case IKEV2_XFORMTYPE_DH:
378 		map = ikev2_xformdh_map;
379 		break;
380 	case IKEV2_XFORMTYPE_ESN:
381 		map = ikev2_xformesn_map;
382 		break;
383 	default:
384 		log_debug("%s: invalid transform type %d", __func__, type);
385 		return (-2);
386 	}
387 
388 	for (i = 0; i < prop->prop_nxforms; i++) {
389 		xform = prop->prop_xforms + i;
390 		if (xform->xform_type == type &&
391 		    xform->xform_id == id &&
392 		    xform->xform_length == length)
393 			return (0);
394 	}
395 
396 	for (i = 0; i < prop->prop_nxforms; i++) {
397 		xform = prop->prop_xforms + i;
398 		if (xform->xform_type == type) {
399 			switch (type) {
400 			case IKEV2_XFORMTYPE_ENCR:
401 			case IKEV2_XFORMTYPE_INTEGR:
402 				score += 3;
403 				break;
404 			case IKEV2_XFORMTYPE_DH:
405 				score += 2;
406 				break;
407 			default:
408 				score += 1;
409 				break;
410 			}
411 		}
412 	}
413 
414 	if ((xform = reallocarray(prop->prop_xforms,
415 	    prop->prop_nxforms + 1, sizeof(*xform))) == NULL) {
416 		return (-1);
417 	}
418 
419 	prop->prop_xforms = xform;
420 	xform = prop->prop_xforms + prop->prop_nxforms++;
421 	bzero(xform, sizeof(*xform));
422 
423 	xform->xform_type = type;
424 	xform->xform_id = id;
425 	xform->xform_length = length;
426 	xform->xform_keylength = keylength;
427 	xform->xform_score = score;
428 	xform->xform_map = map;
429 
430 	return (0);
431 }
432 
433 struct iked_transform *
config_findtransform_ext(struct iked_proposals * props,uint8_t type,int id,unsigned int proto)434 config_findtransform_ext(struct iked_proposals *props, uint8_t type, int id,
435     unsigned int proto)
436 {
437 	struct iked_proposal	*prop;
438 	struct iked_transform	*xform;
439 	unsigned int		 i;
440 
441 	/* Search of the first transform with the desired type */
442 	TAILQ_FOREACH(prop, props, prop_entry) {
443 		/* Find any proposal or only selected SA proto */
444 		if (proto != 0 && prop->prop_protoid != proto)
445 			continue;
446 		for (i = 0; i < prop->prop_nxforms; i++) {
447 			xform = prop->prop_xforms + i;
448 			/* optional lookup of specific transform */
449 			if (id >= 0 && xform->xform_id != id)
450 				continue;
451 			if (xform->xform_type == type)
452 				return (xform);
453 		}
454 	}
455 
456 	return (NULL);
457 }
458 
459 struct iked_transform *
config_findtransform(struct iked_proposals * props,uint8_t type,unsigned int proto)460 config_findtransform(struct iked_proposals *props, uint8_t type,
461     unsigned int proto)
462 {
463 	return config_findtransform_ext(props, type, -1, proto);
464 }
465 
466 struct iked_user *
config_new_user(struct iked * env,struct iked_user * new)467 config_new_user(struct iked *env, struct iked_user *new)
468 {
469 	struct iked_user	*usr, *old;
470 
471 	if ((usr = calloc(1, sizeof(*usr))) == NULL)
472 		return (NULL);
473 
474 	memcpy(usr, new, sizeof(*usr));
475 
476 	if ((old = RB_INSERT(iked_users, &env->sc_users, usr)) != NULL) {
477 		/* Update the password of an existing user*/
478 		memcpy(old->usr_pass, new->usr_pass, IKED_PASSWORD_SIZE);
479 
480 		log_debug("%s: updating user %s", __func__, usr->usr_name);
481 		freezero(usr, sizeof *usr);
482 
483 		return (old);
484 	}
485 
486 	log_debug("%s: inserting new user %s", __func__, usr->usr_name);
487 	return (usr);
488 }
489 
490 /*
491  * Inter-process communication of configuration items.
492  */
493 
494 int
config_setcoupled(struct iked * env,unsigned int couple)495 config_setcoupled(struct iked *env, unsigned int couple)
496 {
497 	unsigned int	 type;
498 
499 	type = couple ? IMSG_CTL_COUPLE : IMSG_CTL_DECOUPLE;
500 	proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0);
501 
502 	return (0);
503 }
504 
505 int
config_getcoupled(struct iked * env,unsigned int type)506 config_getcoupled(struct iked *env, unsigned int type)
507 {
508 	return (pfkey_couple(env, &env->sc_sas,
509 	    type == IMSG_CTL_COUPLE ? 1 : 0));
510 }
511 
512 int
config_setmode(struct iked * env,unsigned int passive)513 config_setmode(struct iked *env, unsigned int passive)
514 {
515 	unsigned int	 type;
516 
517 	/*
518 	 * In order to control the startup of the processes,
519 	 * the messages are sent in this order:
520 	 *   PROC_PARENT -> PROC_CERT -> PROC_PARENT -> PROC_IKEV2
521 	 * so PROC_CERT is ready before PROC_IKEV2 is activated.
522 	 */
523 	type = passive ? IMSG_CTL_PASSIVE : IMSG_CTL_ACTIVE;
524 	proc_compose(&env->sc_ps, PROC_CERT, type, NULL, 0);
525 
526 	return (0);
527 }
528 
529 int
config_getmode(struct iked * env,unsigned int type)530 config_getmode(struct iked *env, unsigned int type)
531 {
532 	uint8_t		 old;
533 	unsigned char	*mode[] = { "active", "passive" };
534 
535 	old = env->sc_passive ? 1 : 0;
536 	env->sc_passive = type == IMSG_CTL_PASSIVE ? 1 : 0;
537 
538 	if (old == env->sc_passive)
539 		return (0);
540 
541 	log_debug("%s: mode %s -> %s", __func__,
542 	    mode[old], mode[env->sc_passive]);
543 
544 	return (0);
545 }
546 
547 int
config_setreset(struct iked * env,unsigned int mode,enum privsep_procid id)548 config_setreset(struct iked *env, unsigned int mode, enum privsep_procid id)
549 {
550 	proc_compose(&env->sc_ps, id, IMSG_CTL_RESET, &mode, sizeof(mode));
551 	return (0);
552 }
553 
554 int
config_getreset(struct iked * env,struct imsg * imsg)555 config_getreset(struct iked *env, struct imsg *imsg)
556 {
557 	unsigned int		 mode;
558 
559 	IMSG_SIZE_CHECK(imsg, &mode);
560 	memcpy(&mode, imsg->data, sizeof(mode));
561 
562 	return (config_doreset(env, mode));
563 }
564 
565 int
config_doreset(struct iked * env,unsigned int mode)566 config_doreset(struct iked *env, unsigned int mode)
567 {
568 	struct iked_policy	*pol, *poltmp;
569 	struct iked_sa		*sa;
570 	struct iked_user	*usr;
571 
572 	if (mode == RESET_ALL || mode == RESET_POLICY) {
573 		log_debug("%s: flushing policies", __func__);
574 		TAILQ_FOREACH_SAFE(pol, &env->sc_policies, pol_entry, poltmp) {
575 			config_free_policy(env, pol);
576 		}
577 	}
578 
579 	if (mode == RESET_ALL || mode == RESET_SA) {
580 		log_debug("%s: flushing SAs", __func__);
581 		while ((sa = RB_MIN(iked_sas, &env->sc_sas))) {
582 			/* for RESET_SA we try send a DELETE */
583 			if (mode == RESET_ALL ||
584 			    ikev2_ike_sa_delete(env, sa) != 0) {
585 				RB_REMOVE(iked_sas, &env->sc_sas, sa);
586 				if (sa->sa_dstid_entry_valid)
587 					sa_dstid_remove(env, sa);
588 				config_free_sa(env, sa);
589 			}
590 		}
591 	}
592 
593 	if (mode == RESET_ALL || mode == RESET_USER) {
594 		log_debug("%s: flushing users", __func__);
595 		while ((usr = RB_MIN(iked_users, &env->sc_users))) {
596 			RB_REMOVE(iked_users, &env->sc_users, usr);
597 			free(usr);
598 		}
599 	}
600 
601 	if (mode == RESET_ALL || mode == RESET_RADIUS) {
602 		struct iked_radserver_req	*req;
603 		struct iked_radserver		*rad, *radt;
604 		struct iked_radcfgmap		*cfg, *cfgt;
605 		struct iked_raddae		*dae, *daet;
606 		struct iked_radclient		*client, *clientt;
607 
608 		TAILQ_FOREACH_SAFE(rad, &env->sc_radauthservers, rs_entry,
609 		    radt) {
610 			close(rad->rs_sock);
611 			event_del(&rad->rs_ev);
612 			TAILQ_REMOVE(&env->sc_radauthservers, rad, rs_entry);
613 			while ((req = TAILQ_FIRST(&rad->rs_reqs)) != NULL)
614 				iked_radius_request_free(env, req);
615 			freezero(rad, sizeof(*rad));
616 		}
617 		TAILQ_FOREACH_SAFE(rad, &env->sc_radacctservers, rs_entry,
618 		    radt) {
619 			close(rad->rs_sock);
620 			event_del(&rad->rs_ev);
621 			TAILQ_REMOVE(&env->sc_radacctservers, rad, rs_entry);
622 			while ((req = TAILQ_FIRST(&rad->rs_reqs)) != NULL)
623 				iked_radius_request_free(env, req);
624 			freezero(rad, sizeof(*rad));
625 		}
626 		TAILQ_FOREACH_SAFE(cfg, &env->sc_radcfgmaps, entry, cfgt) {
627 			TAILQ_REMOVE(&env->sc_radcfgmaps, cfg, entry);
628 			free(cfg);
629 		}
630 		TAILQ_FOREACH_SAFE(dae, &env->sc_raddaes, rd_entry, daet) {
631 			close(dae->rd_sock);
632 			event_del(&dae->rd_ev);
633 			TAILQ_REMOVE(&env->sc_raddaes, dae, rd_entry);
634 			free(dae);
635 		}
636 		TAILQ_FOREACH_SAFE(client, &env->sc_raddaeclients, rc_entry,
637 		    clientt) {
638 			TAILQ_REMOVE(&env->sc_raddaeclients, client, rc_entry);
639 			free(client);
640 		}
641 	}
642 
643 	return (0);
644 }
645 
646 /*
647  * The first call of this function sets the UDP socket for IKEv2.
648  * The second call is optional, setting the UDP socket used for NAT-T.
649  */
650 int
config_setsocket(struct iked * env,struct sockaddr_storage * ss,in_port_t port,enum privsep_procid id)651 config_setsocket(struct iked *env, struct sockaddr_storage *ss,
652     in_port_t port, enum privsep_procid id)
653 {
654 	int	 s;
655 
656 	if ((s = udp_bind((struct sockaddr *)ss, port)) == -1)
657 		return (-1);
658 	proc_compose_imsg(&env->sc_ps, id, -1,
659 	    IMSG_UDP_SOCKET, -1, s, ss, sizeof(*ss));
660 	return (0);
661 }
662 
663 int
config_getsocket(struct iked * env,struct imsg * imsg,void (* cb)(int,short,void *))664 config_getsocket(struct iked *env, struct imsg *imsg,
665     void (*cb)(int, short, void *))
666 {
667 	struct iked_socket	*sock, **sock0 = NULL, **sock1 = NULL;
668 
669 	if ((sock = calloc(1, sizeof(*sock))) == NULL)
670 		fatal("config_getsocket: calloc");
671 
672 	IMSG_SIZE_CHECK(imsg, &sock->sock_addr);
673 
674 	memcpy(&sock->sock_addr, imsg->data, sizeof(sock->sock_addr));
675 	sock->sock_fd = imsg_get_fd(imsg);
676 	sock->sock_env = env;
677 
678 	log_debug("%s: received socket fd %d", __func__, sock->sock_fd);
679 
680 	switch (sock->sock_addr.ss_family) {
681 	case AF_INET:
682 		sock0 = &env->sc_sock4[0];
683 		sock1 = &env->sc_sock4[1];
684 		break;
685 	case AF_INET6:
686 		sock0 = &env->sc_sock6[0];
687 		sock1 = &env->sc_sock6[1];
688 		break;
689 	default:
690 		fatal("config_getsocket: socket af: %u",
691 		    sock->sock_addr.ss_family);
692 		/* NOTREACHED */
693 	}
694 	if (*sock0 == NULL)
695 		*sock0 = sock;
696 	else if (*sock1 == NULL)
697 		*sock1 = sock;
698 	else
699 		fatalx("%s: too many call", __func__);
700 
701 	event_set(&sock->sock_ev, sock->sock_fd,
702 	    EV_READ|EV_PERSIST, cb, sock);
703 
704 	return (0);
705 }
706 
707 void
config_enablesocket(struct iked * env)708 config_enablesocket(struct iked *env)
709 {
710 	struct iked_socket	*sock;
711 	size_t			 i;
712 
713 	for (i = 0; i < nitems(env->sc_sock4); i++)
714 		if ((sock = env->sc_sock4[i]) != NULL)
715 			event_add(&sock->sock_ev, NULL);
716 	for (i = 0; i < nitems(env->sc_sock6); i++)
717 		if ((sock = env->sc_sock6[i]) != NULL)
718 			event_add(&sock->sock_ev, NULL);
719 }
720 
721 int
config_setpfkey(struct iked * env)722 config_setpfkey(struct iked *env)
723 {
724 	int	 s;
725 
726 	if ((s = pfkey_socket(env)) == -1)
727 		return (-1);
728 	proc_compose_imsg(&env->sc_ps, PROC_IKEV2, -1,
729 	    IMSG_PFKEY_SOCKET, -1, s, NULL, 0);
730 	return (0);
731 }
732 
733 int
config_getpfkey(struct iked * env,struct imsg * imsg)734 config_getpfkey(struct iked *env, struct imsg *imsg)
735 {
736 	int fd = imsg_get_fd(imsg);
737 
738 	log_debug("%s: received pfkey fd %d", __func__, fd);
739 	pfkey_init(env, fd);
740 	return (0);
741 }
742 
743 int
config_setuser(struct iked * env,struct iked_user * usr,enum privsep_procid id)744 config_setuser(struct iked *env, struct iked_user *usr, enum privsep_procid id)
745 {
746 	if (env->sc_opts & IKED_OPT_NOACTION) {
747 		print_user(usr);
748 		return (0);
749 	}
750 
751 	proc_compose(&env->sc_ps, id, IMSG_CFG_USER, usr, sizeof(*usr));
752 	return (0);
753 }
754 
755 int
config_getuser(struct iked * env,struct imsg * imsg)756 config_getuser(struct iked *env, struct imsg *imsg)
757 {
758 	struct iked_user	 usr;
759 	int			 ret = -1;
760 
761 	IMSG_SIZE_CHECK(imsg, &usr);
762 	memcpy(&usr, imsg->data, sizeof(usr));
763 
764 	if (config_new_user(env, &usr) != NULL) {
765 		print_user(&usr);
766 		ret = 0;
767 	}
768 
769 	explicit_bzero(&usr, sizeof(usr));
770 	return (ret);
771 }
772 
773 int
config_setpolicy(struct iked * env,struct iked_policy * pol,enum privsep_procid id)774 config_setpolicy(struct iked *env, struct iked_policy *pol,
775     enum privsep_procid id)
776 {
777 	struct iked_proposal	*prop;
778 	struct iked_transform	*xform;
779 	size_t			 iovcnt, j, c = 0;
780 	struct iovec		 iov[IOV_MAX];
781 
782 	iovcnt = 1;
783 	TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) {
784 		iovcnt += prop->prop_nxforms + 1;
785 	}
786 
787 	if (iovcnt > IOV_MAX) {
788 		log_warn("%s: too many proposals", __func__);
789 		return (-1);
790 	}
791 
792 	iov[c].iov_base = pol;
793 	iov[c++].iov_len = sizeof(*pol);
794 
795 	TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) {
796 		iov[c].iov_base = prop;
797 		iov[c++].iov_len = sizeof(*prop);
798 
799 		for (j = 0; j < prop->prop_nxforms; j++) {
800 			xform = prop->prop_xforms + j;
801 
802 			iov[c].iov_base = xform;
803 			iov[c++].iov_len = sizeof(*xform);
804 		}
805 	}
806 
807 	print_policy(pol);
808 
809 	if (env->sc_opts & IKED_OPT_NOACTION)
810 		return (0);
811 
812 	if (proc_composev(&env->sc_ps, id, IMSG_CFG_POLICY, iov,
813 	    iovcnt) == -1) {
814 		log_debug("%s: proc_composev failed", __func__);
815 		return (-1);
816 	}
817 
818 	return (0);
819 }
820 
821 int
config_setflow(struct iked * env,struct iked_policy * pol,enum privsep_procid id)822 config_setflow(struct iked *env, struct iked_policy *pol,
823     enum privsep_procid id)
824 {
825 	struct iked_flow	*flow;
826 	struct iovec		 iov[2];
827 
828 	if (env->sc_opts & IKED_OPT_NOACTION)
829 		return (0);
830 
831 	RB_FOREACH(flow, iked_flows, &pol->pol_flows) {
832 		iov[0].iov_base = &pol->pol_id;
833 		iov[0].iov_len = sizeof(pol->pol_id);
834 		iov[1].iov_base = flow;
835 		iov[1].iov_len = sizeof(*flow);
836 
837 		if (proc_composev(&env->sc_ps, id, IMSG_CFG_FLOW,
838 		    iov, 2) == -1) {
839 			log_debug("%s: proc_composev failed", __func__);
840 			return (-1);
841 		}
842 	}
843 
844 	return (0);
845 }
846 
847 int
config_getpolicy(struct iked * env,struct imsg * imsg)848 config_getpolicy(struct iked *env, struct imsg *imsg)
849 {
850 	struct iked_policy	*pol;
851 	struct iked_proposal	 pp, *prop;
852 	struct iked_transform	 xf;
853 	off_t			 offset = 0;
854 	unsigned int		 i, j;
855 	uint8_t			*buf = (uint8_t *)imsg->data;
856 
857 	IMSG_SIZE_CHECK(imsg, pol);
858 	log_debug("%s: received policy", __func__);
859 
860 	if ((pol = config_new_policy(NULL)) == NULL)
861 		fatal("config_getpolicy: new policy");
862 
863 	memcpy(pol, buf, sizeof(*pol));
864 	offset += sizeof(*pol);
865 
866 	TAILQ_INIT(&pol->pol_tssrc);
867 	TAILQ_INIT(&pol->pol_tsdst);
868 	TAILQ_INIT(&pol->pol_proposals);
869 	TAILQ_INIT(&pol->pol_sapeers);
870 	RB_INIT(&pol->pol_flows);
871 
872 	for (i = 0; i < pol->pol_nproposals; i++) {
873 		memcpy(&pp, buf + offset, sizeof(pp));
874 		offset += sizeof(pp);
875 
876 		if ((prop = config_add_proposal(&pol->pol_proposals,
877 		    pp.prop_id, pp.prop_protoid)) == NULL)
878 			fatal("config_getpolicy: add proposal");
879 
880 		for (j = 0; j < pp.prop_nxforms; j++) {
881 			memcpy(&xf, buf + offset, sizeof(xf));
882 			offset += sizeof(xf);
883 
884 			if (config_add_transform(prop, xf.xform_type,
885 			    xf.xform_id, xf.xform_length,
886 			    xf.xform_keylength) != 0)
887 				fatal("config_getpolicy: add transform");
888 		}
889 	}
890 
891 	/* Flows are sent separately */
892 	pol->pol_nflows = 0;
893 
894 	TAILQ_INSERT_TAIL(&env->sc_policies, pol, pol_entry);
895 
896 	if (pol->pol_flags & IKED_POLICY_DEFAULT) {
897 		/* Only one default policy, just free/unref the old one */
898 		if (env->sc_defaultcon != NULL)
899 			config_free_policy(env, env->sc_defaultcon);
900 		env->sc_defaultcon = pol;
901 	}
902 
903 	return (0);
904 }
905 
906 int
config_getflow(struct iked * env,struct imsg * imsg)907 config_getflow(struct iked *env, struct imsg *imsg)
908 {
909 	struct iked_policy	*pol;
910 	struct iked_flow	*flow;
911 	off_t			 offset = 0;
912 	unsigned int		 id;
913 	uint8_t			*buf = (uint8_t *)imsg->data;
914 
915 	if (IMSG_DATA_SIZE(imsg) < sizeof(id))
916 		fatalx("bad length imsg received");
917 
918 	memcpy(&id, buf, sizeof(id));
919 	offset += sizeof(id);
920 
921 	TAILQ_FOREACH(pol, &env->sc_policies, pol_entry) {
922 		if (pol->pol_id == id)
923 			break;
924 	}
925 	if (pol == NULL) {
926 		log_warnx("%s: unknown policy %u", __func__, id);
927 		return (-1);
928 	}
929 
930 	if ((flow = calloc(1, sizeof(*flow))) == NULL)
931 		fatal("config_getpolicy: new flow");
932 
933 	memcpy(flow, buf + offset, sizeof(*flow));
934 
935 	if (RB_INSERT(iked_flows, &pol->pol_flows, flow)) {
936 		log_warnx("%s: received duplicate flow", __func__);
937 		free(flow);
938 		return (-1);
939 	}
940 	pol->pol_nflows++;
941 
942 	return (0);
943 }
944 
945 int
config_setcompile(struct iked * env,enum privsep_procid id)946 config_setcompile(struct iked *env, enum privsep_procid id)
947 {
948 	if (env->sc_opts & IKED_OPT_NOACTION)
949 		return (0);
950 
951 	proc_compose(&env->sc_ps, id, IMSG_COMPILE, NULL, 0);
952 	return (0);
953 }
954 
955 int
config_getcompile(struct iked * env)956 config_getcompile(struct iked *env)
957 {
958 	/*
959 	 * Do any necessary steps after configuration, for now we
960 	 * only need to compile the skip steps.
961 	 */
962 	policy_calc_skip_steps(&env->sc_policies);
963 
964 	log_debug("%s: compilation done", __func__);
965 	return (0);
966 }
967 
968 int
config_setstatic(struct iked * env)969 config_setstatic(struct iked *env)
970 {
971 	proc_compose(&env->sc_ps, PROC_IKEV2, IMSG_CTL_STATIC,
972 	    &env->sc_static, sizeof(env->sc_static));
973 	proc_compose(&env->sc_ps, PROC_CERT, IMSG_CTL_STATIC,
974 	    &env->sc_static, sizeof(env->sc_static));
975 	return (0);
976 }
977 
978 int
config_getstatic(struct iked * env,struct imsg * imsg)979 config_getstatic(struct iked *env, struct imsg *imsg)
980 {
981 	IMSG_SIZE_CHECK(imsg, &env->sc_static);
982 	memcpy(&env->sc_static, imsg->data, sizeof(env->sc_static));
983 
984 	log_debug("%s: dpd_check_interval %llu", __func__, env->sc_alive_timeout);
985 	log_debug("%s: %senforcesingleikesa", __func__,
986 	    env->sc_enforcesingleikesa ? "" : "no ");
987 	log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no ");
988 	log_debug("%s: %smobike", __func__, env->sc_mobike ? "" : "no ");
989 	log_debug("%s: nattport %u", __func__, env->sc_nattport);
990 	log_debug("%s: %sstickyaddress", __func__,
991 	    env->sc_stickyaddress ? "" : "no ");
992 
993 	ikev2_reset_alive_timer(env);
994 
995 	return (0);
996 }
997 
998 int
config_setocsp(struct iked * env)999 config_setocsp(struct iked *env)
1000 {
1001 	struct iovec		 iov[3];
1002 	int			 iovcnt = 0;
1003 
1004 	if (env->sc_opts & IKED_OPT_NOACTION)
1005 		return (0);
1006 
1007 	iov[0].iov_base = &env->sc_ocsp_tolerate;
1008 	iov[0].iov_len = sizeof(env->sc_ocsp_tolerate);
1009 	iovcnt++;
1010 	iov[1].iov_base = &env->sc_ocsp_maxage;
1011 	iov[1].iov_len = sizeof(env->sc_ocsp_maxage);
1012 	iovcnt++;
1013 	if (env->sc_ocsp_url) {
1014 		iov[2].iov_base = env->sc_ocsp_url;
1015 		iov[2].iov_len = strlen(env->sc_ocsp_url);
1016 		iovcnt++;
1017 	}
1018 	return (proc_composev(&env->sc_ps, PROC_CERT, IMSG_OCSP_CFG,
1019 	    iov, iovcnt));
1020 }
1021 
1022 int
config_getocsp(struct iked * env,struct imsg * imsg)1023 config_getocsp(struct iked *env, struct imsg *imsg)
1024 {
1025 	size_t		 have, need;
1026 	uint8_t		*ptr;
1027 
1028 	free(env->sc_ocsp_url);
1029 	ptr = (uint8_t *)imsg->data;
1030 	have = IMSG_DATA_SIZE(imsg);
1031 
1032 	/* get tolerate */
1033 	need = sizeof(env->sc_ocsp_tolerate);
1034 	if (have < need)
1035 		fatalx("bad 'tolerate' length imsg received");
1036 	memcpy(&env->sc_ocsp_tolerate, ptr, need);
1037 	ptr += need;
1038 	have -= need;
1039 
1040 	/* get maxage */
1041 	need = sizeof(env->sc_ocsp_maxage);
1042 	if (have < need)
1043 		fatalx("bad 'maxage' length imsg received");
1044 	memcpy(&env->sc_ocsp_maxage, ptr, need);
1045 	ptr += need;
1046 	have -= need;
1047 
1048 	/* get url */
1049 	if (have > 0)
1050 		env->sc_ocsp_url = get_string(ptr, have);
1051 	else
1052 		env->sc_ocsp_url = NULL;
1053 	log_debug("%s: ocsp_url %s tolerate %ld maxage %ld", __func__,
1054 	    env->sc_ocsp_url ? env->sc_ocsp_url : "none",
1055 	    env->sc_ocsp_tolerate, env->sc_ocsp_maxage);
1056 	return (0);
1057 }
1058 
1059 int
config_setkeys(struct iked * env)1060 config_setkeys(struct iked *env)
1061 {
1062 	FILE			*fp = NULL;
1063 	EVP_PKEY		*key = NULL;
1064 	struct iked_id		 privkey;
1065 	struct iked_id		 pubkey;
1066 	struct iovec		 iov[2];
1067 	int			 ret = -1;
1068 
1069 	memset(&privkey, 0, sizeof(privkey));
1070 	memset(&pubkey, 0, sizeof(pubkey));
1071 
1072 	/* Read private key */
1073 	if ((fp = fopen(IKED_PRIVKEY, "r")) == NULL) {
1074 		log_warn("%s: failed to open private key", __func__);
1075 		goto done;
1076 	}
1077 
1078 	if ((key = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) {
1079 		log_warnx("%s: failed to read private key", __func__);
1080 		goto done;
1081 	}
1082 
1083 	if (ca_privkey_serialize(key, &privkey) != 0) {
1084 		log_warnx("%s: failed to serialize private key", __func__);
1085 		goto done;
1086 	}
1087 	if (ca_pubkey_serialize(key, &pubkey) != 0) {
1088 		log_warnx("%s: failed to serialize public key", __func__);
1089 		goto done;
1090 	}
1091 
1092 	iov[0].iov_base = &privkey;
1093 	iov[0].iov_len = sizeof(privkey);
1094 	iov[1].iov_base = ibuf_data(privkey.id_buf);
1095 	iov[1].iov_len = ibuf_size(privkey.id_buf);
1096 
1097 	if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PRIVKEY, iov, 2) == -1) {
1098 		log_warnx("%s: failed to send private key", __func__);
1099 		goto done;
1100 	}
1101 
1102 	iov[0].iov_base = &pubkey;
1103 	iov[0].iov_len = sizeof(pubkey);
1104 	iov[1].iov_base = ibuf_data(pubkey.id_buf);
1105 	iov[1].iov_len = ibuf_size(pubkey.id_buf);
1106 
1107 	if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PUBKEY, iov, 2) == -1) {
1108 		log_warnx("%s: failed to send public key", __func__);
1109 		goto done;
1110 	}
1111 
1112 	ret = 0;
1113  done:
1114 	if (fp != NULL)
1115 		fclose(fp);
1116 
1117 	ibuf_free(pubkey.id_buf);
1118 	ibuf_free(privkey.id_buf);
1119 	EVP_PKEY_free(key);
1120 
1121 	return (ret);
1122 }
1123 
1124 int
config_getkey(struct iked * env,struct imsg * imsg)1125 config_getkey(struct iked *env, struct imsg *imsg)
1126 {
1127 	size_t		 len;
1128 	struct iked_id	 id;
1129 
1130 	len = IMSG_DATA_SIZE(imsg);
1131 	if (len <= sizeof(id))
1132 		fatalx("%s: invalid key message", __func__);
1133 
1134 	memcpy(&id, imsg->data, sizeof(id));
1135 	if ((id.id_buf = ibuf_new((uint8_t *)imsg->data + sizeof(id),
1136 	    len - sizeof(id))) == NULL)
1137 		fatalx("%s: failed to get key", __func__);
1138 
1139 	explicit_bzero(imsg->data, len);
1140 	ca_getkey(&env->sc_ps, &id, imsg->hdr.type);
1141 
1142 	return (0);
1143 }
1144 
1145 int
config_setradauth(struct iked * env)1146 config_setradauth(struct iked *env)
1147 {
1148 	proc_compose(&env->sc_ps, PROC_IKEV2, IMSG_CFG_RADAUTH,
1149 	    &env->sc_radauth, sizeof(env->sc_radauth));
1150 	return (0);
1151 }
1152 
1153 int
config_getradauth(struct iked * env,struct imsg * imsg)1154 config_getradauth(struct iked *env, struct imsg *imsg)
1155 {
1156 	if (IMSG_DATA_SIZE(imsg) < sizeof(struct iked_radopts))
1157 		fatalx("%s: invalid radauth message", __func__);
1158 
1159 	memcpy(&env->sc_radauth, imsg->data, sizeof(struct iked_radopts));
1160 
1161 	return (0);
1162 }
1163 
1164 int
config_setradacct(struct iked * env)1165 config_setradacct(struct iked *env)
1166 {
1167 	proc_compose(&env->sc_ps, PROC_IKEV2, IMSG_CFG_RADACCT,
1168 	    &env->sc_radacct, sizeof(env->sc_radacct));
1169 	return (0);
1170 }
1171 
1172 int
config_getradacct(struct iked * env,struct imsg * imsg)1173 config_getradacct(struct iked *env, struct imsg *imsg)
1174 {
1175 	if (IMSG_DATA_SIZE(imsg) < sizeof(struct iked_radopts))
1176 		fatalx("%s: invalid radacct message", __func__);
1177 
1178 	memcpy(&env->sc_radacct, imsg->data, sizeof(struct iked_radopts));
1179 
1180 	return (0);
1181 }
1182 
1183 int
config_setradserver(struct iked * env,struct sockaddr * sa,socklen_t salen,char * secret,int isaccounting)1184 config_setradserver(struct iked *env, struct sockaddr *sa, socklen_t salen,
1185     char *secret, int isaccounting)
1186 {
1187 	int			 sock = -1;
1188 	struct iovec		 iov[2];
1189 	struct iked_radserver	 server;
1190 
1191 	if (env->sc_opts & IKED_OPT_NOACTION)
1192 		return (0);
1193 	memset(&server, 0, sizeof(server));
1194 	memcpy(&server.rs_sockaddr, sa, salen);
1195 	server.rs_accounting = isaccounting;
1196 	if ((sock = socket(sa->sa_family, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
1197 		log_warn("%s: socket() failed", __func__);
1198 		goto error;
1199 	}
1200 	if (connect(sock, sa, salen) == -1) {
1201 		log_warn("%s: connect() failed", __func__);
1202 		goto error;
1203 	}
1204 	iov[0].iov_base = &server;
1205 	iov[0].iov_len = offsetof(struct iked_radserver, rs_secret[0]);
1206 	iov[1].iov_base = secret;
1207 	iov[1].iov_len = strlen(secret) + 1;
1208 
1209 	proc_composev_imsg(&env->sc_ps, PROC_IKEV2, -1, IMSG_CFG_RADSERVER, -1,
1210 	    sock, iov, 2);
1211 
1212 	return (0);
1213  error:
1214 	if (sock >= 0)
1215 		close(sock);
1216 	return (-1);
1217 }
1218 
1219 int
config_getradserver(struct iked * env,struct imsg * imsg)1220 config_getradserver(struct iked *env, struct imsg *imsg)
1221 {
1222 	size_t			 len;
1223 	struct iked_radserver	*server;
1224 
1225 	len = IMSG_DATA_SIZE(imsg);
1226 	if (len <= sizeof(*server))
1227 		fatalx("%s: invalid IMSG_CFG_RADSERVER message", __func__);
1228 
1229 	if ((server = calloc(1, len)) == NULL) {
1230 		log_warn("%s: calloc() failed", __func__);
1231 		return (-1);
1232 	}
1233 	memcpy(server, imsg->data, len);
1234 	explicit_bzero(imsg->data, len);
1235 	TAILQ_INIT(&server->rs_reqs);
1236 	server->rs_sock = imsg_get_fd(imsg);
1237 	server->rs_env = env;
1238 
1239 	if (!server->rs_accounting)
1240 		TAILQ_INSERT_TAIL(&env->sc_radauthservers, server, rs_entry);
1241 	else
1242 		TAILQ_INSERT_TAIL(&env->sc_radacctservers, server, rs_entry);
1243 	event_set(&server->rs_ev, server->rs_sock, EV_READ | EV_PERSIST,
1244 	    iked_radius_on_event, server);
1245 	event_add(&server->rs_ev, NULL);
1246 
1247 	return (0);
1248 }
1249 
1250 int
config_setradcfgmap(struct iked * env,int cfg_type,uint32_t vendor_id,uint8_t attr_type)1251 config_setradcfgmap(struct iked *env, int cfg_type, uint32_t vendor_id,
1252     uint8_t attr_type)
1253 {
1254 	struct iked_radcfgmap cfgmap;
1255 
1256 	if (env->sc_opts & IKED_OPT_NOACTION)
1257 		return (0);
1258 	memset(&cfgmap, 0, sizeof(cfgmap));
1259 	cfgmap.cfg_type = cfg_type;
1260 	cfgmap.vendor_id = vendor_id;
1261 	cfgmap.attr_type = attr_type;
1262 
1263 	proc_compose_imsg(&env->sc_ps, PROC_IKEV2, -1, IMSG_CFG_RADCFGMAP, -1,
1264 	    -1, &cfgmap, sizeof(cfgmap));
1265 
1266 	return (0);
1267 }
1268 
1269 int
config_getradcfgmap(struct iked * env,struct imsg * imsg)1270 config_getradcfgmap(struct iked *env, struct imsg *imsg)
1271 {
1272 	int			 i;
1273 	size_t			 len;
1274 	struct iked_radcfgmap	*cfgmap, *cfgmap0;
1275 	struct iked_radcfgmaps	 cfgmaps = TAILQ_HEAD_INITIALIZER(cfgmaps);
1276 
1277 	len = IMSG_DATA_SIZE(imsg);
1278 	if (len < sizeof(*cfgmap))
1279 		fatalx("%s: invalid IMSG_CFG_RADCFGMAP message", __func__);
1280 
1281 	if (TAILQ_EMPTY(&env->sc_radcfgmaps)) {
1282 		/* no customized config map yet */
1283 		for (i = 0; radius_cfgmaps[i].cfg_type != 0; i++) {
1284 			if ((cfgmap = calloc(1, len)) == NULL) {
1285 				while ((cfgmap = TAILQ_FIRST(&cfgmaps))
1286 				    != NULL) {
1287 					TAILQ_REMOVE(&cfgmaps, cfgmap, entry);
1288 					free(cfgmap);
1289 				}
1290 				return (-1);
1291 			}
1292 			*cfgmap = radius_cfgmaps[i];
1293 			TAILQ_INSERT_TAIL(&cfgmaps, cfgmap, entry);
1294 		}
1295 		TAILQ_CONCAT(&env->sc_radcfgmaps, &cfgmaps, entry);
1296 	}
1297 
1298 	cfgmap0 = (struct iked_radcfgmap *)imsg->data;
1299 	TAILQ_FOREACH(cfgmap, &env->sc_radcfgmaps, entry) {
1300 		if (cfgmap->vendor_id == cfgmap0->vendor_id &&
1301 		    cfgmap->attr_type == cfgmap0->attr_type) {
1302 			/* override existing config map */
1303 			cfgmap->cfg_type = cfgmap0->cfg_type;
1304 			break;
1305 		}
1306 	}
1307 	if (cfgmap == NULL) {
1308 		if ((cfgmap = calloc(1, len)) == NULL) {
1309 			log_warn("%s: calloc() failed", __func__);
1310 			return (-1);
1311 		}
1312 		memcpy(cfgmap, imsg->data, len);
1313 		TAILQ_INSERT_TAIL(&env->sc_radcfgmaps, cfgmap, entry);
1314 	}
1315 	return (0);
1316 }
1317 
1318 int
config_setraddae(struct iked * env,struct sockaddr * sa,socklen_t salen)1319 config_setraddae(struct iked *env, struct sockaddr *sa, socklen_t salen)
1320 {
1321 	int			 sock, on;
1322 	struct iked_raddae	 dae;
1323 
1324 	if (env->sc_opts & IKED_OPT_NOACTION)
1325 		return (0);
1326 	memset(&dae, 0, sizeof(dae));
1327 	memcpy(&dae.rd_sockaddr, sa, salen);
1328 	if ((sock = socket(sa->sa_family, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
1329 		log_warn("%s: socket() failed", __func__);
1330 		goto error;
1331 	}
1332 	on = 1;
1333 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
1334 		log_warn("%s: setsockopt(,,SO_REUSEADDR) failed", __func__);
1335 	/* REUSEPORT is needed because the old sockets may not be closed yet */
1336 	on = 1;
1337 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) == -1)
1338 		log_warn("%s: setsockopt(,,SO_REUSEPORT) failed", __func__);
1339 	if (bind(sock, sa, salen) == -1) {
1340 		log_warn("%s: bind() failed", __func__);
1341 		goto error;
1342 	}
1343 
1344 	proc_compose_imsg(&env->sc_ps, PROC_IKEV2, -1, IMSG_CFG_RADDAE, -1,
1345 	    sock, &dae, sizeof(dae));
1346 
1347 	return (0);
1348  error:
1349 	if (sock >= 0)
1350 		close(sock);
1351 	return (-1);
1352 }
1353 
1354 int
config_getraddae(struct iked * env,struct imsg * imsg)1355 config_getraddae(struct iked *env, struct imsg *imsg)
1356 {
1357 	struct iked_raddae	*dae;
1358 
1359 	if (IMSG_DATA_SIZE(imsg) < sizeof(*dae))
1360 		fatalx("%s: invalid IMSG_CFG_RADDAE message", __func__);
1361 
1362 	if ((dae = calloc(1, sizeof(*dae))) == NULL) {
1363 		log_warn("%s: calloc() failed", __func__);
1364 		return (-1);
1365 	}
1366 	memcpy(dae, imsg->data, sizeof(*dae));
1367 	dae->rd_sock = imsg_get_fd(imsg);
1368 	dae->rd_env = env;
1369 
1370 	event_set(&dae->rd_ev, dae->rd_sock, EV_READ | EV_PERSIST,
1371 	    iked_radius_dae_on_event, dae);
1372 	event_add(&dae->rd_ev, NULL);
1373 
1374 	TAILQ_INSERT_TAIL(&env->sc_raddaes, dae, rd_entry);
1375 
1376 	return (0);
1377 }
1378 
1379 int
config_setradclient(struct iked * env,struct sockaddr * sa,socklen_t salen,char * secret)1380 config_setradclient(struct iked *env, struct sockaddr *sa, socklen_t salen,
1381     char *secret)
1382 {
1383 	struct iovec		 iov[2];
1384 	struct iked_radclient	 client;
1385 
1386 	if (salen > sizeof(client.rc_sockaddr))
1387 		fatal("%s: invalid salen", __func__);
1388 
1389 	memcpy(&client.rc_sockaddr, sa, salen);
1390 
1391 	iov[0].iov_base = &client;
1392 	iov[0].iov_len = offsetof(struct iked_radclient, rc_secret[0]);
1393 	iov[1].iov_base = secret;
1394 	iov[1].iov_len = strlen(secret);
1395 
1396 	proc_composev_imsg(&env->sc_ps, PROC_IKEV2, -1, IMSG_CFG_RADDAECLIENT,
1397 	    -1, -1, iov, 2);
1398 
1399 	return (0);
1400 }
1401 
1402 int
config_getradclient(struct iked * env,struct imsg * imsg)1403 config_getradclient(struct iked *env, struct imsg *imsg)
1404 {
1405 	struct iked_radclient	*client;
1406 	u_int			 len;
1407 
1408 	len = IMSG_DATA_SIZE(imsg);
1409 
1410 	if (len < sizeof(*client))
1411 		fatalx("%s: invalid IMSG_CFG_RADDAE message", __func__);
1412 
1413 	if ((client = calloc(1, len + 1)) == NULL) {
1414 		log_warn("%s: calloc() failed", __func__);
1415 		return (-1);
1416 	}
1417 	memcpy(client, imsg->data, len);
1418 
1419 	TAILQ_INSERT_TAIL(&env->sc_raddaeclients, client, rc_entry);
1420 
1421 	return (0);
1422 }
1423