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