1 /* $OpenBSD: config.c,v 1.31 2014/05/06 14:10:53 markus Exp $ */ 2 3 /* 4 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 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 <getopt.h> 30 #include <signal.h> 31 #include <errno.h> 32 #include <err.h> 33 #include <pwd.h> 34 #include <event.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 u_int64_t 67 config_getspi(void) 68 { 69 u_int64_t spi; 70 71 spi = ((u_int64_t)arc4random() << 32) | arc4random(); 72 if (spi == 0) 73 return (config_getspi()); 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 if (kex->kex_dhgroup != NULL) 88 group_free(kex->kex_dhgroup); 89 ibuf_release(kex->kex_dhiexchange); 90 ibuf_release(kex->kex_dhrexchange); 91 92 free(kex); 93 } 94 95 void 96 config_free_sa(struct iked *env, struct iked_sa *sa) 97 { 98 timer_del(env, &sa->sa_timer); 99 timer_del(env, &sa->sa_rekey); 100 101 config_free_proposals(&sa->sa_proposals, 0); 102 config_free_childsas(env, &sa->sa_childsas, NULL, NULL); 103 sa_free_flows(env, &sa->sa_flows); 104 105 if (sa->sa_addrpool) { 106 (void)RB_REMOVE(iked_addrpool, &env->sc_addrpool, sa); 107 free(sa->sa_addrpool); 108 } 109 110 if (sa->sa_policy) { 111 (void)RB_REMOVE(iked_sapeers, &sa->sa_policy->pol_sapeers, sa); 112 policy_unref(env, sa->sa_policy); 113 } 114 115 ikev2_msg_flushqueue(env, &sa->sa_requests); 116 ikev2_msg_flushqueue(env, &sa->sa_responses); 117 118 ibuf_release(sa->sa_inonce); 119 ibuf_release(sa->sa_rnonce); 120 121 if (sa->sa_dhgroup != NULL) 122 group_free(sa->sa_dhgroup); 123 ibuf_release(sa->sa_dhiexchange); 124 ibuf_release(sa->sa_dhrexchange); 125 126 hash_free(sa->sa_prf); 127 hash_free(sa->sa_integr); 128 cipher_free(sa->sa_encr); 129 130 ibuf_release(sa->sa_key_d); 131 ibuf_release(sa->sa_key_iauth); 132 ibuf_release(sa->sa_key_rauth); 133 ibuf_release(sa->sa_key_iencr); 134 ibuf_release(sa->sa_key_rencr); 135 ibuf_release(sa->sa_key_iprf); 136 ibuf_release(sa->sa_key_rprf); 137 138 ibuf_release(sa->sa_1stmsg); 139 ibuf_release(sa->sa_2ndmsg); 140 141 ibuf_release(sa->sa_iid.id_buf); 142 ibuf_release(sa->sa_rid.id_buf); 143 ibuf_release(sa->sa_icert.id_buf); 144 ibuf_release(sa->sa_rcert.id_buf); 145 146 ibuf_release(sa->sa_eap.id_buf); 147 if (sa->sa_eapid != NULL) 148 free(sa->sa_eapid); 149 ibuf_release(sa->sa_eapmsk); 150 151 free(sa); 152 } 153 154 struct iked_policy * 155 config_new_policy(struct iked *env) 156 { 157 struct iked_policy *pol; 158 159 if ((pol = calloc(1, sizeof(*pol))) == NULL) 160 return (NULL); 161 162 TAILQ_INIT(&pol->pol_proposals); 163 RB_INIT(&pol->pol_sapeers); 164 165 return (pol); 166 } 167 168 void 169 config_free_policy(struct iked *env, struct iked_policy *pol) 170 { 171 struct iked_sa *sa; 172 173 if (pol->pol_flags & IKED_POLICY_REFCNT) 174 goto remove; 175 176 TAILQ_REMOVE(&env->sc_policies, pol, pol_entry); 177 178 RB_FOREACH(sa, iked_sapeers, &pol->pol_sapeers) { 179 /* Remove from the policy tree, but keep for existing SAs */ 180 if (sa->sa_policy == pol) 181 policy_ref(env, pol); 182 } 183 184 if (pol->pol_refcnt) 185 return; 186 187 remove: 188 config_free_proposals(&pol->pol_proposals, 0); 189 config_free_flows(env, &pol->pol_flows); 190 free(pol); 191 } 192 193 struct iked_proposal * 194 config_add_proposal(struct iked_proposals *head, u_int id, u_int proto) 195 { 196 struct iked_proposal *pp; 197 198 TAILQ_FOREACH(pp, head, prop_entry) { 199 if (pp->prop_protoid == proto && 200 pp->prop_id == id) 201 return (pp); 202 } 203 204 if ((pp = calloc(1, sizeof(*pp))) == NULL) 205 return (NULL); 206 207 pp->prop_protoid = proto; 208 pp->prop_id = id; 209 210 TAILQ_INSERT_TAIL(head, pp, prop_entry); 211 212 return (pp); 213 } 214 215 void 216 config_free_proposals(struct iked_proposals *head, u_int proto) 217 { 218 struct iked_proposal *prop, *next; 219 220 for (prop = TAILQ_FIRST(head); prop != NULL; prop = next) { 221 next = TAILQ_NEXT(prop, prop_entry); 222 223 /* Free any proposal or only selected SA proto */ 224 if (proto != 0 && prop->prop_protoid != proto) 225 continue; 226 227 log_debug("%s: free %p", __func__, prop); 228 229 TAILQ_REMOVE(head, prop, prop_entry); 230 if (prop->prop_nxforms) 231 free(prop->prop_xforms); 232 free(prop); 233 } 234 } 235 236 void 237 config_free_flows(struct iked *env, struct iked_flows *head) 238 { 239 struct iked_flow *flow, *next; 240 241 for (flow = RB_MIN(iked_flows, head); flow != NULL; flow = next) { 242 next = RB_NEXT(iked_flows, head, flow); 243 log_debug("%s: free %p", __func__, flow); 244 RB_REMOVE(iked_flows, head, flow); 245 flow_free(flow); 246 } 247 } 248 249 void 250 config_free_childsas(struct iked *env, struct iked_childsas *head, 251 struct iked_spi *peerspi, struct iked_spi *localspi) 252 { 253 struct iked_childsa *csa, *nextcsa; 254 255 if (localspi != NULL) 256 bzero(localspi, sizeof(*localspi)); 257 258 for (csa = TAILQ_FIRST(head); csa != NULL; csa = nextcsa) { 259 nextcsa = TAILQ_NEXT(csa, csa_entry); 260 261 if (peerspi != NULL) { 262 /* Only delete matching peer SPIs */ 263 if (peerspi->spi != csa->csa_peerspi) 264 continue; 265 266 /* Store assigned local SPI */ 267 if (localspi != NULL && localspi->spi == 0) 268 memcpy(localspi, &csa->csa_spi, 269 sizeof(*localspi)); 270 } 271 log_debug("%s: free %p", __func__, csa); 272 273 TAILQ_REMOVE(head, csa, csa_entry); 274 if (csa->csa_loaded) { 275 RB_REMOVE(iked_activesas, &env->sc_activesas, csa); 276 (void)pfkey_sa_delete(env->sc_pfkey, csa); 277 } 278 childsa_free(csa); 279 } 280 } 281 282 struct iked_transform * 283 config_add_transform(struct iked_proposal *prop, u_int type, 284 u_int id, u_int length, u_int keylength) 285 { 286 struct iked_transform *xform; 287 struct iked_constmap *map = NULL; 288 int score = 1; 289 u_int i; 290 291 switch (type) { 292 case IKEV2_XFORMTYPE_ENCR: 293 map = ikev2_xformencr_map; 294 break; 295 case IKEV2_XFORMTYPE_PRF: 296 map = ikev2_xformprf_map; 297 break; 298 case IKEV2_XFORMTYPE_INTEGR: 299 map = ikev2_xformauth_map; 300 break; 301 case IKEV2_XFORMTYPE_DH: 302 map = ikev2_xformdh_map; 303 break; 304 case IKEV2_XFORMTYPE_ESN: 305 map = ikev2_xformesn_map; 306 break; 307 default: 308 log_debug("%s: invalid transform type %d", __func__, type); 309 return (NULL); 310 } 311 312 for (i = 0; i < prop->prop_nxforms; i++) { 313 xform = prop->prop_xforms + i; 314 if (xform->xform_type == type && 315 xform->xform_id == id && 316 xform->xform_length == length) 317 return (xform); 318 } 319 320 for (i = 0; i < prop->prop_nxforms; i++) { 321 xform = prop->prop_xforms + i; 322 if (xform->xform_type == type) { 323 switch (type) { 324 case IKEV2_XFORMTYPE_ENCR: 325 case IKEV2_XFORMTYPE_INTEGR: 326 score += 3; 327 break; 328 case IKEV2_XFORMTYPE_DH: 329 score += 2; 330 break; 331 default: 332 score += 1; 333 break; 334 } 335 } 336 } 337 338 if ((xform = realloc(prop->prop_xforms, 339 (prop->prop_nxforms + 1) * sizeof(*xform))) == NULL) { 340 return (NULL); 341 } 342 343 prop->prop_xforms = xform; 344 xform = prop->prop_xforms + prop->prop_nxforms++; 345 bzero(xform, sizeof(*xform)); 346 347 xform->xform_type = type; 348 xform->xform_id = id; 349 xform->xform_length = length; 350 xform->xform_keylength = keylength; 351 xform->xform_score = score; 352 xform->xform_map = map; 353 354 return (xform); 355 } 356 357 struct iked_transform * 358 config_findtransform(struct iked_proposals *props, u_int8_t type, 359 u_int proto) 360 { 361 struct iked_proposal *prop; 362 struct iked_transform *xform; 363 u_int i; 364 365 /* Search of the first transform with the desired type */ 366 TAILQ_FOREACH(prop, props, prop_entry) { 367 /* Find any proposal or only selected SA proto */ 368 if (proto != 0 && prop->prop_protoid != proto) 369 continue; 370 for (i = 0; i < prop->prop_nxforms; i++) { 371 xform = prop->prop_xforms + i; 372 if (xform->xform_type == type) 373 return (xform); 374 } 375 } 376 377 return (NULL); 378 } 379 380 struct iked_user * 381 config_new_user(struct iked *env, struct iked_user *new) 382 { 383 struct iked_user *usr, *old; 384 385 if ((usr = calloc(1, sizeof(*usr))) == NULL) 386 return (NULL); 387 388 memcpy(usr, new, sizeof(*usr)); 389 390 if ((old = RB_INSERT(iked_users, &env->sc_users, usr)) != NULL) { 391 /* Update the password of an existing user*/ 392 memcpy(old, new, sizeof(*old)); 393 394 log_debug("%s: updating user %s", __func__, usr->usr_name); 395 free(usr); 396 397 return (old); 398 } 399 400 log_debug("%s: inserting new user %s", __func__, usr->usr_name); 401 return (usr); 402 } 403 404 /* 405 * Inter-process communication of configuration items. 406 */ 407 408 int 409 config_setcoupled(struct iked *env, u_int couple) 410 { 411 u_int type; 412 413 type = couple ? IMSG_CTL_COUPLE : IMSG_CTL_DECOUPLE; 414 proc_compose_imsg(&env->sc_ps, PROC_IKEV1, -1, type, -1, NULL, 0); 415 proc_compose_imsg(&env->sc_ps, PROC_IKEV2, -1, type, -1, NULL, 0); 416 417 return (0); 418 } 419 420 int 421 config_getcoupled(struct iked *env, u_int type) 422 { 423 return (pfkey_couple(env->sc_pfkey, &env->sc_sas, 424 type == IMSG_CTL_COUPLE ? 1 : 0)); 425 } 426 427 int 428 config_setmode(struct iked *env, u_int passive) 429 { 430 u_int type; 431 432 type = passive ? IMSG_CTL_PASSIVE : IMSG_CTL_ACTIVE; 433 proc_compose_imsg(&env->sc_ps, PROC_IKEV1, -1, type, -1, NULL, 0); 434 proc_compose_imsg(&env->sc_ps, PROC_IKEV2, -1, type, -1, NULL, 0); 435 436 return (0); 437 } 438 439 int 440 config_getmode(struct iked *env, u_int type) 441 { 442 u_int8_t old; 443 u_char *mode[] = { "active", "passive" }; 444 445 old = env->sc_passive ? 1 : 0; 446 env->sc_passive = type == IMSG_CTL_PASSIVE ? 1 : 0; 447 448 if (old == env->sc_passive) 449 return (0); 450 451 log_debug("%s: mode %s -> %s", __func__, 452 mode[old], mode[env->sc_passive]); 453 454 return (0); 455 } 456 457 int 458 config_setreset(struct iked *env, u_int mode, enum privsep_procid id) 459 { 460 proc_compose_imsg(&env->sc_ps, id, -1, 461 IMSG_CTL_RESET, -1, &mode, sizeof(mode)); 462 return (0); 463 } 464 465 int 466 config_getreset(struct iked *env, struct imsg *imsg) 467 { 468 struct iked_policy *pol, *nextpol; 469 struct iked_sa *sa, *nextsa; 470 struct iked_user *usr, *nextusr; 471 u_int mode; 472 473 IMSG_SIZE_CHECK(imsg, &mode); 474 memcpy(&mode, imsg->data, sizeof(mode)); 475 476 if (mode == RESET_ALL || mode == RESET_POLICY) { 477 log_debug("%s: flushing policies", __func__); 478 for (pol = TAILQ_FIRST(&env->sc_policies); 479 pol != NULL; pol = nextpol) { 480 nextpol = TAILQ_NEXT(pol, pol_entry); 481 config_free_policy(env, pol); 482 } 483 } 484 485 if (mode == RESET_ALL || mode == RESET_SA) { 486 log_debug("%s: flushing SAs", __func__); 487 for (sa = RB_MIN(iked_sas, &env->sc_sas); 488 sa != NULL; sa = nextsa) { 489 nextsa = RB_NEXT(iked_sas, &env->sc_sas, sa); 490 RB_REMOVE(iked_sas, &env->sc_sas, sa); 491 config_free_sa(env, sa); 492 } 493 } 494 495 if (mode == RESET_ALL || mode == RESET_USER) { 496 log_debug("%s: flushing users", __func__); 497 for (usr = RB_MIN(iked_users, &env->sc_users); 498 usr != NULL; usr = nextusr) { 499 nextusr = RB_NEXT(iked_users, &env->sc_users, usr); 500 RB_REMOVE(iked_users, &env->sc_users, usr); 501 free(usr); 502 } 503 } 504 505 return (0); 506 } 507 508 int 509 config_setsocket(struct iked *env, struct sockaddr_storage *ss, 510 in_port_t port, enum privsep_procid id) 511 { 512 int s; 513 514 if ((s = udp_bind((struct sockaddr *)ss, port)) == -1) 515 return (-1); 516 proc_compose_imsg(&env->sc_ps, id, -1, 517 IMSG_UDP_SOCKET, s, ss, sizeof(*ss)); 518 return (0); 519 } 520 521 int 522 config_getsocket(struct iked *env, struct imsg *imsg, 523 void (*cb)(int, short, void *)) 524 { 525 struct iked_socket *sock, **sptr, **nptr; 526 527 log_debug("%s: received socket fd %d", __func__, imsg->fd); 528 529 if ((sock = calloc(1, sizeof(*sock))) == NULL) 530 fatal("config_getsocket: calloc"); 531 532 IMSG_SIZE_CHECK(imsg, &sock->sock_addr); 533 534 memcpy(&sock->sock_addr, imsg->data, sizeof(sock->sock_addr)); 535 sock->sock_fd = imsg->fd; 536 sock->sock_env = env; 537 538 switch (sock->sock_addr.ss_family) { 539 case AF_INET: 540 sptr = &env->sc_sock4[0]; 541 nptr = &env->sc_sock4[1]; 542 break; 543 case AF_INET6: 544 sptr = &env->sc_sock6[0]; 545 nptr = &env->sc_sock6[1]; 546 break; 547 default: 548 fatal("config_getsocket: socket af"); 549 /* NOTREACHED */ 550 } 551 if (*sptr == NULL) 552 *sptr = sock; 553 if (*nptr == NULL && 554 socket_getport((struct sockaddr *)&sock->sock_addr) == 555 IKED_NATT_PORT) 556 *nptr = sock; 557 558 event_set(&sock->sock_ev, sock->sock_fd, 559 EV_READ|EV_PERSIST, cb, sock); 560 event_add(&sock->sock_ev, NULL); 561 562 return (0); 563 } 564 565 int 566 config_setpfkey(struct iked *env, enum privsep_procid id) 567 { 568 int s; 569 570 if ((s = pfkey_socket()) == -1) 571 return (-1); 572 proc_compose_imsg(&env->sc_ps, id, -1, 573 IMSG_PFKEY_SOCKET, s, NULL, 0); 574 return (0); 575 } 576 577 int 578 config_getpfkey(struct iked *env, struct imsg *imsg) 579 { 580 log_debug("%s: received pfkey fd %d", __func__, imsg->fd); 581 pfkey_init(env, imsg->fd); 582 return (0); 583 } 584 585 int 586 config_setuser(struct iked *env, struct iked_user *usr, enum privsep_procid id) 587 { 588 if (env->sc_opts & IKED_OPT_NOACTION) { 589 print_user(usr); 590 return (0); 591 } 592 593 proc_compose_imsg(&env->sc_ps, id, -1, 594 IMSG_CFG_USER, -1, usr, sizeof(*usr)); 595 return (0); 596 } 597 598 int 599 config_getuser(struct iked *env, struct imsg *imsg) 600 { 601 struct iked_user usr; 602 603 IMSG_SIZE_CHECK(imsg, &usr); 604 memcpy(&usr, imsg->data, sizeof(usr)); 605 606 if (config_new_user(env, &usr) == NULL) 607 return (-1); 608 609 print_user(&usr); 610 611 return (0); 612 } 613 614 int 615 config_setpolicy(struct iked *env, struct iked_policy *pol, 616 enum privsep_procid id) 617 { 618 struct iked_proposal *prop; 619 struct iked_flow *flow; 620 struct iked_transform *xform; 621 size_t size, iovcnt, j, c = 0; 622 struct iovec iov[IOV_MAX]; 623 624 iovcnt = 1; 625 size = sizeof(*pol); 626 TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) { 627 size += (prop->prop_nxforms * sizeof(*xform)) + 628 (sizeof(*prop)); 629 iovcnt += prop->prop_nxforms + 1; 630 } 631 632 iovcnt += pol->pol_nflows; 633 634 if (iovcnt > IOV_MAX) { 635 log_warn("%s: too many proposals/flows", __func__); 636 return (-1); 637 } 638 639 iov[c].iov_base = pol; 640 iov[c++].iov_len = sizeof(*pol); 641 642 TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) { 643 iov[c].iov_base = prop; 644 iov[c++].iov_len = sizeof(*prop); 645 646 for (j = 0; j < prop->prop_nxforms; j++) { 647 xform = prop->prop_xforms + j; 648 649 iov[c].iov_base = xform; 650 iov[c++].iov_len = sizeof(*xform); 651 } 652 } 653 654 RB_FOREACH(flow, iked_flows, &pol->pol_flows) { 655 iov[c].iov_base = flow; 656 iov[c++].iov_len = sizeof(*flow); 657 } 658 659 if (env->sc_opts & IKED_OPT_NOACTION) { 660 print_policy(pol); 661 return (0); 662 } 663 664 if (proc_composev_imsg(&env->sc_ps, id, -1, 665 IMSG_CFG_POLICY, -1, iov, iovcnt) == -1) 666 return (-1); 667 668 return (0); 669 } 670 671 int 672 config_getpolicy(struct iked *env, struct imsg *imsg) 673 { 674 struct iked_policy *pol; 675 struct iked_proposal pp, *prop; 676 struct iked_transform xf, *xform; 677 struct iked_flow *flow; 678 off_t offset = 0; 679 u_int i, j; 680 u_int8_t *buf = (u_int8_t *)imsg->data; 681 682 IMSG_SIZE_CHECK(imsg, pol); 683 log_debug("%s: received policy", __func__); 684 685 if ((pol = config_new_policy(NULL)) == NULL) 686 fatal("config_getpolicy: new policy"); 687 688 memcpy(pol, buf, sizeof(*pol)); 689 offset += sizeof(*pol); 690 691 TAILQ_INIT(&pol->pol_proposals); 692 RB_INIT(&pol->pol_flows); 693 694 for (i = 0; i < pol->pol_nproposals; i++) { 695 memcpy(&pp, buf + offset, sizeof(pp)); 696 offset += sizeof(pp); 697 698 if ((prop = config_add_proposal(&pol->pol_proposals, 699 pp.prop_id, pp.prop_protoid)) == NULL) 700 fatal("config_getpolicy: add proposal"); 701 702 for (j = 0; j < pp.prop_nxforms; j++) { 703 memcpy(&xf, buf + offset, sizeof(xf)); 704 offset += sizeof(xf); 705 706 if ((xform = config_add_transform(prop, xf.xform_type, 707 xf.xform_id, xf.xform_length, 708 xf.xform_keylength)) == NULL) 709 fatal("config_getpolicy: add transform"); 710 } 711 } 712 713 for (i = 0; i < pol->pol_nflows; i++) { 714 if ((flow = calloc(1, sizeof(*flow))) == NULL) 715 fatal("config_getpolicy: new flow"); 716 717 memcpy(flow, buf + offset, sizeof(*flow)); 718 offset += sizeof(*flow); 719 720 if (RB_INSERT(iked_flows, &pol->pol_flows, flow)) 721 free(flow); 722 } 723 724 TAILQ_INSERT_TAIL(&env->sc_policies, pol, pol_entry); 725 726 if (pol->pol_flags & IKED_POLICY_DEFAULT) { 727 /* Only one default policy, just free/unref the old one */ 728 if (env->sc_defaultcon != NULL) 729 config_free_policy(env, env->sc_defaultcon); 730 env->sc_defaultcon = pol; 731 } 732 733 print_policy(pol); 734 735 return (0); 736 } 737 738 int 739 config_setcompile(struct iked *env, enum privsep_procid id) 740 { 741 if (env->sc_opts & IKED_OPT_NOACTION) 742 return (0); 743 744 proc_compose_imsg(&env->sc_ps, id, -1, 745 IMSG_COMPILE, -1, NULL, 0); 746 return (0); 747 } 748 749 int 750 config_getcompile(struct iked *env, struct imsg *imsg) 751 { 752 /* 753 * Do any necessary steps after configuration, for now we 754 * only need to compile the skip steps. 755 */ 756 policy_calc_skip_steps(&env->sc_policies); 757 758 log_debug("%s: compilation done", __func__); 759 return (0); 760 } 761 762 int 763 config_setocsp(struct iked *env) 764 { 765 if (env->sc_opts & IKED_OPT_NOACTION) 766 return (0); 767 proc_compose_imsg(&env->sc_ps, PROC_CERT, -1, 768 IMSG_OCSP_URL, -1, env->sc_ocsp_url, 769 env->sc_ocsp_url ? strlen(env->sc_ocsp_url) : 0); 770 771 return (0); 772 } 773 774 int 775 config_getocsp(struct iked *env, struct imsg *imsg) 776 { 777 if (env->sc_ocsp_url) 778 free(env->sc_ocsp_url); 779 if (IMSG_DATA_SIZE(imsg) > 0) 780 env->sc_ocsp_url = get_string(imsg->data, IMSG_DATA_SIZE(imsg)); 781 else 782 env->sc_ocsp_url = NULL; 783 log_debug("%s: ocsp_url %s", __func__, 784 env->sc_ocsp_url ? env->sc_ocsp_url : "none"); 785 return (0); 786 } 787