1 /* $OpenBSD: config.c,v 1.92 2023/05/23 13:12:19 claudio 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 ikestat_inc(env, ikes_sa_created); 64 return (sa); 65 } 66 67 uint64_t 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 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 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 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 * 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 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 * 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 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 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 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 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 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 * 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 * 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 * 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 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 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 506 config_setmode(struct iked *env, unsigned int passive) 507 { 508 unsigned int type; 509 510 type = passive ? IMSG_CTL_PASSIVE : IMSG_CTL_ACTIVE; 511 proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0); 512 513 return (0); 514 } 515 516 int 517 config_getmode(struct iked *env, unsigned int type) 518 { 519 uint8_t old; 520 unsigned char *mode[] = { "active", "passive" }; 521 522 old = env->sc_passive ? 1 : 0; 523 env->sc_passive = type == IMSG_CTL_PASSIVE ? 1 : 0; 524 525 if (old == env->sc_passive) 526 return (0); 527 528 log_debug("%s: mode %s -> %s", __func__, 529 mode[old], mode[env->sc_passive]); 530 531 return (0); 532 } 533 534 int 535 config_setreset(struct iked *env, unsigned int mode, enum privsep_procid id) 536 { 537 proc_compose(&env->sc_ps, id, IMSG_CTL_RESET, &mode, sizeof(mode)); 538 return (0); 539 } 540 541 int 542 config_getreset(struct iked *env, struct imsg *imsg) 543 { 544 unsigned int mode; 545 546 IMSG_SIZE_CHECK(imsg, &mode); 547 memcpy(&mode, imsg->data, sizeof(mode)); 548 549 return (config_doreset(env, mode)); 550 } 551 552 int 553 config_doreset(struct iked *env, unsigned int mode) 554 { 555 struct iked_policy *pol, *poltmp; 556 struct iked_sa *sa; 557 struct iked_user *usr; 558 559 if (mode == RESET_ALL || mode == RESET_POLICY) { 560 log_debug("%s: flushing policies", __func__); 561 TAILQ_FOREACH_SAFE(pol, &env->sc_policies, pol_entry, poltmp) { 562 config_free_policy(env, pol); 563 } 564 } 565 566 if (mode == RESET_ALL || mode == RESET_SA) { 567 log_debug("%s: flushing SAs", __func__); 568 while ((sa = RB_MIN(iked_sas, &env->sc_sas))) { 569 /* for RESET_SA we try send a DELETE */ 570 if (mode == RESET_ALL || 571 ikev2_ike_sa_delete(env, sa) != 0) { 572 RB_REMOVE(iked_sas, &env->sc_sas, sa); 573 if (sa->sa_dstid_entry_valid) 574 sa_dstid_remove(env, sa); 575 config_free_sa(env, sa); 576 } 577 } 578 } 579 580 if (mode == RESET_ALL || mode == RESET_USER) { 581 log_debug("%s: flushing users", __func__); 582 while ((usr = RB_MIN(iked_users, &env->sc_users))) { 583 RB_REMOVE(iked_users, &env->sc_users, usr); 584 free(usr); 585 } 586 } 587 588 return (0); 589 } 590 591 /* 592 * The first call of this function sets the UDP socket for IKEv2. 593 * The second call is optional, setting the UDP socket used for NAT-T. 594 */ 595 int 596 config_setsocket(struct iked *env, struct sockaddr_storage *ss, 597 in_port_t port, enum privsep_procid id) 598 { 599 int s; 600 601 if ((s = udp_bind((struct sockaddr *)ss, port)) == -1) 602 return (-1); 603 proc_compose_imsg(&env->sc_ps, id, -1, 604 IMSG_UDP_SOCKET, -1, s, ss, sizeof(*ss)); 605 return (0); 606 } 607 608 int 609 config_getsocket(struct iked *env, struct imsg *imsg, 610 void (*cb)(int, short, void *)) 611 { 612 struct iked_socket *sock, **sock0 = NULL, **sock1 = NULL; 613 614 log_debug("%s: received socket fd %d", __func__, imsg->fd); 615 616 if ((sock = calloc(1, sizeof(*sock))) == NULL) 617 fatal("config_getsocket: calloc"); 618 619 IMSG_SIZE_CHECK(imsg, &sock->sock_addr); 620 621 memcpy(&sock->sock_addr, imsg->data, sizeof(sock->sock_addr)); 622 sock->sock_fd = imsg->fd; 623 sock->sock_env = env; 624 625 switch (sock->sock_addr.ss_family) { 626 case AF_INET: 627 sock0 = &env->sc_sock4[0]; 628 sock1 = &env->sc_sock4[1]; 629 break; 630 case AF_INET6: 631 sock0 = &env->sc_sock6[0]; 632 sock1 = &env->sc_sock6[1]; 633 break; 634 default: 635 fatal("config_getsocket: socket af: %u", 636 sock->sock_addr.ss_family); 637 /* NOTREACHED */ 638 } 639 if (*sock0 == NULL) 640 *sock0 = sock; 641 else if (*sock1 == NULL) 642 *sock1 = sock; 643 else 644 fatalx("%s: too many call", __func__); 645 646 event_set(&sock->sock_ev, sock->sock_fd, 647 EV_READ|EV_PERSIST, cb, sock); 648 event_add(&sock->sock_ev, NULL); 649 650 return (0); 651 } 652 653 int 654 config_setpfkey(struct iked *env) 655 { 656 int s; 657 658 if ((s = pfkey_socket(env)) == -1) 659 return (-1); 660 proc_compose_imsg(&env->sc_ps, PROC_IKEV2, -1, 661 IMSG_PFKEY_SOCKET, -1, s, NULL, 0); 662 return (0); 663 } 664 665 int 666 config_getpfkey(struct iked *env, struct imsg *imsg) 667 { 668 log_debug("%s: received pfkey fd %d", __func__, imsg->fd); 669 pfkey_init(env, imsg->fd); 670 return (0); 671 } 672 673 int 674 config_setuser(struct iked *env, struct iked_user *usr, enum privsep_procid id) 675 { 676 if (env->sc_opts & IKED_OPT_NOACTION) { 677 print_user(usr); 678 return (0); 679 } 680 681 proc_compose(&env->sc_ps, id, IMSG_CFG_USER, usr, sizeof(*usr)); 682 return (0); 683 } 684 685 int 686 config_getuser(struct iked *env, struct imsg *imsg) 687 { 688 struct iked_user usr; 689 int ret = -1; 690 691 IMSG_SIZE_CHECK(imsg, &usr); 692 memcpy(&usr, imsg->data, sizeof(usr)); 693 694 if (config_new_user(env, &usr) != NULL) { 695 print_user(&usr); 696 ret = 0; 697 } 698 699 explicit_bzero(&usr, sizeof(usr)); 700 return (ret); 701 } 702 703 int 704 config_setpolicy(struct iked *env, struct iked_policy *pol, 705 enum privsep_procid id) 706 { 707 struct iked_proposal *prop; 708 struct iked_transform *xform; 709 size_t iovcnt, j, c = 0; 710 struct iovec iov[IOV_MAX]; 711 712 iovcnt = 1; 713 TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) { 714 iovcnt += prop->prop_nxforms + 1; 715 } 716 717 if (iovcnt > IOV_MAX) { 718 log_warn("%s: too many proposals", __func__); 719 return (-1); 720 } 721 722 iov[c].iov_base = pol; 723 iov[c++].iov_len = sizeof(*pol); 724 725 TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) { 726 iov[c].iov_base = prop; 727 iov[c++].iov_len = sizeof(*prop); 728 729 for (j = 0; j < prop->prop_nxforms; j++) { 730 xform = prop->prop_xforms + j; 731 732 iov[c].iov_base = xform; 733 iov[c++].iov_len = sizeof(*xform); 734 } 735 } 736 737 print_policy(pol); 738 739 if (env->sc_opts & IKED_OPT_NOACTION) 740 return (0); 741 742 if (proc_composev(&env->sc_ps, id, IMSG_CFG_POLICY, iov, 743 iovcnt) == -1) { 744 log_debug("%s: proc_composev failed", __func__); 745 return (-1); 746 } 747 748 return (0); 749 } 750 751 int 752 config_setflow(struct iked *env, struct iked_policy *pol, 753 enum privsep_procid id) 754 { 755 struct iked_flow *flow; 756 struct iovec iov[2]; 757 758 if (env->sc_opts & IKED_OPT_NOACTION) 759 return (0); 760 761 RB_FOREACH(flow, iked_flows, &pol->pol_flows) { 762 iov[0].iov_base = &pol->pol_id; 763 iov[0].iov_len = sizeof(pol->pol_id); 764 iov[1].iov_base = flow; 765 iov[1].iov_len = sizeof(*flow); 766 767 if (proc_composev(&env->sc_ps, id, IMSG_CFG_FLOW, 768 iov, 2) == -1) { 769 log_debug("%s: proc_composev failed", __func__); 770 return (-1); 771 } 772 } 773 774 return (0); 775 } 776 777 int 778 config_getpolicy(struct iked *env, struct imsg *imsg) 779 { 780 struct iked_policy *pol; 781 struct iked_proposal pp, *prop; 782 struct iked_transform xf; 783 off_t offset = 0; 784 unsigned int i, j; 785 uint8_t *buf = (uint8_t *)imsg->data; 786 787 IMSG_SIZE_CHECK(imsg, pol); 788 log_debug("%s: received policy", __func__); 789 790 if ((pol = config_new_policy(NULL)) == NULL) 791 fatal("config_getpolicy: new policy"); 792 793 memcpy(pol, buf, sizeof(*pol)); 794 offset += sizeof(*pol); 795 796 TAILQ_INIT(&pol->pol_tssrc); 797 TAILQ_INIT(&pol->pol_tsdst); 798 TAILQ_INIT(&pol->pol_proposals); 799 TAILQ_INIT(&pol->pol_sapeers); 800 RB_INIT(&pol->pol_flows); 801 802 for (i = 0; i < pol->pol_nproposals; i++) { 803 memcpy(&pp, buf + offset, sizeof(pp)); 804 offset += sizeof(pp); 805 806 if ((prop = config_add_proposal(&pol->pol_proposals, 807 pp.prop_id, pp.prop_protoid)) == NULL) 808 fatal("config_getpolicy: add proposal"); 809 810 for (j = 0; j < pp.prop_nxforms; j++) { 811 memcpy(&xf, buf + offset, sizeof(xf)); 812 offset += sizeof(xf); 813 814 if (config_add_transform(prop, xf.xform_type, 815 xf.xform_id, xf.xform_length, 816 xf.xform_keylength) != 0) 817 fatal("config_getpolicy: add transform"); 818 } 819 } 820 821 /* Flows are sent separately */ 822 pol->pol_nflows = 0; 823 824 TAILQ_INSERT_TAIL(&env->sc_policies, pol, pol_entry); 825 826 if (pol->pol_flags & IKED_POLICY_DEFAULT) { 827 /* Only one default policy, just free/unref the old one */ 828 if (env->sc_defaultcon != NULL) 829 config_free_policy(env, env->sc_defaultcon); 830 env->sc_defaultcon = pol; 831 } 832 833 return (0); 834 } 835 836 int 837 config_getflow(struct iked *env, struct imsg *imsg) 838 { 839 struct iked_policy *pol; 840 struct iked_flow *flow; 841 off_t offset = 0; 842 unsigned int id; 843 uint8_t *buf = (uint8_t *)imsg->data; 844 845 if (IMSG_DATA_SIZE(imsg) < sizeof(id)) 846 fatalx("bad length imsg received"); 847 848 memcpy(&id, buf, sizeof(id)); 849 offset += sizeof(id); 850 851 TAILQ_FOREACH(pol, &env->sc_policies, pol_entry) { 852 if (pol->pol_id == id) 853 break; 854 } 855 if (pol == NULL) { 856 log_warnx("%s: unknown policy %u", __func__, id); 857 return (-1); 858 } 859 860 if ((flow = calloc(1, sizeof(*flow))) == NULL) 861 fatal("config_getpolicy: new flow"); 862 863 memcpy(flow, buf + offset, sizeof(*flow)); 864 865 if (RB_INSERT(iked_flows, &pol->pol_flows, flow)) { 866 log_warnx("%s: received duplicate flow", __func__); 867 free(flow); 868 return (-1); 869 } 870 pol->pol_nflows++; 871 872 return (0); 873 } 874 875 int 876 config_setcompile(struct iked *env, enum privsep_procid id) 877 { 878 if (env->sc_opts & IKED_OPT_NOACTION) 879 return (0); 880 881 proc_compose(&env->sc_ps, id, IMSG_COMPILE, NULL, 0); 882 return (0); 883 } 884 885 int 886 config_getcompile(struct iked *env) 887 { 888 /* 889 * Do any necessary steps after configuration, for now we 890 * only need to compile the skip steps. 891 */ 892 policy_calc_skip_steps(&env->sc_policies); 893 894 log_debug("%s: compilation done", __func__); 895 return (0); 896 } 897 898 int 899 config_setstatic(struct iked *env) 900 { 901 proc_compose(&env->sc_ps, PROC_IKEV2, IMSG_CTL_STATIC, 902 &env->sc_static, sizeof(env->sc_static)); 903 return (0); 904 } 905 906 int 907 config_getstatic(struct iked *env, struct imsg *imsg) 908 { 909 IMSG_SIZE_CHECK(imsg, &env->sc_static); 910 memcpy(&env->sc_static, imsg->data, sizeof(env->sc_static)); 911 912 log_debug("%s: dpd_check_interval %llu", __func__, env->sc_alive_timeout); 913 log_debug("%s: %senforcesingleikesa", __func__, 914 env->sc_enforcesingleikesa ? "" : "no "); 915 log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no "); 916 log_debug("%s: %smobike", __func__, env->sc_mobike ? "" : "no "); 917 log_debug("%s: nattport %u", __func__, env->sc_nattport); 918 log_debug("%s: %sstickyaddress", __func__, 919 env->sc_stickyaddress ? "" : "no "); 920 921 ikev2_reset_alive_timer(env); 922 923 return (0); 924 } 925 926 int 927 config_setocsp(struct iked *env) 928 { 929 struct iovec iov[3]; 930 int iovcnt = 0; 931 932 if (env->sc_opts & IKED_OPT_NOACTION) 933 return (0); 934 935 iov[0].iov_base = &env->sc_ocsp_tolerate; 936 iov[0].iov_len = sizeof(env->sc_ocsp_tolerate); 937 iovcnt++; 938 iov[1].iov_base = &env->sc_ocsp_maxage; 939 iov[1].iov_len = sizeof(env->sc_ocsp_maxage); 940 iovcnt++; 941 if (env->sc_ocsp_url) { 942 iov[2].iov_base = env->sc_ocsp_url; 943 iov[2].iov_len = strlen(env->sc_ocsp_url); 944 iovcnt++; 945 } 946 return (proc_composev(&env->sc_ps, PROC_CERT, IMSG_OCSP_CFG, 947 iov, iovcnt)); 948 } 949 950 int 951 config_getocsp(struct iked *env, struct imsg *imsg) 952 { 953 size_t have, need; 954 uint8_t *ptr; 955 956 free(env->sc_ocsp_url); 957 ptr = (uint8_t *)imsg->data; 958 have = IMSG_DATA_SIZE(imsg); 959 960 /* get tolerate */ 961 need = sizeof(env->sc_ocsp_tolerate); 962 if (have < need) 963 fatalx("bad 'tolerate' length imsg received"); 964 memcpy(&env->sc_ocsp_tolerate, ptr, need); 965 ptr += need; 966 have -= need; 967 968 /* get maxage */ 969 need = sizeof(env->sc_ocsp_maxage); 970 if (have < need) 971 fatalx("bad 'maxage' length imsg received"); 972 memcpy(&env->sc_ocsp_maxage, ptr, need); 973 ptr += need; 974 have -= need; 975 976 /* get url */ 977 if (have > 0) 978 env->sc_ocsp_url = get_string(ptr, have); 979 else 980 env->sc_ocsp_url = NULL; 981 log_debug("%s: ocsp_url %s tolerate %ld maxage %ld", __func__, 982 env->sc_ocsp_url ? env->sc_ocsp_url : "none", 983 env->sc_ocsp_tolerate, env->sc_ocsp_maxage); 984 return (0); 985 } 986 987 int 988 config_setcertpartialchain(struct iked *env) 989 { 990 unsigned int boolval; 991 992 boolval = env->sc_cert_partial_chain; 993 proc_compose(&env->sc_ps, PROC_CERT, IMSG_CERT_PARTIAL_CHAIN, 994 &boolval, sizeof(boolval)); 995 return (0); 996 } 997 998 int 999 config_getcertpartialchain(struct iked *env, struct imsg *imsg) 1000 { 1001 unsigned int boolval; 1002 1003 IMSG_SIZE_CHECK(imsg, &boolval); 1004 memcpy(&boolval, imsg->data, sizeof(boolval)); 1005 env->sc_cert_partial_chain = boolval; 1006 return (0); 1007 } 1008 1009 int 1010 config_setkeys(struct iked *env) 1011 { 1012 FILE *fp = NULL; 1013 EVP_PKEY *key = NULL; 1014 struct iked_id privkey; 1015 struct iked_id pubkey; 1016 struct iovec iov[2]; 1017 int ret = -1; 1018 1019 memset(&privkey, 0, sizeof(privkey)); 1020 memset(&pubkey, 0, sizeof(pubkey)); 1021 1022 /* Read private key */ 1023 if ((fp = fopen(IKED_PRIVKEY, "r")) == NULL) { 1024 log_warn("%s: failed to open private key", __func__); 1025 goto done; 1026 } 1027 1028 if ((key = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) { 1029 log_warnx("%s: failed to read private key", __func__); 1030 goto done; 1031 } 1032 1033 if (ca_privkey_serialize(key, &privkey) != 0) { 1034 log_warnx("%s: failed to serialize private key", __func__); 1035 goto done; 1036 } 1037 if (ca_pubkey_serialize(key, &pubkey) != 0) { 1038 log_warnx("%s: failed to serialize public key", __func__); 1039 goto done; 1040 } 1041 1042 iov[0].iov_base = &privkey; 1043 iov[0].iov_len = sizeof(privkey); 1044 iov[1].iov_base = ibuf_data(privkey.id_buf); 1045 iov[1].iov_len = ibuf_length(privkey.id_buf); 1046 1047 if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PRIVKEY, iov, 2) == -1) { 1048 log_warnx("%s: failed to send private key", __func__); 1049 goto done; 1050 } 1051 1052 iov[0].iov_base = &pubkey; 1053 iov[0].iov_len = sizeof(pubkey); 1054 iov[1].iov_base = ibuf_data(pubkey.id_buf); 1055 iov[1].iov_len = ibuf_length(pubkey.id_buf); 1056 1057 if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PUBKEY, iov, 2) == -1) { 1058 log_warnx("%s: failed to send public key", __func__); 1059 goto done; 1060 } 1061 1062 ret = 0; 1063 done: 1064 if (fp != NULL) 1065 fclose(fp); 1066 1067 ibuf_free(pubkey.id_buf); 1068 ibuf_free(privkey.id_buf); 1069 EVP_PKEY_free(key); 1070 1071 return (ret); 1072 } 1073 1074 int 1075 config_getkey(struct iked *env, struct imsg *imsg) 1076 { 1077 size_t len; 1078 struct iked_id id; 1079 1080 len = IMSG_DATA_SIZE(imsg); 1081 if (len <= sizeof(id)) 1082 fatalx("%s: invalid key message", __func__); 1083 1084 memcpy(&id, imsg->data, sizeof(id)); 1085 if ((id.id_buf = ibuf_new((uint8_t *)imsg->data + sizeof(id), 1086 len - sizeof(id))) == NULL) 1087 fatalx("%s: failed to get key", __func__); 1088 1089 explicit_bzero(imsg->data, len); 1090 ca_getkey(&env->sc_ps, &id, imsg->hdr.type); 1091 1092 return (0); 1093 } 1094