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