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