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