config.c revision 1.59
1/* $OpenBSD: config.c,v 1.59 2020/08/14 21:13:15 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 41struct iked_sa * 42config_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 68uint64_t 69config_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 80void 81config_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 97void 98config_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 113void 114config_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 ibuf_release(sa->sa_localauth.id_buf); 172 173 ibuf_release(sa->sa_eap.id_buf); 174 free(sa->sa_eapid); 175 ibuf_release(sa->sa_eapmsk); 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_proposals(struct iked_proposals *head, unsigned int proto) 261{ 262 struct iked_proposal *prop, *proptmp; 263 264 TAILQ_FOREACH_SAFE(prop, head, prop_entry, proptmp) { 265 /* Free any proposal or only selected SA proto */ 266 if (proto != 0 && prop->prop_protoid != proto) 267 continue; 268 269 log_debug("%s: free %p", __func__, prop); 270 271 TAILQ_REMOVE(head, prop, prop_entry); 272 if (prop->prop_nxforms) 273 free(prop->prop_xforms); 274 free(prop); 275 } 276} 277 278void 279config_free_flows(struct iked *env, struct iked_flows *head) 280{ 281 struct iked_flow *flow, *next; 282 283 for (flow = RB_MIN(iked_flows, head); flow != NULL; flow = next) { 284 next = RB_NEXT(iked_flows, head, flow); 285 log_debug("%s: free %p", __func__, flow); 286 RB_REMOVE(iked_flows, head, flow); 287 flow_free(flow); 288 } 289} 290 291void 292config_free_childsas(struct iked *env, struct iked_childsas *head, 293 struct iked_spi *peerspi, struct iked_spi *localspi) 294{ 295 struct iked_childsa *csa, *csatmp, *ipcomp; 296 297 if (localspi != NULL) 298 bzero(localspi, sizeof(*localspi)); 299 300 TAILQ_FOREACH_SAFE(csa, head, csa_entry, csatmp) { 301 if (peerspi != NULL) { 302 /* Only delete matching peer SPIs */ 303 if (peerspi->spi != csa->csa_peerspi) 304 continue; 305 306 /* Store assigned local SPI */ 307 if (localspi != NULL && localspi->spi == 0) 308 memcpy(localspi, &csa->csa_spi, 309 sizeof(*localspi)); 310 } 311 log_debug("%s: free %p", __func__, csa); 312 313 TAILQ_REMOVE(head, csa, csa_entry); 314 if (csa->csa_loaded) { 315 RB_REMOVE(iked_activesas, &env->sc_activesas, csa); 316 (void)pfkey_sa_delete(env->sc_pfkey, csa); 317 } 318 if ((ipcomp = csa->csa_bundled) != NULL) { 319 log_debug("%s: free IPCOMP %p", __func__, ipcomp); 320 if (ipcomp->csa_loaded) 321 (void)pfkey_sa_delete(env->sc_pfkey, ipcomp); 322 childsa_free(ipcomp); 323 } 324 childsa_free(csa); 325 } 326} 327 328struct iked_transform * 329config_add_transform(struct iked_proposal *prop, unsigned int type, 330 unsigned int id, unsigned int length, unsigned int keylength) 331{ 332 struct iked_transform *xform; 333 struct iked_constmap *map = NULL; 334 int score = 1; 335 unsigned int i; 336 337 switch (type) { 338 case IKEV2_XFORMTYPE_ENCR: 339 map = ikev2_xformencr_map; 340 break; 341 case IKEV2_XFORMTYPE_PRF: 342 map = ikev2_xformprf_map; 343 break; 344 case IKEV2_XFORMTYPE_INTEGR: 345 map = ikev2_xformauth_map; 346 break; 347 case IKEV2_XFORMTYPE_DH: 348 map = ikev2_xformdh_map; 349 break; 350 case IKEV2_XFORMTYPE_ESN: 351 map = ikev2_xformesn_map; 352 break; 353 default: 354 log_debug("%s: invalid transform type %d", __func__, type); 355 return (NULL); 356 } 357 358 for (i = 0; i < prop->prop_nxforms; i++) { 359 xform = prop->prop_xforms + i; 360 if (xform->xform_type == type && 361 xform->xform_id == id && 362 xform->xform_length == length) 363 return (xform); 364 } 365 366 for (i = 0; i < prop->prop_nxforms; i++) { 367 xform = prop->prop_xforms + i; 368 if (xform->xform_type == type) { 369 switch (type) { 370 case IKEV2_XFORMTYPE_ENCR: 371 case IKEV2_XFORMTYPE_INTEGR: 372 score += 3; 373 break; 374 case IKEV2_XFORMTYPE_DH: 375 score += 2; 376 break; 377 default: 378 score += 1; 379 break; 380 } 381 } 382 } 383 384 if ((xform = reallocarray(prop->prop_xforms, 385 prop->prop_nxforms + 1, sizeof(*xform))) == NULL) { 386 return (NULL); 387 } 388 389 prop->prop_xforms = xform; 390 xform = prop->prop_xforms + prop->prop_nxforms++; 391 bzero(xform, sizeof(*xform)); 392 393 xform->xform_type = type; 394 xform->xform_id = id; 395 xform->xform_length = length; 396 xform->xform_keylength = keylength; 397 xform->xform_score = score; 398 xform->xform_map = map; 399 400 return (xform); 401} 402 403struct iked_transform * 404config_findtransform(struct iked_proposals *props, uint8_t type, 405 unsigned int proto) 406{ 407 struct iked_proposal *prop; 408 struct iked_transform *xform; 409 unsigned int i; 410 411 /* Search of the first transform with the desired type */ 412 TAILQ_FOREACH(prop, props, prop_entry) { 413 /* Find any proposal or only selected SA proto */ 414 if (proto != 0 && prop->prop_protoid != proto) 415 continue; 416 for (i = 0; i < prop->prop_nxforms; i++) { 417 xform = prop->prop_xforms + i; 418 if (xform->xform_type == type) 419 return (xform); 420 } 421 } 422 423 return (NULL); 424} 425 426struct iked_user * 427config_new_user(struct iked *env, struct iked_user *new) 428{ 429 struct iked_user *usr, *old; 430 431 if ((usr = calloc(1, sizeof(*usr))) == NULL) 432 return (NULL); 433 434 memcpy(usr, new, sizeof(*usr)); 435 436 if ((old = RB_INSERT(iked_users, &env->sc_users, usr)) != NULL) { 437 /* Update the password of an existing user*/ 438 memcpy(old->usr_pass, new->usr_pass, IKED_PASSWORD_SIZE); 439 440 log_debug("%s: updating user %s", __func__, usr->usr_name); 441 free(usr); 442 443 return (old); 444 } 445 446 log_debug("%s: inserting new user %s", __func__, usr->usr_name); 447 return (usr); 448} 449 450/* 451 * Inter-process communication of configuration items. 452 */ 453 454int 455config_setcoupled(struct iked *env, unsigned int couple) 456{ 457 unsigned int type; 458 459 type = couple ? IMSG_CTL_COUPLE : IMSG_CTL_DECOUPLE; 460 proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0); 461 462 return (0); 463} 464 465int 466config_getcoupled(struct iked *env, unsigned int type) 467{ 468 return (pfkey_couple(env->sc_pfkey, &env->sc_sas, 469 type == IMSG_CTL_COUPLE ? 1 : 0)); 470} 471 472int 473config_setmode(struct iked *env, unsigned int passive) 474{ 475 unsigned int type; 476 477 type = passive ? IMSG_CTL_PASSIVE : IMSG_CTL_ACTIVE; 478 proc_compose(&env->sc_ps, PROC_IKEV2, type, NULL, 0); 479 480 return (0); 481} 482 483int 484config_getmode(struct iked *env, unsigned int type) 485{ 486 uint8_t old; 487 unsigned char *mode[] = { "active", "passive" }; 488 489 old = env->sc_passive ? 1 : 0; 490 env->sc_passive = type == IMSG_CTL_PASSIVE ? 1 : 0; 491 492 if (old == env->sc_passive) 493 return (0); 494 495 log_debug("%s: mode %s -> %s", __func__, 496 mode[old], mode[env->sc_passive]); 497 498 return (0); 499} 500 501int 502config_setreset(struct iked *env, unsigned int mode, enum privsep_procid id) 503{ 504 proc_compose(&env->sc_ps, id, IMSG_CTL_RESET, &mode, sizeof(mode)); 505 return (0); 506} 507 508int 509config_getreset(struct iked *env, struct imsg *imsg) 510{ 511 struct iked_policy *pol, *poltmp; 512 struct iked_sa *sa, *nextsa; 513 struct iked_user *usr, *nextusr; 514 unsigned int mode; 515 516 IMSG_SIZE_CHECK(imsg, &mode); 517 memcpy(&mode, imsg->data, sizeof(mode)); 518 519 if (mode == RESET_ALL || mode == RESET_POLICY) { 520 log_debug("%s: flushing policies", __func__); 521 TAILQ_FOREACH_SAFE(pol, &env->sc_policies, pol_entry, poltmp) { 522 config_free_policy(env, pol); 523 } 524 } 525 526 if (mode == RESET_ALL || mode == RESET_SA) { 527 log_debug("%s: flushing SAs", __func__); 528 for (sa = RB_MIN(iked_sas, &env->sc_sas); 529 sa != NULL; sa = nextsa) { 530 nextsa = RB_NEXT(iked_sas, &env->sc_sas, sa); 531 /* for RESET_SA we try send a DELETE */ 532 if (mode == RESET_ALL || 533 ikev2_ike_sa_delete(env, sa) != 0) { 534 RB_REMOVE(iked_sas, &env->sc_sas, sa); 535 config_free_sa(env, sa); 536 } 537 } 538 } 539 540 if (mode == RESET_ALL || mode == RESET_USER) { 541 log_debug("%s: flushing users", __func__); 542 for (usr = RB_MIN(iked_users, &env->sc_users); 543 usr != NULL; usr = nextusr) { 544 nextusr = RB_NEXT(iked_users, &env->sc_users, usr); 545 RB_REMOVE(iked_users, &env->sc_users, usr); 546 free(usr); 547 } 548 } 549 550 return (0); 551} 552 553/* 554 * The first call of this function sets the UDP socket for IKEv2. 555 * The second call is optional, setting the UDP socket used for NAT-T. 556 */ 557int 558config_setsocket(struct iked *env, struct sockaddr_storage *ss, 559 in_port_t port, enum privsep_procid id) 560{ 561 int s; 562 563 if ((s = udp_bind((struct sockaddr *)ss, port)) == -1) 564 return (-1); 565 proc_compose_imsg(&env->sc_ps, id, -1, 566 IMSG_UDP_SOCKET, -1, s, ss, sizeof(*ss)); 567 return (0); 568} 569 570int 571config_getsocket(struct iked *env, struct imsg *imsg, 572 void (*cb)(int, short, void *)) 573{ 574 struct iked_socket *sock, **sock0, **sock1; 575 576 log_debug("%s: received socket fd %d", __func__, imsg->fd); 577 578 if ((sock = calloc(1, sizeof(*sock))) == NULL) 579 fatal("config_getsocket: calloc"); 580 581 IMSG_SIZE_CHECK(imsg, &sock->sock_addr); 582 583 memcpy(&sock->sock_addr, imsg->data, sizeof(sock->sock_addr)); 584 sock->sock_fd = imsg->fd; 585 sock->sock_env = env; 586 587 switch (sock->sock_addr.ss_family) { 588 case AF_INET: 589 sock0 = &env->sc_sock4[0]; 590 sock1 = &env->sc_sock4[1]; 591 break; 592 case AF_INET6: 593 sock0 = &env->sc_sock6[0]; 594 sock1 = &env->sc_sock6[1]; 595 break; 596 default: 597 fatal("config_getsocket: socket af: %u", 598 sock->sock_addr.ss_family); 599 /* NOTREACHED */ 600 } 601 if (*sock0 == NULL) 602 *sock0 = sock; 603 else if (*sock1 == NULL) 604 *sock1 = sock; 605 else 606 fatalx("%s: too many call", __func__); 607 608 event_set(&sock->sock_ev, sock->sock_fd, 609 EV_READ|EV_PERSIST, cb, sock); 610 event_add(&sock->sock_ev, NULL); 611 612 return (0); 613} 614 615int 616config_setpfkey(struct iked *env, enum privsep_procid id) 617{ 618 int s; 619 620 if ((s = pfkey_socket()) == -1) 621 return (-1); 622 proc_compose_imsg(&env->sc_ps, id, -1, 623 IMSG_PFKEY_SOCKET, -1, s, NULL, 0); 624 return (0); 625} 626 627int 628config_getpfkey(struct iked *env, struct imsg *imsg) 629{ 630 log_debug("%s: received pfkey fd %d", __func__, imsg->fd); 631 pfkey_init(env, imsg->fd); 632 return (0); 633} 634 635int 636config_setuser(struct iked *env, struct iked_user *usr, enum privsep_procid id) 637{ 638 if (env->sc_opts & IKED_OPT_NOACTION) { 639 print_user(usr); 640 return (0); 641 } 642 643 proc_compose(&env->sc_ps, id, IMSG_CFG_USER, usr, sizeof(*usr)); 644 return (0); 645} 646 647int 648config_getuser(struct iked *env, struct imsg *imsg) 649{ 650 struct iked_user usr; 651 652 IMSG_SIZE_CHECK(imsg, &usr); 653 memcpy(&usr, imsg->data, sizeof(usr)); 654 655 if (config_new_user(env, &usr) == NULL) 656 return (-1); 657 658 print_user(&usr); 659 660 return (0); 661} 662 663int 664config_setpolicy(struct iked *env, struct iked_policy *pol, 665 enum privsep_procid id) 666{ 667 struct iked_proposal *prop; 668 struct iked_transform *xform; 669 size_t iovcnt, j, c = 0; 670 struct iovec iov[IOV_MAX]; 671 672 iovcnt = 1; 673 TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) { 674 iovcnt += prop->prop_nxforms + 1; 675 } 676 677 if (iovcnt > IOV_MAX) { 678 log_warn("%s: too many proposals", __func__); 679 return (-1); 680 } 681 682 iov[c].iov_base = pol; 683 iov[c++].iov_len = sizeof(*pol); 684 685 TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) { 686 iov[c].iov_base = prop; 687 iov[c++].iov_len = sizeof(*prop); 688 689 for (j = 0; j < prop->prop_nxforms; j++) { 690 xform = prop->prop_xforms + j; 691 692 iov[c].iov_base = xform; 693 iov[c++].iov_len = sizeof(*xform); 694 } 695 } 696 697 print_policy(pol); 698 699 if (env->sc_opts & IKED_OPT_NOACTION) 700 return (0); 701 702 if (proc_composev(&env->sc_ps, id, IMSG_CFG_POLICY, iov, 703 iovcnt) == -1) { 704 log_debug("%s: proc_composev failed", __func__); 705 return (-1); 706 } 707 708 return (0); 709} 710 711int 712config_setflow(struct iked *env, struct iked_policy *pol, 713 enum privsep_procid id) 714{ 715 struct iked_flow *flow; 716 struct iovec iov[2]; 717 718 if (env->sc_opts & IKED_OPT_NOACTION) 719 return (0); 720 721 RB_FOREACH(flow, iked_flows, &pol->pol_flows) { 722 iov[0].iov_base = &pol->pol_id; 723 iov[0].iov_len = sizeof(pol->pol_id); 724 iov[1].iov_base = flow; 725 iov[1].iov_len = sizeof(*flow); 726 727 if (proc_composev(&env->sc_ps, id, IMSG_CFG_FLOW, 728 iov, 2) == -1) { 729 log_debug("%s: proc_composev failed", __func__); 730 return (-1); 731 } 732 } 733 734 return (0); 735} 736 737int 738config_getpolicy(struct iked *env, struct imsg *imsg) 739{ 740 struct iked_policy *pol; 741 struct iked_proposal pp, *prop; 742 struct iked_transform xf; 743 off_t offset = 0; 744 unsigned int i, j; 745 uint8_t *buf = (uint8_t *)imsg->data; 746 747 IMSG_SIZE_CHECK(imsg, pol); 748 log_debug("%s: received policy", __func__); 749 750 if ((pol = config_new_policy(NULL)) == NULL) 751 fatal("config_getpolicy: new policy"); 752 753 memcpy(pol, buf, sizeof(*pol)); 754 offset += sizeof(*pol); 755 756 TAILQ_INIT(&pol->pol_tssrc); 757 TAILQ_INIT(&pol->pol_tsdst); 758 TAILQ_INIT(&pol->pol_proposals); 759 TAILQ_INIT(&pol->pol_sapeers); 760 RB_INIT(&pol->pol_flows); 761 762 for (i = 0; i < pol->pol_nproposals; i++) { 763 memcpy(&pp, buf + offset, sizeof(pp)); 764 offset += sizeof(pp); 765 766 if ((prop = config_add_proposal(&pol->pol_proposals, 767 pp.prop_id, pp.prop_protoid)) == NULL) 768 fatal("config_getpolicy: add proposal"); 769 770 for (j = 0; j < pp.prop_nxforms; j++) { 771 memcpy(&xf, buf + offset, sizeof(xf)); 772 offset += sizeof(xf); 773 774 if (config_add_transform(prop, xf.xform_type, 775 xf.xform_id, xf.xform_length, 776 xf.xform_keylength) == NULL) 777 fatal("config_getpolicy: add transform"); 778 } 779 } 780 781 /* Flows are sent separately */ 782 pol->pol_nflows = 0; 783 784 TAILQ_INSERT_TAIL(&env->sc_policies, pol, pol_entry); 785 786 if (pol->pol_flags & IKED_POLICY_DEFAULT) { 787 /* Only one default policy, just free/unref the old one */ 788 if (env->sc_defaultcon != NULL) 789 config_free_policy(env, env->sc_defaultcon); 790 env->sc_defaultcon = pol; 791 } 792 793 return (0); 794} 795 796int 797config_getflow(struct iked *env, struct imsg *imsg) 798{ 799 struct iked_policy *pol; 800 struct iked_flow *flow; 801 off_t offset = 0; 802 unsigned int id; 803 uint8_t *buf = (uint8_t *)imsg->data; 804 805 if (IMSG_DATA_SIZE(imsg) < sizeof(id)) 806 fatalx("bad length imsg received"); 807 808 memcpy(&id, buf, sizeof(id)); 809 offset += sizeof(id); 810 811 TAILQ_FOREACH(pol, &env->sc_policies, pol_entry) { 812 if (pol->pol_id == id) 813 break; 814 } 815 if (pol == NULL) { 816 log_warnx("%s: unknown policy %u", __func__, id); 817 return (-1); 818 } 819 820 if ((flow = calloc(1, sizeof(*flow))) == NULL) 821 fatal("config_getpolicy: new flow"); 822 823 memcpy(flow, buf + offset, sizeof(*flow)); 824 825 if (RB_INSERT(iked_flows, &pol->pol_flows, flow)) { 826 log_warnx("%s: received duplicate flow", __func__); 827 free(flow); 828 return (-1); 829 } 830 pol->pol_nflows++; 831 832 return (0); 833} 834 835int 836config_setcompile(struct iked *env, enum privsep_procid id) 837{ 838 if (env->sc_opts & IKED_OPT_NOACTION) 839 return (0); 840 841 proc_compose(&env->sc_ps, id, IMSG_COMPILE, NULL, 0); 842 return (0); 843} 844 845int 846config_getcompile(struct iked *env, struct imsg *imsg) 847{ 848 /* 849 * Do any necessary steps after configuration, for now we 850 * only need to compile the skip steps. 851 */ 852 policy_calc_skip_steps(&env->sc_policies); 853 854 log_debug("%s: compilation done", __func__); 855 return (0); 856} 857 858int 859config_setmobike(struct iked *env) 860{ 861 unsigned int boolval; 862 863 boolval = env->sc_mobike; 864 proc_compose(&env->sc_ps, PROC_IKEV2, IMSG_CTL_MOBIKE, 865 &boolval, sizeof(boolval)); 866 return (0); 867} 868 869int 870config_getmobike(struct iked *env, struct imsg *imsg) 871{ 872 unsigned int boolval; 873 874 IMSG_SIZE_CHECK(imsg, &boolval); 875 memcpy(&boolval, imsg->data, sizeof(boolval)); 876 env->sc_mobike = boolval; 877 log_debug("%s: %smobike", __func__, env->sc_mobike ? "" : "no "); 878 return (0); 879} 880 881int 882config_setfragmentation(struct iked *env) 883{ 884 unsigned int boolval; 885 886 boolval = env->sc_frag; 887 proc_compose(&env->sc_ps, PROC_IKEV2, IMSG_CTL_FRAGMENTATION, 888 &boolval, sizeof(boolval)); 889 return (0); 890} 891 892int 893config_getfragmentation(struct iked *env, struct imsg *imsg) 894{ 895 unsigned int boolval; 896 897 IMSG_SIZE_CHECK(imsg, &boolval); 898 memcpy(&boolval, imsg->data, sizeof(boolval)); 899 env->sc_frag = boolval; 900 log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no "); 901 return (0); 902} 903 904int 905config_setocsp(struct iked *env) 906{ 907 if (env->sc_opts & IKED_OPT_NOACTION) 908 return (0); 909 proc_compose(&env->sc_ps, PROC_CERT, 910 IMSG_OCSP_URL, env->sc_ocsp_url, 911 env->sc_ocsp_url ? strlen(env->sc_ocsp_url) : 0); 912 913 return (0); 914} 915 916int 917config_getocsp(struct iked *env, struct imsg *imsg) 918{ 919 free(env->sc_ocsp_url); 920 if (IMSG_DATA_SIZE(imsg) > 0) 921 env->sc_ocsp_url = get_string(imsg->data, IMSG_DATA_SIZE(imsg)); 922 else 923 env->sc_ocsp_url = NULL; 924 log_debug("%s: ocsp_url %s", __func__, 925 env->sc_ocsp_url ? env->sc_ocsp_url : "none"); 926 return (0); 927} 928 929int 930config_setkeys(struct iked *env) 931{ 932 FILE *fp = NULL; 933 EVP_PKEY *key = NULL; 934 struct iked_id privkey; 935 struct iked_id pubkey; 936 struct iovec iov[2]; 937 int ret = -1; 938 939 memset(&privkey, 0, sizeof(privkey)); 940 memset(&pubkey, 0, sizeof(pubkey)); 941 942 /* Read private key */ 943 if ((fp = fopen(IKED_PRIVKEY, "r")) == NULL) { 944 log_warn("%s: failed to open private key", __func__); 945 goto done; 946 } 947 948 if ((key = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) { 949 log_warnx("%s: failed to read private key", __func__); 950 goto done; 951 } 952 953 if (ca_privkey_serialize(key, &privkey) != 0) { 954 log_warnx("%s: failed to serialize private key", __func__); 955 goto done; 956 } 957 if (ca_pubkey_serialize(key, &pubkey) != 0) { 958 log_warnx("%s: failed to serialize public key", __func__); 959 goto done; 960 } 961 962 iov[0].iov_base = &privkey; 963 iov[0].iov_len = sizeof(privkey); 964 iov[1].iov_base = ibuf_data(privkey.id_buf); 965 iov[1].iov_len = ibuf_length(privkey.id_buf); 966 967 if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PRIVKEY, iov, 2) == -1) { 968 log_warnx("%s: failed to send private key", __func__); 969 goto done; 970 } 971 972 iov[0].iov_base = &pubkey; 973 iov[0].iov_len = sizeof(pubkey); 974 iov[1].iov_base = ibuf_data(pubkey.id_buf); 975 iov[1].iov_len = ibuf_length(pubkey.id_buf); 976 977 if (proc_composev(&env->sc_ps, PROC_CERT, IMSG_PUBKEY, iov, 2) == -1) { 978 log_warnx("%s: failed to send public key", __func__); 979 goto done; 980 } 981 982 ret = 0; 983 done: 984 if (fp != NULL) 985 fclose(fp); 986 987 ibuf_release(pubkey.id_buf); 988 ibuf_release(privkey.id_buf); 989 EVP_PKEY_free(key); 990 991 return (ret); 992} 993 994int 995config_setnattport(struct iked *env) 996{ 997 in_port_t nattport; 998 999 nattport = env->sc_nattport; 1000 proc_compose(&env->sc_ps, PROC_IKEV2, IMSG_CTL_NATTPORT, 1001 &nattport, sizeof(nattport)); 1002 return (0); 1003} 1004 1005int 1006config_getnattport(struct iked *env, struct imsg *imsg) 1007{ 1008 in_port_t nattport; 1009 1010 IMSG_SIZE_CHECK(imsg, &nattport); 1011 memcpy(&nattport, imsg->data, sizeof(nattport)); 1012 env->sc_nattport = nattport; 1013 log_debug("%s: nattport %u", __func__, env->sc_nattport); 1014 return (0); 1015} 1016 1017int 1018config_getkey(struct iked *env, struct imsg *imsg) 1019{ 1020 size_t len; 1021 struct iked_id id; 1022 1023 len = IMSG_DATA_SIZE(imsg); 1024 if (len <= sizeof(id)) 1025 fatalx("%s: invalid key message", __func__); 1026 1027 memcpy(&id, imsg->data, sizeof(id)); 1028 if ((id.id_buf = ibuf_new((uint8_t *)imsg->data + sizeof(id), 1029 len - sizeof(id))) == NULL) 1030 fatalx("%s: failed to get key", __func__); 1031 1032 explicit_bzero(imsg->data, len); 1033 ca_getkey(&env->sc_ps, &id, imsg->hdr.type); 1034 1035 return (0); 1036} 1037