1 /* $NetBSD: handler.c,v 1.9.6.8 2009/04/20 13:25:27 tteras Exp $ */ 2 3 /* Id: handler.c,v 1.28 2006/05/26 12:17:29 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 40 #include <stdlib.h> 41 #include <stdio.h> 42 #include <string.h> 43 #include <time.h> 44 #include <errno.h> 45 46 #include "var.h" 47 #include "misc.h" 48 #include "vmbuf.h" 49 #include "plog.h" 50 #include "sockmisc.h" 51 #include "debug.h" 52 53 #ifdef ENABLE_HYBRID 54 #include <resolv.h> 55 #endif 56 57 #include "schedule.h" 58 #include "grabmyaddr.h" 59 #include "algorithm.h" 60 #include "crypto_openssl.h" 61 #include "policy.h" 62 #include "proposal.h" 63 #include "isakmp_var.h" 64 #include "evt.h" 65 #include "isakmp.h" 66 #ifdef ENABLE_HYBRID 67 #include "isakmp_xauth.h" 68 #include "isakmp_cfg.h" 69 #endif 70 #include "isakmp_inf.h" 71 #include "oakley.h" 72 #include "remoteconf.h" 73 #include "localconf.h" 74 #include "handler.h" 75 #include "gcmalloc.h" 76 #include "nattraversal.h" 77 78 #include "sainfo.h" 79 80 #ifdef HAVE_GSSAPI 81 #include "gssapi.h" 82 #endif 83 84 static LIST_HEAD(_ph1tree_, ph1handle) ph1tree; 85 static LIST_HEAD(_ph2tree_, ph2handle) ph2tree; 86 static LIST_HEAD(_ctdtree_, contacted) ctdtree; 87 static LIST_HEAD(_rcptree_, recvdpkt) rcptree; 88 89 static void del_recvdpkt __P((struct recvdpkt *)); 90 static void rem_recvdpkt __P((struct recvdpkt *)); 91 static void sweep_recvdpkt __P((void *)); 92 93 /* 94 * functions about management of the isakmp status table 95 */ 96 /* %%% management phase 1 handler */ 97 /* 98 * search for isakmpsa handler with isakmp index. 99 */ 100 101 extern caddr_t val2str(const char *, size_t); 102 103 struct ph1handle * 104 getph1byindex(index) 105 isakmp_index *index; 106 { 107 struct ph1handle *p; 108 109 LIST_FOREACH(p, &ph1tree, chain) { 110 if (p->status == PHASE1ST_EXPIRED) 111 continue; 112 if (memcmp(&p->index, index, sizeof(*index)) == 0) 113 return p; 114 } 115 116 return NULL; 117 } 118 119 120 /* 121 * search for isakmp handler by i_ck in index. 122 */ 123 struct ph1handle * 124 getph1byindex0(index) 125 isakmp_index *index; 126 { 127 struct ph1handle *p; 128 129 LIST_FOREACH(p, &ph1tree, chain) { 130 if (p->status == PHASE1ST_EXPIRED) 131 continue; 132 if (memcmp(&p->index, index, sizeof(cookie_t)) == 0) 133 return p; 134 } 135 136 return NULL; 137 } 138 139 /* 140 * search for isakmpsa handler by source and remote address. 141 * don't use port number to search because this function search 142 * with phase 2's destinaion. 143 */ 144 struct ph1handle * 145 getph1byaddr(local, remote, established) 146 struct sockaddr *local, *remote; 147 int established; 148 { 149 struct ph1handle *p; 150 151 plog(LLV_DEBUG2, LOCATION, NULL, "getph1byaddr: start\n"); 152 plog(LLV_DEBUG2, LOCATION, NULL, "local: %s\n", saddr2str(local)); 153 plog(LLV_DEBUG2, LOCATION, NULL, "remote: %s\n", saddr2str(remote)); 154 155 LIST_FOREACH(p, &ph1tree, chain) { 156 if (p->status == PHASE1ST_EXPIRED) 157 continue; 158 plog(LLV_DEBUG2, LOCATION, NULL, "p->local: %s\n", saddr2str(p->local)); 159 plog(LLV_DEBUG2, LOCATION, NULL, "p->remote: %s\n", saddr2str(p->remote)); 160 161 if(established && p->status != PHASE1ST_ESTABLISHED){ 162 plog(LLV_DEBUG2, LOCATION, NULL, "status %d, skipping\n", p->status); 163 continue; 164 } 165 if (CMPSADDR(local, p->local) == 0 166 && CMPSADDR(remote, p->remote) == 0){ 167 plog(LLV_DEBUG2, LOCATION, NULL, "matched\n"); 168 return p; 169 } 170 } 171 172 plog(LLV_DEBUG2, LOCATION, NULL, "no match\n"); 173 174 return NULL; 175 } 176 177 struct ph1handle * 178 getph1byaddrwop(local, remote) 179 struct sockaddr *local, *remote; 180 { 181 struct ph1handle *p; 182 183 LIST_FOREACH(p, &ph1tree, chain) { 184 if (p->status == PHASE1ST_EXPIRED) 185 continue; 186 if (cmpsaddrwop(local, p->local) == 0 187 && cmpsaddrwop(remote, p->remote) == 0) 188 return p; 189 } 190 191 return NULL; 192 } 193 194 /* 195 * search for isakmpsa handler by remote address. 196 * don't use port number to search because this function search 197 * with phase 2's destinaion. 198 */ 199 struct ph1handle * 200 getph1bydstaddrwop(remote) 201 struct sockaddr *remote; 202 { 203 struct ph1handle *p; 204 205 LIST_FOREACH(p, &ph1tree, chain) { 206 if (p->status == PHASE1ST_EXPIRED) 207 continue; 208 if (cmpsaddrwop(remote, p->remote) == 0) 209 return p; 210 } 211 212 return NULL; 213 } 214 215 /* 216 * dump isakmp-sa 217 */ 218 vchar_t * 219 dumpph1() 220 { 221 struct ph1handle *iph1; 222 struct ph1dump *pd; 223 int cnt = 0; 224 vchar_t *buf; 225 226 /* get length of buffer */ 227 LIST_FOREACH(iph1, &ph1tree, chain) 228 cnt++; 229 230 buf = vmalloc(cnt * sizeof(struct ph1dump)); 231 if (buf == NULL) { 232 plog(LLV_ERROR, LOCATION, NULL, 233 "failed to get buffer\n"); 234 return NULL; 235 } 236 pd = (struct ph1dump *)buf->v; 237 238 LIST_FOREACH(iph1, &ph1tree, chain) { 239 memcpy(&pd->index, &iph1->index, sizeof(iph1->index)); 240 pd->status = iph1->status; 241 pd->side = iph1->side; 242 memcpy(&pd->remote, iph1->remote, sysdep_sa_len(iph1->remote)); 243 memcpy(&pd->local, iph1->local, sysdep_sa_len(iph1->local)); 244 pd->version = iph1->version; 245 pd->etype = iph1->etype; 246 pd->created = iph1->created; 247 pd->ph2cnt = iph1->ph2cnt; 248 pd++; 249 } 250 251 return buf; 252 } 253 254 /* 255 * create new isakmp Phase 1 status record to handle isakmp in Phase1 256 */ 257 struct ph1handle * 258 newph1() 259 { 260 struct ph1handle *iph1; 261 262 /* create new iph1 */ 263 iph1 = racoon_calloc(1, sizeof(*iph1)); 264 if (iph1 == NULL) 265 return NULL; 266 267 iph1->status = PHASE1ST_SPAWN; 268 269 #ifdef ENABLE_DPD 270 iph1->dpd_support = 0; 271 iph1->dpd_lastack = 0; 272 iph1->dpd_seq = 0; 273 iph1->dpd_fails = 0; 274 iph1->dpd_r_u = NULL; 275 #endif 276 277 return iph1; 278 } 279 280 /* 281 * delete new isakmp Phase 1 status record to handle isakmp in Phase1 282 */ 283 void 284 delph1(iph1) 285 struct ph1handle *iph1; 286 { 287 if (iph1 == NULL) 288 return; 289 290 /* SA down shell script hook */ 291 script_hook(iph1, SCRIPT_PHASE1_DOWN); 292 293 EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL); 294 295 #ifdef ENABLE_NATT 296 if (iph1->natt_flags & NAT_KA_QUEUED) 297 natt_keepalive_remove (iph1->local, iph1->remote); 298 299 if (iph1->natt_options) { 300 racoon_free(iph1->natt_options); 301 iph1->natt_options = NULL; 302 } 303 #endif 304 305 #ifdef ENABLE_HYBRID 306 if (iph1->mode_cfg) 307 isakmp_cfg_rmstate(iph1); 308 #endif 309 310 #ifdef ENABLE_DPD 311 SCHED_KILL(iph1->dpd_r_u); 312 #endif 313 314 if (iph1->remote) { 315 racoon_free(iph1->remote); 316 iph1->remote = NULL; 317 } 318 if (iph1->local) { 319 racoon_free(iph1->local); 320 iph1->local = NULL; 321 } 322 if (iph1->approval) { 323 delisakmpsa(iph1->approval); 324 iph1->approval = NULL; 325 } 326 327 VPTRINIT(iph1->authstr); 328 329 sched_scrub_param(iph1); 330 iph1->sce = NULL; 331 iph1->scr = NULL; 332 333 VPTRINIT(iph1->sendbuf); 334 335 VPTRINIT(iph1->dhpriv); 336 VPTRINIT(iph1->dhpub); 337 VPTRINIT(iph1->dhpub_p); 338 VPTRINIT(iph1->dhgxy); 339 VPTRINIT(iph1->nonce); 340 VPTRINIT(iph1->nonce_p); 341 VPTRINIT(iph1->skeyid); 342 VPTRINIT(iph1->skeyid_d); 343 VPTRINIT(iph1->skeyid_a); 344 VPTRINIT(iph1->skeyid_e); 345 VPTRINIT(iph1->key); 346 VPTRINIT(iph1->hash); 347 VPTRINIT(iph1->sig); 348 VPTRINIT(iph1->sig_p); 349 oakley_delcert(iph1->cert); 350 iph1->cert = NULL; 351 oakley_delcert(iph1->cert_p); 352 iph1->cert_p = NULL; 353 oakley_delcert(iph1->crl_p); 354 iph1->crl_p = NULL; 355 oakley_delcert(iph1->cr_p); 356 iph1->cr_p = NULL; 357 VPTRINIT(iph1->id); 358 VPTRINIT(iph1->id_p); 359 360 if(iph1->approval != NULL) 361 delisakmpsa(iph1->approval); 362 363 if (iph1->ivm) { 364 oakley_delivm(iph1->ivm); 365 iph1->ivm = NULL; 366 } 367 368 VPTRINIT(iph1->sa); 369 VPTRINIT(iph1->sa_ret); 370 371 #ifdef HAVE_GSSAPI 372 VPTRINIT(iph1->gi_i); 373 VPTRINIT(iph1->gi_r); 374 375 gssapi_free_state(iph1); 376 #endif 377 378 racoon_free(iph1); 379 } 380 381 /* 382 * create new isakmp Phase 1 status record to handle isakmp in Phase1 383 */ 384 int 385 insph1(iph1) 386 struct ph1handle *iph1; 387 { 388 /* validity check */ 389 if (iph1->remote == NULL) { 390 plog(LLV_ERROR, LOCATION, NULL, 391 "invalid isakmp SA handler. no remote address.\n"); 392 return -1; 393 } 394 LIST_INSERT_HEAD(&ph1tree, iph1, chain); 395 396 return 0; 397 } 398 399 void 400 remph1(iph1) 401 struct ph1handle *iph1; 402 { 403 LIST_REMOVE(iph1, chain); 404 } 405 406 /* 407 * flush isakmp-sa 408 */ 409 void 410 flushph1() 411 { 412 struct ph1handle *p, *next; 413 414 for (p = LIST_FIRST(&ph1tree); p; p = next) { 415 next = LIST_NEXT(p, chain); 416 417 /* send delete information */ 418 if (p->status == PHASE1ST_ESTABLISHED) 419 isakmp_info_send_d1(p); 420 421 remph1(p); 422 delph1(p); 423 } 424 } 425 426 void 427 initph1tree() 428 { 429 LIST_INIT(&ph1tree); 430 } 431 432 /* %%% management phase 2 handler */ 433 /* 434 * search ph2handle with policy id. 435 */ 436 struct ph2handle * 437 getph2byspid(spid) 438 u_int32_t spid; 439 { 440 struct ph2handle *p; 441 442 LIST_FOREACH(p, &ph2tree, chain) { 443 /* 444 * there are ph2handle independent on policy 445 * such like informational exchange. 446 */ 447 if (p->spid == spid) 448 return p; 449 } 450 451 return NULL; 452 } 453 454 /* 455 * search ph2handle with sequence number. 456 */ 457 struct ph2handle * 458 getph2byseq(seq) 459 u_int32_t seq; 460 { 461 struct ph2handle *p; 462 463 LIST_FOREACH(p, &ph2tree, chain) { 464 if (p->seq == seq) 465 return p; 466 } 467 468 return NULL; 469 } 470 471 /* 472 * search ph2handle with message id. 473 */ 474 struct ph2handle * 475 getph2bymsgid(iph1, msgid) 476 struct ph1handle *iph1; 477 u_int32_t msgid; 478 { 479 struct ph2handle *p; 480 481 LIST_FOREACH(p, &ph2tree, chain) { 482 if (p->msgid == msgid && p->ph1 == iph1) 483 return p; 484 } 485 486 return NULL; 487 } 488 489 struct ph2handle * 490 getph2byid(src, dst, spid) 491 struct sockaddr *src, *dst; 492 u_int32_t spid; 493 { 494 struct ph2handle *p; 495 496 LIST_FOREACH(p, &ph2tree, chain) { 497 if (spid == p->spid && 498 CMPSADDR(src, p->src) == 0 && 499 CMPSADDR(dst, p->dst) == 0){ 500 /* Sanity check to detect zombie handlers 501 * XXX Sould be done "somewhere" more interesting, 502 * because we have lots of getph2byxxxx(), but this one 503 * is called by pk_recvacquire(), so is the most important. 504 */ 505 if(p->status < PHASE2ST_ESTABLISHED && 506 p->retry_counter == 0 507 && p->sce == NULL && p->scr == NULL){ 508 plog(LLV_DEBUG, LOCATION, NULL, 509 "Zombie ph2 found, expiring it\n"); 510 isakmp_ph2expire(p); 511 }else 512 return p; 513 } 514 } 515 516 return NULL; 517 } 518 519 struct ph2handle * 520 getph2bysaddr(src, dst) 521 struct sockaddr *src, *dst; 522 { 523 struct ph2handle *p; 524 525 LIST_FOREACH(p, &ph2tree, chain) { 526 if (cmpsaddrstrict(src, p->src) == 0 && 527 cmpsaddrstrict(dst, p->dst) == 0) 528 return p; 529 } 530 531 return NULL; 532 } 533 534 /* 535 * call by pk_recvexpire(). 536 */ 537 struct ph2handle * 538 getph2bysaidx(src, dst, proto_id, spi) 539 struct sockaddr *src, *dst; 540 u_int proto_id; 541 u_int32_t spi; 542 { 543 struct ph2handle *iph2; 544 struct saproto *pr; 545 546 LIST_FOREACH(iph2, &ph2tree, chain) { 547 if (iph2->proposal == NULL && iph2->approval == NULL) 548 continue; 549 if (iph2->approval != NULL) { 550 for (pr = iph2->approval->head; pr != NULL; 551 pr = pr->next) { 552 if (proto_id != pr->proto_id) 553 break; 554 if (spi == pr->spi || spi == pr->spi_p) 555 return iph2; 556 } 557 } else if (iph2->proposal != NULL) { 558 for (pr = iph2->proposal->head; pr != NULL; 559 pr = pr->next) { 560 if (proto_id != pr->proto_id) 561 break; 562 if (spi == pr->spi) 563 return iph2; 564 } 565 } 566 } 567 568 return NULL; 569 } 570 571 /* 572 * create new isakmp Phase 2 status record to handle isakmp in Phase2 573 */ 574 struct ph2handle * 575 newph2() 576 { 577 struct ph2handle *iph2 = NULL; 578 579 /* create new iph2 */ 580 iph2 = racoon_calloc(1, sizeof(*iph2)); 581 if (iph2 == NULL) 582 return NULL; 583 584 iph2->status = PHASE1ST_SPAWN; 585 586 return iph2; 587 } 588 589 /* 590 * initialize ph2handle 591 * NOTE: don't initialize src/dst. 592 * SPI in the proposal is cleared. 593 */ 594 void 595 initph2(iph2) 596 struct ph2handle *iph2; 597 { 598 sched_scrub_param(iph2); 599 iph2->sce = NULL; 600 iph2->scr = NULL; 601 602 VPTRINIT(iph2->sendbuf); 603 VPTRINIT(iph2->msg1); 604 605 /* clear spi, keep variables in the proposal */ 606 if (iph2->proposal) { 607 struct saproto *pr; 608 for (pr = iph2->proposal->head; pr != NULL; pr = pr->next) 609 pr->spi = 0; 610 } 611 612 /* clear approval */ 613 if (iph2->approval) { 614 flushsaprop(iph2->approval); 615 iph2->approval = NULL; 616 } 617 618 /* clear the generated policy */ 619 if (iph2->spidx_gen) { 620 delsp_bothdir((struct policyindex *)iph2->spidx_gen); 621 racoon_free(iph2->spidx_gen); 622 iph2->spidx_gen = NULL; 623 } 624 625 if (iph2->pfsgrp) { 626 oakley_dhgrp_free(iph2->pfsgrp); 627 iph2->pfsgrp = NULL; 628 } 629 630 VPTRINIT(iph2->dhpriv); 631 VPTRINIT(iph2->dhpub); 632 VPTRINIT(iph2->dhpub_p); 633 VPTRINIT(iph2->dhgxy); 634 VPTRINIT(iph2->id); 635 VPTRINIT(iph2->id_p); 636 VPTRINIT(iph2->nonce); 637 VPTRINIT(iph2->nonce_p); 638 VPTRINIT(iph2->sa); 639 VPTRINIT(iph2->sa_ret); 640 641 if (iph2->ivm) { 642 oakley_delivm(iph2->ivm); 643 iph2->ivm = NULL; 644 } 645 } 646 647 /* 648 * delete new isakmp Phase 2 status record to handle isakmp in Phase2 649 */ 650 void 651 delph2(iph2) 652 struct ph2handle *iph2; 653 { 654 initph2(iph2); 655 656 if (iph2->src) { 657 racoon_free(iph2->src); 658 iph2->src = NULL; 659 } 660 if (iph2->dst) { 661 racoon_free(iph2->dst); 662 iph2->dst = NULL; 663 } 664 if (iph2->src_id) { 665 racoon_free(iph2->src_id); 666 iph2->src_id = NULL; 667 } 668 if (iph2->dst_id) { 669 racoon_free(iph2->dst_id); 670 iph2->dst_id = NULL; 671 } 672 673 if (iph2->proposal) { 674 flushsaprop(iph2->proposal); 675 iph2->proposal = NULL; 676 } 677 678 racoon_free(iph2); 679 } 680 681 /* 682 * create new isakmp Phase 2 status record to handle isakmp in Phase2 683 */ 684 int 685 insph2(iph2) 686 struct ph2handle *iph2; 687 { 688 LIST_INSERT_HEAD(&ph2tree, iph2, chain); 689 690 return 0; 691 } 692 693 void 694 remph2(iph2) 695 struct ph2handle *iph2; 696 { 697 LIST_REMOVE(iph2, chain); 698 } 699 700 void 701 initph2tree() 702 { 703 LIST_INIT(&ph2tree); 704 } 705 706 void 707 flushph2() 708 { 709 struct ph2handle *p, *next; 710 711 plog(LLV_DEBUG2, LOCATION, NULL, 712 "flushing all ph2 handlers...\n"); 713 714 for (p = LIST_FIRST(&ph2tree); p; p = next) { 715 next = LIST_NEXT(p, chain); 716 717 /* send delete information */ 718 if (p->status == PHASE2ST_ESTABLISHED){ 719 plog(LLV_DEBUG2, LOCATION, NULL, 720 "got a ph2 handler to flush...\n"); 721 isakmp_info_send_d2(p); 722 }else{ 723 plog(LLV_DEBUG2, LOCATION, NULL, 724 "skipping ph2 handler (state %d)\n", p->status); 725 } 726 727 delete_spd(p, 0); 728 unbindph12(p); 729 remph2(p); 730 delph2(p); 731 } 732 } 733 734 /* 735 * Delete all Phase 2 handlers for this src/dst/proto. This 736 * is used during INITIAL-CONTACT processing (so no need to 737 * send a message to the peer). 738 */ 739 void 740 deleteallph2(src, dst, proto_id) 741 struct sockaddr *src, *dst; 742 u_int proto_id; 743 { 744 struct ph2handle *iph2, *next; 745 struct saproto *pr; 746 747 for (iph2 = LIST_FIRST(&ph2tree); iph2 != NULL; iph2 = next) { 748 next = LIST_NEXT(iph2, chain); 749 if (iph2->proposal == NULL && iph2->approval == NULL) 750 continue; 751 if (iph2->approval != NULL) { 752 for (pr = iph2->approval->head; pr != NULL; 753 pr = pr->next) { 754 if (proto_id == pr->proto_id) 755 goto zap_it; 756 } 757 } else if (iph2->proposal != NULL) { 758 for (pr = iph2->proposal->head; pr != NULL; 759 pr = pr->next) { 760 if (proto_id == pr->proto_id) 761 goto zap_it; 762 } 763 } 764 continue; 765 zap_it: 766 unbindph12(iph2); 767 remph2(iph2); 768 delph2(iph2); 769 } 770 } 771 772 /* %%% */ 773 void 774 bindph12(iph1, iph2) 775 struct ph1handle *iph1; 776 struct ph2handle *iph2; 777 { 778 iph2->ph1 = iph1; 779 LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind); 780 } 781 782 void 783 unbindph12(iph2) 784 struct ph2handle *iph2; 785 { 786 if (iph2->ph1 != NULL) { 787 iph2->ph1 = NULL; 788 LIST_REMOVE(iph2, ph1bind); 789 } 790 } 791 792 /* %%% management contacted list */ 793 /* 794 * search contacted list. 795 */ 796 struct contacted * 797 getcontacted(remote) 798 struct sockaddr *remote; 799 { 800 struct contacted *p; 801 802 LIST_FOREACH(p, &ctdtree, chain) { 803 if (cmpsaddrstrict(remote, p->remote) == 0) 804 return p; 805 } 806 807 return NULL; 808 } 809 810 /* 811 * create new isakmp Phase 2 status record to handle isakmp in Phase2 812 */ 813 int 814 inscontacted(remote) 815 struct sockaddr *remote; 816 { 817 struct contacted *new; 818 819 /* create new iph2 */ 820 new = racoon_calloc(1, sizeof(*new)); 821 if (new == NULL) 822 return -1; 823 824 new->remote = dupsaddr(remote); 825 if (new->remote == NULL) { 826 plog(LLV_ERROR, LOCATION, NULL, 827 "failed to allocate buffer.\n"); 828 racoon_free(new); 829 return -1; 830 } 831 832 LIST_INSERT_HEAD(&ctdtree, new, chain); 833 834 return 0; 835 } 836 837 void 838 initctdtree() 839 { 840 LIST_INIT(&ctdtree); 841 } 842 843 /* 844 * check the response has been sent to the peer. when not, simply reply 845 * the buffered packet to the peer. 846 * OUT: 847 * 0: the packet is received at the first time. 848 * 1: the packet was processed before. 849 * 2: the packet was processed before, but the address mismatches. 850 * -1: error happened. 851 */ 852 int 853 check_recvdpkt(remote, local, rbuf) 854 struct sockaddr *remote, *local; 855 vchar_t *rbuf; 856 { 857 vchar_t *hash; 858 struct recvdpkt *r; 859 time_t t; 860 int len, s; 861 862 /* set current time */ 863 t = time(NULL); 864 865 hash = eay_md5_one(rbuf); 866 if (!hash) { 867 plog(LLV_ERROR, LOCATION, NULL, 868 "failed to allocate buffer.\n"); 869 return -1; 870 } 871 872 LIST_FOREACH(r, &rcptree, chain) { 873 if (memcmp(hash->v, r->hash->v, r->hash->l) == 0) 874 break; 875 } 876 vfree(hash); 877 878 /* this is the first time to receive the packet */ 879 if (r == NULL) 880 return 0; 881 882 /* 883 * the packet was processed before, but the remote address mismatches. 884 */ 885 if (cmpsaddrstrict(remote, r->remote) != 0) 886 return 2; 887 888 /* 889 * it should not check the local address because the packet 890 * may arrive at other interface. 891 */ 892 893 /* check the previous time to send */ 894 if (t - r->time_send < 1) { 895 plog(LLV_WARNING, LOCATION, NULL, 896 "the packet retransmitted in a short time from %s\n", 897 saddr2str(remote)); 898 /*XXX should it be error ? */ 899 } 900 901 /* select the socket to be sent */ 902 s = getsockmyaddr(r->local); 903 if (s == -1) 904 return -1; 905 906 /* resend the packet if needed */ 907 len = sendfromto(s, r->sendbuf->v, r->sendbuf->l, 908 r->local, r->remote, lcconf->count_persend); 909 if (len == -1) { 910 plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n"); 911 return -1; 912 } 913 914 /* check the retry counter */ 915 r->retry_counter--; 916 if (r->retry_counter <= 0) { 917 rem_recvdpkt(r); 918 del_recvdpkt(r); 919 plog(LLV_DEBUG, LOCATION, NULL, 920 "deleted the retransmission packet to %s.\n", 921 saddr2str(remote)); 922 } else 923 r->time_send = t; 924 925 return 1; 926 } 927 928 /* 929 * adding a hash of received packet into the received list. 930 */ 931 int 932 add_recvdpkt(remote, local, sbuf, rbuf) 933 struct sockaddr *remote, *local; 934 vchar_t *sbuf, *rbuf; 935 { 936 struct recvdpkt *new = NULL; 937 938 if (lcconf->retry_counter == 0) { 939 /* no need to add it */ 940 return 0; 941 } 942 943 new = racoon_calloc(1, sizeof(*new)); 944 if (!new) { 945 plog(LLV_ERROR, LOCATION, NULL, 946 "failed to allocate buffer.\n"); 947 return -1; 948 } 949 950 new->hash = eay_md5_one(rbuf); 951 if (!new->hash) { 952 plog(LLV_ERROR, LOCATION, NULL, 953 "failed to allocate buffer.\n"); 954 del_recvdpkt(new); 955 return -1; 956 } 957 new->remote = dupsaddr(remote); 958 if (new->remote == NULL) { 959 plog(LLV_ERROR, LOCATION, NULL, 960 "failed to allocate buffer.\n"); 961 del_recvdpkt(new); 962 return -1; 963 } 964 new->local = dupsaddr(local); 965 if (new->local == NULL) { 966 plog(LLV_ERROR, LOCATION, NULL, 967 "failed to allocate buffer.\n"); 968 del_recvdpkt(new); 969 return -1; 970 } 971 new->sendbuf = vdup(sbuf); 972 if (new->sendbuf == NULL) { 973 plog(LLV_ERROR, LOCATION, NULL, 974 "failed to allocate buffer.\n"); 975 del_recvdpkt(new); 976 return -1; 977 } 978 979 new->retry_counter = lcconf->retry_counter; 980 new->time_send = 0; 981 new->created = time(NULL); 982 983 LIST_INSERT_HEAD(&rcptree, new, chain); 984 985 return 0; 986 } 987 988 void 989 del_recvdpkt(r) 990 struct recvdpkt *r; 991 { 992 if (r->remote) 993 racoon_free(r->remote); 994 if (r->local) 995 racoon_free(r->local); 996 if (r->hash) 997 vfree(r->hash); 998 if (r->sendbuf) 999 vfree(r->sendbuf); 1000 racoon_free(r); 1001 } 1002 1003 void 1004 rem_recvdpkt(r) 1005 struct recvdpkt *r; 1006 { 1007 LIST_REMOVE(r, chain); 1008 } 1009 1010 void 1011 sweep_recvdpkt(dummy) 1012 void *dummy; 1013 { 1014 struct recvdpkt *r, *next; 1015 time_t t, lt; 1016 1017 /* set current time */ 1018 t = time(NULL); 1019 1020 /* set the lifetime of the retransmission */ 1021 lt = lcconf->retry_counter * lcconf->retry_interval; 1022 1023 for (r = LIST_FIRST(&rcptree); r; r = next) { 1024 next = LIST_NEXT(r, chain); 1025 1026 if (t - r->created > lt) { 1027 rem_recvdpkt(r); 1028 del_recvdpkt(r); 1029 } 1030 } 1031 1032 sched_new(lt, sweep_recvdpkt, NULL); 1033 } 1034 1035 void 1036 init_recvdpkt() 1037 { 1038 time_t lt = lcconf->retry_counter * lcconf->retry_interval; 1039 1040 LIST_INIT(&rcptree); 1041 1042 sched_new(lt, sweep_recvdpkt, NULL); 1043 } 1044 1045 #ifdef ENABLE_HYBRID 1046 /* 1047 * Retruns 0 if the address was obtained by ISAKMP mode config, 1 otherwise 1048 * This should be in isakmp_cfg.c but ph1tree being private, it must be there 1049 */ 1050 int 1051 exclude_cfg_addr(addr) 1052 const struct sockaddr *addr; 1053 { 1054 struct ph1handle *p; 1055 struct sockaddr_in *sin; 1056 1057 LIST_FOREACH(p, &ph1tree, chain) { 1058 if ((p->mode_cfg != NULL) && 1059 (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) && 1060 (addr->sa_family == AF_INET)) { 1061 sin = (struct sockaddr_in *)addr; 1062 if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr) 1063 return 0; 1064 } 1065 } 1066 1067 return 1; 1068 } 1069 #endif 1070 1071 1072 1073 /* 1074 * Reload conf code 1075 */ 1076 static int revalidate_ph2(struct ph2handle *iph2){ 1077 struct sainfoalg *alg; 1078 int found, check_level; 1079 struct sainfo *sainfo; 1080 struct saprop *approval; 1081 struct ph1handle *iph1; 1082 1083 /* 1084 * Get the new sainfo using values of the old one 1085 */ 1086 if (iph2->sainfo != NULL) { 1087 iph2->sainfo = getsainfo(iph2->sainfo->idsrc, 1088 iph2->sainfo->iddst, iph2->sainfo->id_i, 1089 iph2->sainfo->remoteid); 1090 } 1091 approval = iph2->approval; 1092 sainfo = iph2->sainfo; 1093 1094 if (sainfo == NULL) { 1095 /* 1096 * Sainfo has been removed 1097 */ 1098 plog(LLV_DEBUG, LOCATION, NULL, 1099 "Reload: No sainfo for ph2\n"); 1100 return 0; 1101 } 1102 1103 if (approval == NULL) { 1104 /* 1105 * XXX why do we have a NULL approval sometimes ??? 1106 */ 1107 plog(LLV_DEBUG, LOCATION, NULL, 1108 "No approval found !\n"); 1109 return 0; 1110 } 1111 1112 /* 1113 * Don't care about proposals, should we do something ? 1114 * We have to keep iph2->proposal valid at least for initiator, 1115 * for pk_sendgetspi() 1116 */ 1117 1118 plog(LLV_DEBUG, LOCATION, NULL, "active single bundle:\n"); 1119 printsaprop0(LLV_DEBUG, approval); 1120 1121 /* 1122 * Validate approval against sainfo 1123 * Note: we must have an updated ph1->rmconf before doing that, 1124 * we'll set check_level to EXACT if we don't have a ph1 1125 * XXX try tu find the new remote section to get the new check level ? 1126 * XXX lifebyte 1127 */ 1128 if (iph2->ph1 != NULL) 1129 iph1=iph2->ph1; 1130 else 1131 iph1=getph1byaddr(iph2->src, iph2->dst, 0); 1132 1133 if(iph1 != NULL && iph1->rmconf != NULL) { 1134 check_level = iph1->rmconf->pcheck_level; 1135 } else { 1136 if(iph1 != NULL) 1137 plog(LLV_DEBUG, LOCATION, NULL, "No phase1 rmconf found !\n"); 1138 else 1139 plog(LLV_DEBUG, LOCATION, NULL, "No phase1 found !\n"); 1140 check_level = PROP_CHECK_EXACT; 1141 } 1142 1143 switch (check_level) { 1144 case PROP_CHECK_OBEY: 1145 plog(LLV_DEBUG, LOCATION, NULL, 1146 "Reload: OBEY for ph2, ok\n"); 1147 return 1; 1148 break; 1149 1150 case PROP_CHECK_STRICT: 1151 /* FALLTHROUGH */ 1152 case PROP_CHECK_CLAIM: 1153 if (sainfo->lifetime < approval->lifetime) { 1154 plog(LLV_DEBUG, LOCATION, NULL, 1155 "Reload: lifetime mismatch\n"); 1156 return 0; 1157 } 1158 1159 #if 0 1160 /* Lifebyte is deprecated, just ignore it 1161 */ 1162 if (sainfo->lifebyte < approval->lifebyte) { 1163 plog(LLV_DEBUG, LOCATION, NULL, 1164 "Reload: lifebyte mismatch\n"); 1165 return 0; 1166 } 1167 #endif 1168 1169 if (sainfo->pfs_group && 1170 sainfo->pfs_group != approval->pfs_group) { 1171 plog(LLV_DEBUG, LOCATION, NULL, 1172 "Reload: PFS group mismatch\n"); 1173 return 0; 1174 } 1175 break; 1176 1177 case PROP_CHECK_EXACT: 1178 if (sainfo->lifetime != approval->lifetime || 1179 #if 0 1180 /* Lifebyte is deprecated, just ignore it 1181 */ 1182 sainfo->lifebyte != approval->lifebyte || 1183 #endif 1184 sainfo->pfs_group != iph2->approval->pfs_group) { 1185 plog(LLV_DEBUG, LOCATION, NULL, 1186 "Reload: lifetime | pfs mismatch\n"); 1187 return 0; 1188 } 1189 break; 1190 1191 default: 1192 plog(LLV_DEBUG, LOCATION, NULL, 1193 "Reload: Shouldn't be here !\n"); 1194 return 0; 1195 break; 1196 } 1197 1198 for (alg = sainfo->algs[algclass_ipsec_auth]; alg; alg = alg->next) { 1199 if (alg->alg == approval->head->head->authtype) 1200 break; 1201 } 1202 if (alg == NULL) { 1203 plog(LLV_DEBUG, LOCATION, NULL, 1204 "Reload: alg == NULL (auth)\n"); 1205 return 0; 1206 } 1207 1208 found = 0; 1209 for (alg = sainfo->algs[algclass_ipsec_enc]; 1210 (found == 0 && alg != NULL); alg = alg->next) { 1211 plog(LLV_DEBUG, LOCATION, NULL, 1212 "Reload: next ph2 enc alg...\n"); 1213 1214 if (alg->alg != approval->head->head->trns_id){ 1215 plog(LLV_DEBUG, LOCATION, NULL, 1216 "Reload: encmode mismatch (%d / %d)\n", 1217 alg->alg, approval->head->head->trns_id); 1218 continue; 1219 } 1220 1221 switch (check_level){ 1222 /* PROP_CHECK_STRICT cannot happen here */ 1223 case PROP_CHECK_EXACT: 1224 if (alg->encklen != approval->head->head->encklen) { 1225 plog(LLV_DEBUG, LOCATION, NULL, 1226 "Reload: enclen mismatch\n"); 1227 continue; 1228 } 1229 break; 1230 1231 case PROP_CHECK_CLAIM: 1232 /* FALLTHROUGH */ 1233 case PROP_CHECK_STRICT: 1234 if (alg->encklen > approval->head->head->encklen) { 1235 plog(LLV_DEBUG, LOCATION, NULL, 1236 "Reload: enclen mismatch\n"); 1237 continue; 1238 } 1239 break; 1240 1241 default: 1242 plog(LLV_ERROR, LOCATION, NULL, 1243 "unexpected check_level\n"); 1244 continue; 1245 break; 1246 } 1247 found = 1; 1248 } 1249 1250 if (!found){ 1251 plog(LLV_DEBUG, LOCATION, NULL, 1252 "Reload: No valid enc\n"); 1253 return 0; 1254 } 1255 1256 /* 1257 * XXX comp 1258 */ 1259 plog(LLV_DEBUG, LOCATION, NULL, 1260 "Reload: ph2 check ok\n"); 1261 1262 return 1; 1263 } 1264 1265 1266 static void 1267 remove_ph2(struct ph2handle *iph2) 1268 { 1269 u_int32_t spis[2]; 1270 1271 if(iph2 == NULL) 1272 return; 1273 1274 plog(LLV_DEBUG, LOCATION, NULL, 1275 "Deleting a Ph2...\n"); 1276 1277 if (iph2->status == PHASE2ST_ESTABLISHED) 1278 isakmp_info_send_d2(iph2); 1279 1280 if(iph2->approval != NULL && iph2->approval->head != NULL){ 1281 spis[0]=iph2->approval->head->spi; 1282 spis[1]=iph2->approval->head->spi_p; 1283 1284 /* purge_ipsec_spi() will do all the work: 1285 * - delete SPIs in kernel 1286 * - delete generated SPD 1287 * - unbind / rem / del ph2 1288 */ 1289 purge_ipsec_spi(iph2->dst, iph2->approval->head->proto_id, 1290 spis, 2); 1291 }else{ 1292 unbindph12(iph2); 1293 remph2(iph2); 1294 delph2(iph2); 1295 } 1296 } 1297 1298 static void remove_ph1(struct ph1handle *iph1){ 1299 struct ph2handle *iph2, *iph2_next; 1300 1301 if(iph1 == NULL) 1302 return; 1303 1304 plog(LLV_DEBUG, LOCATION, NULL, 1305 "Removing PH1...\n"); 1306 1307 if (iph1->status == PHASE1ST_ESTABLISHED){ 1308 for (iph2 = LIST_FIRST(&iph1->ph2tree); iph2; iph2 = iph2_next) { 1309 iph2_next = LIST_NEXT(iph2, chain); 1310 remove_ph2(iph2); 1311 } 1312 isakmp_info_send_d1(iph1); 1313 } 1314 iph1->status = PHASE1ST_EXPIRED; 1315 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); 1316 } 1317 1318 1319 static int revalidate_ph1tree_rmconf(void){ 1320 struct ph1handle *p, *next; 1321 struct remoteconf *newrmconf; 1322 1323 for (p = LIST_FIRST(&ph1tree); p; p = next) { 1324 next = LIST_NEXT(p, chain); 1325 1326 if (p->status == PHASE1ST_EXPIRED) 1327 continue; 1328 1329 newrmconf=getrmconf(p->remote); 1330 if(newrmconf == NULL){ 1331 p->rmconf = NULL; 1332 remove_ph1(p); 1333 }else{ 1334 /* Do not free old rmconf, it is just a pointer to an entry in rmtree 1335 */ 1336 p->rmconf=newrmconf; 1337 if(p->approval != NULL){ 1338 struct isakmpsa *tmpsa; 1339 1340 tmpsa=dupisakmpsa(p->approval); 1341 if(tmpsa != NULL){ 1342 delisakmpsa(p->approval); 1343 p->approval=tmpsa; 1344 p->approval->rmconf=newrmconf; 1345 } 1346 } 1347 } 1348 } 1349 1350 return 1; 1351 } 1352 1353 1354 /* rmconf is already updated here 1355 */ 1356 static int revalidate_ph1(struct ph1handle *iph1){ 1357 struct isakmpsa *p, *approval; 1358 struct etypes *e; 1359 1360 if(iph1 == NULL || 1361 iph1->approval == NULL || 1362 iph1->rmconf == NULL) 1363 return 0; 1364 1365 approval=iph1->approval; 1366 1367 for (e = iph1->rmconf->etypes; e != NULL; e = e->next){ 1368 if (iph1->etype == e->type) 1369 break; 1370 } 1371 1372 if (e == NULL){ 1373 plog(LLV_DEBUG, LOCATION, NULL, 1374 "Reload: Exchange type mismatch\n"); 1375 return 0; 1376 } 1377 1378 if (iph1->etype == ISAKMP_ETYPE_AGG && 1379 approval->dh_group != iph1->rmconf->dh_group){ 1380 plog(LLV_DEBUG, LOCATION, NULL, 1381 "Reload: DH mismatch\n"); 1382 return 0; 1383 } 1384 1385 for (p=iph1->rmconf->proposal; p != NULL; p=p->next){ 1386 plog(LLV_DEBUG, LOCATION, NULL, 1387 "Reload: Trying next proposal...\n"); 1388 1389 if(approval->authmethod != p->authmethod){ 1390 plog(LLV_DEBUG, LOCATION, NULL, 1391 "Reload: Authmethod mismatch\n"); 1392 continue; 1393 } 1394 1395 if(approval->enctype != p->enctype){ 1396 plog(LLV_DEBUG, LOCATION, NULL, 1397 "Reload: enctype mismatch\n"); 1398 continue; 1399 } 1400 1401 switch (iph1->rmconf->pcheck_level) { 1402 case PROP_CHECK_OBEY: 1403 plog(LLV_DEBUG, LOCATION, NULL, 1404 "Reload: OBEY pcheck level, ok...\n"); 1405 return 1; 1406 break; 1407 1408 case PROP_CHECK_CLAIM: 1409 /* FALLTHROUGH */ 1410 case PROP_CHECK_STRICT: 1411 if (approval->encklen < p->encklen) { 1412 plog(LLV_DEBUG, LOCATION, NULL, 1413 "Reload: encklen mismatch\n"); 1414 continue; 1415 } 1416 1417 if (approval->lifetime > p->lifetime) { 1418 plog(LLV_DEBUG, LOCATION, NULL, 1419 "Reload: lifetime mismatch\n"); 1420 continue; 1421 } 1422 1423 #if 0 1424 /* Lifebyte is deprecated, just ignore it 1425 */ 1426 if (approval->lifebyte > p->lifebyte) { 1427 plog(LLV_DEBUG, LOCATION, NULL, 1428 "Reload: lifebyte mismatch\n"); 1429 continue; 1430 } 1431 #endif 1432 break; 1433 1434 case PROP_CHECK_EXACT: 1435 if (approval->encklen != p->encklen) { 1436 plog(LLV_DEBUG, LOCATION, NULL, 1437 "Reload: encklen mismatch\n"); 1438 continue; 1439 } 1440 1441 if (approval->lifetime != p->lifetime) { 1442 plog(LLV_DEBUG, LOCATION, NULL, 1443 "Reload: lifetime mismatch\n"); 1444 continue; 1445 } 1446 1447 #if 0 1448 /* Lifebyte is deprecated, just ignore it 1449 */ 1450 if (approval->lifebyte != p->lifebyte) { 1451 plog(LLV_DEBUG, LOCATION, NULL, 1452 "Reload: lifebyte mismatch\n"); 1453 continue; 1454 } 1455 #endif 1456 break; 1457 1458 default: 1459 plog(LLV_ERROR, LOCATION, NULL, 1460 "unexpected check_level\n"); 1461 continue; 1462 break; 1463 } 1464 1465 if (approval->hashtype != p->hashtype) { 1466 plog(LLV_DEBUG, LOCATION, NULL, 1467 "Reload: hashtype mismatch\n"); 1468 continue; 1469 } 1470 1471 if (iph1->etype != ISAKMP_ETYPE_AGG && 1472 approval->dh_group != p->dh_group) { 1473 plog(LLV_DEBUG, LOCATION, NULL, 1474 "Reload: dhgroup mismatch\n"); 1475 continue; 1476 } 1477 1478 plog(LLV_DEBUG, LOCATION, NULL, "Reload: Conf ok\n"); 1479 return 1; 1480 } 1481 1482 plog(LLV_DEBUG, LOCATION, NULL, "Reload: No valid conf found\n"); 1483 return 0; 1484 } 1485 1486 1487 static int revalidate_ph1tree(void){ 1488 struct ph1handle *p, *next; 1489 1490 for (p = LIST_FIRST(&ph1tree); p; p = next) { 1491 next = LIST_NEXT(p, chain); 1492 1493 if (p->status == PHASE1ST_EXPIRED) 1494 continue; 1495 1496 if(!revalidate_ph1(p)) 1497 remove_ph1(p); 1498 } 1499 1500 return 1; 1501 } 1502 1503 static int revalidate_ph2tree(void){ 1504 struct ph2handle *p, *next; 1505 1506 for (p = LIST_FIRST(&ph2tree); p; p = next) { 1507 next = LIST_NEXT(p, chain); 1508 1509 if (p->status == PHASE2ST_EXPIRED) 1510 continue; 1511 1512 if(!revalidate_ph2(p)){ 1513 plog(LLV_DEBUG, LOCATION, NULL, 1514 "PH2 not validated, removing it\n"); 1515 remove_ph2(p); 1516 } 1517 } 1518 1519 return 1; 1520 } 1521 1522 int 1523 revalidate_ph12(void) 1524 { 1525 1526 revalidate_ph1tree_rmconf(); 1527 1528 revalidate_ph2tree(); 1529 revalidate_ph1tree(); 1530 1531 return 1; 1532 } 1533 1534 #ifdef ENABLE_HYBRID 1535 struct ph1handle * 1536 getph1bylogin(login) 1537 char *login; 1538 { 1539 struct ph1handle *p; 1540 1541 LIST_FOREACH(p, &ph1tree, chain) { 1542 if (p->mode_cfg == NULL) 1543 continue; 1544 if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) 1545 return p; 1546 } 1547 1548 return NULL; 1549 } 1550 1551 int 1552 purgeph1bylogin(login) 1553 char *login; 1554 { 1555 struct ph1handle *p; 1556 int found = 0; 1557 1558 LIST_FOREACH(p, &ph1tree, chain) { 1559 if (p->mode_cfg == NULL) 1560 continue; 1561 if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) { 1562 if (p->status == PHASE1ST_ESTABLISHED) 1563 isakmp_info_send_d1(p); 1564 purge_remote(p); 1565 found++; 1566 } 1567 } 1568 1569 return found; 1570 } 1571 #endif 1572