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