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