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