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