1/* $NetBSD: handler.c,v 1.9.6.6 2007/06/06 09:20:12 vanhu 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#include "fsm.h" 53 54#ifdef ENABLE_HYBRID 55#include <resolv.h> 56#endif 57 58#include "schedule.h" 59#include "grabmyaddr.h" 60#include "algorithm.h" 61#include "crypto_openssl.h" 62#include "policy.h" 63#include "proposal.h" 64#include "isakmp_var.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#include "ike_session.h" 78#include "isakmp_frag.h" 79 80#include "sainfo.h" 81 82#include "power_mgmt.h" 83 84extern LIST_HEAD(_ike_session_tree_, ike_session) ike_session_tree; 85static LIST_HEAD(_ctdtree_, contacted) ctdtree; 86static LIST_HEAD(_rcptree_, recvdpkt) rcptree; 87 88static void ike_session_del_recvdpkt (struct recvdpkt *); 89static void ike_session_rem_recvdpkt (struct recvdpkt *); 90static void sweep_recvdpkt (void *); 91 92/* 93 * functions about management of the isakmp status table 94 */ 95/* %%% management phase 1 handler */ 96/* 97 * search for isakmpsa handler with isakmp index. 98 */ 99 100extern caddr_t val2str (const char *, size_t); 101 102static phase1_handle_t * 103getph1byindex(ike_session_t *session, isakmp_index *index) 104{ 105 phase1_handle_t *p = NULL; 106 107 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 108 if (FSM_STATE_IS_EXPIRED(p->status)) 109 continue; 110 if (memcmp(&p->index, index, sizeof(*index)) == 0) 111 return p; 112 } 113 114 return NULL; 115} 116 117phase1_handle_t * 118ike_session_getph1byindex(ike_session_t *session, isakmp_index *index) 119{ 120 phase1_handle_t *p; 121 ike_session_t *cur_session = NULL; 122 123 if (session) 124 return getph1byindex(session, index); 125 126 LIST_FOREACH(cur_session, &ike_session_tree, chain) { 127 if ((p = getph1byindex(cur_session, index)) != NULL) 128 return p; 129 } 130 return NULL; 131} 132 133 134/* 135 * search for isakmp handler by i_ck in index. 136 */ 137 138static phase1_handle_t * 139getph1byindex0 (ike_session_t *session, isakmp_index *index) 140{ 141 phase1_handle_t *p = NULL; 142 143 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 144 if (FSM_STATE_IS_EXPIRED(p->status)) 145 continue; 146 if (memcmp(&p->index.i_ck, &index->i_ck, sizeof(cookie_t)) == 0) 147 return p; 148 } 149 return NULL; 150} 151 152phase1_handle_t * 153ike_session_getph1byindex0(ike_session_t *session, isakmp_index *index) 154{ 155 phase1_handle_t *p = NULL; 156 ike_session_t *cur_session = NULL; 157 158 if (session) 159 return getph1byindex0(session, index); 160 161 LIST_FOREACH(cur_session, &ike_session_tree, chain) { 162 if ((p = getph1byindex0(cur_session, index)) != NULL) 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 */ 174phase1_handle_t * 175ike_session_getph1byaddr(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote) 176{ 177 phase1_handle_t *p = NULL; 178 179 plog(ASL_LEVEL_DEBUG, "getph1byaddr: start\n"); 180 plog(ASL_LEVEL_DEBUG, "local: %s\n", saddr2str((struct sockaddr *)local)); 181 plog(ASL_LEVEL_DEBUG, "remote: %s\n", saddr2str((struct sockaddr *)remote)); 182 183 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 184 if (FSM_STATE_IS_EXPIRED(p->status)) 185 continue; 186 plog(ASL_LEVEL_DEBUG, "p->local: %s\n", saddr2str((struct sockaddr *)p->local)); 187 plog(ASL_LEVEL_DEBUG, "p->remote: %s\n", saddr2str((struct sockaddr *)p->remote)); 188 if (CMPSADDR(local, p->local) == 0 189 && CMPSADDR(remote, p->remote) == 0){ 190 plog(ASL_LEVEL_DEBUG, "matched\n"); 191 return p; 192 } 193 } 194 195 plog(ASL_LEVEL_DEBUG, "no match\n"); 196 197 return NULL; 198} 199 200static phase1_handle_t * 201sgetph1byaddrwop(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote) 202{ 203 phase1_handle_t *p = NULL; 204 205 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 206 if (FSM_STATE_IS_EXPIRED(p->status)) 207 continue; 208 if (cmpsaddrwop(local, p->local) == 0 209 && cmpsaddrwop(remote, p->remote) == 0) 210 return p; 211 } 212 213 return NULL; 214} 215 216phase1_handle_t * 217ike_session_getph1byaddrwop(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote) 218{ 219 phase1_handle_t *p; 220 ike_session_t *cur_session = NULL; 221 222 if (session) 223 return sgetph1byaddrwop(session, local, remote); 224 225 LIST_FOREACH(cur_session, &ike_session_tree, chain) { 226 if ((p = sgetph1byaddrwop(cur_session, local, remote)) != NULL) 227 return p; 228 } 229 230 return NULL; 231} 232 233/* 234 * search for isakmpsa handler by remote address. 235 * don't use port number to search because this function search 236 * with phase 2's destinaion. 237 */ 238phase1_handle_t * 239sike_session_getph1bydstaddrwop(ike_session_t *session, struct sockaddr_storage *remote) 240{ 241 phase1_handle_t *p = NULL; 242 243 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 244 if (FSM_STATE_IS_EXPIRED(p->status)) 245 continue; 246 if (cmpsaddrwop(remote, p->remote) == 0) 247 return p; 248 } 249 250 return NULL; 251} 252 253phase1_handle_t * 254ike_session_getph1bydstaddrwop(ike_session_t *session, struct sockaddr_storage *remote) 255{ 256 phase1_handle_t *p; 257 ike_session_t *cur_session = NULL; 258 259 if (session) 260 return sike_session_getph1bydstaddrwop(session, remote); 261 else { 262 LIST_FOREACH(cur_session, &ike_session_tree, chain) { 263 if ((p = sike_session_getph1bydstaddrwop(cur_session, remote)) != NULL) 264 return p; 265 } 266 } 267 return NULL; 268} 269 270int 271ike_session_islast_ph1(phase1_handle_t *ph1) 272{ 273 phase1_handle_t *p = NULL; 274 275 LIST_FOREACH(p, &ph1->parent_session->ph1tree, ph1ofsession_chain) { 276 if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) 277 continue; 278 if (CMPSADDR(ph1->remote, p->remote) == 0) { 279 if (p == ph1) 280 continue; 281 return 0; 282 } 283 } 284 return 1; 285} 286 287/* 288 * create new isakmp Phase 1 status record to handle isakmp in Phase1 289 */ 290phase1_handle_t * 291ike_session_newph1(unsigned int version) 292{ 293 phase1_handle_t *iph1; 294 295 /* create new iph1 */ 296 iph1 = racoon_calloc(1, sizeof(*iph1)); 297 if (iph1 == NULL) 298 return NULL; 299 iph1->version = version; 300 301#ifdef ENABLE_DPD 302 iph1->dpd_support = 0; 303 iph1->dpd_lastack = 0; 304 iph1->dpd_seq = 0; 305 iph1->dpd_fails = 0; 306 iph1->peer_sent_ike = 0; 307 iph1->dpd_r_u = NULL; 308#endif 309#ifdef ENABLE_VPNCONTROL_PORT 310 iph1->ping_sched = NULL; 311#endif 312 iph1->is_dying = 0; 313 plog(ASL_LEVEL_DEBUG, "*** New Phase 1\n"); 314 return iph1; 315} 316 317/* 318 * delete new isakmp Phase 1 status record to handle isakmp in Phase1 319 */ 320void 321ike_session_delph1(phase1_handle_t *iph1) 322{ 323 if (iph1 == NULL) 324 return; 325 326#ifdef ENABLE_NATT 327 if (iph1->natt_options) { 328 racoon_free(iph1->natt_options); 329 iph1->natt_options = NULL; 330 } 331#endif 332 333#ifdef ENABLE_HYBRID 334 if (iph1->mode_cfg) 335 isakmp_cfg_rmstate(iph1); 336 VPTRINIT(iph1->xauth_awaiting_userinput_msg); 337#endif 338 339#ifdef ENABLE_DPD 340 if (iph1->dpd_r_u) 341 SCHED_KILL(iph1->dpd_r_u); 342#endif 343#ifdef ENABLE_VPNCONTROL_PORT 344 if (iph1->ping_sched) 345 SCHED_KILL(iph1->ping_sched); 346#endif 347 348 if (iph1->remote) { 349 racoon_free(iph1->remote); 350 iph1->remote = NULL; 351 } 352 if (iph1->local) { 353 racoon_free(iph1->local); 354 iph1->local = NULL; 355 } 356 357 if (iph1->approval) { 358 delisakmpsa(iph1->approval); 359 iph1->approval = NULL; 360 } 361 362 sched_scrub_param(iph1); 363 if (iph1->sce) 364 SCHED_KILL(iph1->sce); 365 if (iph1->sce_rekey) 366 SCHED_KILL(iph1->sce_rekey); 367 if (iph1->scr) 368 SCHED_KILL(iph1->scr); 369 370 VPTRINIT(iph1->sendbuf); 371 372 VPTRINIT(iph1->dhpriv); 373 VPTRINIT(iph1->dhpub); 374 VPTRINIT(iph1->dhpub_p); 375 VPTRINIT(iph1->dhgxy); 376 VPTRINIT(iph1->nonce); 377 VPTRINIT(iph1->nonce_p); 378 VPTRINIT(iph1->skeyid); 379 VPTRINIT(iph1->skeyid_d); 380 VPTRINIT(iph1->skeyid_a); 381 VPTRINIT(iph1->skeyid_a_p); 382 VPTRINIT(iph1->skeyid_e); 383 VPTRINIT(iph1->skeyid_e_p); 384 VPTRINIT(iph1->key); 385 VPTRINIT(iph1->key_p); 386 VPTRINIT(iph1->hash); 387 VPTRINIT(iph1->sig); 388 VPTRINIT(iph1->sig_p); 389 oakley_delcert(iph1->cert); 390 iph1->cert = NULL; 391 oakley_delcert(iph1->cert_p); 392 iph1->cert_p = NULL; 393 oakley_delcert(iph1->crl_p); 394 iph1->crl_p = NULL; 395 oakley_delcert(iph1->cr_p); 396 iph1->cr_p = NULL; 397 VPTRINIT(iph1->id); 398 VPTRINIT(iph1->id_p); 399 400 if(iph1->approval != NULL) 401 delisakmpsa(iph1->approval); 402 403 if (iph1->ivm) { 404 oakley_delivm(iph1->ivm); 405 iph1->ivm = NULL; 406 } 407 408 VPTRINIT(iph1->sa); 409 VPTRINIT(iph1->sa_ret); 410 411 if (iph1->rmconf) { 412 release_rmconf(iph1->rmconf); 413 iph1->rmconf = NULL; 414 } 415 416 racoon_free(iph1); 417} 418 419void 420ike_session_flush_all_phase1_for_session(ike_session_t *session, int ignore_estab_or_assert_handles) 421{ 422 phase1_handle_t *p, *next; 423 424 LIST_FOREACH_SAFE(p, &session->ph1tree, ph1ofsession_chain, next) { 425 if (ignore_estab_or_assert_handles && p->parent_session && !p->parent_session->stopped_by_vpn_controller && p->parent_session->is_asserted) { 426 plog(ASL_LEVEL_DEBUG, 427 "Skipping Phase 1 %s that's asserted...\n", 428 isakmp_pindex(&p->index, 0)); 429 continue; 430 } 431 432 /* send delete information */ 433 if (FSM_STATE_IS_ESTABLISHED(p->status)) { 434 if (ignore_estab_or_assert_handles && 435 (ike_session_has_negoing_ph2(p->parent_session) || ike_session_has_established_ph2(p->parent_session))) { 436 plog(ASL_LEVEL_DEBUG, 437 "Skipping Phase 1 %s that's established... because it's needed by children Phase 2s\n", 438 isakmp_pindex(&p->index, 0)); 439 continue; 440 } 441 /* send delete information */ 442 plog(ASL_LEVEL_DEBUG, 443 "Got a Phase 1 %s to flush...\n", 444 isakmp_pindex(&p->index, 0)); 445 isakmp_info_send_d1(p); 446 } 447 448 ike_session_stopped_by_controller(p->parent_session, 449 ike_session_stopped_by_flush); 450 451 ike_session_unlink_phase1(p); 452 } 453} 454 455/* 456 * flush isakmp-sa 457 */ 458void 459ike_session_flush_all_phase1(int ignore_estab_or_assert_handles) 460{ 461 ike_session_t *session = NULL; 462 ike_session_t *next_session = NULL; 463 464 plog(ASL_LEVEL_DEBUG, 465 "Flushing Phase 1 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles); 466 467 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) { 468 ike_session_flush_all_phase1_for_session(session, ignore_estab_or_assert_handles); 469 } 470} 471 472 473 474/* 475 * search ph2handle with policy id. 476 */ 477phase2_handle_t * 478ike_session_getph2byspid(u_int32_t spid) 479{ 480 ike_session_t *session = NULL; 481 phase2_handle_t *p; 482 483 LIST_FOREACH(session, &ike_session_tree, chain) { 484 LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) { 485 /* 486 * there are ph2handle independent on policy 487 * such like informational exchange. 488 */ 489 if (p->spid == spid) 490 return p; 491 } 492 } 493 494 return NULL; 495} 496 497 498/* 499 * search ph2handle with sequence number. 500 * Used by PF_KEY functions to locate the phase2 501 */ 502phase2_handle_t * 503ike_session_getph2byseq(u_int32_t seq) 504{ 505 ike_session_t *session; 506 phase2_handle_t *p; 507 508 LIST_FOREACH(session, &ike_session_tree, chain) { 509 LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) { 510 if (p->seq == seq) 511 return p; 512 } 513 } 514 return NULL; 515} 516 517/* 518 * search ph2handle with message id. 519 */ 520phase2_handle_t * 521ike_session_getph2bymsgid(phase1_handle_t *iph1, u_int32_t msgid) 522{ 523 phase2_handle_t *p; 524 525 LIST_FOREACH(p, &iph1->parent_session->ph2tree, ph2ofsession_chain) { 526 if (p->msgid == msgid && !p->is_defunct) 527 return p; 528 } 529 530 return NULL; 531} 532 533phase2_handle_t * 534ike_session_getonlyph2(phase1_handle_t *iph1) 535{ 536 phase2_handle_t *only_ph2 = NULL; 537 phase2_handle_t *p = NULL; 538 539 LIST_FOREACH(p, &iph1->bound_ph2tree, ph2ofsession_chain) { 540 if (only_ph2) return NULL; 541 only_ph2 = p; 542 } 543 544 return only_ph2; 545} 546 547phase2_handle_t * 548ike_session_getph2byid(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int32_t spid) 549{ 550 ike_session_t *session = NULL; 551 ike_session_t *next_session = NULL; 552 phase2_handle_t *p; 553 phase2_handle_t *next_iph2; 554 555 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) { 556 LIST_FOREACH_SAFE(p, &session->ph2tree, ph2ofsession_chain, next_iph2) { 557 if (spid == p->spid && 558 CMPSADDR(src, p->src) == 0 && 559 CMPSADDR(dst, p->dst) == 0){ 560 /* Sanity check to detect zombie handlers 561 * XXX Sould be done "somewhere" more interesting, 562 * because we have lots of getph2byxxxx(), but this one 563 * is called by pk_recvacquire(), so is the most important. 564 */ 565 if(!FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(p->status) && 566 p->retry_counter == 0 567 && p->sce == 0 && p->scr == 0 && 568 p->retry_checkph1 == 0){ 569 plog(ASL_LEVEL_DEBUG, 570 "Zombie ph2 found, expiring it\n"); 571 isakmp_ph2expire(p); 572 }else 573 return p; 574 } 575 } 576 } 577 578 return NULL; 579} 580 581#ifdef NOT_USED 582phase2_handle_t * 583ike_session_getph2bysaddr(struct sockaddr_storage *src, struct sockaddr_storage *dst) 584{ 585 ike_session_t *session; 586 phase2_handle_t *p; 587 588 LIST_FOREACH(session, &ike_session_tree, chain) { 589 LIST_FOREACH(p, &session->ph2tree, chain) { 590 if (cmpsaddrstrict(src, p->src) == 0 && 591 cmpsaddrstrict(dst, p->dst) == 0) 592 return p; 593 } 594 } 595 596 return NULL; 597} 598#endif /* NOT_USED */ 599 600/* 601 * call by pk_recvexpire(). 602 */ 603phase2_handle_t * 604ike_session_getph2bysaidx(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id, u_int32_t spi) 605{ 606 ike_session_t *session; 607 phase2_handle_t *iph2; 608 struct saproto *pr; 609 610 LIST_FOREACH(session, &ike_session_tree, chain) { 611 LIST_FOREACH(iph2, &session->ph2tree, ph2ofsession_chain) { 612 if (iph2->proposal == NULL && iph2->approval == NULL) 613 continue; 614 if (iph2->approval != NULL) { 615 for (pr = iph2->approval->head; pr != NULL; 616 pr = pr->next) { 617 if (proto_id != pr->proto_id) 618 break; 619 if (spi == pr->spi || spi == pr->spi_p) 620 return iph2; 621 } 622 } else if (iph2->proposal != NULL) { 623 for (pr = iph2->proposal->head; pr != NULL; 624 pr = pr->next) { 625 if (proto_id != pr->proto_id) 626 break; 627 if (spi == pr->spi) 628 return iph2; 629 } 630 } 631 } 632 } 633 634 return NULL; 635} 636 637phase2_handle_t * 638ike_session_getph2bysaidx2(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id, u_int32_t spi, u_int32_t *opposite_spi) 639{ 640 ike_session_t *session; 641 phase2_handle_t *iph2; 642 struct saproto *pr; 643 644 LIST_FOREACH(session, &ike_session_tree, chain) { 645 LIST_FOREACH(iph2, &session->ph2tree, ph2ofsession_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 if (opposite_spi) { 655 *opposite_spi = (spi == pr->spi)? pr->spi_p : pr->spi; 656 } 657 return iph2; 658 } 659 } 660 } else if (iph2->proposal != NULL) { 661 for (pr = iph2->proposal->head; pr != NULL; 662 pr = pr->next) { 663 if (proto_id != pr->proto_id) 664 break; 665 if (spi == pr->spi || spi == pr->spi_p) { 666 if (opposite_spi) { 667 *opposite_spi = (spi == pr->spi)? pr->spi_p : pr->spi; 668 } 669 return iph2; 670 } 671 } 672 } 673 } 674 } 675 676 return NULL; 677} 678 679/* 680 * create new isakmp Phase 2 status record to handle isakmp in Phase2 681 */ 682phase2_handle_t * 683ike_session_newph2(unsigned int version, int type) 684{ 685 phase2_handle_t *iph2 = NULL; 686 687 /* create new iph2 */ 688 iph2 = racoon_calloc(1, sizeof(*iph2)); 689 if (iph2 == NULL) 690 return NULL; 691 iph2->version = version; 692 iph2->phase2_type = type; 693 iph2->is_dying = 0; 694 695 plog(ASL_LEVEL_DEBUG, "*** New Phase 2\n"); 696 return iph2; 697} 698 699/* 700 * initialize ph2handle 701 * NOTE: don't initialize src/dst. 702 * SPI in the proposal is cleared. 703 */ 704void 705ike_session_initph2(phase2_handle_t *iph2) 706{ 707 sched_scrub_param(iph2); 708 iph2->sce = NULL; 709 iph2->scr = NULL; 710 711 VPTRINIT(iph2->sendbuf); 712 VPTRINIT(iph2->msg1); 713 714 /* clear spi, keep variables in the proposal */ 715 if (iph2->proposal) { 716 struct saproto *pr; 717 for (pr = iph2->proposal->head; pr != NULL; pr = pr->next) 718 pr->spi = 0; 719 } 720 721 /* clear approval */ 722 if (iph2->approval) { 723 flushsaprop(iph2->approval); 724 iph2->approval = NULL; 725 } 726 727 /* clear the generated policy */ 728 if (iph2->spidx_gen) { 729 delsp_bothdir(iph2->spidx_gen); 730 racoon_free(iph2->spidx_gen); 731 iph2->spidx_gen = NULL; 732 } 733 734 if (iph2->pfsgrp) { 735 oakley_dhgrp_free(iph2->pfsgrp); 736 iph2->pfsgrp = NULL; 737 } 738 739 VPTRINIT(iph2->dhpriv); 740 VPTRINIT(iph2->dhpub); 741 VPTRINIT(iph2->dhpub_p); 742 VPTRINIT(iph2->dhgxy); 743 VPTRINIT(iph2->id); 744 VPTRINIT(iph2->id_p); 745 VPTRINIT(iph2->nonce); 746 VPTRINIT(iph2->nonce_p); 747 VPTRINIT(iph2->sa); 748 VPTRINIT(iph2->sa_ret); 749 750 if (iph2->ivm) { 751 oakley_delivm(iph2->ivm); 752 iph2->ivm = NULL; 753 } 754} 755 756/* 757 * delete new isakmp Phase 2 status record to handle isakmp in Phase2 758 */ 759void 760ike_session_delph2(phase2_handle_t *iph2) 761{ 762 ike_session_initph2(iph2); 763 764 if (iph2->src) { 765 racoon_free(iph2->src); 766 iph2->src = NULL; 767 } 768 if (iph2->dst) { 769 racoon_free(iph2->dst); 770 iph2->dst = NULL; 771 } 772 if (iph2->src_id) { 773 racoon_free(iph2->src_id); 774 iph2->src_id = NULL; 775 } 776 if (iph2->dst_id) { 777 racoon_free(iph2->dst_id); 778 iph2->dst_id = NULL; 779 } 780 781 if (iph2->proposal) { 782 flushsaprop(iph2->proposal); 783 iph2->proposal = NULL; 784 } 785 786 if (iph2->sainfo) { 787 release_sainfo(iph2->sainfo); 788 iph2->sainfo = NULL; 789 } 790 VPTRINIT(iph2->id); 791 VPTRINIT(iph2->id_p); 792 VPTRINIT(iph2->ext_nat_id); 793 VPTRINIT(iph2->ext_nat_id_p); 794 795 if (iph2->sce) 796 SCHED_KILL(iph2->sce); 797 if (iph2->scr) 798 SCHED_KILL(iph2->scr); 799 800 racoon_free(iph2); 801} 802 803void 804ike_session_flush_all_phase2_for_session(ike_session_t *session, int ignore_estab_or_assert_handles) 805{ 806 phase2_handle_t *p = NULL; 807 phase2_handle_t *next = NULL; 808 LIST_FOREACH_SAFE(p, &session->ph2tree, ph2ofsession_chain, next) { 809 if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) { 810 continue; 811 } 812 if (ignore_estab_or_assert_handles && p->parent_session && !p->parent_session->stopped_by_vpn_controller && p->parent_session->is_asserted) { 813 plog(ASL_LEVEL_DEBUG, 814 "skipping phase2 handle that's asserted...\n"); 815 continue; 816 } 817 if (FSM_STATE_IS_ESTABLISHED(p->status)){ 818 if (ignore_estab_or_assert_handles) { 819 plog(ASL_LEVEL_DEBUG, 820 "skipping ph2 handler that's established...\n"); 821 continue; 822 } 823 /* send delete information */ 824 plog(ASL_LEVEL_DEBUG, 825 "got an established ph2 handler to flush...\n"); 826 isakmp_info_send_d2(p); 827 }else{ 828 plog(ASL_LEVEL_DEBUG, 829 "got a ph2 handler to flush (state %d)\n", p->status); 830 } 831 832 ike_session_stopped_by_controller(p->parent_session, 833 ike_session_stopped_by_flush); 834 delete_spd(p); 835 ike_session_unlink_phase2(p); 836 } 837} 838 839void 840ike_session_flush_all_phase2(int ignore_estab_or_assert_handles) 841{ 842 ike_session_t *session = NULL; 843 ike_session_t *next_session = NULL; 844 845 plog(ASL_LEVEL_DEBUG, 846 "flushing ph2 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles); 847 848 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) { 849 ike_session_flush_all_phase2_for_session(session, ignore_estab_or_assert_handles); 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//%%%%%%%%%%%%%%%%%%% make this smarter - find session using addresses ???? 859void 860ike_session_deleteallph2(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id) 861{ 862 ike_session_t *session = NULL; 863 ike_session_t *next_session = NULL; 864 phase2_handle_t *iph2 = NULL; 865 phase2_handle_t *next_iph2 = NULL; 866 struct saproto *pr; 867 868 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) { 869 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) { 870 if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) { 871 continue; 872 } 873 if (iph2->proposal == NULL && iph2->approval == NULL) 874 continue; 875 if (cmpsaddrwop(src, iph2->src) != 0 || 876 cmpsaddrwop(dst, iph2->dst) != 0) { 877 continue; 878 } 879 if (iph2->approval != NULL) { 880 for (pr = iph2->approval->head; pr != NULL; 881 pr = pr->next) { 882 if (proto_id == pr->proto_id) 883 goto zap_it; 884 } 885 } else if (iph2->proposal != NULL) { 886 for (pr = iph2->proposal->head; pr != NULL; 887 pr = pr->next) { 888 if (proto_id == pr->proto_id) 889 goto zap_it; 890 } 891 } 892 continue; 893 zap_it: 894 plog(ASL_LEVEL_DEBUG, 895 "deleteallph2: got a ph2 handler...\n"); 896 if (FSM_STATE_IS_ESTABLISHED(iph2->status)) 897 isakmp_info_send_d2(iph2); 898 ike_session_stopped_by_controller(iph2->parent_session, 899 ike_session_stopped_by_flush); 900 ike_session_unlink_phase2(iph2); 901 } 902 } 903} 904 905/* 906 * Delete all Phase 1 handlers for this src/dst. 907 */ 908void 909ike_session_deleteallph1(struct sockaddr_storage *src, struct sockaddr_storage *dst) 910{ 911 ike_session_t *session = NULL; 912 ike_session_t *next_session = NULL; 913 phase1_handle_t *iph1 = NULL; 914 phase1_handle_t *next_iph1 = NULL; 915 916 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) { 917 LIST_FOREACH_SAFE(iph1, &session->ph1tree, ph1ofsession_chain, next_iph1) { 918 if (cmpsaddrwop(src, iph1->local) != 0 || 919 cmpsaddrwop(dst, iph1->remote) != 0) { 920 continue; 921 } 922 plog(ASL_LEVEL_DEBUG, 923 "deleteallph1: got a ph1 handler...\n"); 924 if (FSM_STATE_IS_ESTABLISHED(iph1->status)) 925 isakmp_info_send_d1(iph1); 926 927 ike_session_stopped_by_controller(iph1->parent_session, ike_session_stopped_by_flush); 928 ike_session_unlink_phase1(iph1); 929 } 930 } 931} 932 933 934/* %%% management contacted list */ 935/* 936 * search contacted list. 937 */ 938struct contacted * 939ike_session_getcontacted(remote) 940struct sockaddr_storage *remote; 941{ 942 struct contacted *p; 943 944 LIST_FOREACH(p, &ctdtree, chain) { 945 if (cmpsaddrstrict(remote, p->remote) == 0) 946 return p; 947 } 948 949 return NULL; 950} 951 952/* 953 * create new isakmp Phase 2 status record to handle isakmp in Phase2 954 */ 955int 956ike_session_inscontacted(remote) 957struct sockaddr_storage *remote; 958{ 959 struct contacted *new; 960 961 /* create new iph2 */ 962 new = racoon_calloc(1, sizeof(*new)); 963 if (new == NULL) 964 return -1; 965 966 new->remote = dupsaddr(remote); 967 if (new->remote == NULL) { 968 plog(ASL_LEVEL_ERR, 969 "failed to allocate buffer.\n"); 970 racoon_free(new); 971 return -1; 972 } 973 974 LIST_INSERT_HEAD(&ctdtree, new, chain); 975 976 return 0; 977} 978 979 980void 981ike_session_clear_contacted() 982{ 983 struct contacted *c, *next; 984 LIST_FOREACH_SAFE(c, &ctdtree, chain, next) { 985 LIST_REMOVE(c, chain); 986 racoon_free(c->remote); 987 racoon_free(c); 988 } 989} 990 991void 992ike_session_initctdtree() 993{ 994 LIST_INIT(&ctdtree); 995} 996 997time_t 998ike_session_get_exp_retx_interval (int num_retries, int fixed_retry_interval) 999{ 1000 // first 3 retries aren't exponential 1001 if (num_retries <= 3) { 1002 return (time_t)fixed_retry_interval; 1003 } else { 1004 return (time_t)(num_retries * fixed_retry_interval); 1005 } 1006} 1007 1008/* 1009 * check the response has been sent to the peer. when not, simply reply 1010 * the buffered packet to the peer. 1011 * OUT: 1012 * 0: the packet is received at the first time. 1013 * 1: the packet was processed before. 1014 * 2: the packet was processed before, but the address mismatches. 1015 * -1: error happened. 1016 */ 1017int 1018ike_session_check_recvdpkt(remote, local, rbuf) 1019struct sockaddr_storage *remote, *local; 1020vchar_t *rbuf; 1021{ 1022 vchar_t *hash; 1023 struct recvdpkt *r; 1024 time_t t, d; 1025 int len, s; 1026 1027 /* set current time */ 1028 t = time(NULL); 1029 1030 hash = eay_md5_one(rbuf); 1031 if (!hash) { 1032 plog(ASL_LEVEL_ERR, 1033 "failed to allocate buffer.\n"); 1034 return -1; 1035 } 1036 1037 LIST_FOREACH(r, &rcptree, chain) { 1038 if (memcmp(hash->v, r->hash->v, r->hash->l) == 0) 1039 break; 1040 } 1041 vfree(hash); 1042 1043 /* this is the first time to receive the packet */ 1044 if (r == NULL) 1045 return 0; 1046 1047 /* 1048 * the packet was processed before, but the remote address mismatches. 1049 * ignore the port to accomodate port changes (e.g. floating). 1050 */ 1051 if (cmpsaddrwop(remote, r->remote) != 0) { 1052 return 2; 1053 } 1054 1055 /* 1056 * it should not check the local address because the packet 1057 * may arrive at other interface. 1058 */ 1059 1060 /* check the previous time to send */ 1061 if (t - r->time_send < 1) { 1062 plog(ASL_LEVEL_WARNING, 1063 "the packet retransmitted in a short time from %s\n", 1064 saddr2str((struct sockaddr *)remote)); 1065 /*XXX should it be error ? */ 1066 } 1067 1068 /* select the socket to be sent */ 1069 s = getsockmyaddr((struct sockaddr *)r->local); 1070 if (s == -1) 1071 return -1; 1072 1073 // don't send if we recently sent a response. 1074 if (r->time_send && t > r->time_send) { 1075 d = t - r->time_send; 1076 if (d < r->retry_interval) { 1077 plog(ASL_LEVEL_ERR, "already responded within the past %ld secs\n", d); 1078 return 1; 1079 } 1080 } 1081 1082#ifdef ENABLE_FRAG 1083 if (r->frag_flags && r->sendbuf->l > ISAKMP_FRAG_MAXLEN) { 1084 /* resend the packet if needed */ 1085 plog(ASL_LEVEL_ERR, "!!! retransmitting frags\n"); 1086 len = sendfragsfromto(s, r->sendbuf, 1087 r->local, r->remote, lcconf->count_persend, 1088 r->frag_flags); 1089 } else { 1090 plog(ASL_LEVEL_ERR, "!!! skipped retransmitting frags: frag_flags %x, r->sendbuf->l %zu, max %d\n", r->frag_flags, r->sendbuf->l, ISAKMP_FRAG_MAXLEN); 1091 /* resend the packet if needed */ 1092 len = sendfromto(s, r->sendbuf->v, r->sendbuf->l, 1093 r->local, r->remote, lcconf->count_persend); 1094 } 1095#else 1096 /* resend the packet if needed */ 1097 len = sendfromto(s, r->sendbuf->v, r->sendbuf->l, 1098 r->local, r->remote, lcconf->count_persend); 1099#endif 1100 if (len == -1) { 1101 plog(ASL_LEVEL_ERR, "sendfromto failed\n"); 1102 return -1; 1103 } 1104 1105 /* check the retry counter */ 1106 r->retry_counter--; 1107 if (r->retry_counter <= 0) { 1108 ike_session_rem_recvdpkt(r); 1109 ike_session_del_recvdpkt(r); 1110 plog(ASL_LEVEL_DEBUG, 1111 "deleted the retransmission packet to %s.\n", 1112 saddr2str((struct sockaddr *)remote)); 1113 } else { 1114 r->time_send = t; 1115 r->retry_interval = ike_session_get_exp_retx_interval((lcconf->retry_counter - r->retry_counter), 1116 lcconf->retry_interval); 1117 } 1118 1119 return 1; 1120} 1121 1122/* 1123 * adding a hash of received packet into the received list. 1124 */ 1125int 1126ike_session_add_recvdpkt(remote, local, sbuf, rbuf, non_esp, frag_flags) 1127struct sockaddr_storage *remote, *local; 1128vchar_t *sbuf, *rbuf; 1129size_t non_esp; 1130u_int32_t frag_flags; 1131{ 1132 struct recvdpkt *new = NULL; 1133 1134 if (lcconf->retry_counter == 0) { 1135 /* no need to add it */ 1136 return 0; 1137 } 1138 1139 new = racoon_calloc(1, sizeof(*new)); 1140 if (!new) { 1141 plog(ASL_LEVEL_ERR, 1142 "failed to allocate buffer.\n"); 1143 return -1; 1144 } 1145 1146 new->hash = eay_md5_one(rbuf); 1147 if (!new->hash) { 1148 plog(ASL_LEVEL_ERR, 1149 "failed to allocate buffer.\n"); 1150 ike_session_del_recvdpkt(new); 1151 return -1; 1152 } 1153 new->remote = dupsaddr(remote); 1154 if (new->remote == NULL) { 1155 plog(ASL_LEVEL_ERR, 1156 "failed to allocate buffer.\n"); 1157 ike_session_del_recvdpkt(new); 1158 return -1; 1159 } 1160 new->local = dupsaddr(local); 1161 if (new->local == NULL) { 1162 plog(ASL_LEVEL_ERR, 1163 "failed to allocate buffer.\n"); 1164 ike_session_del_recvdpkt(new); 1165 return -1; 1166 } 1167 1168 if (non_esp) { 1169 plog (ASL_LEVEL_DEBUG, "Adding NON-ESP marker\n"); 1170 1171 /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker) 1172 must added just before the packet itself. For this we must 1173 allocate a new buffer and release it at the end. */ 1174 if ((new->sendbuf = vmalloc (sbuf->l + non_esp)) == NULL) { 1175 plog(ASL_LEVEL_ERR, 1176 "failed to allocate extra buf for non-esp\n"); 1177 ike_session_del_recvdpkt(new); 1178 return -1; 1179 } 1180 *ALIGNED_CAST(u_int32_t *)new->sendbuf->v = 0; 1181 memcpy(new->sendbuf->v + non_esp, sbuf->v, sbuf->l); 1182 } else { 1183 new->sendbuf = vdup(sbuf); 1184 if (new->sendbuf == NULL) { 1185 plog(ASL_LEVEL_ERR, 1186 "failed to allocate buffer.\n"); 1187 ike_session_del_recvdpkt(new); 1188 return -1; 1189 } 1190 } 1191 1192 new->retry_counter = lcconf->retry_counter; 1193 new->time_send = 0; 1194 new->created = time(NULL); 1195#ifdef ENABLE_FRAG 1196 if (frag_flags) { 1197 new->frag_flags = frag_flags; 1198 } 1199#endif 1200 new->retry_interval = ike_session_get_exp_retx_interval((lcconf->retry_counter - new->retry_counter), 1201 lcconf->retry_interval); 1202 1203 LIST_INSERT_HEAD(&rcptree, new, chain); 1204 1205 return 0; 1206} 1207 1208void 1209ike_session_del_recvdpkt(r) 1210struct recvdpkt *r; 1211{ 1212 if (r->remote) 1213 racoon_free(r->remote); 1214 if (r->local) 1215 racoon_free(r->local); 1216 if (r->hash) 1217 vfree(r->hash); 1218 if (r->sendbuf) 1219 vfree(r->sendbuf); 1220 racoon_free(r); 1221} 1222 1223void 1224ike_session_rem_recvdpkt(r) 1225struct recvdpkt *r; 1226{ 1227 LIST_REMOVE(r, chain); 1228} 1229 1230void 1231sweep_recvdpkt(dummy) 1232void *dummy; 1233{ 1234 struct recvdpkt *r, *next; 1235 time_t t, lt; 1236 1237 /* set current time */ 1238 t = time(NULL); 1239 1240 /* set the lifetime of the retransmission */ 1241 lt = lcconf->retry_counter * lcconf->retry_interval; 1242 1243 LIST_FOREACH_SAFE(r, &rcptree, chain, next) { 1244 if (t - r->created > lt) { 1245 ike_session_rem_recvdpkt(r); 1246 ike_session_del_recvdpkt(r); 1247 } 1248 } 1249 1250 sched_new(lt, sweep_recvdpkt, &rcptree); 1251} 1252 1253void 1254ike_session_clear_recvdpkt() 1255{ 1256 struct recvdpkt *r, *next; 1257 1258 LIST_FOREACH_SAFE(r, &rcptree, chain, next) { 1259 ike_session_rem_recvdpkt(r); 1260 ike_session_del_recvdpkt(r); 1261 } 1262 sched_scrub_param(&rcptree); 1263} 1264 1265void 1266ike_session_init_recvdpkt() 1267{ 1268 time_t lt = lcconf->retry_counter * lcconf->retry_interval; 1269 1270 LIST_INIT(&rcptree); 1271 1272 sched_new(lt, sweep_recvdpkt, &rcptree); 1273} 1274 1275#ifdef NOT_USED 1276#ifdef ENABLE_HYBRID 1277/* 1278 * Returns 0 if the address was obtained by ISAKMP mode config, 1 otherwise 1279 * This should be in isakmp_cfg.c but ph1tree being private, it must be there 1280 */ 1281int 1282exclude_cfg_addr(const struct sockaddr_storage *addr) 1283{ 1284 ike_session_t *session; 1285 phase1_handle_t *p; 1286 struct sockaddr_in *sin; 1287 1288 LIST_FOREACH(session, &ike_session_tree, chain) { 1289 LIST_FOREACH(p, &session->ph1tree, chain) { 1290 if ((p->mode_cfg != NULL) && 1291 (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) && 1292 (addr->ss_family == AF_INET)) { 1293 sin = (struct sockaddr_in *)addr; 1294 if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr) 1295 return 0; 1296 } 1297 } 1298 } 1299 1300 return 1; 1301} 1302#endif 1303#endif /* NOT_USED */ 1304 1305int 1306ike_session_expire_session(ike_session_t *session) 1307{ 1308 int found = 0; 1309 phase1_handle_t *p; 1310 phase1_handle_t *next; 1311 phase2_handle_t *p2; 1312 1313 if (session == NULL) 1314 return 0; 1315 1316 LIST_FOREACH(p2, &session->ph2tree, ph2ofsession_chain) { 1317 if (p2->is_dying || FSM_STATE_IS_EXPIRED(p2->status)) { 1318 continue; 1319 } 1320 1321 // Don't send a delete, since the ph1 implies the removal of ph2s 1322 isakmp_ph2expire(p2); 1323 found++; 1324 } 1325 1326 LIST_FOREACH_SAFE(p, &session->ph1tree, ph1ofsession_chain, next) { 1327 if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) { 1328 continue; 1329 } 1330 1331 ike_session_purge_ph2s_by_ph1(p); 1332 if (FSM_STATE_IS_ESTABLISHED(p->status)) 1333 isakmp_info_send_d1(p); 1334 isakmp_ph1expire(p); 1335 found++; 1336 } 1337 1338 return found; 1339} 1340 1341#ifdef ENABLE_HYBRID 1342int 1343ike_session_purgephXbydstaddrwop(struct sockaddr_storage *remote) 1344{ 1345 int found = 0; 1346 ike_session_t *session = NULL; 1347 ike_session_t *next_session = NULL; 1348 phase1_handle_t *p; 1349 phase2_handle_t *p2; 1350 1351 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) { 1352 LIST_FOREACH(p2, &session->ph2tree, ph2ofsession_chain) { 1353 if (p2->is_dying || FSM_STATE_IS_EXPIRED(p2->status)) { 1354 continue; 1355 } 1356 if (cmpsaddrwop(remote, p2->dst) == 0) { 1357 plog(ASL_LEVEL_DEBUG, 1358 "in %s... purging Phase 2 structures\n", __FUNCTION__); 1359 if (FSM_STATE_IS_ESTABLISHED(p2->status)) 1360 isakmp_info_send_d2(p2); 1361 isakmp_ph2expire(p2); 1362 found++; 1363 } 1364 } 1365 1366 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 1367 if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) { 1368 continue; 1369 } 1370 if (cmpsaddrwop(remote, p->remote) == 0) { 1371 plog(ASL_LEVEL_DEBUG, 1372 "in %s... purging Phase 1 and related Phase 2 structures\n", __FUNCTION__); 1373 ike_session_purge_ph2s_by_ph1(p); 1374 if (FSM_STATE_IS_ESTABLISHED(p->status)) 1375 isakmp_info_send_d1(p); 1376 isakmp_ph1expire(p); 1377 found++; 1378 } 1379 } 1380 } 1381 1382 return found; 1383} 1384 1385void 1386ike_session_purgephXbyspid(u_int32_t spid, int del_boundph1) 1387{ 1388 ike_session_t *session = NULL; 1389 ike_session_t *next_session = NULL; 1390 phase2_handle_t *iph2 = NULL; 1391 phase2_handle_t *next_iph2 = NULL; 1392 phase1_handle_t *iph1 = NULL; 1393 phase1_handle_t *next_iph1 = NULL; 1394 1395 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) { 1396 // do ph2's first... we need the ph1s for notifications 1397 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) { 1398 if (spid == iph2->spid) { 1399 if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) { 1400 continue; 1401 } 1402 if (FSM_STATE_IS_ESTABLISHED(iph2->status)) { 1403 isakmp_info_send_d2(iph2); 1404 } 1405 ike_session_stopped_by_controller(iph2->parent_session, 1406 ike_session_stopped_by_flush); 1407 isakmp_ph2expire(iph2); // iph2 will go down 1 second later. 1408 } 1409 } 1410 1411 // do the ph1s last. %%%%%%%%%%%%%%%%%% re-organize this - check del_boundph1 first 1412 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) { 1413 if (spid == iph2->spid) { 1414 if (del_boundph1 && iph2->parent_session) { 1415 LIST_FOREACH_SAFE(iph1, &iph2->parent_session->ph1tree, ph1ofsession_chain, next_iph1) { 1416 if (iph1->is_dying || FSM_STATE_IS_EXPIRED(iph1->status)) { 1417 continue; 1418 } 1419 if (FSM_STATE_IS_ESTABLISHED(iph1->status)) { 1420 isakmp_info_send_d1(iph1); 1421 } 1422 isakmp_ph1expire(iph1); 1423 } 1424 } 1425 } 1426 } 1427 } 1428} 1429 1430#endif 1431 1432#ifdef ENABLE_DPD 1433int 1434ike_session_ph1_force_dpd (struct sockaddr_storage *remote) 1435{ 1436 int status = -1; 1437 ike_session_t *session = NULL; 1438 phase1_handle_t *p = NULL; 1439 1440 LIST_FOREACH(session, &ike_session_tree, chain) { 1441 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 1442 if (cmpsaddrwop(remote, p->remote) == 0) { 1443 if (FSM_STATE_IS_ESTABLISHED(p->status) && 1444 !p->is_dying && 1445 p->dpd_support && 1446 p->rmconf->dpd_interval) { 1447 if(!p->dpd_fails) { 1448 isakmp_info_send_r_u(p); 1449 status = 0; 1450 } else { 1451 plog(ASL_LEVEL_DEBUG, "Skipping forced-DPD for Phase 1 (dpd already in progress).\n"); 1452 } 1453 if (p->parent_session) { 1454 p->parent_session->controller_awaiting_peer_resp = 1; 1455 } 1456 } else { 1457 plog(ASL_LEVEL_DEBUG, "Skipping forced-DPD for Phase 1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n", 1458 p->status, p->is_dying, p->dpd_support, p->rmconf->dpd_interval); 1459 } 1460 } 1461 } 1462 } 1463 1464 return status; 1465} 1466#endif 1467 1468void 1469sweep_sleepwake(void) 1470{ 1471 ike_session_t *session = NULL; 1472 ike_session_t *next_session = NULL; 1473 phase2_handle_t *iph2 = NULL; 1474 phase2_handle_t *next_iph2 = NULL; 1475 phase1_handle_t *iph1 = NULL; 1476 phase1_handle_t *next_iph1 = NULL; 1477 1478 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) { 1479 // do the ph1s. 1480 LIST_FOREACH_SAFE(iph1, &session->ph1tree, ph1ofsession_chain, next_iph1) { 1481 if (iph1->parent_session && iph1->parent_session->is_asserted) { 1482 plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 1 %s because it's been asserted.\n", 1483 isakmp_pindex(&iph1->index, 0)); 1484 continue; 1485 } 1486 if (iph1->is_dying || FSM_STATE_IS_EXPIRED(iph1->status)) { 1487 plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 1 %s because it's already expired.\n", 1488 isakmp_pindex(&iph1->index, 0)); 1489 continue; 1490 } 1491 if (iph1->sce) { 1492 time_t xtime; 1493 if (sched_get_time(iph1->sce, &xtime)) { 1494 if (xtime <= swept_at) { 1495 SCHED_KILL(iph1->sce); 1496 SCHED_KILL(iph1->sce_rekey); 1497 iph1->is_dying = 1; 1498 fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_EXPIRED); 1499 ike_session_update_ph1_ph2tree(iph1); // move unbind/rebind ph2s to from current ph1 1500 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); 1501 plog(ASL_LEVEL_DEBUG, "Phase 1 %s expired while sleeping: quick deletion.\n", 1502 isakmp_pindex(&iph1->index, 0)); 1503 } 1504 } 1505 } 1506 if (iph1->sce_rekey) { 1507 time_t xtime; 1508 if (sched_get_time(iph1->sce_rekey, &xtime)) { 1509 if (FSM_STATE_IS_EXPIRED(iph1->status) || xtime <= swept_at) { 1510 SCHED_KILL(iph1->sce_rekey); 1511 } 1512 } 1513 } 1514 if (iph1->scr) { 1515 time_t xtime; 1516 if (sched_get_time(iph1->scr, &xtime)) { 1517 if (FSM_STATE_IS_EXPIRED(iph1->status) || xtime <= swept_at) { 1518 SCHED_KILL(iph1->scr); 1519 } 1520 } 1521 } 1522 #ifdef ENABLE_DPD 1523 if (iph1->dpd_r_u) { 1524 time_t xtime; 1525 if (sched_get_time(iph1->dpd_r_u, &xtime)) { 1526 if (FSM_STATE_IS_EXPIRED(iph1->status) || xtime <= swept_at) { 1527 SCHED_KILL(iph1->dpd_r_u); 1528 } 1529 } 1530 } 1531 #endif 1532 } 1533 1534 // do ph2's next 1535 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) { 1536 if (iph2->parent_session && iph2->parent_session->is_asserted) { 1537 plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 2 because it's been asserted.\n"); 1538 continue; 1539 } 1540 if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) { 1541 plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 2 because it's already expired.\n"); 1542 continue; 1543 } 1544 if (iph2->sce) { 1545 time_t xtime; 1546 if (sched_get_time(iph2->sce, &xtime)) { 1547 if (xtime <= swept_at) { 1548 fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED); 1549 iph2->is_dying = 1; 1550 isakmp_ph2expire(iph2); // iph2 will go down 1 second later. 1551 ike_session_stopped_by_controller(iph2->parent_session, 1552 ike_session_stopped_by_sleepwake); 1553 plog(ASL_LEVEL_DEBUG, "Phase 2 expired while sleeping: quick deletion.\n"); 1554 } 1555 } 1556 } 1557 if (iph2->scr) { 1558 time_t xtime; 1559 if (sched_get_time(iph2->scr, &xtime)) { 1560 if (FSM_STATE_IS_EXPIRED(iph2->status) || xtime <= swept_at) { 1561 SCHED_KILL(iph2->scr); 1562 } 1563 } 1564 } 1565 } 1566 } 1567 //%%%%%%%%%%%%%%% fix this 1568 // do the ike_session last 1569 ike_session_sweep_sleepwake(); 1570} 1571