1/* $NetBSD: remoteconf.c,v 1.27 2012/01/01 15:29:28 tteras 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 83typedef TAILQ_HEAD(_rmtree, remoteconf) remoteconf_tailq_head_t; 84static remoteconf_tailq_head_t rmtree, rmtree_save; 85 86/* 87 * Script hook names and script hook paths 88 */ 89char *script_names[SCRIPT_MAX + 1] = { 90 "phase1_up", "phase1_down", "phase1_dead" }; 91 92/*%%%*/ 93 94int 95rmconf_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 165static int 166rmconf_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 190enum 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 199static int 200rmconf_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 294void 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 307int 308enumrmconf(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 341struct rmconf_find_context { 342 struct rmconfselector sel; 343 344 struct remoteconf *rmconf; 345 int match_type; 346 int num_found; 347}; 348 349static int 350rmconf_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 389struct remoteconf * 390getrmconf(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 426struct remoteconf * 427getrmconf_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 473struct remoteconf * 474getrmconf_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 494struct remoteconf * 495newrmconf() 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 552void * 553dupidvl(entry, arg) 554 void *entry; 555 void *arg; 556{ 557 struct idspec *id; 558 struct idspec *old = (struct idspec *) entry; 559 id = newidspec(); 560 if (!id) return (void *) -1; 561 562 if (set_identifier(&id->id, old->idtype, old->id) != 0) { 563 racoon_free(id); 564 return (void *) -1; 565 } 566 567 id->idtype = old->idtype; 568 569 genlist_append(arg, id); 570 return NULL; 571} 572 573void * 574duprsa(entry, arg) 575 void *entry; 576 void *arg; 577{ 578 struct rsa_key *new; 579 580 new = rsa_key_dup((struct rsa_key *)entry); 581 if (new == NULL) 582 return (void *) -1; 583 genlist_append(arg, new); 584 585 /* keep genlist_foreach going */ 586 return NULL; 587} 588 589/* Creates shallow copy of a remote config. Used for "inherit" keyword. */ 590struct remoteconf * 591duprmconf_shallow (rmconf) 592 struct remoteconf *rmconf; 593{ 594 struct remoteconf *new; 595 struct proposalspec *prspec; 596 597 new = racoon_calloc(1, sizeof(*new)); 598 if (new == NULL) 599 return NULL; 600 601 memcpy(new, rmconf, sizeof(*new)); 602 new->name = NULL; 603 new->inherited_from = rmconf; 604 605 new->proposal = NULL; /* will be filled by set_isakmp_proposal() */ 606 607 /* Better to set remote to NULL to avoid that the destination 608 * rmconf uses the same allocated memory as the source rmconf. 609 */ 610 new->remote = NULL; 611 612 return new; 613} 614 615/* Copies pointer structures of an inherited remote config. 616 * Used by "inherit" mechanism in a two step copy method, necessary to 617 * prevent both double free() and memory leak during config reload. 618 */ 619int 620duprmconf_finish (new) 621 struct remoteconf *new; 622{ 623 struct remoteconf *rmconf; 624 int i; 625 626 if (new->inherited_from == NULL) 627 return 0; /* nothing todo, no inheritance */ 628 629 rmconf = new->inherited_from; 630 631 /* duplicate dynamic structures unless value overridden */ 632 if (new->etypes != NULL && new->etypes == rmconf->etypes) 633 new->etypes = dupetypes(new->etypes); 634 if (new->idvl_p == rmconf->idvl_p) { 635 new->idvl_p = genlist_init(); 636 genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p); 637 } 638 639 if (new->rsa_private == rmconf->rsa_private) { 640 new->rsa_private = genlist_init(); 641 genlist_foreach(rmconf->rsa_private, duprsa, new->rsa_private); 642 } 643 if (new->rsa_public == rmconf->rsa_public) { 644 new->rsa_public = genlist_init(); 645 genlist_foreach(rmconf->rsa_public, duprsa, new->rsa_public); 646 } 647 if (new->remote != NULL && new->remote == rmconf->remote) { 648 new->remote = racoon_malloc(sizeof(*new->remote)); 649 if (new->remote == NULL) { 650 plog(LLV_ERROR, LOCATION, NULL, 651 "duprmconf_finish: malloc failed (remote)\n"); 652 exit(1); 653 } 654 memcpy(new->remote, rmconf->remote, sizeof(*new->remote)); 655 } 656 if (new->spspec != NULL && new->spspec == rmconf->spspec) { 657 dupspspec_list(new, rmconf); 658 } 659 660 /* proposal has been deep copied already from spspec's, see 661 * cfparse.y:set_isakmp_proposal, which in turn calls 662 * cfparse.y:expand_isakmpspec where the copying happens. 663 */ 664 665#ifdef ENABLE_HYBRID 666 if (new->xauth != NULL && new->xauth == rmconf->xauth) { 667 new->xauth = xauth_rmconf_dup(new->xauth); 668 if (new->xauth == NULL) 669 exit(1); 670 } 671#endif 672 673 /* duplicate strings unless value overridden */ 674 if (new->mycertfile != NULL && new->mycertfile == rmconf->mycertfile) { 675 new->mycertfile = racoon_strdup(new->mycertfile); 676 STRDUP_FATAL(new->mycertfile); 677 } 678 if (new->myprivfile != NULL && new->myprivfile == rmconf->myprivfile) { 679 new->myprivfile = racoon_strdup(new->myprivfile); 680 STRDUP_FATAL(new->myprivfile); 681 } 682 if (new->peerscertfile != NULL && new->peerscertfile == rmconf->peerscertfile) { 683 new->peerscertfile = racoon_strdup(new->peerscertfile); 684 STRDUP_FATAL(new->peerscertfile); 685 } 686 if (new->cacertfile != NULL && new->cacertfile == rmconf->cacertfile) { 687 new->cacertfile = racoon_strdup(new->cacertfile); 688 STRDUP_FATAL(new->cacertfile); 689 } 690 if (new->idv != NULL && new->idv == rmconf->idv) { 691 new->idv = vdup(new->idv); 692 STRDUP_FATAL(new->idv); 693 } 694 if (new->key != NULL && new->key == rmconf->key) { 695 new->key = vdup(new->key); 696 STRDUP_FATAL(new->key); 697 } 698 if (new->mycert != NULL && new->mycert == rmconf->mycert) { 699 new->mycert = vdup(new->mycert); 700 STRDUP_FATAL(new->mycert); 701 } 702 if (new->peerscert != NULL && new->peerscert == rmconf->peerscert) { 703 new->peerscert = vdup(new->peerscert); 704 STRDUP_FATAL(new->peerscert); 705 } 706 if (new->cacert != NULL && new->cacert == rmconf->cacert) { 707 new->cacert = vdup(new->cacert); 708 STRDUP_FATAL(new->cacert); 709 } 710 for (i = 0; i <= SCRIPT_MAX; i++) 711 if (new->script[i] != NULL && new->script[i] == rmconf->script[i]) { 712 new->script[i] = vdup(new->script[i]); 713 STRDUP_FATAL(new->script[i]); 714 } 715 716 return 0; 717} 718 719static void 720idspec_free(void *data) 721{ 722 vfree (((struct idspec *)data)->id); 723 free (data); 724} 725 726void 727delrmconf(rmconf) 728 struct remoteconf *rmconf; 729{ 730 int i; 731 732 if (rmconf == NULL) 733 return; 734 735#ifdef ENABLE_HYBRID 736 if (rmconf->xauth) 737 xauth_rmconf_delete(&rmconf->xauth); 738#endif 739 if (rmconf->etypes){ 740 deletypes(rmconf->etypes); 741 rmconf->etypes=NULL; 742 } 743 if (rmconf->idv) 744 vfree(rmconf->idv); 745 if (rmconf->key) 746 vfree(rmconf->key); 747 if (rmconf->idvl_p) 748 genlist_free(rmconf->idvl_p, idspec_free); 749 if (rmconf->dhgrp) 750 oakley_dhgrp_free(rmconf->dhgrp); 751 if (rmconf->proposal) 752 delisakmpsa(rmconf->proposal); 753 flushspspec(rmconf); 754 if (rmconf->mycert) 755 vfree(rmconf->mycert); 756 if (rmconf->mycertfile) 757 racoon_free(rmconf->mycertfile); 758 if (rmconf->myprivfile) 759 racoon_free(rmconf->myprivfile); 760 if (rmconf->peerscert) 761 vfree(rmconf->peerscert); 762 if (rmconf->peerscertfile) 763 racoon_free(rmconf->peerscertfile); 764 if (rmconf->cacert) 765 vfree(rmconf->cacert); 766 if (rmconf->cacertfile) 767 racoon_free(rmconf->cacertfile); 768 if (rmconf->rsa_private) 769 genlist_free(rmconf->rsa_private, rsa_key_free); 770 if (rmconf->rsa_public) 771 genlist_free(rmconf->rsa_public, rsa_key_free); 772 if (rmconf->name) 773 racoon_free(rmconf->name); 774 if (rmconf->remote) 775 racoon_free(rmconf->remote); 776 for (i = 0; i <= SCRIPT_MAX; i++) 777 if (rmconf->script[i]) 778 vfree(rmconf->script[i]); 779 780 racoon_free(rmconf); 781} 782 783void 784delisakmpsa(sa) 785 struct isakmpsa *sa; 786{ 787 if (sa->dhgrp) 788 oakley_dhgrp_free(sa->dhgrp); 789 if (sa->next) 790 delisakmpsa(sa->next); 791#ifdef HAVE_GSSAPI 792 if (sa->gssid) 793 vfree(sa->gssid); 794#endif 795 racoon_free(sa); 796} 797 798struct etypes * 799dupetypes(orig) 800 struct etypes *orig; 801{ 802 struct etypes *new; 803 804 if (!orig) 805 return NULL; 806 807 new = racoon_malloc(sizeof(struct etypes)); 808 if (new == NULL) 809 return NULL; 810 811 new->type = orig->type; 812 new->next = NULL; 813 814 if (orig->next) 815 new->next=dupetypes(orig->next); 816 817 return new; 818} 819 820void 821deletypes(e) 822 struct etypes *e; 823{ 824 if (e->next) 825 deletypes(e->next); 826 racoon_free(e); 827} 828 829/* 830 * insert into head of list. 831 */ 832void 833insrmconf(new) 834 struct remoteconf *new; 835{ 836 if (new->name == NULL) { 837 new->name = racoon_strdup(saddr2str(new->remote)); 838 } 839 if (new->remote == NULL) { 840 new->remote = newsaddr(sizeof(struct sockaddr)); 841 new->remote->sa_family = AF_UNSPEC; 842 } 843 844 TAILQ_INSERT_HEAD(&rmtree, new, chain); 845} 846 847void 848remrmconf(rmconf) 849 struct remoteconf *rmconf; 850{ 851 TAILQ_REMOVE(&rmtree, rmconf, chain); 852} 853 854void 855flushrmconf() 856{ 857 struct remoteconf *p, *next; 858 859 for (p = TAILQ_FIRST(&rmtree); p; p = next) { 860 next = TAILQ_NEXT(p, chain); 861 remrmconf(p); 862 delrmconf(p); 863 } 864} 865 866void 867initrmconf() 868{ 869 TAILQ_INIT(&rmtree); 870} 871 872void 873rmconf_start_reload() 874{ 875 rmtree_save=rmtree; 876 initrmconf(); 877} 878 879void 880rmconf_finish_reload() 881{ 882 remoteconf_tailq_head_t rmtree_tmp; 883 884 rmtree_tmp=rmtree; 885 rmtree=rmtree_save; 886 flushrmconf(); 887 initrmconf(); 888 rmtree=rmtree_tmp; 889} 890 891 892 893/* check exchange type to be acceptable */ 894int 895check_etypeok(rmconf, ctx) 896 struct remoteconf *rmconf; 897 void *ctx; 898{ 899 u_int8_t etype = (u_int8_t) (intptr_t) ctx; 900 struct etypes *e; 901 902 for (e = rmconf->etypes; e != NULL; e = e->next) { 903 if (e->type == etype) 904 return 1; 905 plog(LLV_DEBUG2, LOCATION, NULL, 906 "Etype mismatch: got %d, expected %d.\n", e->type, etype); 907 } 908 909 return 0; 910} 911 912/*%%%*/ 913struct isakmpsa * 914newisakmpsa() 915{ 916 struct isakmpsa *new; 917 918 new = racoon_calloc(1, sizeof(*new)); 919 if (new == NULL) 920 return NULL; 921 922 /* 923 * Just for sanity, make sure this is initialized. This is 924 * filled in for real when the ISAKMP proposal is configured. 925 */ 926 new->vendorid = VENDORID_UNKNOWN; 927 928 new->next = NULL; 929#ifdef HAVE_GSSAPI 930 new->gssid = NULL; 931#endif 932 933 return new; 934} 935 936/* 937 * insert into tail of list. 938 */ 939void 940insisakmpsa(new, rmconf) 941 struct isakmpsa *new; 942 struct remoteconf *rmconf; 943{ 944 struct isakmpsa *p; 945 946 if (rmconf->proposal == NULL) { 947 rmconf->proposal = new; 948 return; 949 } 950 951 for (p = rmconf->proposal; p->next != NULL; p = p->next) 952 ; 953 p->next = new; 954} 955 956static void * 957dump_peers_identifiers (void *entry, void *arg) 958{ 959 struct idspec *id = (struct idspec*) entry; 960 char buf[1024], *pbuf; 961 pbuf = buf; 962 pbuf += sprintf (pbuf, "\tpeers_identifier %s", 963 s_idtype (id->idtype)); 964 if (id->id) 965 pbuf += sprintf (pbuf, " \"%s\"", id->id->v); 966 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 967 return NULL; 968} 969 970static int 971dump_rmconf_single (struct remoteconf *p, void *data) 972{ 973 struct etypes *etype = p->etypes; 974 struct isakmpsa *prop = p->proposal; 975 char buf[1024], *pbuf; 976 977 pbuf = buf; 978 979 pbuf += sprintf(pbuf, "remote \"%s\"", p->name); 980 if (p->inherited_from) 981 pbuf += sprintf(pbuf, " inherit \"%s\"", 982 p->inherited_from->name); 983 plog(LLV_INFO, LOCATION, NULL, "%s {\n", buf); 984 pbuf = buf; 985 pbuf += sprintf(pbuf, "\texchange_type "); 986 while (etype) { 987 pbuf += sprintf (pbuf, "%s%s", s_etype(etype->type), 988 etype->next != NULL ? ", " : ";\n"); 989 etype = etype->next; 990 } 991 plog(LLV_INFO, LOCATION, NULL, "%s", buf); 992 plog(LLV_INFO, LOCATION, NULL, "\tdoi %s;\n", s_doi(p->doitype)); 993 pbuf = buf; 994 pbuf += sprintf(pbuf, "\tmy_identifier %s", s_idtype (p->idvtype)); 995 if (p->idvtype == IDTYPE_ASN1DN) { 996 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 997 plog(LLV_INFO, LOCATION, NULL, 998 "\tcertificate_type %s \"%s\" \"%s\";\n", 999 oakley_get_certtype(p->mycert) == ISAKMP_CERT_X509SIGN 1000 ? "x509" : "*UNKNOWN*", 1001 p->mycertfile, p->myprivfile); 1002 1003 switch (oakley_get_certtype(p->peerscert)) { 1004 case ISAKMP_CERT_NONE: 1005 plog(LLV_INFO, LOCATION, NULL, 1006 "\t/* peers certificate from payload */\n"); 1007 break; 1008 case ISAKMP_CERT_X509SIGN: 1009 plog(LLV_INFO, LOCATION, NULL, 1010 "\tpeers_certfile \"%s\";\n", p->peerscertfile); 1011 break; 1012 case ISAKMP_CERT_DNS: 1013 plog(LLV_INFO, LOCATION, NULL, 1014 "\tpeers_certfile dnssec;\n"); 1015 break; 1016 default: 1017 plog(LLV_INFO, LOCATION, NULL, 1018 "\tpeers_certfile *UNKNOWN* (%d)\n", 1019 oakley_get_certtype(p->peerscert)); 1020 break; 1021 } 1022 } 1023 else { 1024 if (p->idv) 1025 pbuf += sprintf (pbuf, " \"%s\"", p->idv->v); 1026 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 1027 genlist_foreach(p->idvl_p, &dump_peers_identifiers, NULL); 1028 } 1029 1030 plog(LLV_INFO, LOCATION, NULL, "\trekey %s;\n", 1031 p->rekey == REKEY_FORCE ? "force" : s_switch (p->rekey)); 1032 plog(LLV_INFO, LOCATION, NULL, "\tsend_cert %s;\n", 1033 s_switch (p->send_cert)); 1034 plog(LLV_INFO, LOCATION, NULL, "\tsend_cr %s;\n", 1035 s_switch (p->send_cr)); 1036 plog(LLV_INFO, LOCATION, NULL, "\tmatch_empty_cr %s;\n", 1037 s_switch (p->match_empty_cr)); 1038 plog(LLV_INFO, LOCATION, NULL, "\tverify_cert %s;\n", 1039 s_switch (p->verify_cert)); 1040 plog(LLV_INFO, LOCATION, NULL, "\tverify_identifier %s;\n", 1041 s_switch (p->verify_identifier)); 1042 plog(LLV_INFO, LOCATION, NULL, "\tnat_traversal %s;\n", 1043 p->nat_traversal == NATT_FORCE ? 1044 "force" : s_switch (p->nat_traversal)); 1045 plog(LLV_INFO, LOCATION, NULL, "\tnonce_size %d;\n", 1046 p->nonce_size); 1047 plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n", 1048 s_switch (p->passive)); 1049 plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n", 1050 p->ike_frag == ISAKMP_FRAG_FORCE ? 1051 "force" : s_switch (p->ike_frag)); 1052 plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag); 1053 plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n", 1054 s_switch (p->ini_contact)); 1055 plog(LLV_INFO, LOCATION, NULL, "\tgenerate_policy %s;\n", 1056 s_switch (p->gen_policy)); 1057 plog(LLV_INFO, LOCATION, NULL, "\tsupport_proxy %s;\n", 1058 s_switch (p->support_proxy)); 1059 1060 while (prop) { 1061 plog(LLV_INFO, LOCATION, NULL, "\n"); 1062 plog(LLV_INFO, LOCATION, NULL, 1063 "\t/* prop_no=%d, trns_no=%d */\n", 1064 prop->prop_no, prop->trns_no); 1065 plog(LLV_INFO, LOCATION, NULL, "\tproposal {\n"); 1066 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime time %lu sec;\n", 1067 (long)prop->lifetime); 1068 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime bytes %zd;\n", 1069 prop->lifebyte); 1070 plog(LLV_INFO, LOCATION, NULL, "\t\tdh_group %s;\n", 1071 alg_oakley_dhdef_name(prop->dh_group)); 1072 plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n", 1073 alg_oakley_encdef_name(prop->enctype)); 1074 plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n", 1075 alg_oakley_hashdef_name(prop->hashtype)); 1076 plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n", 1077 alg_oakley_authdef_name(prop->authmethod)); 1078 plog(LLV_INFO, LOCATION, NULL, "\t}\n"); 1079 prop = prop->next; 1080 } 1081 plog(LLV_INFO, LOCATION, NULL, "}\n"); 1082 plog(LLV_INFO, LOCATION, NULL, "\n"); 1083 1084 return 0; 1085} 1086 1087void 1088dumprmconf() 1089{ 1090 enumrmconf(NULL, dump_rmconf_single, NULL); 1091} 1092 1093struct idspec * 1094newidspec() 1095{ 1096 struct idspec *new; 1097 1098 new = racoon_calloc(1, sizeof(*new)); 1099 if (new == NULL) 1100 return NULL; 1101 new->idtype = IDTYPE_ADDRESS; 1102 new->id = NULL; 1103 return new; 1104} 1105 1106vchar_t * 1107script_path_add(path) 1108 vchar_t *path; 1109{ 1110 char *script_dir; 1111 vchar_t *new_path; 1112 vchar_t *new_storage; 1113 vchar_t **sp; 1114 size_t len; 1115 size_t size; 1116 1117 script_dir = lcconf->pathinfo[LC_PATHTYPE_SCRIPT]; 1118 1119 /* Try to find the script in the script directory */ 1120 if ((path->v[0] != '/') && (script_dir != NULL)) { 1121 len = strlen(script_dir) + sizeof("/") + path->l + 1; 1122 1123 if ((new_path = vmalloc(len)) == NULL) { 1124 plog(LLV_ERROR, LOCATION, NULL, 1125 "Cannot allocate memory: %s\n", strerror(errno)); 1126 return NULL; 1127 } 1128 1129 new_path->v[0] = '\0'; 1130 (void)strlcat(new_path->v, script_dir, len); 1131 (void)strlcat(new_path->v, "/", len); 1132 (void)strlcat(new_path->v, path->v, len); 1133 1134 vfree(path); 1135 path = new_path; 1136 } 1137 1138 return path; 1139} 1140 1141 1142struct isakmpsa * 1143dupisakmpsa(struct isakmpsa *sa) 1144{ 1145 struct isakmpsa *res = NULL; 1146 1147 if(sa == NULL) 1148 return NULL; 1149 1150 res = newisakmpsa(); 1151 if(res == NULL) 1152 return NULL; 1153 1154 *res = *sa; 1155#ifdef HAVE_GSSAPI 1156 if (sa->gssid != NULL) 1157 res->gssid = vdup(sa->gssid); 1158#endif 1159 res->next = NULL; 1160 1161 if(sa->dhgrp != NULL) 1162 oakley_setdhgroup(sa->dh_group, &res->dhgrp); 1163 1164 return res; 1165 1166} 1167 1168#ifdef ENABLE_HYBRID 1169int 1170isakmpsa_switch_authmethod(authmethod) 1171 int authmethod; 1172{ 1173 switch(authmethod) { 1174 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 1175 authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I; 1176 break; 1177 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 1178 authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I; 1179 break; 1180 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 1181 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I; 1182 break; 1183 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 1184 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I; 1185 break; 1186 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 1187 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I; 1188 break; 1189 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 1190 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I; 1191 break; 1192 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 1193 authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I; 1194 break; 1195 default: 1196 break; 1197 } 1198 1199 return authmethod; 1200} 1201#endif 1202 1203/* 1204 * Given a proposed ISAKMP SA, and a list of acceptable 1205 * ISAKMP SAs, it compares using pcheck_level policy and 1206 * returns first match (if any). 1207 */ 1208struct isakmpsa * 1209checkisakmpsa(pcheck_level, proposal, acceptable) 1210 int pcheck_level; 1211 struct isakmpsa *proposal, *acceptable; 1212{ 1213 struct isakmpsa *p; 1214 1215 for (p = acceptable; p != NULL; p = p->next){ 1216 plog(LLV_DEBUG2, LOCATION, NULL, 1217 "checkisakmpsa:\nauthmethod: %d / %d\n", 1218 isakmpsa_switch_authmethod(proposal->authmethod), isakmpsa_switch_authmethod(p->authmethod)); 1219 if (isakmpsa_switch_authmethod(proposal->authmethod) != isakmpsa_switch_authmethod(p->authmethod) || 1220 proposal->enctype != p->enctype || 1221 proposal->dh_group != p->dh_group || 1222 proposal->hashtype != p->hashtype) 1223 continue; 1224 1225 switch (pcheck_level) { 1226 case PROP_CHECK_OBEY: 1227 break; 1228 1229 case PROP_CHECK_CLAIM: 1230 case PROP_CHECK_STRICT: 1231 if (proposal->encklen < p->encklen || 1232#if 0 1233 proposal->lifebyte > p->lifebyte || 1234#endif 1235 proposal->lifetime > p->lifetime) 1236 continue; 1237 break; 1238 1239 case PROP_CHECK_EXACT: 1240 if (proposal->encklen != p->encklen || 1241#if 0 1242 proposal->lifebyte != p->lifebyte || 1243#endif 1244 proposal->lifetime != p->lifetime) 1245 continue; 1246 break; 1247 1248 default: 1249 continue; 1250 } 1251 1252 return p; 1253 } 1254 1255 return NULL; 1256} 1257