1 /* $NetBSD: remoteconf.c,v 1.10 2007/07/18 12:07:52 vanhu Exp $ */ 2 3 /* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 manubsd Exp */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "config.h" 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/socket.h> 39 #include <sys/queue.h> 40 41 #include <netinet/in.h> 42 #include <netinet/in_systm.h> 43 #include <netinet/ip.h> 44 45 #include PATH_IPSEC_H 46 47 #include <stdlib.h> 48 #include <stdio.h> 49 #include <string.h> 50 #include <errno.h> 51 52 #include "var.h" 53 #include "misc.h" 54 #include "vmbuf.h" 55 #include "plog.h" 56 #include "sockmisc.h" 57 #include "genlist.h" 58 #include "debug.h" 59 60 #include "isakmp_var.h" 61 #ifdef ENABLE_HYBRID 62 #include "isakmp_xauth.h" 63 #endif 64 #include "isakmp.h" 65 #include "ipsec_doi.h" 66 #include "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 switch (remote->sa_family) { 120 case AF_INET: 121 if (((struct sockaddr_in *)remote)->sin_port != IPSEC_PORT_ANY) 122 withport = 1; 123 break; 124 #ifdef INET6 125 case AF_INET6: 126 if (((struct sockaddr_in6 *)remote)->sin6_port != IPSEC_PORT_ANY) 127 withport = 1; 128 break; 129 #endif 130 case AF_UNSPEC: 131 break; 132 133 default: 134 plog(LLV_ERROR, LOCATION, NULL, 135 "invalid family: %d\n", remote->sa_family); 136 exit(1); 137 } 138 #endif /* ENABLE_NATT */ 139 140 if (remote->sa_family == AF_UNSPEC) 141 snprintf (buf, sizeof(buf), "%s", "anonymous"); 142 else { 143 GETNAMEINFO(remote, addr, port); 144 snprintf(buf, sizeof(buf), "%s%s%s%s", addr, 145 withport ? "[" : "", 146 withport ? port : "", 147 withport ? "]" : ""); 148 } 149 150 TAILQ_FOREACH(p, &rmtree, chain) { 151 if ((remote->sa_family == AF_UNSPEC 152 && remote->sa_family == p->remote->sa_family) 153 || (!withport && cmpsaddrwop(remote, p->remote) == 0) 154 || (withport && cmpsaddrstrict(remote, p->remote) == 0)) { 155 plog(LLV_DEBUG, LOCATION, NULL, 156 "configuration found for %s.\n", buf); 157 return p; 158 } 159 160 /* save the pointer to the anonymous configuration */ 161 if (p->remote->sa_family == AF_UNSPEC) 162 anon = p; 163 } 164 165 if (allow_anon && anon != NULL) { 166 plog(LLV_DEBUG, LOCATION, NULL, 167 "anonymous configuration selected for %s.\n", buf); 168 return anon; 169 } 170 171 plog(LLV_DEBUG, LOCATION, NULL, 172 "no remote configuration found.\n"); 173 174 return NULL; 175 } 176 177 struct remoteconf * 178 getrmconf(remote) 179 struct sockaddr *remote; 180 { 181 return getrmconf_strict(remote, 1); 182 } 183 184 struct remoteconf * 185 newrmconf() 186 { 187 struct remoteconf *new; 188 int i; 189 190 new = racoon_calloc(1, sizeof(*new)); 191 if (new == NULL) 192 return NULL; 193 194 new->proposal = NULL; 195 196 /* set default */ 197 new->doitype = IPSEC_DOI; 198 new->sittype = IPSECDOI_SIT_IDENTITY_ONLY; 199 new->idvtype = IDTYPE_UNDEFINED; 200 new->idvl_p = genlist_init(); 201 new->nonce_size = DEFAULT_NONCE_SIZE; 202 new->passive = FALSE; 203 new->ike_frag = FALSE; 204 new->esp_frag = IP_MAXPACKET; 205 new->ini_contact = TRUE; 206 new->mode_cfg = FALSE; 207 new->pcheck_level = PROP_CHECK_STRICT; 208 new->verify_identifier = FALSE; 209 new->verify_cert = TRUE; 210 new->getcert_method = ISAKMP_GETCERT_PAYLOAD; 211 new->getcacert_method = ISAKMP_GETCERT_LOCALFILE; 212 new->cacerttype = ISAKMP_CERT_X509SIGN; 213 new->certtype = ISAKMP_CERT_NONE; 214 new->cacertfile = NULL; 215 new->send_cert = TRUE; 216 new->send_cr = TRUE; 217 new->support_proxy = FALSE; 218 for (i = 0; i <= SCRIPT_MAX; i++) 219 new->script[i] = NULL; 220 new->gen_policy = FALSE; 221 new->retry_counter = lcconf->retry_counter; 222 new->retry_interval = lcconf->retry_interval; 223 new->nat_traversal = FALSE; 224 new->rsa_private = genlist_init(); 225 new->rsa_public = genlist_init(); 226 new->idv = NULL; 227 new->key = NULL; 228 229 new->dpd = TRUE; /* Enable DPD support by default */ 230 new->dpd_interval = 0; /* Disable DPD checks by default */ 231 new->dpd_retry = 5; 232 new->dpd_maxfails = 5; 233 234 new->weak_phase1_check = 0; 235 236 #ifdef ENABLE_HYBRID 237 new->xauth = NULL; 238 #endif 239 240 return new; 241 } 242 243 struct remoteconf * 244 copyrmconf(remote) 245 struct sockaddr *remote; 246 { 247 struct remoteconf *new, *old; 248 249 old = getrmconf_strict (remote, 0); 250 if (old == NULL) { 251 plog (LLV_ERROR, LOCATION, NULL, 252 "Remote configuration for '%s' not found!\n", 253 saddr2str (remote)); 254 return NULL; 255 } 256 257 new = duprmconf (old); 258 259 return new; 260 } 261 262 void * 263 dupidvl(entry, arg) 264 void *entry; 265 void *arg; 266 { 267 struct idspec *id; 268 struct idspec *old = (struct idspec *) entry; 269 id = newidspec(); 270 if (!id) return (void *) -1; 271 272 if (set_identifier(&id->id, old->idtype, old->id) != 0) { 273 racoon_free(id); 274 return (void *) -1; 275 } 276 277 id->idtype = old->idtype; 278 279 genlist_append(arg, id); 280 return NULL; 281 } 282 283 struct remoteconf * 284 duprmconf (rmconf) 285 struct remoteconf *rmconf; 286 { 287 struct remoteconf *new; 288 289 new = racoon_calloc(1, sizeof(*new)); 290 if (new == NULL) 291 return NULL; 292 memcpy (new, rmconf, sizeof (*new)); 293 // FIXME: We should duplicate the proposal as well. 294 // This is now handled in the cfparse.y 295 // new->proposal = ...; 296 297 /* duplicate dynamic structures */ 298 if (new->etypes) 299 new->etypes=dupetypes(new->etypes); 300 new->idvl_p = genlist_init(); 301 genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p); 302 303 return new; 304 } 305 306 static void 307 idspec_free(void *data) 308 { 309 vfree (((struct idspec *)data)->id); 310 free (data); 311 } 312 313 void 314 delrmconf(rmconf) 315 struct remoteconf *rmconf; 316 { 317 #ifdef ENABLE_HYBRID 318 if (rmconf->xauth) 319 xauth_rmconf_delete(&rmconf->xauth); 320 #endif 321 if (rmconf->etypes){ 322 deletypes(rmconf->etypes); 323 rmconf->etypes=NULL; 324 } 325 if (rmconf->idvl_p) 326 genlist_free(rmconf->idvl_p, idspec_free); 327 if (rmconf->dhgrp) 328 oakley_dhgrp_free(rmconf->dhgrp); 329 if (rmconf->proposal) 330 delisakmpsa(rmconf->proposal); 331 racoon_free(rmconf); 332 } 333 334 void 335 delisakmpsa(sa) 336 struct isakmpsa *sa; 337 { 338 if (sa->dhgrp) 339 oakley_dhgrp_free(sa->dhgrp); 340 if (sa->next) 341 delisakmpsa(sa->next); 342 #ifdef HAVE_GSSAPI 343 if (sa->gssid) 344 vfree(sa->gssid); 345 #endif 346 racoon_free(sa); 347 } 348 349 struct etypes * 350 dupetypes(orig) 351 struct etypes *orig; 352 { 353 struct etypes *new; 354 355 if (!orig) 356 return NULL; 357 358 new = racoon_malloc(sizeof(struct etypes)); 359 if (new == NULL) 360 return NULL; 361 362 new->type = orig->type; 363 new->next = NULL; 364 365 if (orig->next) 366 new->next=dupetypes(orig->next); 367 368 return new; 369 } 370 371 void 372 deletypes(e) 373 struct etypes *e; 374 { 375 if (e->next) 376 deletypes(e->next); 377 racoon_free(e); 378 } 379 380 /* 381 * insert into head of list. 382 */ 383 void 384 insrmconf(new) 385 struct remoteconf *new; 386 { 387 TAILQ_INSERT_HEAD(&rmtree, new, chain); 388 } 389 390 void 391 remrmconf(rmconf) 392 struct remoteconf *rmconf; 393 { 394 TAILQ_REMOVE(&rmtree, rmconf, chain); 395 } 396 397 void 398 flushrmconf() 399 { 400 struct remoteconf *p, *next; 401 402 for (p = TAILQ_FIRST(&rmtree); p; p = next) { 403 next = TAILQ_NEXT(p, chain); 404 remrmconf(p); 405 delrmconf(p); 406 } 407 } 408 409 void 410 initrmconf() 411 { 412 TAILQ_INIT(&rmtree); 413 } 414 415 void 416 save_rmconf() 417 { 418 rmtree_save=rmtree; 419 initrmconf(); 420 } 421 422 void 423 save_rmconf_flush() 424 { 425 rmtree_tmp=rmtree; 426 rmtree=rmtree_save; 427 flushrmconf(); 428 initrmconf(); 429 rmtree=rmtree_tmp; 430 } 431 432 433 434 /* check exchange type to be acceptable */ 435 struct etypes * 436 check_etypeok(rmconf, etype) 437 struct remoteconf *rmconf; 438 u_int8_t etype; 439 { 440 struct etypes *e; 441 442 for (e = rmconf->etypes; e != NULL; e = e->next) { 443 if (e->type == etype) 444 break; 445 } 446 447 return e; 448 } 449 450 /*%%%*/ 451 struct isakmpsa * 452 newisakmpsa() 453 { 454 struct isakmpsa *new; 455 456 new = racoon_calloc(1, sizeof(*new)); 457 if (new == NULL) 458 return NULL; 459 460 /* 461 * Just for sanity, make sure this is initialized. This is 462 * filled in for real when the ISAKMP proposal is configured. 463 */ 464 new->vendorid = VENDORID_UNKNOWN; 465 466 new->next = NULL; 467 new->rmconf = NULL; 468 #ifdef HAVE_GSSAPI 469 new->gssid = NULL; 470 #endif 471 472 return new; 473 } 474 475 /* 476 * insert into tail of list. 477 */ 478 void 479 insisakmpsa(new, rmconf) 480 struct isakmpsa *new; 481 struct remoteconf *rmconf; 482 { 483 struct isakmpsa *p; 484 485 new->rmconf = rmconf; 486 487 if (rmconf->proposal == NULL) { 488 rmconf->proposal = new; 489 return; 490 } 491 492 for (p = rmconf->proposal; p->next != NULL; p = p->next) 493 ; 494 p->next = new; 495 496 return; 497 } 498 499 struct remoteconf * 500 foreachrmconf(rmconf_func_t rmconf_func, void *data) 501 { 502 struct remoteconf *p, *ret = NULL; 503 RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) { 504 ret = (*rmconf_func)(p, data); 505 if (ret) 506 break; 507 } 508 509 return ret; 510 } 511 512 static void * 513 dump_peers_identifiers (void *entry, void *arg) 514 { 515 struct idspec *id = (struct idspec*) entry; 516 char buf[1024], *pbuf; 517 pbuf = buf; 518 pbuf += sprintf (pbuf, "\tpeers_identifier %s", 519 s_idtype (id->idtype)); 520 if (id->id) 521 pbuf += sprintf (pbuf, " \"%s\"", id->id->v); 522 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 523 return NULL; 524 } 525 526 static struct remoteconf * 527 dump_rmconf_single (struct remoteconf *p, void *data) 528 { 529 struct etypes *etype = p->etypes; 530 struct isakmpsa *prop = p->proposal; 531 char buf[1024], *pbuf; 532 533 pbuf = buf; 534 pbuf += sprintf(pbuf, "remote %s", saddr2str(p->remote)); 535 if (p->inherited_from) 536 pbuf += sprintf(pbuf, " inherit %s", 537 saddr2str(p->inherited_from->remote)); 538 plog(LLV_INFO, LOCATION, NULL, "%s {\n", buf); 539 pbuf = buf; 540 pbuf += sprintf(pbuf, "\texchange_type "); 541 while (etype) { 542 pbuf += sprintf (pbuf, "%s%s", s_etype(etype->type), 543 etype->next != NULL ? ", " : ";\n"); 544 etype = etype->next; 545 } 546 plog(LLV_INFO, LOCATION, NULL, "%s", buf); 547 plog(LLV_INFO, LOCATION, NULL, "\tdoi %s;\n", s_doi(p->doitype)); 548 pbuf = buf; 549 pbuf += sprintf(pbuf, "\tmy_identifier %s", s_idtype (p->idvtype)); 550 if (p->idvtype == IDTYPE_ASN1DN) { 551 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 552 plog(LLV_INFO, LOCATION, NULL, "\tcertificate_type %s \"%s\" \"%s\";\n", 553 p->certtype == ISAKMP_CERT_X509SIGN ? "x509" : "*UNKNOWN*", 554 p->mycertfile, p->myprivfile); 555 switch (p->getcert_method) { 556 case 0: 557 break; 558 case ISAKMP_GETCERT_PAYLOAD: 559 plog(LLV_INFO, LOCATION, NULL, "\t/* peers certificate from payload */\n"); 560 break; 561 case ISAKMP_GETCERT_LOCALFILE: 562 plog(LLV_INFO, LOCATION, NULL, "\tpeers_certfile \"%s\";\n", p->peerscertfile); 563 break; 564 case ISAKMP_GETCERT_DNS: 565 plog(LLV_INFO, LOCATION, NULL, "\tpeer_certfile dnssec;\n"); 566 break; 567 default: 568 plog(LLV_INFO, LOCATION, NULL, "\tpeers_certfile *UNKNOWN* (%d)\n", p->getcert_method); 569 } 570 } 571 else { 572 if (p->idv) 573 pbuf += sprintf (pbuf, " \"%s\"", p->idv->v); 574 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf); 575 genlist_foreach(p->idvl_p, &dump_peers_identifiers, NULL); 576 } 577 578 plog(LLV_INFO, LOCATION, NULL, "\tsend_cert %s;\n", 579 s_switch (p->send_cert)); 580 plog(LLV_INFO, LOCATION, NULL, "\tsend_cr %s;\n", 581 s_switch (p->send_cr)); 582 plog(LLV_INFO, LOCATION, NULL, "\tverify_cert %s;\n", 583 s_switch (p->verify_cert)); 584 plog(LLV_INFO, LOCATION, NULL, "\tverify_identifier %s;\n", 585 s_switch (p->verify_identifier)); 586 plog(LLV_INFO, LOCATION, NULL, "\tnat_traversal %s;\n", 587 p->nat_traversal == NATT_FORCE ? 588 "force" : s_switch (p->nat_traversal)); 589 plog(LLV_INFO, LOCATION, NULL, "\tnonce_size %d;\n", 590 p->nonce_size); 591 plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n", 592 s_switch (p->passive)); 593 plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n", 594 p->ike_frag == ISAKMP_FRAG_FORCE ? 595 "force" : s_switch (p->ike_frag)); 596 plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag); 597 plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n", 598 s_switch (p->ini_contact)); 599 plog(LLV_INFO, LOCATION, NULL, "\tgenerate_policy %s;\n", 600 s_switch (p->gen_policy)); 601 plog(LLV_INFO, LOCATION, NULL, "\tsupport_proxy %s;\n", 602 s_switch (p->support_proxy)); 603 604 while (prop) { 605 plog(LLV_INFO, LOCATION, NULL, "\n"); 606 plog(LLV_INFO, LOCATION, NULL, 607 "\t/* prop_no=%d, trns_no=%d, rmconf=%s */\n", 608 prop->prop_no, prop->trns_no, 609 saddr2str(prop->rmconf->remote)); 610 plog(LLV_INFO, LOCATION, NULL, "\tproposal {\n"); 611 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime time %lu sec;\n", 612 (long)prop->lifetime); 613 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime bytes %zd;\n", 614 prop->lifebyte); 615 plog(LLV_INFO, LOCATION, NULL, "\t\tdh_group %s;\n", 616 alg_oakley_dhdef_name(prop->dh_group)); 617 plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n", 618 alg_oakley_encdef_name(prop->enctype)); 619 plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n", 620 alg_oakley_hashdef_name(prop->hashtype)); 621 plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n", 622 alg_oakley_authdef_name(prop->authmethod)); 623 plog(LLV_INFO, LOCATION, NULL, "\t}\n"); 624 prop = prop->next; 625 } 626 plog(LLV_INFO, LOCATION, NULL, "}\n"); 627 plog(LLV_INFO, LOCATION, NULL, "\n"); 628 629 return NULL; 630 } 631 632 void 633 dumprmconf() 634 { 635 foreachrmconf (dump_rmconf_single, NULL); 636 } 637 638 struct idspec * 639 newidspec() 640 { 641 struct idspec *new; 642 643 new = racoon_calloc(1, sizeof(*new)); 644 if (new == NULL) 645 return NULL; 646 new->idtype = IDTYPE_ADDRESS; 647 648 return new; 649 } 650 651 vchar_t * 652 script_path_add(path) 653 vchar_t *path; 654 { 655 char *script_dir; 656 vchar_t *new_path; 657 vchar_t *new_storage; 658 vchar_t **sp; 659 size_t len; 660 size_t size; 661 662 script_dir = lcconf->pathinfo[LC_PATHTYPE_SCRIPT]; 663 664 /* Try to find the script in the script directory */ 665 if ((path->v[0] != '/') && (script_dir != NULL)) { 666 len = strlen(script_dir) + sizeof("/") + path->l + 1; 667 668 if ((new_path = vmalloc(len)) == NULL) { 669 plog(LLV_ERROR, LOCATION, NULL, 670 "Cannot allocate memory: %s\n", strerror(errno)); 671 return NULL; 672 } 673 674 new_path->v[0] = '\0'; 675 (void)strlcat(new_path->v, script_dir, len); 676 (void)strlcat(new_path->v, "/", len); 677 (void)strlcat(new_path->v, path->v, len); 678 679 vfree(path); 680 path = new_path; 681 } 682 683 return path; 684 } 685 686 687 struct isakmpsa * 688 dupisakmpsa(struct isakmpsa *sa) 689 { 690 struct isakmpsa *res=NULL; 691 692 if(sa == NULL) 693 return NULL; 694 695 res=newisakmpsa(); 696 if(res == NULL) 697 return NULL; 698 699 *res=*sa; 700 #ifdef HAVE_GSSAPI 701 /* XXX gssid 702 */ 703 #endif 704 res->next=NULL; 705 706 if(sa->dhgrp != NULL) 707 oakley_setdhgroup (sa->dh_group, &(res->dhgrp)); 708 709 return res; 710 711 } 712