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