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