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