1/* 2 * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23#include <sys/param.h> 24#include <sys/types.h> 25#include <sys/socket.h> 26#include <string.h> 27 28#include "var.h" 29#include "misc.h" 30#include "vmbuf.h" 31#include "plog.h" 32#include "sockmisc.h" 33#include "debug.h" 34#include "fsm.h" 35 36#include "isakmp_var.h" 37#include "isakmp.h" 38#include "ike_session.h" 39#include "handler.h" 40#include "gcmalloc.h" 41#include "nattraversal.h" 42#include "schedule.h" 43#include "pfkey.h" 44#include "ipsec_doi.h" 45#include "ipsecSessionTracer.h" 46#include "ipsecMessageTracer.h" 47#include "isakmp_inf.h" 48#include "localconf.h" 49#include "remoteconf.h" 50#include "vpn_control.h" 51#include "vpn_control_var.h" 52#include "proposal.h" 53#include "sainfo.h" 54#include "power_mgmt.h" 55 56#define GET_SAMPLE_PERIOD(s,m) do { \ 57 s = m / 20; \ 58 if (s < 3) { \ 59 s = 3; \ 60 if (m < (s * 2)) { \ 61 s = 1; /* bad */\ 62 } \ 63 } \ 64 } while(0); 65 66const char *ike_session_stopped_by_vpn_disconnect = "Stopped by VPN disconnect"; 67const char *ike_session_stopped_by_controller_comm_lost = "Stopped by loss of controller communication"; 68const char *ike_session_stopped_by_flush = "Stopped by Flush"; 69const char *ike_session_stopped_by_idle = "Stopped by Idle"; 70const char *ike_session_stopped_by_xauth_timeout = "Stopped by XAUTH timeout"; 71const char *ike_session_stopped_by_sleepwake = "Stopped by Sleep-Wake"; 72const char *ike_session_stopped_by_assert = "Stopped by Assert"; 73const char *ike_session_stopped_by_peer = "Stopped by Peer"; 74 75LIST_HEAD(_ike_session_tree_, ike_session) ike_session_tree = { NULL }; 76 77static void ike_session_bindph12(phase1_handle_t *, phase2_handle_t *); 78static void ike_session_rebindph12(phase1_handle_t *, phase2_handle_t *); 79static void ike_session_unbind_all_ph2_from_ph1 (phase1_handle_t *); 80static void ike_session_rebind_all_ph12_to_new_ph1 (phase1_handle_t *, phase1_handle_t *); 81 82static ike_session_t * 83new_ike_session (ike_session_id_t *id) 84{ 85 ike_session_t *session; 86 87 if (!id) { 88 plog(ASL_LEVEL_DEBUG, "Invalid parameters in %s.\n", __FUNCTION__); 89 return NULL; 90 } 91 92 session = racoon_calloc(1, sizeof(*session)); 93 if (session) { 94 bzero(session, sizeof(*session)); 95 memcpy(&session->session_id, id, sizeof(*id)); 96 LIST_INIT(&session->ph1tree); 97 LIST_INIT(&session->ph2tree); 98 LIST_INSERT_HEAD(&ike_session_tree, session, chain); 99 IPSECSESSIONTRACERSTART(session); 100 } 101 return session; 102} 103 104static void 105free_ike_session (ike_session_t *session) 106{ 107 int is_failure = TRUE; 108 if (session) { 109 SCHED_KILL(session->traffic_monitor.sc_mon); 110 SCHED_KILL(session->traffic_monitor.sc_idle); 111 SCHED_KILL(session->sc_xauth); 112 if (session->start_timestamp.tv_sec || session->start_timestamp.tv_usec) { 113 if (!(session->stop_timestamp.tv_sec || session->stop_timestamp.tv_usec)) { 114 gettimeofday(&session->stop_timestamp, NULL); 115 } 116 if (session->term_reason != ike_session_stopped_by_vpn_disconnect || 117 session->term_reason != ike_session_stopped_by_controller_comm_lost || 118 session->term_reason != ike_session_stopped_by_flush || 119 session->term_reason != ike_session_stopped_by_idle) { 120 is_failure = FALSE; 121 } 122 IPSECSESSIONTRACERSTOP(session, 123 is_failure, 124 session->term_reason); 125 } 126 // do MessageTracer cleanup here 127 plog(ASL_LEVEL_DEBUG, 128 "Freeing IKE-Session to %s.\n", 129 saddr2str((struct sockaddr *)&session->session_id.remote)); 130 LIST_REMOVE(session, chain); 131 racoon_free(session); 132 } 133} 134 135 136void 137ike_session_init (void) 138{ 139 LIST_INIT(&ike_session_tree); 140} 141 142u_int 143ike_session_get_rekey_lifetime (int local_spi_is_higher, u_int expiry_lifetime) 144{ 145 u_int rekey_lifetime = expiry_lifetime / 10; 146 147 if (rekey_lifetime) { 148 if (local_spi_is_higher) { 149 return (rekey_lifetime * 9); 150 } else { 151 return (rekey_lifetime * 8); 152 } 153 } else { 154 if (local_spi_is_higher) { 155 rekey_lifetime = expiry_lifetime - 1; 156 } else { 157 rekey_lifetime = expiry_lifetime - 2; 158 } 159 } 160 if (rekey_lifetime < expiry_lifetime) { 161 return rekey_lifetime; 162 } 163 return 0; 164} 165 166ike_session_t * 167ike_session_create_session (ike_session_id_t *session_id) 168{ 169 if (!session_id) 170 return NULL; 171 172 plog(ASL_LEVEL_DEBUG, "New IKE Session to %s.\n", saddr2str((struct sockaddr *)&session_id->remote)); 173 174 return new_ike_session(session_id); 175} 176 177void 178ike_session_release_session (ike_session_t *session) 179{ 180 while (!LIST_EMPTY(&session->ph2tree)) { 181 phase2_handle_t *phase2 = LIST_FIRST(&session->ph2tree); 182 ike_session_unlink_phase2(phase2); 183 } 184 185 while (!LIST_EMPTY(&session->ph1tree)) { 186 phase1_handle_t *phase1 = LIST_FIRST(&session->ph1tree); 187 ike_session_unlink_phase1(phase1); 188 } 189} 190 191// %%%%%%%%% re-examine this - keep both floated and unfloated port when behind nat 192ike_session_t * 193ike_session_get_session (struct sockaddr_storage *local, 194 struct sockaddr_storage *remote, 195 int alloc_if_absent, 196 isakmp_index *optionalIndex) 197{ 198 ike_session_t *p = NULL; 199 ike_session_id_t id; 200 ike_session_id_t id_default; 201 ike_session_id_t id_floated_default; 202 ike_session_id_t id_wop; 203 ike_session_t *best_match = NULL; 204 u_int16_t remote_port; 205 int is_isakmp_remote_port; 206 207 if (!local || !remote) { 208 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 209 return NULL; 210 } 211 212 remote_port = extract_port(remote); 213 if (remote_port && remote_port != PORT_ISAKMP && remote_port != PORT_ISAKMP_NATT) { 214 is_isakmp_remote_port = 0; 215 } else { 216 is_isakmp_remote_port = 1; 217 } 218 219 /* we will try a couple of matches first: if the exact id isn't found, then we'll try for an id that has zero'd ports */ 220 bzero(&id, sizeof(id)); 221 bzero(&id_default, sizeof(id_default)); 222 bzero(&id_floated_default, sizeof(id_floated_default)); 223 bzero(&id_wop, sizeof(id_wop)); 224 if (local->ss_family == AF_INET) { 225 memcpy(&id.local, local, sizeof(struct sockaddr_in)); 226 memcpy(&id_default.local, local, sizeof(struct sockaddr_in)); 227 memcpy(&id_floated_default.local, local, sizeof(struct sockaddr_in)); 228 memcpy(&id_wop.local, local, sizeof(struct sockaddr_in)); 229 } else if (local->ss_family == AF_INET6) { 230 memcpy(&id.local, local, sizeof(struct sockaddr_in6)); 231 memcpy(&id_default.local, local, sizeof(struct sockaddr_in6)); 232 memcpy(&id_floated_default.local, local, sizeof(struct sockaddr_in6)); 233 memcpy(&id_wop.local, local, sizeof(struct sockaddr_in6)); 234 } 235 set_port(&id_default.local, PORT_ISAKMP); 236 set_port(&id_floated_default.local, PORT_ISAKMP_NATT); 237 set_port(&id_wop.local, 0); 238 if (remote->ss_family == AF_INET) { 239 memcpy(&id.remote, remote, sizeof(struct sockaddr_in)); 240 memcpy(&id_default.remote, remote, sizeof(struct sockaddr_in)); 241 memcpy(&id_floated_default.remote, remote, sizeof(struct sockaddr_in)); 242 memcpy(&id_wop.remote, remote, sizeof(struct sockaddr_in)); 243 } else if (remote->ss_family == AF_INET6) { 244 memcpy(&id.remote, remote, sizeof(struct sockaddr_in6)); 245 memcpy(&id_default.remote, remote, sizeof(struct sockaddr_in6)); 246 memcpy(&id_floated_default.remote, remote, sizeof(struct sockaddr_in6)); 247 memcpy(&id_wop.remote, remote, sizeof(struct sockaddr_in6)); 248 } 249 set_port(&id_default.remote, PORT_ISAKMP); 250 set_port(&id_floated_default.remote, PORT_ISAKMP_NATT); 251 set_port(&id_wop.remote, 0); 252 253 plog(ASL_LEVEL_DEBUG, 254 "start search for IKE-Session. target %s.\n", 255 saddr2str((struct sockaddr *)remote)); 256 257 LIST_FOREACH(p, &ike_session_tree, chain) { 258 plog(ASL_LEVEL_DEBUG, 259 "still search for IKE-Session. this %s.\n", 260 saddr2str((struct sockaddr *)&p->session_id.remote)); 261 262 // for now: ignore any stopped sessions as they will go down 263 if (p->is_dying || p->stopped_by_vpn_controller || p->stop_timestamp.tv_sec || p->stop_timestamp.tv_usec) { 264 plog(ASL_LEVEL_DEBUG, "still searching. skipping... session to %s is already stopped, active ph1 %d ph2 %d.\n", 265 saddr2str((struct sockaddr *)&p->session_id.remote), 266 p->ikev1_state.active_ph1cnt, p->ikev1_state.active_ph2cnt); 267 continue; 268 } 269 270 // Skip if the spi doesn't match 271 if (optionalIndex != NULL && ike_session_getph1byindex(p, optionalIndex) == NULL) { 272 continue; 273 } 274 275 if (memcmp(&p->session_id, &id, sizeof(id)) == 0) { 276 plog(ASL_LEVEL_DEBUG, 277 "Pre-existing IKE-Session to %s. case 1.\n", 278 saddr2str((struct sockaddr *)remote)); 279 return p; 280 } else if (is_isakmp_remote_port && memcmp(&p->session_id, &id_default, sizeof(id_default)) == 0) { 281 plog(ASL_LEVEL_DEBUG, 282 "Pre-existing IKE-Session to %s. case 2.\n", 283 saddr2str((struct sockaddr *)remote)); 284 return p; 285 } else if (is_isakmp_remote_port && p->ports_floated && memcmp(&p->session_id, &id_floated_default, sizeof(id_floated_default)) == 0) { 286 plog(ASL_LEVEL_DEBUG, 287 "Pre-existing IKE-Session to %s. case 3.\n", 288 saddr2str((struct sockaddr *)remote)); 289 return p; 290 } else if (is_isakmp_remote_port && memcmp(&p->session_id, &id_wop, sizeof(id_wop)) == 0) { 291 best_match = p; 292 } else if (optionalIndex != NULL) { 293 // If the SPI did match, this one counts as a best match 294 best_match = p; 295 } 296 } 297 if (best_match) { 298 plog(ASL_LEVEL_DEBUG, 299 "Best-match IKE-Session to %s.\n", 300 saddr2str((struct sockaddr *)&best_match->session_id.remote)); 301 return best_match; 302 } 303 if (alloc_if_absent) { 304 plog(ASL_LEVEL_DEBUG, 305 "New IKE-Session to %s.\n", 306 saddr2str((struct sockaddr *)&id.remote)); 307 return new_ike_session(&id); 308 } else { 309 return NULL; 310 } 311} 312 313void 314ike_session_init_traffic_cop_params (phase1_handle_t *iph1) 315{ 316 if (!iph1 || 317 !iph1->rmconf || 318 (!iph1->rmconf->idle_timeout && !iph1->rmconf->dpd_interval)) { 319 return; 320 } 321 322 if (!iph1->parent_session->traffic_monitor.interv_idle) { 323 iph1->parent_session->traffic_monitor.interv_idle = iph1->rmconf->idle_timeout; 324 } 325 if (!iph1->parent_session->traffic_monitor.dir_idle) { 326 iph1->parent_session->traffic_monitor.dir_idle = iph1->rmconf->idle_timeout_dir; 327 } 328 329 if (!iph1->parent_session->traffic_monitor.interv_mon) { 330 int min_period, max_period, sample_period = 0; 331 332 /* calculate the sampling interval... half the smaller interval */ 333 if (iph1->rmconf->dpd_interval && 334 (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT || 335 iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT)) { 336 // when certain types of dpd are enabled 337 min_period = MIN(iph1->rmconf->dpd_interval, iph1->rmconf->idle_timeout); 338 max_period = MAX(iph1->rmconf->dpd_interval, iph1->rmconf->idle_timeout); 339 } else if (iph1->rmconf->idle_timeout) { 340 min_period = max_period = iph1->rmconf->idle_timeout; 341 } else { 342 // DPD_ALGO_DEFAULT is configured and there's no idle timeout... we don't need to monitor traffic 343 return; 344 } 345 if (min_period) { 346 GET_SAMPLE_PERIOD(sample_period, min_period); 347 } else { 348 GET_SAMPLE_PERIOD(sample_period, max_period); 349 } 350 iph1->parent_session->traffic_monitor.interv_mon = sample_period; 351 } 352} 353 354void 355ike_session_update_mode (phase2_handle_t *iph2) 356{ 357 if (!iph2 || !iph2->parent_session) { 358 return; 359 } 360 if (iph2->phase2_type != PHASE2_TYPE_SA) 361 return; 362 if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV2) { 363 return; // for now 364 } 365 // exit early if we already detected cisco-ipsec 366 if (iph2->parent_session->is_cisco_ipsec) { 367 return; 368 } 369 370 if (iph2->approval) { 371 if (!ipsecdoi_any_transportmode(iph2->approval)) { 372 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1) 373 iph2->parent_session->is_cisco_ipsec = 0; 374 iph2->parent_session->is_l2tpvpn_ipsec = 0; 375 iph2->parent_session->is_btmm_ipsec = 1; 376 return; 377 } else if (ipsecdoi_transportmode(iph2->approval)) { 378 iph2->parent_session->is_cisco_ipsec = 0; 379 iph2->parent_session->is_l2tpvpn_ipsec = 1; 380 iph2->parent_session->is_btmm_ipsec = 0; 381 return; 382 } 383 } else if (iph2->proposal) { 384 if (!ipsecdoi_any_transportmode(iph2->proposal)) { 385 // cisco & btmm ipsec are pure tunnel-mode (but cisco ipsec is detected by ph1) 386 iph2->parent_session->is_cisco_ipsec = 0; 387 iph2->parent_session->is_l2tpvpn_ipsec = 0; 388 iph2->parent_session->is_btmm_ipsec = 1; 389 return; 390 } else if (ipsecdoi_transportmode(iph2->proposal)) { 391 iph2->parent_session->is_cisco_ipsec = 0; 392 iph2->parent_session->is_l2tpvpn_ipsec = 1; 393 iph2->parent_session->is_btmm_ipsec = 0; 394 return; 395 } 396 } 397} 398 399static void 400ike_session_cleanup_xauth_timeout (void *arg) 401{ 402 ike_session_t *session = (ike_session_t *)arg; 403 404 SCHED_KILL(session->sc_xauth); 405 // if there are no more established ph2s, start a timer to teardown the session 406 if (!ike_session_has_established_ph2(session)) { 407 ike_session_cleanup(session, ike_session_stopped_by_xauth_timeout); 408 } else { 409 session->sc_xauth = sched_new(300 /* 5 mins */, 410 ike_session_cleanup_xauth_timeout, 411 session); 412 } 413} 414 415int 416ike_session_link_phase1 (ike_session_t *session, phase1_handle_t *iph1) 417{ 418 419 if (!session || !iph1) { 420 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 421 return -1; 422 } 423 424 gettimeofday(&session->start_timestamp, NULL); 425 426 if (iph1->started_by_api) { 427 session->is_cisco_ipsec = 1; 428 session->is_l2tpvpn_ipsec = 0; 429 session->is_btmm_ipsec = 0; 430 } 431 iph1->parent_session = session; 432 LIST_INSERT_HEAD(&session->ph1tree, iph1, ph1ofsession_chain); 433 session->ikev1_state.active_ph1cnt++; 434 if ((!session->ikev1_state.ph1cnt && 435 iph1->side == INITIATOR) || 436 iph1->started_by_api) { 437 // client initiates the first phase1 or, is started by controller api 438 session->is_client = 1; 439 } 440 if (session->established && 441 session->ikev1_state.ph1cnt && 442 iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 443 iph1->is_rekey = 1; 444 } 445 session->ikev1_state.ph1cnt++; 446 ike_session_init_traffic_cop_params(iph1); 447 448 return 0; 449} 450 451int 452ike_session_link_phase2 (ike_session_t *session, phase2_handle_t *iph2) 453{ 454 if (!iph2) { 455 plog(ASL_LEVEL_DEBUG, "Invalid parameters in %s.\n", __FUNCTION__); 456 return -1; 457 } 458 if (iph2->parent_session) { 459 plog(ASL_LEVEL_ERR, "Phase 2 already linked to session %s.\n", __FUNCTION__); 460 } 461 462 iph2->parent_session = session; 463 LIST_INSERT_HEAD(&session->ph2tree, iph2, ph2ofsession_chain); 464 session->ikev1_state.active_ph2cnt++; 465 if (!session->ikev1_state.ph2cnt && 466 iph2->side == INITIATOR) { 467 // client initiates the first phase2 468 session->is_client = 1; 469 } 470 if (iph2->phase2_type == PHASE2_TYPE_SA && 471 session->established && 472 session->ikev1_state.ph2cnt && 473 iph2->version == ISAKMP_VERSION_NUMBER_IKEV1) { 474 iph2->is_rekey = 1; 475 } 476 session->ikev1_state.ph2cnt++; 477 ike_session_update_mode(iph2); 478 479 return 0; 480} 481 482int 483ike_session_link_ph2_to_ph1 (phase1_handle_t *iph1, phase2_handle_t *iph2) 484{ 485 struct sockaddr_storage *local; 486 struct sockaddr_storage *remote; 487 int error = 0; 488 489 if (!iph2) { 490 plog(ASL_LEVEL_DEBUG, "Invalid parameters in %s.\n", __FUNCTION__); 491 return -1; 492 } 493 if (iph2->ph1) { 494 plog(ASL_LEVEL_ERR, "Phase 2 already linked %s.\n", __FUNCTION__); 495 if (iph2->ph1 == iph1) 496 return 0; 497 else 498 return -1; // This shouldn't happen 499 } 500 501 local = iph2->src; 502 remote = iph2->dst; 503 504 if (iph2->parent_session == NULL) 505 if ((error = ike_session_link_phase2(iph1->parent_session, iph2))) 506 return error; 507 508 ike_session_bindph12(iph1, iph2); 509 return 0; 510} 511 512int 513ike_session_unlink_phase1 (phase1_handle_t *iph1) 514{ 515 ike_session_t *session; 516 517 if (!iph1 || !iph1->parent_session) { 518 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 519 return -1; 520 } 521 522 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 523 if (LIST_FIRST(&iph1->bound_ph2tree)) { 524 // reparent any phase2 that may be hanging on to this phase1 525 ike_session_update_ph1_ph2tree(iph1); 526 } 527 } 528 529 sched_scrub_param(iph1); 530 session = iph1->parent_session; 531 LIST_REMOVE(iph1, ph1ofsession_chain); 532 iph1->parent_session = NULL; 533 session->ikev1_state.active_ph1cnt--; 534 if (session->ikev1_state.active_ph1cnt == 0 && session->ikev1_state.active_ph2cnt == 0) { 535 session->is_dying = 1; 536 free_ike_session(session); 537 } 538 ike_session_delph1(iph1); 539 return 0; 540} 541 542int 543ike_session_unlink_phase2 (phase2_handle_t *iph2) 544{ 545 ike_session_t *session; 546 547 if (!iph2 || !iph2->parent_session) { 548 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 549 return -1; 550 } 551 sched_scrub_param(iph2); 552 ike_session_unbindph12(iph2); 553 554 LIST_REMOVE(iph2, ph2ofsession_chain); 555 session = iph2->parent_session; 556 iph2->parent_session = NULL; 557 session->ikev1_state.active_ph2cnt--; 558 if (session->ikev1_state.active_ph1cnt == 0 && session->ikev1_state.active_ph2cnt == 0) { 559 session->is_dying = 1; 560 free_ike_session(session); 561 } 562 ike_session_delph2(iph2); 563 return 0; 564} 565 566 567phase1_handle_t * 568ike_session_update_ph1_ph2tree (phase1_handle_t *iph1) 569{ 570 phase1_handle_t *new_iph1 = NULL; 571 572 if (!iph1) { 573 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 574 return NULL; 575 } 576 577 if (iph1->parent_session) { 578 new_iph1 = ike_session_get_established_ph1(iph1->parent_session); 579 580 if (!new_iph1) { 581 plog(ASL_LEVEL_DEBUG, "no ph1bind replacement found. NULL ph1.\n"); 582 ike_session_unbind_all_ph2_from_ph1(iph1); 583 } else if (iph1 == new_iph1) { 584 plog(ASL_LEVEL_DEBUG, "no ph1bind replacement found. same ph1.\n"); 585 ike_session_unbind_all_ph2_from_ph1(iph1); 586 } else { 587 ike_session_rebind_all_ph12_to_new_ph1(iph1, new_iph1); 588 } 589 } else { 590 plog(ASL_LEVEL_DEBUG, "invalid parent session in %s.\n", __FUNCTION__); 591 } 592 return new_iph1; 593} 594 595phase1_handle_t * 596ike_session_update_ph2_ph1bind (phase2_handle_t *iph2) 597{ 598 phase1_handle_t *iph1; 599 600 if (!iph2 || iph2->phase2_type != PHASE2_TYPE_SA) { 601 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 602 return NULL; 603 } 604 605 iph1 = ike_session_get_established_ph1(iph2->parent_session); 606 if (iph1 && iph2->ph1 && iph1 != iph2->ph1) { 607 ike_session_rebindph12(iph1, iph2); 608 } else if (iph1 && !iph2->ph1) { 609 ike_session_bindph12(iph1, iph2); 610 } 611 612 return iph1; 613} 614 615phase1_handle_t * 616ike_session_get_established_or_negoing_ph1 (ike_session_t *session) 617{ 618 phase1_handle_t *p, *iph1 = NULL; 619 620 if (!session) { 621 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 622 return NULL; 623 } 624 625 // look for the most mature ph1 under the session 626 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 627 if (!p->is_dying && (FSM_STATE_IS_ESTABLISHED(p->status) || FSM_STATE_IS_NEGOTIATING(p->status))) { 628 if (!iph1 || p->status > iph1->status) { 629 iph1 = p; 630 } else if (iph1 && p->status == iph1->status) { 631 // TODO: pick better one based on farthest rekey/expiry remaining 632 } 633 } 634 } 635 636 return iph1; 637} 638 639phase1_handle_t * 640ike_session_get_established_ph1 (ike_session_t *session) 641{ 642 phase1_handle_t *p; 643 644 if (!session) { 645 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 646 return NULL; 647 } 648 649 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 650 if (!p->is_dying && FSM_STATE_IS_ESTABLISHED(p->status)) { 651 return p; 652 } 653 } 654 655 return NULL; 656} 657 658 659int 660ike_session_has_other_established_ph1 (ike_session_t *session, phase1_handle_t *iph1) 661{ 662 phase1_handle_t *p; 663 664 if (!session) { 665 return 0; 666 } 667 668 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 669 if (iph1 != p && !p->is_dying) { 670 if (FSM_STATE_IS_ESTABLISHED(p->status) && p->sce_rekey) { 671 return 1; 672 } 673 } 674 } 675 676 return 0; 677} 678 679int 680ike_session_has_other_negoing_ph1 (ike_session_t *session, phase1_handle_t *iph1) 681{ 682 phase1_handle_t *p; 683 684 if (!session) { 685 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 686 return 0; 687 } 688 689 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 690 if (iph1 != p && !p->is_dying) { 691 if (FSM_STATE_IS_NEGOTIATING(p->status)) { 692 return 1; 693 } 694 } 695 } 696 697 return 0; 698} 699 700int 701ike_session_has_other_established_ph2 (ike_session_t *session, phase2_handle_t *iph2) 702{ 703 phase2_handle_t *p; 704 705 if (!session) { 706 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 707 return 0; 708 } 709 710 LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) { 711 if (p->phase2_type == PHASE2_TYPE_SA && iph2 != p && !p->is_dying && iph2->spid == p->spid) { 712 if (FSM_STATE_IS_ESTABLISHED(p->status)) { 713 return 1; 714 } 715 } 716 } 717 718 return 0; 719} 720 721int 722ike_session_has_other_negoing_ph2 (ike_session_t *session, phase2_handle_t *iph2) 723{ 724 phase2_handle_t *p; 725 726 if (!session) { 727 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 728 return 0; 729 } 730 731 LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) { 732 plog(ASL_LEVEL_DEBUG, "%s: ph2 sub spid %d, db spid %d\n", __FUNCTION__, iph2->spid, p->spid); 733 if (p->phase2_type == PHASE2_TYPE_SA && iph2 != p && !p->is_dying && iph2->spid == p->spid) { 734 if (FSM_STATE_IS_NEGOTIATING(p->status)) { 735 return 1; 736 } 737 } 738 } 739 740 return 0; 741} 742 743 744void 745ike_session_ikev1_float_ports (phase1_handle_t *iph1) 746{ 747 struct sockaddr_storage *local, *remote; 748 phase2_handle_t *p; 749 750 if (iph1->parent_session) { 751 local = &iph1->parent_session->session_id.local; 752 remote = &iph1->parent_session->session_id.remote; 753 754 set_port(local, extract_port(iph1->local)); 755 set_port(remote, extract_port(iph1->remote)); 756 iph1->parent_session->ports_floated = 1; 757 758 LIST_FOREACH(p, &iph1->parent_session->ph2tree, ph2ofsession_chain) { 759 760 local = p->src; 761 remote = p->dst; 762 763 set_port(local, extract_port(iph1->local)); 764 set_port(remote, extract_port(iph1->remote)); 765 } 766 } else { 767 plog(ASL_LEVEL_DEBUG, "invalid parent session in %s.\n", __FUNCTION__); 768 } 769} 770 771static void 772ike_session_traffic_cop (void *arg) 773{ 774 ike_session_t *session = (__typeof__(session))arg; 775 776 if (session && 777 (session->established && !session->stopped_by_vpn_controller && !session->stop_timestamp.tv_sec && !session->stop_timestamp.tv_usec)) { 778 SCHED_KILL(session->traffic_monitor.sc_mon); 779 /* get traffic query from kernel */ 780 if (pk_sendget_inbound_sastats(session) < 0) { 781 // log message 782 plog(ASL_LEVEL_DEBUG, "pk_sendget_inbound_sastats failed in %s.\n", __FUNCTION__); 783 } 784 if (pk_sendget_outbound_sastats(session) < 0) { 785 // log message 786 plog(ASL_LEVEL_DEBUG, "pk_sendget_outbound_sastats failed in %s.\n", __FUNCTION__); 787 } 788 session->traffic_monitor.sc_mon = sched_new(session->traffic_monitor.interv_mon, 789 ike_session_traffic_cop, 790 session); 791 } else { 792 // log message 793 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 794 } 795} 796 797static void 798ike_session_cleanup_idle (void *arg) 799{ 800 ike_session_cleanup((ike_session_t *)arg, ike_session_stopped_by_idle); 801} 802 803static void 804ike_session_monitor_idle (ike_session_t *session) 805{ 806 if (!session) 807 return; 808 809 if (session->traffic_monitor.dir_idle == IPSEC_DIR_INBOUND || 810 session->traffic_monitor.dir_idle == IPSEC_DIR_ANY) { 811 if (session->peer_sent_data_sc_idle) { 812 plog(ASL_LEVEL_DEBUG, "%s: restart idle-timeout because peer sent data. monitoring dir %d.\n", 813 __FUNCTION__, session->traffic_monitor.dir_idle); 814 SCHED_KILL(session->traffic_monitor.sc_idle); 815 if (session->traffic_monitor.interv_idle) { 816 session->traffic_monitor.sc_idle = sched_new(session->traffic_monitor.interv_idle, 817 ike_session_cleanup_idle, 818 session); 819 } 820 session->peer_sent_data_sc_idle = 0; 821 session->i_sent_data_sc_idle = 0; 822 return; 823 } 824 } 825 if (session->traffic_monitor.dir_idle == IPSEC_DIR_OUTBOUND || 826 session->traffic_monitor.dir_idle == IPSEC_DIR_ANY) { 827 if (session->i_sent_data_sc_idle) { 828 plog(ASL_LEVEL_DEBUG, "%s: restart idle-timeout because i sent data. monitoring dir %d.\n", 829 __FUNCTION__, session->traffic_monitor.dir_idle); 830 SCHED_KILL(session->traffic_monitor.sc_idle); 831 if (session->traffic_monitor.interv_idle) { 832 session->traffic_monitor.sc_idle = sched_new(session->traffic_monitor.interv_idle, 833 ike_session_cleanup_idle, 834 session); 835 } 836 session->peer_sent_data_sc_idle = 0; 837 session->i_sent_data_sc_idle = 0; 838 return; 839 } 840 } 841} 842 843static void 844ike_session_start_traffic_mon (ike_session_t *session) 845{ 846 if (session->traffic_monitor.interv_mon) { 847 session->traffic_monitor.sc_mon = sched_new(session->traffic_monitor.interv_mon, 848 ike_session_traffic_cop, 849 session); 850 } 851 if (session->traffic_monitor.interv_idle) { 852 session->traffic_monitor.sc_idle = sched_new(session->traffic_monitor.interv_idle, 853 ike_session_cleanup_idle, 854 session); 855 } 856} 857 858void 859ike_session_ph2_established (phase2_handle_t *iph2) 860{ 861 if (!iph2->parent_session || iph2->phase2_type != PHASE2_TYPE_SA) { 862 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 863 return; 864 } 865 SCHED_KILL(iph2->parent_session->sc_xauth); 866 if (!iph2->parent_session->established) { 867 gettimeofday(&iph2->parent_session->estab_timestamp, NULL); 868 iph2->parent_session->established = 1; 869 IPSECSESSIONTRACERESTABLISHED(iph2->parent_session); 870 ike_session_start_traffic_mon(iph2->parent_session); 871 } else if (iph2->parent_session->is_asserted) { 872 ike_session_start_traffic_mon(iph2->parent_session); 873 } 874 iph2->parent_session->is_asserted = 0; 875 // nothing happening to this session 876 iph2->parent_session->term_reason = NULL; 877 878 ike_session_update_mode(iph2); 879 if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV1) 880 ike_session_unbindph12(iph2); 881 882#ifdef ENABLE_VPNCONTROL_PORT 883 vpncontrol_notify_peer_resp_ph2(1, iph2); 884#endif /* ENABLE_VPNCONTROL_PORT */ 885 plog(ASL_LEVEL_DEBUG, "%s: ph2 established, spid %d\n", __FUNCTION__, iph2->spid); 886} 887 888void 889ike_session_cleanup_ph1 (phase1_handle_t *iph1) 890{ 891 if (FSM_STATE_IS_EXPIRED(iph1->status)) { 892 // since this got here via ike_session_cleanup_other_established_ph1s, assumes LIST_FIRST(&iph1->ph2tree) == NULL 893 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1); 894 return; 895 } 896 897 /* send delete information */ 898 if (FSM_STATE_IS_ESTABLISHED(iph1->status)) { 899 isakmp_info_send_d1(iph1); 900 } 901 902 isakmp_ph1expire(iph1); 903} 904 905void 906ike_session_cleanup_ph1_stub (void *p) 907{ 908 909 ike_session_cleanup_ph1((phase1_handle_t *)p); 910} 911 912void 913ike_session_replace_other_ph1 (phase1_handle_t *new_iph1, 914 phase1_handle_t *old_iph1) 915{ 916 char *local, *remote, *index; 917 ike_session_t *session = NULL; 918 919 if (new_iph1) 920 session = new_iph1->parent_session; 921 922 if (!session || !new_iph1 || !old_iph1 || session != old_iph1->parent_session || new_iph1 == old_iph1) { 923 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 924 return; 925 } 926 927 /* 928 * if we are responder, then we should wait until the server sends a delete notification. 929 */ 930 if ((new_iph1->version == ISAKMP_VERSION_NUMBER_IKEV2 || session->is_client) && 931 new_iph1->side == RESPONDER) { 932 return; 933 } 934 935 SCHED_KILL(old_iph1->sce); 936 SCHED_KILL(old_iph1->sce_rekey); 937 old_iph1->is_dying = 1; 938 939 //log deletion 940 local = racoon_strdup(saddr2str((struct sockaddr *)old_iph1->local)); 941 remote = racoon_strdup(saddr2str((struct sockaddr *)old_iph1->remote)); 942 index = racoon_strdup(isakmp_pindex(&old_iph1->index, 0)); 943 STRDUP_FATAL(local); 944 STRDUP_FATAL(remote); 945 STRDUP_FATAL(index); 946 plog(ASL_LEVEL_DEBUG, "ISAKMP-SA %s-%s (spi:%s) needs to be deleted, replaced by (spi:%s)\n", local, remote, index, isakmp_pindex(&new_iph1->index, 0)); 947 racoon_free(local); 948 racoon_free(remote); 949 racoon_free(index); 950 951 // first rebind the children ph2s of this dying ph1 to the new ph1. 952 ike_session_rebind_all_ph12_to_new_ph1 (old_iph1, new_iph1); 953 954 if (old_iph1->side == INITIATOR) { 955 /* everyone deletes old outbound SA */ 956 old_iph1->sce = sched_new(5, ike_session_cleanup_ph1_stub, old_iph1); 957 } else { 958 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */ 959 old_iph1->sce = sched_new(7, ike_session_cleanup_ph1_stub, old_iph1); 960 } 961} 962 963void 964ike_session_cleanup_other_established_ph1s (ike_session_t *session, 965 phase1_handle_t *new_iph1) 966{ 967 phase1_handle_t *p, *next; 968 char *local, *remote; 969 970 if (!session || !new_iph1 || session != new_iph1->parent_session) { 971 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 972 return; 973 } 974 975 /* 976 * if we are responder, then we should wait until the server sends a delete notification. 977 */ 978 if ((new_iph1->version == ISAKMP_VERSION_NUMBER_IKEV2 || session->is_client) && 979 new_iph1->side == RESPONDER) { 980 return; 981 } 982 983 LIST_FOREACH_SAFE(p, &session->ph1tree, ph1ofsession_chain, next) { 984 /* 985 * TODO: currently, most recently established SA wins. Need to revisit to see if 986 * alternative selections is better (e.g. largest p->index stays). 987 */ 988 if (p != new_iph1 && !p->is_dying) { 989 SCHED_KILL(p->sce); 990 SCHED_KILL(p->sce_rekey); 991 p->is_dying = 1; 992 993 //log deletion 994 local = racoon_strdup(saddr2str((struct sockaddr *)p->local)); 995 remote = racoon_strdup(saddr2str((struct sockaddr *)p->remote)); 996 STRDUP_FATAL(local); 997 STRDUP_FATAL(remote); 998 plog(ASL_LEVEL_DEBUG, 999 "ISAKMP-SA needs to be deleted %s-%s spi:%s\n", 1000 local, remote, isakmp_pindex(&p->index, 0)); 1001 racoon_free(local); 1002 racoon_free(remote); 1003 1004 // first rebind the children ph2s of this dying ph1 to the new ph1. 1005 ike_session_rebind_all_ph12_to_new_ph1 (p, new_iph1); 1006 1007 if (p->side == INITIATOR) { 1008 /* everyone deletes old outbound SA */ 1009 p->sce = sched_new(5, ike_session_cleanup_ph1_stub, p); 1010 } else { 1011 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */ 1012 p->sce = sched_new(7, ike_session_cleanup_ph1_stub, p); 1013 } 1014 } 1015 } 1016} 1017 1018void 1019ike_session_cleanup_ph2 (phase2_handle_t *iph2) 1020{ 1021 if (iph2->phase2_type != PHASE2_TYPE_SA) 1022 return; 1023 if (FSM_STATE_IS_EXPIRED(iph2->status)) { 1024 return; 1025 } 1026 1027 SCHED_KILL(iph2->sce); 1028 1029 plog(ASL_LEVEL_ERR, 1030 "about to cleanup ph2: status %d, seq %d dying %d\n", 1031 iph2->status, iph2->seq, iph2->is_dying); 1032 1033 /* send delete information */ 1034 if (FSM_STATE_IS_ESTABLISHED(iph2->status)) { 1035 isakmp_info_send_d2(iph2); 1036 1037 // delete outgoing SAs 1038 if (iph2->approval) { 1039 struct saproto *pr; 1040 1041 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 1042 if (pr->ok) { 1043 pfkey_send_delete(lcconf->sock_pfkey, 1044 ipsecdoi2pfkey_proto(pr->proto_id), 1045 IPSEC_MODE_ANY, 1046 iph2->src, iph2->dst, pr->spi_p /* pr->reqid_out */); 1047 } 1048 } 1049 } 1050 } 1051 1052 delete_spd(iph2); 1053 ike_session_unlink_phase2(iph2); 1054} 1055 1056void 1057ike_session_cleanup_ph2_stub (void *p) 1058{ 1059 1060 ike_session_cleanup_ph2((phase2_handle_t *)p); 1061} 1062 1063void 1064ike_session_cleanup_other_established_ph2s (ike_session_t *session, 1065 phase2_handle_t *new_iph2) 1066{ 1067 phase2_handle_t *p, *next; 1068 1069 if (!session || !new_iph2 || session != new_iph2->parent_session || new_iph2->phase2_type != PHASE2_TYPE_SA) { 1070 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1071 return; 1072 } 1073 1074 /* 1075 * if we are responder, then we should wait until the server sends a delete notification. 1076 */ 1077 if (session->is_client && new_iph2->side == RESPONDER) { 1078 return; 1079 } 1080 1081 LIST_FOREACH_SAFE(p, &session->ph2tree, ph2ofsession_chain, next) { 1082 /* 1083 * TODO: currently, most recently established SA wins. Need to revisit to see if 1084 * alternative selections is better. 1085 */ 1086 if (p != new_iph2 && p->spid == new_iph2->spid && !p->is_dying) { 1087 SCHED_KILL(p->sce); 1088 p->is_dying = 1; 1089 1090 //log deletion 1091 plog(ASL_LEVEL_DEBUG, 1092 "IPsec-SA needs to be deleted: %s\n", 1093 sadbsecas2str(p->src, p->dst, 1094 p->satype, p->spid, 0)); 1095 1096 if (p->side == INITIATOR) { 1097 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */ 1098 p->sce = sched_new(3, ike_session_cleanup_ph2_stub, p); 1099 } else { 1100 /* responder sets up timer to delete old inbound SAs... say 5 secs later and flags them as rekeyed */ 1101 p->sce = sched_new(5, ike_session_cleanup_ph2_stub, p); 1102 } 1103 } 1104 } 1105} 1106 1107void 1108ike_session_stopped_by_controller (ike_session_t *session, 1109 const char *reason) 1110{ 1111 if (!session) { 1112 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1113 return; 1114 } 1115 if (session->stop_timestamp.tv_sec || 1116 session->stop_timestamp.tv_usec) { 1117 plog(ASL_LEVEL_DEBUG, "already stopped %s.\n", __FUNCTION__); 1118 return; 1119 } 1120 session->stopped_by_vpn_controller = 1; 1121 gettimeofday(&session->stop_timestamp, NULL); 1122 if (!session->term_reason) { 1123 session->term_reason = (__typeof__(session->term_reason))reason; 1124 } 1125} 1126 1127void 1128ike_sessions_stopped_by_controller (struct sockaddr_storage *remote, 1129 int withport, 1130 const char *reason) 1131{ 1132 ike_session_t *p = NULL; 1133 ike_session_t *next_session = NULL; 1134 1135 if (!remote) { 1136 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1137 return; 1138 } 1139 1140 LIST_FOREACH_SAFE(p, &ike_session_tree, chain, next_session) { 1141 if ((withport && cmpsaddrstrict(&p->session_id.remote, remote) == 0) || 1142 (!withport && cmpsaddrwop(&p->session_id.remote, remote) == 0)) { 1143 ike_session_stopped_by_controller(p, reason); 1144 } 1145 } 1146} 1147 1148void 1149ike_session_purge_ph2s_by_ph1 (phase1_handle_t *iph1) 1150{ 1151 phase2_handle_t *p, *next; 1152 1153 if (!iph1 || !iph1->parent_session) { 1154 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1155 return; 1156 } 1157 1158 LIST_FOREACH_SAFE(p, &iph1->parent_session->ph2tree, ph2ofsession_chain, next) { 1159 if (p->is_dying) { 1160 continue; 1161 } 1162 SCHED_KILL(p->sce); 1163 p->is_dying = 1; 1164 1165 //log deletion 1166 plog(ASL_LEVEL_DEBUG, 1167 "IPsec-SA needs to be purged: %s\n", 1168 sadbsecas2str(p->src, p->dst, 1169 p->satype, p->spid, 0)); 1170 1171 ike_session_cleanup_ph2(p); 1172 } 1173} 1174 1175void 1176ike_session_update_ph2_ports (phase2_handle_t *iph2) 1177{ 1178 struct sockaddr_storage *local; 1179 struct sockaddr_storage *remote; 1180 1181 if (iph2->parent_session) { 1182 local = &iph2->parent_session->session_id.local; 1183 remote = &iph2->parent_session->session_id.remote; 1184 1185 set_port(iph2->src, extract_port(local)); 1186 set_port(iph2->dst, extract_port(remote)); 1187 } else { 1188 plog(ASL_LEVEL_DEBUG, "invalid parent session in %s.\n", __FUNCTION__); 1189 } 1190} 1191 1192u_int32_t 1193ike_session_get_sas_for_stats (ike_session_t *session, 1194 u_int8_t dir, 1195 u_int32_t *seq, 1196 struct sastat *stats, 1197 u_int32_t max_stats) 1198{ 1199 int found = 0; 1200 phase2_handle_t *iph2; 1201 1202 if (!session || !seq || !stats || !max_stats || (dir != IPSEC_DIR_INBOUND && dir != IPSEC_DIR_OUTBOUND)) { 1203 plog(ASL_LEVEL_DEBUG, "invalid args in %s.\n", __FUNCTION__); 1204 return found; 1205 } 1206 1207 *seq = 0; 1208 LIST_FOREACH(iph2, &session->ph2tree, ph2ofsession_chain) { 1209 if (iph2->approval) { 1210 struct saproto *pr; 1211 1212 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 1213 if (pr->ok && pr->proto_id == IPSECDOI_PROTO_IPSEC_ESP) { 1214 if (!*seq) { 1215 *seq = iph2->seq; 1216 } 1217 if (dir == IPSEC_DIR_INBOUND) { 1218 stats[found].spi = pr->spi; 1219 } else { 1220 stats[found].spi = pr->spi_p; 1221 } 1222 if (++found == max_stats) { 1223 return found; 1224 } 1225 } 1226 } 1227 } 1228 } 1229 return found; 1230} 1231 1232void 1233ike_session_update_traffic_idle_status (ike_session_t *session, 1234 u_int32_t dir, 1235 struct sastat *new_stats, 1236 u_int32_t max_stats) 1237{ 1238 int i, j, found = 0, idle = 1; 1239 1240 if (!session || !new_stats || (dir != IPSEC_DIR_INBOUND && dir != IPSEC_DIR_OUTBOUND)) { 1241 plog(ASL_LEVEL_DEBUG, "invalid args in %s.\n", __FUNCTION__); 1242 return; 1243 } 1244 1245 if (!session->established || session->stopped_by_vpn_controller || session->stop_timestamp.tv_sec || session->stop_timestamp.tv_usec) { 1246 plog(ASL_LEVEL_DEBUG, "dropping update on invalid session in %s.\n", __FUNCTION__); 1247 return; 1248 } 1249 1250 for (i = 0; i < max_stats; i++) { 1251 if (dir == IPSEC_DIR_INBOUND) { 1252 for (j = 0; j < session->traffic_monitor.num_in_last_poll; j++) { 1253 if (new_stats[i].spi != session->traffic_monitor.in_last_poll[j].spi) { 1254 continue; 1255 } 1256 found = 1; 1257 if (new_stats[i].lft_c.sadb_lifetime_bytes != session->traffic_monitor.in_last_poll[j].lft_c.sadb_lifetime_bytes) { 1258 idle = 0; 1259 } 1260 } 1261 } else { 1262 for (j = 0; j < session->traffic_monitor.num_out_last_poll; j++) { 1263 if (new_stats[i].spi != session->traffic_monitor.out_last_poll[j].spi) { 1264 continue; 1265 } 1266 found = 1; 1267 if (new_stats[i].lft_c.sadb_lifetime_bytes != session->traffic_monitor.out_last_poll[j].lft_c.sadb_lifetime_bytes) { 1268 idle = 0; 1269 } 1270 } 1271 } 1272 // new SA.... check for any activity 1273 if (!found) { 1274 if (new_stats[i].lft_c.sadb_lifetime_bytes) { 1275 plog(ASL_LEVEL_DEBUG, "new SA: dir %d....\n", dir); 1276 idle = 0; 1277 } 1278 } 1279 } 1280 if (dir == IPSEC_DIR_INBOUND) { 1281 // overwrite old stats 1282 bzero(session->traffic_monitor.in_last_poll, sizeof(session->traffic_monitor.in_last_poll)); 1283 bcopy(new_stats, session->traffic_monitor.in_last_poll, (max_stats * sizeof(*new_stats))); 1284 session->traffic_monitor.num_in_last_poll = max_stats; 1285 if (!idle) { 1286 //plog(ASL_LEVEL_DEBUG, "peer sent data....\n"); 1287 session->peer_sent_data_sc_dpd = 1; 1288 session->peer_sent_data_sc_idle = 1; 1289 } 1290 } else { 1291 // overwrite old stats 1292 bzero(session->traffic_monitor.out_last_poll, sizeof(session->traffic_monitor.out_last_poll)); 1293 bcopy(new_stats, session->traffic_monitor.out_last_poll, (max_stats * sizeof(*new_stats))); 1294 session->traffic_monitor.num_out_last_poll = max_stats; 1295 if (!idle) { 1296 //plog(ASL_LEVEL_DEBUG, "i sent data....\n"); 1297 session->i_sent_data_sc_dpd = 1; 1298 session->i_sent_data_sc_idle = 1; 1299 } 1300 } 1301 if (!idle) 1302 session->last_time_data_sc_detected = time(NULL); 1303 1304 ike_session_monitor_idle(session); 1305} 1306 1307void 1308ike_session_cleanup (ike_session_t *session, 1309 const char *reason) 1310{ 1311 phase2_handle_t *iph2 = NULL; 1312 phase2_handle_t *next_iph2 = NULL; 1313 phase1_handle_t *iph1 = NULL; 1314 phase1_handle_t *next_iph1 = NULL; 1315 1316 if (!session) 1317 return; 1318 1319 session->is_dying = 1; 1320 ike_session_stopped_by_controller(session, reason); 1321 1322 SCHED_KILL(session->traffic_monitor.sc_idle); 1323 // do ph2's first... we need the ph1s for notifications 1324 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) { 1325 if (FSM_STATE_IS_ESTABLISHED(iph2->status)) { 1326 isakmp_info_send_d2(iph2); 1327 } 1328 isakmp_ph2expire(iph2); // iph2 will go down 1 second later. 1329 } 1330 1331 // do the ph1s last. 1332 LIST_FOREACH_SAFE(iph1, &session->ph1tree, ph1ofsession_chain, next_iph1) { 1333 if (FSM_STATE_IS_ESTABLISHED(iph1->status)) { 1334 isakmp_info_send_d1(iph1); 1335 } 1336 isakmp_ph1expire(iph1); 1337 } 1338 1339 // send ipsecManager a notification 1340 if (session->is_cisco_ipsec && reason && reason != ike_session_stopped_by_vpn_disconnect 1341 && reason != ike_session_stopped_by_controller_comm_lost) { 1342 u_int32_t address; 1343 if ((&session->session_id.remote)->ss_family == AF_INET) { 1344 address = ((struct sockaddr_in *)&session->session_id.remote)->sin_addr.s_addr; 1345 } else { 1346 address = 0; 1347 } 1348 // TODO: log 1349 if (reason == ike_session_stopped_by_idle) { 1350 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_IDLE_TIMEOUT, FROM_LOCAL, address, 0, NULL); 1351 } else { 1352 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_INTERNAL_ERROR, FROM_LOCAL, address, 0, NULL); 1353 } 1354 } 1355} 1356 1357int 1358ike_session_has_negoing_ph1 (ike_session_t *session) 1359{ 1360 phase1_handle_t *p; 1361 1362 if (!session) { 1363 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1364 return 0; 1365 } 1366 1367 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 1368 if (!p->is_dying && FSM_STATE_IS_NEGOTIATING(p->status)) { 1369 return 1; 1370 } 1371 } 1372 1373 return 0; 1374} 1375 1376int 1377ike_session_has_established_ph1 (ike_session_t *session) 1378{ 1379 phase1_handle_t *p; 1380 1381 if (!session) { 1382 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1383 return 0; 1384 } 1385 1386 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) { 1387 if (!p->is_dying && FSM_STATE_IS_ESTABLISHED(p->status)) { 1388 return 1; 1389 } 1390 } 1391 1392 return 0; 1393} 1394 1395int 1396ike_session_has_negoing_ph2 (ike_session_t *session) 1397{ 1398 phase2_handle_t *p; 1399 1400 if (!session) { 1401 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1402 return 0; 1403 } 1404 1405 LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) { 1406 if (!p->is_dying && FSM_STATE_IS_NEGOTIATING(p->status)) { 1407 return 1; 1408 } 1409 } 1410 1411 return 0; 1412} 1413 1414int 1415ike_session_has_established_ph2 (ike_session_t *session) 1416{ 1417 phase2_handle_t *p; 1418 1419 if (!session) { 1420 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1421 return 0; 1422 } 1423 1424 LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) { 1425 if (!p->is_dying && FSM_STATE_IS_ESTABLISHED(p->status)) { 1426 return 1; 1427 } 1428 } 1429 1430 return 0; 1431} 1432 1433void 1434ike_session_cleanup_ph1s_by_ph2 (phase2_handle_t *iph2) 1435{ 1436 phase1_handle_t *iph1 = NULL; 1437 phase1_handle_t *next_iph1 = NULL; 1438 1439 if (!iph2 || !iph2->parent_session) { 1440 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1441 return; 1442 } 1443 1444 // phase1 is no longer useful 1445 LIST_FOREACH_SAFE(iph1, &iph2->parent_session->ph1tree, ph1ofsession_chain, next_iph1) { 1446 if (FSM_STATE_IS_ESTABLISHED(iph1->status)) { 1447 isakmp_info_send_d1(iph1); 1448 } 1449 isakmp_ph1expire(iph1); 1450 } 1451} 1452 1453int 1454ike_session_is_client_ph2_rekey (phase2_handle_t *iph2) 1455{ 1456 if (iph2->parent_session && 1457 iph2->parent_session->is_client && 1458 iph2->is_rekey && 1459 iph2->parent_session->is_cisco_ipsec) { 1460 return 1; 1461 } 1462 return 0; 1463} 1464 1465int 1466ike_session_is_client_ph1_rekey (phase1_handle_t *iph1) 1467{ 1468 if (iph1->parent_session && 1469 iph1->parent_session->is_client && 1470 iph1->is_rekey && 1471 iph1->parent_session->is_cisco_ipsec) { 1472 return 1; 1473 } 1474 return 0; 1475} 1476 1477int 1478ike_session_is_client_ph1 (phase1_handle_t *iph1) 1479{ 1480 if (iph1->parent_session && 1481 iph1->parent_session->is_client) { 1482 return 1; 1483 } 1484 return 0; 1485} 1486 1487int 1488ike_session_is_client_ph2 (phase2_handle_t *iph2) 1489{ 1490 if (iph2->parent_session && 1491 iph2->parent_session->is_client) { 1492 return 1; 1493 } 1494 return 0; 1495} 1496 1497void 1498ike_session_start_xauth_timer (phase1_handle_t *iph1) 1499{ 1500 // if there are no more established ph2s, start a timer to teardown the session 1501 if (iph1->parent_session && 1502 iph1->parent_session->is_client && 1503 iph1->parent_session->is_cisco_ipsec && 1504 !iph1->parent_session->sc_xauth) { 1505 iph1->parent_session->sc_xauth = sched_new(300 /* 5 mins */, 1506 ike_session_cleanup_xauth_timeout, 1507 iph1->parent_session); 1508 } 1509} 1510 1511void 1512ike_session_stop_xauth_timer (phase1_handle_t *iph1) 1513{ 1514 if (iph1->parent_session) { 1515 SCHED_KILL(iph1->parent_session->sc_xauth); 1516 } 1517} 1518 1519static int 1520ike_session_is_id_ipany (vchar_t *ext_id) 1521{ 1522 struct id { 1523 u_int8_t type; /* ID Type */ 1524 u_int8_t proto_id; /* Protocol ID */ 1525 u_int16_t port; /* Port */ 1526 u_int32_t addr; /* IPv4 address */ 1527 u_int32_t mask; 1528 } *id_ptr; 1529 1530 /* ignore protocol and port */ 1531 id_ptr = ALIGNED_CAST(struct id *)ext_id->v; 1532 if (id_ptr->type == IPSECDOI_ID_IPV4_ADDR && 1533 id_ptr->addr == 0) { 1534 return 1; 1535 } else if (id_ptr->type == IPSECDOI_ID_IPV4_ADDR_SUBNET && 1536 id_ptr->mask == 0 && 1537 id_ptr->addr == 0) { 1538 return 1; 1539 } 1540 plog(ASL_LEVEL_DEBUG, "not ipany_ids in %s: type %d, addr %x, mask %x.\n", 1541 __FUNCTION__, id_ptr->type, id_ptr->addr, id_ptr->mask); 1542 return 0; 1543} 1544 1545static int 1546ike_session_is_id_portany (vchar_t *ext_id) 1547{ 1548 struct id { 1549 u_int8_t type; /* ID Type */ 1550 u_int8_t proto_id; /* Protocol ID */ 1551 u_int16_t port; /* Port */ 1552 u_int32_t addr; /* IPv4 address */ 1553 u_int32_t mask; 1554 } *id_ptr; 1555 1556 /* ignore addr */ 1557 id_ptr = ALIGNED_CAST(struct id *)ext_id->v; 1558 if (id_ptr->type == IPSECDOI_ID_IPV4_ADDR && 1559 id_ptr->port == 0) { 1560 return 1; 1561 } 1562 plog(ASL_LEVEL_DEBUG, "not portany_ids in %s: type %d, port %x.\n", 1563 __FUNCTION__, id_ptr->type, id_ptr->port); 1564 return 0; 1565} 1566 1567static void 1568ike_session_set_id_portany (vchar_t *ext_id) 1569{ 1570 struct id { 1571 u_int8_t type; /* ID Type */ 1572 u_int8_t proto_id; /* Protocol ID */ 1573 u_int16_t port; /* Port */ 1574 u_int32_t addr; /* IPv4 address */ 1575 u_int32_t mask; 1576 } *id_ptr; 1577 1578 /* ignore addr */ 1579 id_ptr = ALIGNED_CAST(struct id *)ext_id->v; 1580 if (id_ptr->type == IPSECDOI_ID_IPV4_ADDR) { 1581 id_ptr->port = 0; 1582 return; 1583 } 1584} 1585 1586static int 1587ike_session_cmp_ph2_ids_ipany (vchar_t *ext_id, 1588 vchar_t *ext_id_p) 1589{ 1590 if (ike_session_is_id_ipany(ext_id) && 1591 ike_session_is_id_ipany(ext_id_p)) { 1592 return 1; 1593 } 1594 return 0; 1595} 1596 1597/* 1598 * ipsec rekeys for l2tp-over-ipsec fail particularly when client is behind nat because the client's configs and policies don't 1599 * match the server's view of the client's address and port. 1600 * servers behave differently when using this address-port info to generate ids during phase2 rekeys, so try to match the incoming id to 1601 * a variety of info saved in the older phase2. 1602 */ 1603int 1604ike_session_cmp_ph2_ids (phase2_handle_t *iph2, 1605 phase2_handle_t *older_ph2) 1606{ 1607 vchar_t *portany_id = NULL; 1608 vchar_t *portany_id_p = NULL; 1609 1610 if (iph2->id && older_ph2->id && 1611 iph2->id->l == older_ph2->id->l && 1612 memcmp(iph2->id->v, older_ph2->id->v, iph2->id->l) == 0 && 1613 iph2->id_p && older_ph2->id_p && 1614 iph2->id_p->l == older_ph2->id_p->l && 1615 memcmp(iph2->id_p->v, older_ph2->id_p->v, iph2->id_p->l) == 0) { 1616 return 0; 1617 } 1618 if (iph2->ext_nat_id && older_ph2->ext_nat_id && 1619 iph2->ext_nat_id->l == older_ph2->ext_nat_id->l && 1620 memcmp(iph2->ext_nat_id->v, older_ph2->ext_nat_id->v, iph2->ext_nat_id->l) == 0 && 1621 iph2->ext_nat_id_p && older_ph2->ext_nat_id_p && 1622 iph2->ext_nat_id_p->l == older_ph2->ext_nat_id_p->l && 1623 memcmp(iph2->ext_nat_id_p->v, older_ph2->ext_nat_id_p->v, iph2->ext_nat_id_p->l) == 0) { 1624 return 0; 1625 } 1626 if (iph2->id && older_ph2->ext_nat_id && 1627 iph2->id->l == older_ph2->ext_nat_id->l && 1628 memcmp(iph2->id->v, older_ph2->ext_nat_id->v, iph2->id->l) == 0 && 1629 iph2->id_p && older_ph2->ext_nat_id_p && 1630 iph2->id_p->l == older_ph2->ext_nat_id_p->l && 1631 memcmp(iph2->id_p->v, older_ph2->ext_nat_id_p->v, iph2->id_p->l) == 0) { 1632 return 0; 1633 } 1634 if (iph2->id && older_ph2->ext_nat_id && 1635 iph2->id->l == older_ph2->ext_nat_id->l && 1636 memcmp(iph2->id->v, older_ph2->ext_nat_id->v, iph2->id->l) == 0 && 1637 iph2->id_p && older_ph2->id_p && 1638 iph2->id_p->l == older_ph2->id_p->l && 1639 memcmp(iph2->id_p->v, older_ph2->id_p->v, iph2->id_p->l) == 0) { 1640 return 0; 1641 } 1642 if (iph2->id && older_ph2->id && 1643 iph2->id->l == older_ph2->id->l && 1644 memcmp(iph2->id->v, older_ph2->id->v, iph2->id->l) == 0 && 1645 iph2->id_p && older_ph2->ext_nat_id_p && 1646 iph2->id_p->l == older_ph2->ext_nat_id_p->l && 1647 memcmp(iph2->id_p->v, older_ph2->ext_nat_id_p->v, iph2->id_p->l) == 0) { 1648 return 0; 1649 } 1650 1651 /* check if the external id has a wildcard port and compare ids accordingly */ 1652 if ((older_ph2->ext_nat_id && ike_session_is_id_portany(older_ph2->ext_nat_id)) || 1653 (older_ph2->ext_nat_id_p && ike_session_is_id_portany(older_ph2->ext_nat_id_p))) { 1654 // try ignoring ports in iph2->id and iph2->id 1655 if (iph2->id && (portany_id = vdup(iph2->id))) { 1656 ike_session_set_id_portany(portany_id); 1657 } 1658 if (iph2->id_p && (portany_id_p = vdup(iph2->id_p))) { 1659 ike_session_set_id_portany(portany_id_p); 1660 } 1661 if (portany_id && older_ph2->ext_nat_id && 1662 portany_id->l == older_ph2->ext_nat_id->l && 1663 memcmp(portany_id->v, older_ph2->ext_nat_id->v, portany_id->l) == 0 && 1664 portany_id_p && older_ph2->ext_nat_id_p && 1665 portany_id_p->l == older_ph2->ext_nat_id_p->l && 1666 memcmp(portany_id_p->v, older_ph2->ext_nat_id_p->v, portany_id_p->l) == 0) { 1667 if (portany_id) { 1668 vfree(portany_id); 1669 } 1670 if (portany_id_p) { 1671 vfree(portany_id_p); 1672 } 1673 return 0; 1674 } 1675 if (portany_id && iph2->id && older_ph2->ext_nat_id && 1676 iph2->id->l == older_ph2->ext_nat_id->l && 1677 memcmp(portany_id->v, older_ph2->ext_nat_id->v, portany_id->l) == 0 && 1678 iph2->id_p && older_ph2->id_p && 1679 iph2->id_p->l == older_ph2->id_p->l && 1680 memcmp(iph2->id_p->v, older_ph2->id_p->v, iph2->id_p->l) == 0) { 1681 if (portany_id) { 1682 vfree(portany_id); 1683 } 1684 if (portany_id_p) { 1685 vfree(portany_id_p); 1686 } 1687 return 0; 1688 } 1689 if (portany_id_p && iph2->id && older_ph2->id && 1690 iph2->id->l == older_ph2->id->l && 1691 memcmp(iph2->id->v, older_ph2->id->v, iph2->id->l) == 0 && 1692 iph2->id_p && older_ph2->ext_nat_id_p && 1693 iph2->id_p->l == older_ph2->ext_nat_id_p->l && 1694 memcmp(portany_id_p->v, older_ph2->ext_nat_id_p->v, portany_id_p->l) == 0) { 1695 if (portany_id) { 1696 vfree(portany_id); 1697 } 1698 if (portany_id_p) { 1699 vfree(portany_id_p); 1700 } 1701 return 0; 1702 } 1703 if (portany_id) { 1704 vfree(portany_id); 1705 } 1706 if (portany_id_p) { 1707 vfree(portany_id_p); 1708 } 1709 } 1710 return -1; 1711} 1712 1713int 1714ike_session_get_sainfo_r (phase2_handle_t *iph2) 1715{ 1716 if (iph2->parent_session && 1717 iph2->parent_session->is_client && 1718 iph2->id && iph2->id_p) { 1719 phase2_handle_t *p; 1720 int ipany_ids = ike_session_cmp_ph2_ids_ipany(iph2->id, iph2->id_p); 1721 plog(ASL_LEVEL_DEBUG, "ipany_ids %d in %s.\n", ipany_ids, __FUNCTION__); 1722 1723 LIST_FOREACH(p, &iph2->parent_session->ph2tree, ph2ofsession_chain) { 1724 if (iph2 != p && !p->is_dying && FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(p->status) && p->sainfo) { 1725 plog(ASL_LEVEL_DEBUG, "candidate ph2 found in %s.\n", __FUNCTION__); 1726 if (ipany_ids || 1727 ike_session_cmp_ph2_ids(iph2, p) == 0) { 1728 plog(ASL_LEVEL_DEBUG, "candidate ph2 matched in %s.\n", __FUNCTION__); 1729 iph2->sainfo = p->sainfo; 1730 if (iph2->sainfo) 1731 retain_sainfo(iph2->sainfo); 1732 if (!iph2->spid) { 1733 iph2->spid = p->spid; 1734 } else { 1735 plog(ASL_LEVEL_DEBUG, "%s: pre-assigned spid %d.\n", __FUNCTION__, iph2->spid); 1736 } 1737 if (p->ext_nat_id) { 1738 if (iph2->ext_nat_id) { 1739 vfree(iph2->ext_nat_id); 1740 } 1741 iph2->ext_nat_id = vdup(p->ext_nat_id); 1742 } 1743 if (p->ext_nat_id_p) { 1744 if (iph2->ext_nat_id_p) { 1745 vfree(iph2->ext_nat_id_p); 1746 } 1747 iph2->ext_nat_id_p = vdup(p->ext_nat_id_p); 1748 } 1749 return 0; 1750 } 1751 } 1752 } 1753 } 1754 return -1; 1755} 1756 1757int 1758ike_session_get_proposal_r (phase2_handle_t *iph2) 1759{ 1760 if (iph2->parent_session && 1761 iph2->parent_session->is_client && 1762 iph2->id && iph2->id_p) { 1763 phase2_handle_t *p; 1764 int ipany_ids = ike_session_cmp_ph2_ids_ipany(iph2->id, iph2->id_p); 1765 plog(ASL_LEVEL_DEBUG, "ipany_ids %d in %s.\n", ipany_ids, __FUNCTION__); 1766 1767 LIST_FOREACH(p, &iph2->parent_session->ph2tree, ph2ofsession_chain) { 1768 if (iph2 != p && !p->is_dying && FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(p->status) && 1769 p->approval) { 1770 plog(ASL_LEVEL_DEBUG, "candidate ph2 found in %s.\n", __FUNCTION__); 1771 if (ipany_ids || 1772 ike_session_cmp_ph2_ids(iph2, p) == 0) { 1773 plog(ASL_LEVEL_DEBUG, "candidate ph2 matched in %s.\n", __FUNCTION__); 1774 iph2->proposal = dupsaprop(p->approval, 1); 1775 if (!iph2->spid) { 1776 iph2->spid = p->spid; 1777 } else { 1778 plog(ASL_LEVEL_DEBUG, "%s: pre-assigned spid %d.\n", __FUNCTION__, iph2->spid); 1779 } 1780 return 0; 1781 } 1782 } 1783 } 1784 } 1785 return -1; 1786} 1787 1788void 1789ike_session_update_natt_version (phase1_handle_t *iph1) 1790{ 1791 if (iph1->parent_session) { 1792 if (iph1->natt_options) { 1793 iph1->parent_session->natt_version = iph1->natt_options->version; 1794 } else { 1795 iph1->parent_session->natt_version = 0; 1796 } 1797 } 1798} 1799 1800int 1801ike_session_get_natt_version (phase1_handle_t *iph1) 1802{ 1803 if (iph1->parent_session) { 1804 return(iph1->parent_session->natt_version); 1805 } 1806 return 0; 1807} 1808 1809int 1810ike_session_drop_rekey (ike_session_t *session, ike_session_rekey_type_t rekey_type) 1811{ 1812 if (session) { 1813 if (session->is_btmm_ipsec && 1814 session->last_time_data_sc_detected && 1815 session->traffic_monitor.interv_mon && 1816 session->traffic_monitor.interv_idle) { 1817 // for btmm: drop ph1/ph2 rekey if session is idle 1818 time_t now = time(NULL); 1819 1820 if ((now - session->last_time_data_sc_detected) > (session->traffic_monitor.interv_mon << 1)) { 1821 plog(ASL_LEVEL_DEBUG, "btmm session is idle: drop ph%drekey.\n", 1822 rekey_type); 1823 return 1; 1824 } 1825 } else if (!session->is_btmm_ipsec) { 1826 if (rekey_type == IKE_SESSION_REKEY_TYPE_PH1 && 1827 !ike_session_has_negoing_ph2(session) && !ike_session_has_established_ph2(session)) { 1828 // for vpn: only drop ph1 if there are no more ph2s. 1829 plog(ASL_LEVEL_DEBUG, "vpn session is idle: drop ph1 rekey.\n"); 1830 return 1; 1831 } 1832 } 1833 } 1834 return 0; 1835} 1836 1837/* 1838 * this is called after racooon receives a 'kIOMessageSystemHasPoweredOn' 1839 * a lot is done to make sure that we don't sweep a session that's already been asserted. 1840 * however, it'll be too bad if the assertion comes after the session has already been swept. 1841 */ 1842void 1843ike_session_sweep_sleepwake (void) 1844{ 1845 ike_session_t *p = NULL; 1846 ike_session_t *next_session = NULL; 1847 1848 // flag session as dying if all ph1/ph2 are dead/dying 1849 LIST_FOREACH_SAFE(p, &ike_session_tree, chain, next_session) { 1850 if (p->is_dying) { 1851 plog(ASL_LEVEL_DEBUG, "skipping sweep of dying session.\n"); 1852 continue; 1853 } 1854 SCHED_KILL(p->sc_xauth); 1855 if (p->is_asserted) { 1856 // for asserted session, traffic monitors will be restared after phase2 becomes established. 1857 SCHED_KILL(p->traffic_monitor.sc_mon); 1858 SCHED_KILL(p->traffic_monitor.sc_idle); 1859 plog(ASL_LEVEL_DEBUG, "skipping sweep of asserted session.\n"); 1860 continue; 1861 } 1862 1863 // cleanup any stopped sessions as they will go down 1864 if (p->stopped_by_vpn_controller || p->stop_timestamp.tv_sec || p->stop_timestamp.tv_usec) { 1865 plog(ASL_LEVEL_DEBUG, "sweeping stopped session.\n"); 1866 ike_session_cleanup(p, ike_session_stopped_by_sleepwake); 1867 continue; 1868 } 1869 1870 if (!ike_session_has_established_ph1(p) && !ike_session_has_established_ph2(p)) { 1871 plog(ASL_LEVEL_DEBUG, "session died while sleeping.\n"); 1872 ike_session_cleanup(p, ike_session_stopped_by_sleepwake); 1873 continue; 1874 } 1875 if (p->traffic_monitor.sc_mon) { 1876 time_t xtime; 1877 if (sched_get_time(p->traffic_monitor.sc_mon, &xtime)) { 1878 if (xtime <= swept_at) { 1879 SCHED_KILL(p->traffic_monitor.sc_mon); 1880 if (!p->is_dying && p->traffic_monitor.interv_mon) { 1881 p->traffic_monitor.sc_mon = sched_new(p->traffic_monitor.interv_mon, 1882 ike_session_traffic_cop, 1883 p); 1884 } 1885 } 1886 } 1887 } 1888 if (p->traffic_monitor.sc_idle) { 1889 time_t xtime; 1890 if (sched_get_time(p->traffic_monitor.sc_idle, &xtime)) { 1891 if (xtime <= swept_at) { 1892 SCHED_KILL(p->traffic_monitor.sc_idle); 1893 if (!p->is_dying && p->traffic_monitor.interv_idle) { 1894 p->traffic_monitor.sc_idle = sched_new(p->traffic_monitor.interv_idle, 1895 ike_session_cleanup_idle, 1896 p); 1897 } 1898 } 1899 } 1900 } 1901 } 1902} 1903 1904/* 1905 * this is called after racooon receives an assert command from the controller/pppd. 1906 * this is intended to make racoon prepare to rekey both SAs because a network event occurred. 1907 * in the event of a sleepwake, the assert could happen before or after 'ike_session_sweep_sleepwake'. 1908 */ 1909int 1910ike_session_assert_session (ike_session_t *session) 1911{ 1912 phase2_handle_t *iph2 = NULL; 1913 phase2_handle_t *iph2_next = NULL; 1914 phase1_handle_t *iph1 = NULL; 1915 phase1_handle_t *iph1_next = NULL; 1916 1917 if (!session || session->is_dying) { 1918 plog(ASL_LEVEL_DEBUG, "Invalid parameters in %s.\n", __FUNCTION__); 1919 return -1; 1920 } 1921 1922 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase2s 1923 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, iph2_next) { 1924 if (!iph2->is_dying && !FSM_STATE_IS_EXPIRED(iph2->status)) { 1925 SCHED_KILL(iph2->sce); 1926 iph2->is_dying = 1; 1927 1928 // delete SAs (in the kernel) 1929 if (FSM_STATE_IS_ESTABLISHED(iph2->status) && iph2->approval) { 1930 struct saproto *pr; 1931 1932 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 1933 if (pr->ok) { 1934 //log deletion 1935 plog(ASL_LEVEL_DEBUG, 1936 "Assert: Phase 2 %s deleted\n", 1937 sadbsecas2str(iph2->src, iph2->dst, iph2->satype, iph2->spid, ipsecdoi2pfkey_mode(pr->encmode))); 1938 1939 pfkey_send_delete(lcconf->sock_pfkey, 1940 ipsecdoi2pfkey_proto(pr->proto_id), 1941 ipsecdoi2pfkey_mode(pr->encmode), 1942 iph2->src, iph2->dst, pr->spi_p); 1943 } 1944 } 1945 } 1946 1947 fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED); // we want to delete SAs without telling the PEER 1948 iph2->sce = sched_new(3, ike_session_cleanup_ph2_stub, iph2); 1949 } 1950 } 1951 1952 // the goal is to prepare the session for fresh rekeys by silently deleting the currently active phase1s 1953 LIST_FOREACH_SAFE(iph1, &session->ph1tree, ph1ofsession_chain, iph1_next) { 1954 if (!iph1->is_dying && !FSM_STATE_IS_EXPIRED(iph1->status)) { 1955 SCHED_KILL(iph1->sce); 1956 SCHED_KILL(iph1->sce_rekey); 1957 iph1->is_dying = 1; 1958 1959 //log deletion 1960 plog(ASL_LEVEL_DEBUG, 1961 "Assert: Phase 1 %s deleted\n", 1962 isakmp_pindex(&iph1->index, 0)); 1963 1964 ike_session_unbind_all_ph2_from_ph1(iph1); 1965 1966 fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_EXPIRED); // we want to delete SAs without telling the PEER 1967 /* responder sets up timer to delete old inbound SAs... say 7 secs later and flags them as rekeyed */ 1968 iph1->sce = sched_new(5, ike_session_cleanup_ph1_stub, iph1); 1969 } 1970 } 1971 session->is_asserted = 1; 1972 1973 return 0; 1974} 1975 1976int 1977ike_session_assert (struct sockaddr_storage *local, 1978 struct sockaddr_storage *remote) 1979{ 1980 ike_session_t *sess; 1981 1982 if (!local || !remote) { 1983 plog(ASL_LEVEL_DEBUG, "invalid parameters in %s.\n", __FUNCTION__); 1984 return -1; 1985 } 1986 1987 if ((sess = ike_session_get_session(local, remote, FALSE, NULL))) { 1988 return(ike_session_assert_session(sess)); 1989 } 1990 return -1; 1991} 1992 1993void 1994ike_session_ph2_retransmits (phase2_handle_t *iph2) 1995{ 1996 int num_retransmits; 1997 1998 if (!iph2->is_dying && 1999 iph2->is_rekey && 2000 iph2->ph1 && 2001 iph2->ph1->sce_rekey && !sched_is_dead(iph2->ph1->sce_rekey) && 2002 iph2->side == INITIATOR && 2003 iph2->parent_session && 2004 !iph2->parent_session->is_cisco_ipsec && /* not for Cisco */ 2005 iph2->parent_session->is_client) { 2006 num_retransmits = iph2->ph1->rmconf->retry_counter - iph2->retry_counter; 2007 if (num_retransmits == 3) { 2008 /* 2009 * phase2 negotiation is stalling on retransmits, inspite of a valid ph1. 2010 * one of the following is possible: 2011 * - (0) severe packet loss. 2012 * - (1) the peer is dead. 2013 * - (2) the peer is out of sync hence dropping this phase2 rekey (and perhaps responding with insecure 2014 * invalid-cookie notifications... but those are untrusted and so we can't rekey phase1 off that) 2015 * (2.1) the peer rebooted (or process restarted) and is now alive. 2016 * (2.2) the peer has deleted phase1 without notifying us (or the notification got dropped somehow). 2017 * (2.3) the peer has a policy/bug stopping this phase2 rekey 2018 * 2019 * in all these cases, one sure way to know is to trigger a phase1 rekey early. 2020 */ 2021 plog(ASL_LEVEL_DEBUG, "Many Phase 2 retransmits: try Phase 1 rekey and this Phase 2 to quit earlier.\n"); 2022 isakmp_ph1rekeyexpire(iph2->ph1, TRUE); 2023 iph2->retry_counter = 0; 2024 } 2025 } 2026} 2027 2028void 2029ike_session_ph1_retransmits (phase1_handle_t *iph1) 2030{ 2031 int num_retransmits; 2032 2033 if (!iph1->is_dying && 2034 iph1->is_rekey && 2035 !iph1->sce_rekey && 2036 FSM_STATE_IS_NEGOTIATING(iph1->status) && 2037 iph1->side == INITIATOR && 2038 iph1->parent_session && 2039 iph1->parent_session->is_client && 2040 !ike_session_has_other_negoing_ph1(iph1->parent_session, iph1)) { 2041 num_retransmits = iph1->rmconf->retry_counter - iph1->retry_counter; 2042 if (num_retransmits == 3) { 2043 plog(ASL_LEVEL_DEBUG, "Many Phase 1 retransmits: try quit earlier.\n"); 2044 iph1->retry_counter = 0; 2045 } 2046 } 2047} 2048 2049static void 2050ike_session_bindph12(phase1_handle_t *iph1, phase2_handle_t *iph2) 2051{ 2052 if (iph2->ph1) { 2053 plog(ASL_LEVEL_ERR, "Phase 2 already bound %s.\n", __FUNCTION__); 2054 } 2055 iph2->ph1 = iph1; 2056 LIST_INSERT_HEAD(&iph1->bound_ph2tree, iph2, ph1bind_chain); 2057} 2058 2059void 2060ike_session_unbindph12(phase2_handle_t *iph2) 2061{ 2062 if (iph2->ph1 != NULL) { 2063 iph2->ph1 = NULL; 2064 LIST_REMOVE(iph2, ph1bind_chain); 2065 } 2066} 2067 2068static void 2069ike_session_rebindph12(phase1_handle_t *new_ph1, phase2_handle_t *iph2) 2070{ 2071 if (!new_ph1) { 2072 return; 2073 } 2074 2075 // reconcile the ph1-to-ph2 binding 2076 ike_session_unbindph12(iph2); 2077 ike_session_bindph12(new_ph1, iph2); 2078 // recalculate ivm since ph1 binding has changed 2079 if (iph2->ivm != NULL) { 2080 oakley_delivm(iph2->ivm); 2081 if (FSM_STATE_IS_ESTABLISHED(new_ph1->status)) { 2082 iph2->ivm = oakley_newiv2(new_ph1, iph2->msgid); 2083 plog(ASL_LEVEL_DEBUG, "Phase 1-2 binding changed... recalculated ivm.\n"); 2084 } else { 2085 iph2->ivm = NULL; 2086 } 2087 } 2088} 2089 2090static void 2091ike_session_unbind_all_ph2_from_ph1 (phase1_handle_t *iph1) 2092{ 2093 phase2_handle_t *p = NULL; 2094 phase2_handle_t *next = NULL; 2095 2096 LIST_FOREACH_SAFE(p, &iph1->bound_ph2tree, ph1bind_chain, next) { 2097 ike_session_unbindph12(p); 2098 } 2099} 2100 2101static void 2102ike_session_rebind_all_ph12_to_new_ph1 (phase1_handle_t *old_iph1, 2103 phase1_handle_t *new_iph1) 2104{ 2105 phase2_handle_t *p = NULL; 2106 phase2_handle_t *next = NULL; 2107 2108 if (old_iph1 == new_iph1 || !old_iph1 || !new_iph1) { 2109 plog(ASL_LEVEL_DEBUG, "Invalid parameters in %s.\n", __FUNCTION__); 2110 return; 2111 } 2112 2113 if (old_iph1->parent_session != new_iph1->parent_session) { 2114 plog(ASL_LEVEL_DEBUG, "Invalid parent sessions in %s.\n", __FUNCTION__); 2115 return; 2116 } 2117 2118 LIST_FOREACH_SAFE(p, &old_iph1->bound_ph2tree, ph1bind_chain, next) { 2119 if (p->parent_session != new_iph1->parent_session) { 2120 plog(ASL_LEVEL_ERR, "Mismatched parent session in ph1bind replacement.\n"); 2121 } 2122 if (p->ph1 == new_iph1) { 2123 plog(ASL_LEVEL_ERR, "Same Phase 2 in ph1bind replacement in %s.\n",__FUNCTION__); 2124 } 2125 ike_session_rebindph12(new_iph1, p); 2126 } 2127} 2128 2129