1 /* $NetBSD: remoteconf.c,v 1.9.4.2 2008/06/18 07:30:19 mgrooms 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 "oakley.h" 67 #include "remoteconf.h" 68 #include "localconf.h" 69 #include "grabmyaddr.h" 70 #include "policy.h" 71 #include "proposal.h" 72 #include "vendorid.h" 73 #include "gcmalloc.h" 74 #include "strnames.h" 75 #include "algorithm.h" 76 #include "nattraversal.h" 77 #include "isakmp_frag.h" 78 #include "genlist.h" 79 80 static TAILQ_HEAD(_rmtree, remoteconf) rmtree, rmtree_save, rmtree_tmp; 81 82 /* 83 * Script hook names and script hook paths 84 */ 85 char *script_names[SCRIPT_MAX + 1] = { "phase1_up", "phase1_down" }; 86 87 /*%%%*/ 88 /* 89 * search remote configuration. 90 * don't use port number to search if its value is either IPSEC_PORT_ANY. 91 * If matching anonymous entry, then new entry is copied from anonymous entry. 92 * If no anonymous entry found, then return NULL. 93 * OUT: NULL: NG 94 * Other: remote configuration entry. 95 */ 96 struct remoteconf * 97 getrmconf_strict(remote, allow_anon) 98 struct sockaddr *remote; 99 int allow_anon; 100 { 101 struct remoteconf *p; 102 struct remoteconf *anon = NULL; 103 int withport; 104 char buf[NI_MAXHOST + NI_MAXSERV + 10]; 105 char addr[NI_MAXHOST], port[NI_MAXSERV]; 106 107 withport = 0; 108 109 #ifndef ENABLE_NATT 110 /* 111 * We never have ports set in our remote configurations, but when 112 * NAT-T is enabled, the kernel can have policies with ports and 113 * send us an acquire message for a destination that has a port set. 114 * If we do this port check here, we don't find the remote config. 115 * 116 * In an ideal world, we would be able to have remote conf with 117 * port, and the port could be a wildcard. That test could be used. 118 */ 119 if (remote->sa_family != AF_UNSPEC && 120 extract_port(remote) != IPSEC_PORT_ANY) 121 withport = 1; 122 #endif /* ENABLE_NATT */ 123 124 if (remote->sa_family == AF_UNSPEC) 125 snprintf (buf, sizeof(buf), "%s", "anonymous"); 126 else { 127 GETNAMEINFO(remote, addr, port); 128 snprintf(buf, sizeof(buf), "%s%s%s%s", addr, 129 withport ? "[" : "", 130 withport ? port : "", 131 withport ? "]" : ""); 132 } 133 134 TAILQ_FOREACH(p, &rmtree, chain) { 135 if ((remote->sa_family == AF_UNSPEC 136 && remote->sa_family == p->remote->sa_family) 137 || (!withport && cmpsaddrwop(remote, p->remote) == 0) 138 || (withport && cmpsaddrstrict(remote, p->remote) == 0)) { 139 plog(LLV_DEBUG, LOCATION, NULL, 140 "configuration found for %s.\n", buf); 141 return p; 142 } 143 144 /* save the pointer to the anonymous configuration */ 145 if (p->remote->sa_family == AF_UNSPEC) 146 anon = p; 147 } 148 149 if (allow_anon && anon != NULL) { 150 plog(LLV_DEBUG, LOCATION, NULL, 151 "anonymous configuration selected for %s.\n", buf); 152 return anon; 153 } 154 155 plog(LLV_DEBUG, LOCATION, NULL, 156 "no remote configuration found.\n"); 157 158 return NULL; 159 } 160 161 struct remoteconf * 162 getrmconf(remote) 163 struct sockaddr *remote; 164 { 165 return getrmconf_strict(remote, 1); 166 } 167 168 struct remoteconf * 169 newrmconf() 170 { 171 struct remoteconf *new; 172 int i; 173 174 new = racoon_calloc(1, sizeof(*new)); 175 if (new == NULL) 176 return NULL; 177 178 new->proposal = NULL; 179 180 /* set default */ 181 new->doitype = IPSEC_DOI; 182 new->sittype = IPSECDOI_SIT_IDENTITY_ONLY; 183 new->idvtype = IDTYPE_UNDEFINED; 184 new->idvl_p = genlist_init(); 185 new->nonce_size = DEFAULT_NONCE_SIZE; 186 new->passive = FALSE; 187 new->ike_frag = FALSE; 188 new->esp_frag = IP_MAXPACKET; 189 new->ini_contact = TRUE; 190 new->mode_cfg = FALSE; 191 new->pcheck_level = PROP_CHECK_STRICT; 192 new->verify_identifier = FALSE; 193 new->verify_cert = TRUE; 194 new->getcert_method = ISAKMP_GETCERT_PAYLOAD; 195 new->getcacert_method = ISAKMP_GETCERT_LOCALFILE; 196 new->cacerttype = ISAKMP_CERT_X509SIGN; 197 new->certtype = ISAKMP_CERT_NONE; 198 new->cacertfile = NULL; 199 new->send_cert = TRUE; 200 new->send_cr = TRUE; 201 new->support_proxy = FALSE; 202 for (i = 0; i <= SCRIPT_MAX; i++) 203 new->script[i] = NULL; 204 new->gen_policy = FALSE; 205 new->retry_counter = lcconf->retry_counter; 206 new->retry_interval = lcconf->retry_interval; 207 new->nat_traversal = FALSE; 208 new->rsa_private = genlist_init(); 209 new->rsa_public = genlist_init(); 210 new->idv = NULL; 211 new->key = NULL; 212 213 new->dpd = TRUE; /* Enable DPD support by default */ 214 new->dpd_interval = 0; /* Disable DPD checks by default */ 215 new->dpd_retry = 5; 216 new->dpd_maxfails = 5; 217 218 new->weak_phase1_check = 0; 219 220 #ifdef ENABLE_HYBRID 221 new->xauth = NULL; 222 #endif 223 224 return new; 225 } 226 227 struct remoteconf * 228 copyrmconf(remote) 229 struct sockaddr *remote; 230 { 231 struct remoteconf *new, *old; 232 233 old = getrmconf_strict (remote, 0); 234 if (old == NULL) { 235 plog (LLV_ERROR, LOCATION, NULL, 236 "Remote configuration for '%s' not found!\n", 237 saddr2str (remote)); 238 return NULL; 239 } 240 241 new = duprmconf (old); 242 243 return new; 244 } 245 246 void * 247 dupidvl(entry, arg) 248 void *entry; 249 void *arg; 250 { 251 struct idspec *id; 252 struct idspec *old = (struct idspec *) entry; 253 id = newidspec(); 254 if (!id) return (void *) -1; 255 256 if (set_identifier(&id->id, old->idtype, old->id) != 0) { 257 racoon_free(id); 258 return (void *) -1; 259 } 260 261 id->idtype = old->idtype; 262 263 genlist_append(arg, id); 264 return NULL; 265 } 266 267 struct remoteconf * 268 duprmconf (rmconf) 269 struct remoteconf *rmconf; 270 { 271 struct remoteconf *new; 272 273 new = racoon_calloc(1, sizeof(*new)); 274 if (new == NULL) 275 return NULL; 276 memcpy (new, rmconf, sizeof (*new)); 277 // FIXME: We should duplicate the proposal as well. 278 // This is now handled in the cfparse.y 279 // new->proposal = ...; 280 281 /* duplicate dynamic structures */ 282 if (new->etypes) 283 new->etypes=dupetypes(new->etypes); 284 new->idvl_p = genlist_init(); 285 genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p); 286 287 return new; 288 } 289 290 static void 291 idspec_free(void *data) 292 { 293 vfree (((struct idspec *)data)->id); 294 free (data); 295 } 296 297 void 298 delrmconf(rmconf) 299 struct remoteconf *rmconf; 300 { 301 #ifdef ENABLE_HYBRID 302 if (rmconf->xauth) 303 xauth_rmconf_delete(&rmconf->xauth); 304 #endif 305 if (rmconf->etypes){ 306 deletypes(rmconf->etypes); 307 rmconf->etypes=NULL; 308 } 309 if (rmconf->idvl_p) 310 genlist_free(rmconf->idvl_p, idspec_free); 311 if (rmconf->dhgrp) 312 oakley_dhgrp_free(rmconf->dhgrp); 313 if (rmconf->proposal) 314 delisakmpsa(rmconf->proposal); 315 racoon_free(rmconf); 316 } 317 318 void 319 delisakmpsa(sa) 320 struct isakmpsa *sa; 321 { 322 if (sa->dhgrp) 323 oakley_dhgrp_free(sa->dhgrp); 324 if (sa->next) 325 delisakmpsa(sa->next); 326 #ifdef HAVE_GSSAPI 327 if (sa->gssid) 328 vfree(sa->gssid); 329 #endif 330 racoon_free(sa); 331 } 332 333 struct etypes * 334 dupetypes(orig) 335 struct etypes *orig; 336 { 337 struct etypes *new; 338 339 if (!orig) 340 return NULL; 341 342 new = racoon_malloc(sizeof(struct etypes)); 343 if (new == NULL) 344 return NULL; 345 346 new->type = orig->type; 347 new->next = NULL; 348 349 if (orig->next) 350 new->next=dupetypes(orig->next); 351 352 return new; 353 } 354 355 void 356 deletypes(e) 357 struct etypes *e; 358 { 359 if (e->next) 360 deletypes(e->next); 361 racoon_free(e); 362 } 363 364 /* 365 * insert into head of list. 366 */ 367 void 368 insrmconf(new) 369 struct remoteconf *new; 370 { 371 TAILQ_INSERT_HEAD(&rmtree, new, chain); 372 } 373 374 void 375 remrmconf(rmconf) 376 struct remoteconf *rmconf; 377 { 378 TAILQ_REMOVE(&rmtree, rmconf, chain); 379 } 380 381 void 382 flushrmconf() 383 { 384 struct remoteconf *p, *next; 385 386 for (p = TAILQ_FIRST(&rmtree); p; p = next) { 387 next = TAILQ_NEXT(p, chain); 388 remrmconf(p); 389 delrmconf(p); 390 } 391 } 392 393 void 394 initrmconf() 395 { 396 TAILQ_INIT(&rmtree); 397 } 398 399 void 400 save_rmconf() 401 { 402 rmtree_save=rmtree; 403 initrmconf(); 404 } 405 406 void 407 save_rmconf_flush() 408 { 409 rmtree_tmp=rmtree; 410 rmtree=rmtree_save; 411 flushrmconf(); 412 initrmconf(); 413 rmtree=rmtree_tmp; 414 } 415 416 417 418 /* check exchange type to be acceptable */ 419 struct etypes * 420 check_etypeok(rmconf, etype) 421 struct remoteconf *rmconf; 422 u_int8_t etype; 423 { 424 struct etypes *e; 425 426 for (e = rmconf->etypes; e != NULL; e = e->next) { 427 if (e->type == etype) 428 break; 429 } 430 431 return e; 432 } 433 434 /*%%%*/ 435 struct isakmpsa * 436 newisakmpsa() 437 { 438 struct isakmpsa *new; 439 440 new = racoon_calloc(1, sizeof(*new)); 441 if (new == NULL) 442 return NULL; 443 444 /* 445 * Just for sanity, make sure this is initialized. This is 446 * filled in for real when the ISAKMP proposal is configured. 447 */ 448 new->vendorid = VENDORID_UNKNOWN; 449 450 new->next = NULL; 451 new->rmconf = NULL; 452 #ifdef HAVE_GSSAPI 453 new->gssid = NULL; 454 #endif 455 456 return new; 457 } 458 459 /* 460 * insert into tail of list. 461 */ 462 void 463 insisakmpsa(new, rmconf) 464 struct isakmpsa *new; 465 struct remoteconf *rmconf; 466 { 467 struct isakmpsa *p; 468 469 new->rmconf = rmconf; 470 471 if (rmconf->proposal == NULL) { 472 rmconf->proposal = new; 473 return; 474 } 475 476 for (p = rmconf->proposal; p->next != NULL; p = p->next) 477 ; 478 p->next = new; 479 480 return; 481 } 482 483 struct remoteconf * 484 foreachrmconf(rmconf_func_t rmconf_func, void *data) 485 { 486 struct remoteconf *p, *ret = NULL; 487 RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) { 488 ret = (*rmconf_func)(p, data); 489 if (ret) 490 break; 491 } 492 493 return ret; 494 } 495 496 static void * 497 dump_peers_identifiers (void *entry, void *arg) 498 { 499 struct idspec *id = (struct idspec*) entry; 500 char buf[1024], *pbuf; 501 pbuf = buf; 502 pbuf += sprintf (pbuf, "\tpeers_identifier %s", 503 s_idtype (id->idtype)); 504 if (id->id) 505 pbuf += sprintf (pbuf, " \"%s\"", id->id->v); 506 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 507 return NULL; 508 } 509 510 static struct remoteconf * 511 dump_rmconf_single (struct remoteconf *p, void *data) 512 { 513 struct etypes *etype = p->etypes; 514 struct isakmpsa *prop = p->proposal; 515 char buf[1024], *pbuf; 516 517 pbuf = buf; 518 pbuf += sprintf(pbuf, "remote %s", saddr2str(p->remote)); 519 if (p->inherited_from) 520 pbuf += sprintf(pbuf, " inherit %s", 521 saddr2str(p->inherited_from->remote)); 522 plog(LLV_INFO, LOCATION, NULL, "%s {\n", buf); 523 pbuf = buf; 524 pbuf += sprintf(pbuf, "\texchange_type "); 525 while (etype) { 526 pbuf += sprintf (pbuf, "%s%s", s_etype(etype->type), 527 etype->next != NULL ? ", " : ";\n"); 528 etype = etype->next; 529 } 530 plog(LLV_INFO, LOCATION, NULL, "%s", buf); 531 plog(LLV_INFO, LOCATION, NULL, "\tdoi %s;\n", s_doi(p->doitype)); 532 pbuf = buf; 533 pbuf += sprintf(pbuf, "\tmy_identifier %s", s_idtype (p->idvtype)); 534 if (p->idvtype == IDTYPE_ASN1DN) { 535 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 536 plog(LLV_INFO, LOCATION, NULL, "\tcertificate_type %s \"%s\" \"%s\";\n", 537 p->certtype == ISAKMP_CERT_X509SIGN ? "x509" : "*UNKNOWN*", 538 p->mycertfile, p->myprivfile); 539 switch (p->getcert_method) { 540 case 0: 541 break; 542 case ISAKMP_GETCERT_PAYLOAD: 543 plog(LLV_INFO, LOCATION, NULL, "\t/* peers certificate from payload */\n"); 544 break; 545 case ISAKMP_GETCERT_LOCALFILE: 546 plog(LLV_INFO, LOCATION, NULL, "\tpeers_certfile \"%s\";\n", p->peerscertfile); 547 break; 548 case ISAKMP_GETCERT_DNS: 549 plog(LLV_INFO, LOCATION, NULL, "\tpeer_certfile dnssec;\n"); 550 break; 551 default: 552 plog(LLV_INFO, LOCATION, NULL, "\tpeers_certfile *UNKNOWN* (%d)\n", p->getcert_method); 553 } 554 } 555 else { 556 if (p->idv) 557 pbuf += sprintf (pbuf, " \"%s\"", p->idv->v); 558 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 559 genlist_foreach(p->idvl_p, &dump_peers_identifiers, NULL); 560 } 561 562 plog(LLV_INFO, LOCATION, NULL, "\tsend_cert %s;\n", 563 s_switch (p->send_cert)); 564 plog(LLV_INFO, LOCATION, NULL, "\tsend_cr %s;\n", 565 s_switch (p->send_cr)); 566 plog(LLV_INFO, LOCATION, NULL, "\tverify_cert %s;\n", 567 s_switch (p->verify_cert)); 568 plog(LLV_INFO, LOCATION, NULL, "\tverify_identifier %s;\n", 569 s_switch (p->verify_identifier)); 570 plog(LLV_INFO, LOCATION, NULL, "\tnat_traversal %s;\n", 571 p->nat_traversal == NATT_FORCE ? 572 "force" : s_switch (p->nat_traversal)); 573 plog(LLV_INFO, LOCATION, NULL, "\tnonce_size %d;\n", 574 p->nonce_size); 575 plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n", 576 s_switch (p->passive)); 577 plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n", 578 p->ike_frag == ISAKMP_FRAG_FORCE ? 579 "force" : s_switch (p->ike_frag)); 580 plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag); 581 plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n", 582 s_switch (p->ini_contact)); 583 plog(LLV_INFO, LOCATION, NULL, "\tgenerate_policy %s;\n", 584 s_switch (p->gen_policy)); 585 plog(LLV_INFO, LOCATION, NULL, "\tsupport_proxy %s;\n", 586 s_switch (p->support_proxy)); 587 588 while (prop) { 589 plog(LLV_INFO, LOCATION, NULL, "\n"); 590 plog(LLV_INFO, LOCATION, NULL, 591 "\t/* prop_no=%d, trns_no=%d, rmconf=%s */\n", 592 prop->prop_no, prop->trns_no, 593 saddr2str(prop->rmconf->remote)); 594 plog(LLV_INFO, LOCATION, NULL, "\tproposal {\n"); 595 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime time %lu sec;\n", 596 (long)prop->lifetime); 597 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime bytes %zd;\n", 598 prop->lifebyte); 599 plog(LLV_INFO, LOCATION, NULL, "\t\tdh_group %s;\n", 600 alg_oakley_dhdef_name(prop->dh_group)); 601 plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n", 602 alg_oakley_encdef_name(prop->enctype)); 603 plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n", 604 alg_oakley_hashdef_name(prop->hashtype)); 605 plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n", 606 alg_oakley_authdef_name(prop->authmethod)); 607 plog(LLV_INFO, LOCATION, NULL, "\t}\n"); 608 prop = prop->next; 609 } 610 plog(LLV_INFO, LOCATION, NULL, "}\n"); 611 plog(LLV_INFO, LOCATION, NULL, "\n"); 612 613 return NULL; 614 } 615 616 void 617 dumprmconf() 618 { 619 foreachrmconf (dump_rmconf_single, NULL); 620 } 621 622 struct idspec * 623 newidspec() 624 { 625 struct idspec *new; 626 627 new = racoon_calloc(1, sizeof(*new)); 628 if (new == NULL) 629 return NULL; 630 new->idtype = IDTYPE_ADDRESS; 631 632 return new; 633 } 634 635 vchar_t * 636 script_path_add(path) 637 vchar_t *path; 638 { 639 char *script_dir; 640 vchar_t *new_path; 641 vchar_t *new_storage; 642 vchar_t **sp; 643 size_t len; 644 size_t size; 645 646 script_dir = lcconf->pathinfo[LC_PATHTYPE_SCRIPT]; 647 648 /* Try to find the script in the script directory */ 649 if ((path->v[0] != '/') && (script_dir != NULL)) { 650 len = strlen(script_dir) + sizeof("/") + path->l + 1; 651 652 if ((new_path = vmalloc(len)) == NULL) { 653 plog(LLV_ERROR, LOCATION, NULL, 654 "Cannot allocate memory: %s\n", strerror(errno)); 655 return NULL; 656 } 657 658 new_path->v[0] = '\0'; 659 (void)strlcat(new_path->v, script_dir, len); 660 (void)strlcat(new_path->v, "/", len); 661 (void)strlcat(new_path->v, path->v, len); 662 663 vfree(path); 664 path = new_path; 665 } 666 667 return path; 668 } 669 670 671 struct isakmpsa * 672 dupisakmpsa(struct isakmpsa *sa) 673 { 674 struct isakmpsa *res=NULL; 675 676 if(sa == NULL) 677 return NULL; 678 679 res=newisakmpsa(); 680 if(res == NULL) 681 return NULL; 682 683 *res=*sa; 684 #ifdef HAVE_GSSAPI 685 /* XXX gssid 686 */ 687 #endif 688 res->next=NULL; 689 690 if(sa->dhgrp != NULL) 691 oakley_setdhgroup (sa->dh_group, &(res->dhgrp)); 692 693 return res; 694 695 } 696