1 /* $NetBSD: remoteconf.c,v 1.32 2025/03/08 16:39:08 christos Exp $ */ 2 3 /* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 manubsd Exp */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "config.h" 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/socket.h> 39 #include <sys/queue.h> 40 41 #include <netinet/in.h> 42 #include <netinet/in_systm.h> 43 #include <netinet/ip.h> 44 45 #include PATH_IPSEC_H 46 47 #include <stdlib.h> 48 #include <stdio.h> 49 #include <string.h> 50 #include <errno.h> 51 52 #include "var.h" 53 #include "misc.h" 54 #include "vmbuf.h" 55 #include "plog.h" 56 #include "sockmisc.h" 57 #include "genlist.h" 58 #include "debug.h" 59 60 #include "isakmp_var.h" 61 #ifdef ENABLE_HYBRID 62 #include "isakmp_xauth.h" 63 #endif 64 #include "isakmp.h" 65 #include "ipsec_doi.h" 66 #include "crypto_openssl.h" 67 #include "oakley.h" 68 #include "remoteconf.h" 69 #include "localconf.h" 70 #include "grabmyaddr.h" 71 #include "policy.h" 72 #include "proposal.h" 73 #include "vendorid.h" 74 #include "gcmalloc.h" 75 #include "strnames.h" 76 #include "algorithm.h" 77 #include "nattraversal.h" 78 #include "isakmp_frag.h" 79 #include "handler.h" 80 #include "genlist.h" 81 #include "rsalist.h" 82 83 typedef TAILQ_HEAD(_rmtree, remoteconf) remoteconf_tailq_head_t; 84 static remoteconf_tailq_head_t rmtree, rmtree_save; 85 86 /* 87 * Script hook names and script hook paths 88 */ 89 const char *script_names[SCRIPT_MAX + 1] = { 90 "phase1_up", "phase1_down", "phase1_dead" }; 91 92 /*%%%*/ 93 94 int 95 rmconf_match_identity(struct remoteconf *rmconf, vchar_t *id_p) 96 { 97 struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *) id_p->v; 98 struct sockaddr *sa; 99 caddr_t sa1, sa2; 100 vchar_t ident; 101 struct idspec *id; 102 struct genlist_entry *gpb; 103 104 /* compare with the ID if specified. */ 105 if (!genlist_next(rmconf->idvl_p, 0)) 106 return 0; 107 108 for (id = genlist_next(rmconf->idvl_p, &gpb); id; id = genlist_next(0, &gpb)) { 109 /* No ID specified in configuration, so it is ok */ 110 if (id->id == 0) 111 return 0; 112 113 /* check the type of both IDs */ 114 if (id->idtype != doi2idtype(id_b->type)) 115 continue; /* ID type mismatch */ 116 117 /* compare defined ID with the ID sent by peer. */ 118 switch (id->idtype) { 119 case IDTYPE_ASN1DN: 120 ident.v = id_p->v + sizeof(*id_b); 121 ident.l = id_p->l - sizeof(*id_b); 122 if (eay_cmp_asn1dn(id->id, &ident) == 0) 123 return 0; 124 break; 125 case IDTYPE_ADDRESS: 126 sa = (struct sockaddr *)id->id->v; 127 sa2 = (caddr_t)(id_b + 1); 128 switch (sa->sa_family) { 129 case AF_INET: 130 if (id_p->l - sizeof(*id_b) != sizeof(struct in_addr)) 131 continue; /* ID value mismatch */ 132 sa1 = (caddr_t) &((struct sockaddr_in *)sa)->sin_addr; 133 if (memcmp(sa1, sa2, sizeof(struct in_addr)) == 0) 134 return 0; 135 break; 136 #ifdef INET6 137 case AF_INET6: 138 if (id_p->l - sizeof(*id_b) != sizeof(struct in6_addr)) 139 continue; /* ID value mismatch */ 140 sa1 = (caddr_t) &((struct sockaddr_in6 *)sa)->sin6_addr; 141 if (memcmp(sa1, sa2, sizeof(struct in6_addr)) == 0) 142 return 0; 143 break; 144 #endif 145 default: 146 break; 147 } 148 break; 149 default: 150 if (memcmp(id->id->v, id_b + 1, id->id->l) == 0) 151 return 0; 152 break; 153 } 154 } 155 156 plog(LLV_WARNING, LOCATION, NULL, "No ID match.\n"); 157 if (rmconf->verify_identifier) 158 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 159 160 return 0; 161 } 162 163 static int 164 rmconf_match_etype_and_approval(struct remoteconf *rmconf, int etype, 165 struct isakmpsa *approval) 166 { 167 if (check_etypeok(rmconf, (void *) (intptr_t) etype) == 0) 168 return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 169 170 if (approval == NULL) 171 return 0; 172 173 if (etype == ISAKMP_ETYPE_AGG && 174 approval->dh_group != rmconf->dh_group) 175 return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 176 177 if (checkisakmpsa(rmconf->pcheck_level, approval, 178 rmconf->proposal) == NULL) 179 return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN; 180 181 return 0; 182 } 183 184 enum rmconf_match_t { 185 MATCH_NONE = 0, 186 MATCH_BASIC = 0x0000001, 187 MATCH_ADDRESS = 0x0000002, 188 MATCH_SA = 0x0000004, 189 MATCH_IDENTITY = 0x0000008, 190 MATCH_AUTH_IDENTITY = 0x0000010, 191 }; 192 193 static int 194 rmconf_match_type(struct rmconfselector *rmsel, struct remoteconf *rmconf) 195 { 196 int ret = MATCH_NONE, tmp; 197 198 /* No match at all: unwanted anonymous */ 199 if ((rmsel->flags & GETRMCONF_F_NO_ANONYMOUS) && 200 rmconf->remote->sa_family == AF_UNSPEC){ 201 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 202 "Not matched: Anonymous conf.\n"); 203 return MATCH_NONE; 204 } 205 206 if ((rmsel->flags & GETRMCONF_F_NO_PASSIVE) && rmconf->passive){ 207 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 208 "Not matched: passive conf.\n"); 209 return MATCH_NONE; 210 } 211 212 ret |= MATCH_BASIC; 213 214 /* Check address */ 215 if (rmsel->remote != NULL) { 216 if (rmconf->remote->sa_family != AF_UNSPEC) { 217 if (cmpsaddr(rmsel->remote, rmconf->remote) == CMPSADDR_MISMATCH){ 218 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 219 "Not matched: address mismatch.\n"); 220 return MATCH_NONE; 221 } 222 223 /* Address matched */ 224 ret |= MATCH_ADDRESS; 225 } 226 } 227 228 /* Check etype and approval */ 229 if (rmsel->etype != ISAKMP_ETYPE_NONE) { 230 tmp=rmconf_match_etype_and_approval(rmconf, rmsel->etype, 231 rmsel->approval); 232 if (tmp != 0){ 233 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 234 "Not matched: etype (%d)/approval mismatch (%d).\n", rmsel->etype, tmp); 235 return MATCH_NONE; 236 } 237 ret |= MATCH_SA; 238 } 239 240 /* Check identity */ 241 if (rmsel->identity != NULL && rmconf->verify_identifier) { 242 if (rmconf_match_identity(rmconf, rmsel->identity) != 0){ 243 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 244 "Not matched: identity mismatch.\n"); 245 return MATCH_NONE; 246 } 247 ret |= MATCH_IDENTITY; 248 } 249 250 /* Check certificate request */ 251 if (rmsel->certificate_request != NULL) { 252 if (oakley_get_certtype(rmsel->certificate_request) != 253 oakley_get_certtype(rmconf->mycert)){ 254 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 255 "Not matched: cert type mismatch.\n"); 256 return MATCH_NONE; 257 } 258 259 if (rmsel->certificate_request->l > 1) { 260 vchar_t *issuer; 261 262 issuer = eay_get_x509asn1issuername(rmconf->mycert); 263 if (rmsel->certificate_request->l - 1 != issuer->l || 264 memcmp(rmsel->certificate_request->v + 1, 265 issuer->v, issuer->l) != 0) { 266 vfree(issuer); 267 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 268 "Not matched: cert issuer mismatch.\n"); 269 return MATCH_NONE; 270 } 271 vfree(issuer); 272 } else { 273 if (!rmconf->match_empty_cr){ 274 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 275 "Not matched: empty certificate request.\n"); 276 return MATCH_NONE; 277 } 278 } 279 280 ret |= MATCH_AUTH_IDENTITY; 281 } 282 283 return ret; 284 } 285 286 void 287 rmconf_selector_from_ph1(struct rmconfselector *rmsel, struct ph1handle *iph1) 288 { 289 memset(rmsel, 0, sizeof(*rmsel)); 290 rmsel->flags = 0; 291 rmsel->remote = iph1->remote; 292 rmsel->etype = iph1->etype; 293 rmsel->approval = iph1->approval; 294 rmsel->identity = iph1->id_p; 295 rmsel->certificate_request = iph1->cr_p; 296 } 297 298 int 299 enumrmconf(struct rmconfselector *rmsel, 300 int (*enum_func)(struct remoteconf *, void *), void *enum_arg) 301 { 302 struct remoteconf *p; 303 int ret = 0; 304 305 RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) { 306 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 307 "Checking remote conf \"%s\" %s.\n", p->name, 308 p->remote->sa_family == AF_UNSPEC ? 309 "anonymous" : saddr2str(p->remote)); 310 311 if (rmsel != NULL) { 312 if (rmconf_match_type(rmsel, p) == MATCH_NONE){ 313 plog(LLV_DEBUG2, LOCATION, rmsel->remote, 314 "Not matched.\n"); 315 continue; 316 } 317 } 318 319 plog(LLV_DEBUG2, LOCATION, NULL, 320 "enumrmconf: \"%s\" matches.\n", p->name); 321 322 ret = (*enum_func)(p, enum_arg); 323 if (ret) 324 break; 325 } 326 327 return ret; 328 } 329 330 struct rmconf_find_context { 331 struct rmconfselector sel; 332 333 struct remoteconf *rmconf; 334 int match_type; 335 int num_found; 336 }; 337 338 static int 339 rmconf_find(struct remoteconf *rmconf, void *ctx) 340 { 341 struct rmconf_find_context *fctx = (struct rmconf_find_context *) ctx; 342 int match_type; 343 344 /* First matching remote conf? */ 345 match_type = rmconf_match_type(&fctx->sel, rmconf); 346 347 if (fctx->rmconf != NULL) { 348 /* More ambiguous matches are ignored. */ 349 if (match_type < fctx->match_type) 350 return 0; 351 352 if (match_type == fctx->match_type) { 353 /* Ambiguous match */ 354 fctx->num_found++; 355 return 0; 356 } 357 } 358 359 /* More exact match found */ 360 fctx->match_type = match_type; 361 fctx->num_found = 1; 362 fctx->rmconf = rmconf; 363 364 return 0; 365 } 366 367 /* 368 * search remote configuration. 369 * don't use port number to search if its value is either IPSEC_PORT_ANY. 370 * If matching anonymous entry, then new entry is copied from anonymous entry. 371 * If no anonymous entry found, then return NULL. 372 * OUT: NULL: NG 373 * Other: remote configuration entry. 374 */ 375 376 struct remoteconf * 377 getrmconf(struct sockaddr *remote, int flags) 378 { 379 struct rmconf_find_context ctx; 380 381 memset(&ctx, 0, sizeof(ctx)); 382 ctx.sel.flags = flags; 383 ctx.sel.remote = remote; 384 385 if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) { 386 plog(LLV_ERROR, LOCATION, remote, 387 "multiple exact configurations.\n"); 388 return NULL; 389 } 390 391 if (ctx.rmconf == NULL) { 392 plog(LLV_DEBUG, LOCATION, remote, 393 "no remote configuration found.\n"); 394 return NULL; 395 } 396 397 if (ctx.num_found != 1) { 398 plog(LLV_DEBUG, LOCATION, remote, 399 "multiple non-exact configurations found.\n"); 400 return NULL; 401 } 402 403 plog(LLV_DEBUG, LOCATION, remote, 404 "configuration \"%s\" selected.\n", 405 ctx.rmconf->name); 406 407 return ctx.rmconf; 408 } 409 410 struct remoteconf * 411 getrmconf_by_ph1(struct ph1handle *iph1) 412 { 413 struct rmconf_find_context ctx; 414 415 memset(&ctx, 0, sizeof(ctx)); 416 rmconf_selector_from_ph1(&ctx.sel, iph1); 417 if (loglevel >= LLV_DEBUG) { 418 char *idstr = NULL; 419 420 if (iph1->id_p != NULL) 421 idstr = ipsecdoi_id2str(iph1->id_p); 422 423 plog(LLV_DEBUG, LOCATION, iph1->remote, 424 "getrmconf_by_ph1: remote %s, identity %s.\n", 425 saddr2str(iph1->remote), idstr ? idstr : "<any>"); 426 427 if (idstr) 428 racoon_free(idstr); 429 } 430 431 if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) { 432 plog(LLV_ERROR, LOCATION, iph1->remote, 433 "multiple exact configurations.\n"); 434 return RMCONF_ERR_MULTIPLE; 435 } 436 437 if (ctx.rmconf == NULL) { 438 plog(LLV_DEBUG, LOCATION, iph1->remote, 439 "no remote configuration found\n"); 440 return NULL; 441 } 442 443 if (ctx.num_found != 1) { 444 plog(LLV_DEBUG, LOCATION, iph1->remote, 445 "multiple non-exact configurations found.\n"); 446 return RMCONF_ERR_MULTIPLE; 447 } 448 449 plog(LLV_DEBUG, LOCATION, iph1->remote, 450 "configuration \"%s\" selected.\n", 451 ctx.rmconf->name); 452 453 return ctx.rmconf; 454 } 455 456 struct remoteconf * 457 getrmconf_by_name(const char *name) 458 { 459 struct remoteconf *p; 460 461 plog(LLV_DEBUG, LOCATION, NULL, 462 "getrmconf_by_name: remote \"%s\".\n", 463 name); 464 465 RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) { 466 if (p->name == NULL) 467 continue; 468 469 if (strcmp(name, p->name) == 0) 470 return p; 471 } 472 473 return NULL; 474 } 475 476 struct remoteconf * 477 newrmconf(void) 478 { 479 struct remoteconf *new; 480 int i; 481 482 new = racoon_calloc(1, sizeof(*new)); 483 if (new == NULL) 484 return NULL; 485 486 new->proposal = NULL; 487 488 /* set default */ 489 new->doitype = IPSEC_DOI; 490 new->sittype = IPSECDOI_SIT_IDENTITY_ONLY; 491 new->idvtype = IDTYPE_UNDEFINED; 492 new->idvl_p = genlist_init(); 493 new->nonce_size = DEFAULT_NONCE_SIZE; 494 new->passive = FALSE; 495 new->ike_frag = FALSE; 496 new->esp_frag = IP_MAXPACKET; 497 new->ini_contact = TRUE; 498 new->mode_cfg = FALSE; 499 new->pcheck_level = PROP_CHECK_STRICT; 500 new->verify_identifier = FALSE; 501 new->verify_cert = TRUE; 502 new->cacertfile = NULL; 503 new->send_cert = TRUE; 504 new->send_cr = TRUE; 505 new->match_empty_cr = FALSE; 506 new->support_proxy = FALSE; 507 for (i = 0; i <= SCRIPT_MAX; i++) 508 new->script[i] = NULL; 509 new->gen_policy = FALSE; 510 new->nat_traversal = FALSE; 511 new->rsa_private = genlist_init(); 512 new->rsa_public = genlist_init(); 513 new->idv = NULL; 514 new->key = NULL; 515 516 new->dpd = TRUE; /* Enable DPD support by default */ 517 new->dpd_interval = 0; /* Disable DPD checks by default */ 518 new->dpd_retry = 5; 519 new->dpd_maxfails = 5; 520 521 new->rekey = REKEY_ON; 522 523 new->weak_phase1_check = 0; 524 525 #ifdef ENABLE_HYBRID 526 new->xauth = NULL; 527 #endif 528 529 new->lifetime = oakley_get_defaultlifetime(); 530 531 return new; 532 } 533 534 static void * 535 dupidvl(void *entry, void *arg) 536 { 537 struct idspec *id; 538 struct idspec *old = (struct idspec *) entry; 539 id = newidspec(); 540 if (!id) return (void *) -1; 541 542 if (set_identifier(&id->id, old->idtype, old->id) != 0) { 543 racoon_free(id); 544 return (void *) -1; 545 } 546 547 id->idtype = old->idtype; 548 549 genlist_append(arg, id); 550 return NULL; 551 } 552 553 static void * 554 duprsa(void *entry, void *arg) 555 { 556 struct rsa_key *new; 557 558 new = rsa_key_dup((struct rsa_key *)entry); 559 if (new == NULL) 560 return (void *) -1; 561 genlist_append(arg, new); 562 563 /* keep genlist_foreach going */ 564 return NULL; 565 } 566 567 /* Creates shallow copy of a remote config. Used for "inherit" keyword. */ 568 struct remoteconf * 569 duprmconf_shallow(struct remoteconf *rmconf) 570 { 571 struct remoteconf *new; 572 573 new = racoon_calloc(1, sizeof(*new)); 574 if (new == NULL) 575 return NULL; 576 577 memcpy(new, rmconf, sizeof(*new)); 578 new->name = NULL; 579 new->inherited_from = rmconf; 580 581 new->proposal = NULL; /* will be filled by set_isakmp_proposal() */ 582 583 /* Better to set remote to NULL to avoid that the destination 584 * rmconf uses the same allocated memory as the source rmconf. 585 */ 586 new->remote = NULL; 587 588 return new; 589 } 590 591 /* Copies pointer structures of an inherited remote config. 592 * Used by "inherit" mechanism in a two step copy method, necessary to 593 * prevent both double free() and memory leak during config reload. 594 */ 595 int 596 duprmconf_finish(struct remoteconf *new) 597 { 598 struct remoteconf *rmconf; 599 int i; 600 601 if (new->inherited_from == NULL) 602 return 0; /* nothing todo, no inheritance */ 603 604 rmconf = new->inherited_from; 605 606 /* duplicate dynamic structures unless value overridden */ 607 if (new->etypes != NULL && new->etypes == rmconf->etypes) 608 new->etypes = dupetypes(new->etypes); 609 if (new->idvl_p == rmconf->idvl_p) { 610 new->idvl_p = genlist_init(); 611 genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p); 612 } 613 614 if (new->rsa_private == rmconf->rsa_private) { 615 new->rsa_private = genlist_init(); 616 genlist_foreach(rmconf->rsa_private, duprsa, new->rsa_private); 617 } 618 if (new->rsa_public == rmconf->rsa_public) { 619 new->rsa_public = genlist_init(); 620 genlist_foreach(rmconf->rsa_public, duprsa, new->rsa_public); 621 } 622 if (new->remote != NULL && new->remote == rmconf->remote) { 623 new->remote = racoon_malloc(sizeof(*new->remote)); 624 if (new->remote == NULL) { 625 plog(LLV_ERROR, LOCATION, NULL, 626 "duprmconf_finish: malloc failed (remote)\n"); 627 exit(1); 628 } 629 memcpy(new->remote, rmconf->remote, sizeof(*new->remote)); 630 } 631 if (new->spspec != NULL && new->spspec == rmconf->spspec) { 632 dupspspec_list(new, rmconf); 633 } 634 635 /* proposal has been deep copied already from spspec's, see 636 * cfparse.y:set_isakmp_proposal, which in turn calls 637 * cfparse.y:expand_isakmpspec where the copying happens. 638 */ 639 640 #ifdef ENABLE_HYBRID 641 if (new->xauth != NULL && new->xauth == rmconf->xauth) { 642 new->xauth = xauth_rmconf_dup(new->xauth); 643 if (new->xauth == NULL) 644 exit(1); 645 } 646 #endif 647 648 /* duplicate strings unless value overridden */ 649 if (new->mycertfile != NULL && new->mycertfile == rmconf->mycertfile) { 650 new->mycertfile = racoon_strdup(new->mycertfile); 651 STRDUP_FATAL(new->mycertfile); 652 } 653 if (new->myprivfile != NULL && new->myprivfile == rmconf->myprivfile) { 654 new->myprivfile = racoon_strdup(new->myprivfile); 655 STRDUP_FATAL(new->myprivfile); 656 } 657 if (new->peerscertfile != NULL && new->peerscertfile == rmconf->peerscertfile) { 658 new->peerscertfile = racoon_strdup(new->peerscertfile); 659 STRDUP_FATAL(new->peerscertfile); 660 } 661 if (new->cacertfile != NULL && new->cacertfile == rmconf->cacertfile) { 662 new->cacertfile = racoon_strdup(new->cacertfile); 663 STRDUP_FATAL(new->cacertfile); 664 } 665 if (new->idv != NULL && new->idv == rmconf->idv) { 666 new->idv = vdup(new->idv); 667 STRDUP_FATAL(new->idv); 668 } 669 if (new->key != NULL && new->key == rmconf->key) { 670 new->key = vdup(new->key); 671 STRDUP_FATAL(new->key); 672 } 673 if (new->mycert != NULL && new->mycert == rmconf->mycert) { 674 new->mycert = vdup(new->mycert); 675 STRDUP_FATAL(new->mycert); 676 } 677 if (new->peerscert != NULL && new->peerscert == rmconf->peerscert) { 678 new->peerscert = vdup(new->peerscert); 679 STRDUP_FATAL(new->peerscert); 680 } 681 if (new->cacert != NULL && new->cacert == rmconf->cacert) { 682 new->cacert = vdup(new->cacert); 683 STRDUP_FATAL(new->cacert); 684 } 685 for (i = 0; i <= SCRIPT_MAX; i++) 686 if (new->script[i] != NULL && new->script[i] == rmconf->script[i]) { 687 new->script[i] = vdup(new->script[i]); 688 STRDUP_FATAL(new->script[i]); 689 } 690 691 return 0; 692 } 693 694 static void 695 idspec_free(void *data) 696 { 697 vfree (((struct idspec *)data)->id); 698 free (data); 699 } 700 701 void 702 delrmconf(struct remoteconf *rmconf) 703 { 704 int i; 705 706 if (rmconf == NULL) 707 return; 708 709 #ifdef ENABLE_HYBRID 710 if (rmconf->xauth) 711 xauth_rmconf_delete(&rmconf->xauth); 712 #endif 713 if (rmconf->etypes){ 714 deletypes(rmconf->etypes); 715 rmconf->etypes=NULL; 716 } 717 if (rmconf->idv) 718 vfree(rmconf->idv); 719 if (rmconf->key) 720 vfree(rmconf->key); 721 if (rmconf->idvl_p) 722 genlist_free(rmconf->idvl_p, idspec_free); 723 if (rmconf->dhgrp) 724 oakley_dhgrp_free(rmconf->dhgrp); 725 if (rmconf->proposal) 726 delisakmpsa(rmconf->proposal); 727 flushspspec(rmconf); 728 if (rmconf->mycert) 729 vfree(rmconf->mycert); 730 if (rmconf->mycertfile) 731 racoon_free(rmconf->mycertfile); 732 if (rmconf->myprivfile) 733 racoon_free(rmconf->myprivfile); 734 if (rmconf->peerscert) 735 vfree(rmconf->peerscert); 736 if (rmconf->peerscertfile) 737 racoon_free(rmconf->peerscertfile); 738 if (rmconf->cacert) 739 vfree(rmconf->cacert); 740 if (rmconf->cacertfile) 741 racoon_free(rmconf->cacertfile); 742 if (rmconf->rsa_private) 743 genlist_free(rmconf->rsa_private, rsa_key_free); 744 if (rmconf->rsa_public) 745 genlist_free(rmconf->rsa_public, rsa_key_free); 746 if (rmconf->name) 747 racoon_free(rmconf->name); 748 if (rmconf->remote) 749 racoon_free(rmconf->remote); 750 for (i = 0; i <= SCRIPT_MAX; i++) 751 if (rmconf->script[i]) 752 vfree(rmconf->script[i]); 753 754 racoon_free(rmconf); 755 } 756 757 void 758 delisakmpsa(struct isakmpsa *sa) 759 { 760 if (sa->dhgrp) 761 oakley_dhgrp_free(sa->dhgrp); 762 if (sa->next) 763 delisakmpsa(sa->next); 764 #ifdef HAVE_GSSAPI 765 if (sa->gssid) 766 vfree(sa->gssid); 767 #endif 768 racoon_free(sa); 769 } 770 771 struct etypes * 772 dupetypes(struct etypes *orig) 773 { 774 struct etypes *new; 775 776 if (!orig) 777 return NULL; 778 779 new = racoon_malloc(sizeof(struct etypes)); 780 if (new == NULL) 781 return NULL; 782 783 new->type = orig->type; 784 new->next = NULL; 785 786 if (orig->next) 787 new->next=dupetypes(orig->next); 788 789 return new; 790 } 791 792 void 793 deletypes(struct etypes *e) 794 { 795 if (e->next) 796 deletypes(e->next); 797 racoon_free(e); 798 } 799 800 /* 801 * insert into head of list. 802 */ 803 void 804 insrmconf(struct remoteconf *new) 805 { 806 if (new->name == NULL) { 807 new->name = racoon_strdup(saddr2str(new->remote)); 808 } 809 if (new->remote == NULL) { 810 new->remote = newsaddr(sizeof(struct sockaddr)); 811 new->remote->sa_family = AF_UNSPEC; 812 } 813 814 TAILQ_INSERT_HEAD(&rmtree, new, chain); 815 } 816 817 void 818 remrmconf(struct remoteconf *rmconf) 819 { 820 TAILQ_REMOVE(&rmtree, rmconf, chain); 821 } 822 823 void 824 flushrmconf(void) 825 { 826 struct remoteconf *p, *next; 827 828 for (p = TAILQ_FIRST(&rmtree); p; p = next) { 829 next = TAILQ_NEXT(p, chain); 830 remrmconf(p); 831 delrmconf(p); 832 } 833 } 834 835 void 836 initrmconf(void) 837 { 838 TAILQ_INIT(&rmtree); 839 } 840 841 void 842 rmconf_start_reload(void) 843 { 844 rmtree_save=rmtree; 845 initrmconf(); 846 } 847 848 void 849 rmconf_finish_reload(void) 850 { 851 remoteconf_tailq_head_t rmtree_tmp; 852 853 rmtree_tmp=rmtree; 854 rmtree=rmtree_save; 855 flushrmconf(); 856 initrmconf(); 857 rmtree=rmtree_tmp; 858 } 859 860 861 862 /* check exchange type to be acceptable */ 863 int 864 check_etypeok(struct remoteconf *rmconf, void *ctx) 865 { 866 u_int8_t etype = (u_int8_t) (intptr_t) ctx; 867 struct etypes *e; 868 869 for (e = rmconf->etypes; e != NULL; e = e->next) { 870 if (e->type == etype) 871 return 1; 872 plog(LLV_DEBUG2, LOCATION, NULL, 873 "Etype mismatch: got %d, expected %d.\n", e->type, etype); 874 } 875 876 return 0; 877 } 878 879 /*%%%*/ 880 struct isakmpsa * 881 newisakmpsa(void) 882 { 883 struct isakmpsa *new; 884 885 new = racoon_calloc(1, sizeof(*new)); 886 if (new == NULL) 887 return NULL; 888 889 /* 890 * Just for sanity, make sure this is initialized. This is 891 * filled in for real when the ISAKMP proposal is configured. 892 */ 893 new->vendorid = VENDORID_UNKNOWN; 894 895 new->next = NULL; 896 #ifdef HAVE_GSSAPI 897 new->gssid = NULL; 898 #endif 899 900 return new; 901 } 902 903 /* 904 * insert into tail of list. 905 */ 906 void 907 insisakmpsa(struct isakmpsa *new, struct remoteconf *rmconf) 908 { 909 struct isakmpsa *p; 910 911 if (rmconf->proposal == NULL) { 912 rmconf->proposal = new; 913 return; 914 } 915 916 for (p = rmconf->proposal; p->next != NULL; p = p->next) 917 ; 918 p->next = new; 919 } 920 921 /*ARGSUSED*/ 922 static void * 923 dump_peers_identifiers (void *entry, void *arg __unused) 924 { 925 struct idspec *id = (struct idspec*) entry; 926 char buf[1024], *pbuf; 927 pbuf = buf; 928 pbuf += sprintf (pbuf, "\tpeers_identifier %s", 929 s_idtype (id->idtype)); 930 if (id->id) 931 pbuf += sprintf (pbuf, " \"%s\"", id->id->v); 932 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 933 return NULL; 934 } 935 936 /*ARGSUSED*/ 937 static int 938 dump_rmconf_single (struct remoteconf *p, void *data __unused) 939 { 940 struct etypes *etype = p->etypes; 941 struct isakmpsa *prop = p->proposal; 942 char buf[1024], *pbuf; 943 944 pbuf = buf; 945 946 pbuf += sprintf(pbuf, "remote \"%s\"", p->name); 947 if (p->inherited_from) 948 pbuf += sprintf(pbuf, " inherit \"%s\"", 949 p->inherited_from->name); 950 plog(LLV_INFO, LOCATION, NULL, "%s {\n", buf); 951 pbuf = buf; 952 pbuf += sprintf(pbuf, "\texchange_type "); 953 while (etype) { 954 pbuf += sprintf (pbuf, "%s%s", s_etype(etype->type), 955 etype->next != NULL ? ", " : ";\n"); 956 etype = etype->next; 957 } 958 plog(LLV_INFO, LOCATION, NULL, "%s", buf); 959 plog(LLV_INFO, LOCATION, NULL, "\tdoi %s;\n", s_doi(p->doitype)); 960 pbuf = buf; 961 pbuf += sprintf(pbuf, "\tmy_identifier %s", s_idtype (p->idvtype)); 962 if (p->idvtype == IDTYPE_ASN1DN) { 963 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 964 plog(LLV_INFO, LOCATION, NULL, 965 "\tcertificate_type %s \"%s\" \"%s\";\n", 966 oakley_get_certtype(p->mycert) == ISAKMP_CERT_X509SIGN 967 ? "x509" : "*UNKNOWN*", 968 p->mycertfile, p->myprivfile); 969 970 switch (oakley_get_certtype(p->peerscert)) { 971 case ISAKMP_CERT_NONE: 972 plog(LLV_INFO, LOCATION, NULL, 973 "\t/* peers certificate from payload */\n"); 974 break; 975 case ISAKMP_CERT_X509SIGN: 976 plog(LLV_INFO, LOCATION, NULL, 977 "\tpeers_certfile \"%s\";\n", p->peerscertfile); 978 break; 979 case ISAKMP_CERT_DNS: 980 plog(LLV_INFO, LOCATION, NULL, 981 "\tpeers_certfile dnssec;\n"); 982 break; 983 default: 984 plog(LLV_INFO, LOCATION, NULL, 985 "\tpeers_certfile *UNKNOWN* (%d)\n", 986 oakley_get_certtype(p->peerscert)); 987 break; 988 } 989 } 990 else { 991 if (p->idv) 992 pbuf += sprintf (pbuf, " \"%s\"", p->idv->v); 993 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 994 genlist_foreach(p->idvl_p, &dump_peers_identifiers, NULL); 995 } 996 997 plog(LLV_INFO, LOCATION, NULL, "\trekey %s;\n", 998 p->rekey == REKEY_FORCE ? "force" : s_switch (p->rekey)); 999 plog(LLV_INFO, LOCATION, NULL, "\tsend_cert %s;\n", 1000 s_switch (p->send_cert)); 1001 plog(LLV_INFO, LOCATION, NULL, "\tsend_cr %s;\n", 1002 s_switch (p->send_cr)); 1003 plog(LLV_INFO, LOCATION, NULL, "\tmatch_empty_cr %s;\n", 1004 s_switch (p->match_empty_cr)); 1005 plog(LLV_INFO, LOCATION, NULL, "\tverify_cert %s;\n", 1006 s_switch (p->verify_cert)); 1007 plog(LLV_INFO, LOCATION, NULL, "\tverify_identifier %s;\n", 1008 s_switch (p->verify_identifier)); 1009 plog(LLV_INFO, LOCATION, NULL, "\tnat_traversal %s;\n", 1010 p->nat_traversal == NATT_FORCE ? 1011 "force" : s_switch (p->nat_traversal)); 1012 plog(LLV_INFO, LOCATION, NULL, "\tnonce_size %d;\n", 1013 p->nonce_size); 1014 plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n", 1015 s_switch (p->passive)); 1016 plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n", 1017 p->ike_frag == ISAKMP_FRAG_FORCE ? 1018 "force" : s_switch (p->ike_frag)); 1019 plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag); 1020 plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n", 1021 s_switch (p->ini_contact)); 1022 plog(LLV_INFO, LOCATION, NULL, "\tgenerate_policy %s;\n", 1023 s_switch (p->gen_policy)); 1024 plog(LLV_INFO, LOCATION, NULL, "\tsupport_proxy %s;\n", 1025 s_switch (p->support_proxy)); 1026 1027 while (prop) { 1028 plog(LLV_INFO, LOCATION, NULL, "\n"); 1029 plog(LLV_INFO, LOCATION, NULL, 1030 "\t/* prop_no=%d, trns_no=%d */\n", 1031 prop->prop_no, prop->trns_no); 1032 plog(LLV_INFO, LOCATION, NULL, "\tproposal {\n"); 1033 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime time %lu sec;\n", 1034 (long)prop->lifetime); 1035 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime bytes %zd;\n", 1036 prop->lifebyte); 1037 plog(LLV_INFO, LOCATION, NULL, "\t\tdh_group %s;\n", 1038 alg_oakley_dhdef_name(prop->dh_group)); 1039 plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n", 1040 alg_oakley_encdef_name(prop->enctype)); 1041 plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n", 1042 alg_oakley_hashdef_name(prop->hashtype)); 1043 plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n", 1044 alg_oakley_authdef_name(prop->authmethod)); 1045 plog(LLV_INFO, LOCATION, NULL, "\t}\n"); 1046 prop = prop->next; 1047 } 1048 plog(LLV_INFO, LOCATION, NULL, "}\n"); 1049 plog(LLV_INFO, LOCATION, NULL, "\n"); 1050 1051 return 0; 1052 } 1053 1054 void 1055 dumprmconf(void) 1056 { 1057 enumrmconf(NULL, dump_rmconf_single, NULL); 1058 } 1059 1060 struct idspec * 1061 newidspec(void) 1062 { 1063 struct idspec *new; 1064 1065 new = racoon_calloc(1, sizeof(*new)); 1066 if (new == NULL) 1067 return NULL; 1068 new->idtype = IDTYPE_ADDRESS; 1069 new->id = NULL; 1070 return new; 1071 } 1072 1073 vchar_t * 1074 script_path_add(vchar_t *path) 1075 { 1076 char *script_dir; 1077 vchar_t *new_path; 1078 size_t len; 1079 1080 script_dir = lcconf->pathinfo[LC_PATHTYPE_SCRIPT]; 1081 1082 /* Try to find the script in the script directory */ 1083 if ((path->v[0] != '/') && (script_dir != NULL)) { 1084 len = strlen(script_dir) + sizeof("/") + path->l + 1; 1085 1086 if ((new_path = vmalloc(len)) == NULL) { 1087 plog(LLV_ERROR, LOCATION, NULL, 1088 "Cannot allocate memory: %s\n", strerror(errno)); 1089 return NULL; 1090 } 1091 1092 new_path->v[0] = '\0'; 1093 (void)strlcat(new_path->v, script_dir, len); 1094 (void)strlcat(new_path->v, "/", len); 1095 (void)strlcat(new_path->v, path->v, len); 1096 1097 vfree(path); 1098 path = new_path; 1099 } 1100 1101 return path; 1102 } 1103 1104 1105 struct isakmpsa * 1106 dupisakmpsa(struct isakmpsa *sa) 1107 { 1108 struct isakmpsa *res = NULL; 1109 1110 if(sa == NULL) 1111 return NULL; 1112 1113 res = newisakmpsa(); 1114 if(res == NULL) 1115 return NULL; 1116 1117 *res = *sa; 1118 #ifdef HAVE_GSSAPI 1119 if (sa->gssid != NULL) 1120 res->gssid = vdup(sa->gssid); 1121 #endif 1122 res->next = NULL; 1123 1124 if(sa->dhgrp != NULL) 1125 oakley_setdhgroup(sa->dh_group, &res->dhgrp); 1126 1127 return res; 1128 1129 } 1130 1131 #ifdef ENABLE_HYBRID 1132 int 1133 isakmpsa_switch_authmethod(int authmethod) 1134 { 1135 switch(authmethod) { 1136 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 1137 authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I; 1138 break; 1139 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 1140 authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I; 1141 break; 1142 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 1143 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I; 1144 break; 1145 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 1146 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I; 1147 break; 1148 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 1149 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I; 1150 break; 1151 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 1152 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I; 1153 break; 1154 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 1155 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I; 1156 break; 1157 default: 1158 break; 1159 } 1160 1161 return authmethod; 1162 } 1163 #endif 1164 1165 /* 1166 * Given a proposed ISAKMP SA, and a list of acceptable 1167 * ISAKMP SAs, it compares using pcheck_level policy and 1168 * returns first match (if any). 1169 */ 1170 struct isakmpsa * 1171 checkisakmpsa(int pcheck_level, struct isakmpsa *proposal, 1172 struct isakmpsa *acceptable) 1173 { 1174 struct isakmpsa *p; 1175 1176 for (p = acceptable; p != NULL; p = p->next){ 1177 plog(LLV_DEBUG2, LOCATION, NULL, 1178 "checkisakmpsa:\nauthmethod: %d / %d\n", 1179 isakmpsa_switch_authmethod(proposal->authmethod), isakmpsa_switch_authmethod(p->authmethod)); 1180 if (isakmpsa_switch_authmethod(proposal->authmethod) != isakmpsa_switch_authmethod(p->authmethod) || 1181 proposal->enctype != p->enctype || 1182 proposal->dh_group != p->dh_group || 1183 proposal->hashtype != p->hashtype) 1184 continue; 1185 1186 switch (pcheck_level) { 1187 case PROP_CHECK_OBEY: 1188 break; 1189 1190 case PROP_CHECK_CLAIM: 1191 case PROP_CHECK_STRICT: 1192 if (proposal->encklen < p->encklen || 1193 #if 0 1194 proposal->lifebyte > p->lifebyte || 1195 #endif 1196 proposal->lifetime > p->lifetime) 1197 continue; 1198 break; 1199 1200 case PROP_CHECK_EXACT: 1201 if (proposal->encklen != p->encklen || 1202 #if 0 1203 proposal->lifebyte != p->lifebyte || 1204 #endif 1205 proposal->lifetime != p->lifetime) 1206 continue; 1207 break; 1208 1209 default: 1210 continue; 1211 } 1212 1213 return p; 1214 } 1215 1216 return NULL; 1217 } 1218