1/* $NetBSD: isakmp_inf.c,v 1.14.4.8 2007/08/01 11:52:20 vanhu Exp $ */ 2 3/* Id: isakmp_inf.c,v 1.44 2006/05/06 20:45:52 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#include "racoon_types.h" 36 37#include <sys/types.h> 38#include <sys/param.h> 39#include <sys/socket.h> 40 41#include <net/pfkeyv2.h> 42#include <netinet/in.h> 43#include <sys/queue.h> 44#ifndef HAVE_NETINET6_IPSEC 45#include <netinet/ipsec.h> 46#else 47#include <netinet6/ipsec.h> 48#endif 49 50#include <stdlib.h> 51#include <stdio.h> 52#include <string.h> 53#include <errno.h> 54#if TIME_WITH_SYS_TIME 55# include <sys/time.h> 56# include <time.h> 57#else 58# if HAVE_SYS_TIME_H 59# include <sys/time.h> 60# else 61# include <time.h> 62# endif 63#endif 64#ifdef ENABLE_HYBRID 65#include <resolv.h> 66#endif 67 68#include "libpfkey.h" 69 70#include "var.h" 71#include "vmbuf.h" 72#include "schedule.h" 73#include "str2val.h" 74#include "misc.h" 75#include "plog.h" 76#include "debug.h" 77#include "fsm.h" 78#include "session.h" 79#include "ike_session.h" 80 81#include "localconf.h" 82#include "remoteconf.h" 83#include "sockmisc.h" 84#include "handler.h" 85#include "policy.h" 86#include "proposal.h" 87#include "isakmp_var.h" 88#include "isakmp.h" 89#ifdef ENABLE_HYBRID 90#include "isakmp_xauth.h" 91#include "isakmp_unity.h" 92#include "isakmp_cfg.h" 93#endif 94#include "isakmp_inf.h" 95#include "ikev2_info_rfc.h" 96#include "oakley.h" 97#include "ipsec_doi.h" 98#include "crypto_openssl.h" 99#include "pfkey.h" 100#include "policy.h" 101#include "algorithm.h" 102#include "proposal.h" 103#include "strnames.h" 104#ifdef ENABLE_NATT 105#include "nattraversal.h" 106#endif 107#include "vpn_control_var.h" 108#include "vpn_control.h" 109#include "ike_session.h" 110#include "ipsecSessionTracer.h" 111#include "ipsecMessageTracer.h" 112 113/* information exchange */ 114static int isakmp_info_recv_n (phase1_handle_t *, struct isakmp_pl_n *, u_int32_t, int); 115static int isakmp_info_recv_d (phase1_handle_t *, struct isakmp_pl_d *, u_int32_t, int); 116 117#ifdef ENABLE_DPD 118static int isakmp_info_recv_r_u (phase1_handle_t *, struct isakmp_pl_ru *, u_int32_t); 119static int isakmp_info_recv_r_u_ack (phase1_handle_t *, struct isakmp_pl_ru *, u_int32_t); 120#endif 121 122#ifdef ENABLE_VPNCONTROL_PORT 123static int isakmp_info_recv_lb (phase1_handle_t *, struct isakmp_pl_lb *lb, int); 124#endif 125 126static int 127isakmp_ph1_responder_lifetime (phase1_handle_t *iph1, struct isakmp_pl_resp_lifetime *notify) 128{ 129 char *spi; 130 131 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { 132 plog(ASL_LEVEL_ERR, 133 "invalid spi_size in notification payload.\n"); 134 return -1; 135 } 136 spi = val2str((char *)(notify + 1), notify->spi_size); 137 138 plog(ASL_LEVEL_DEBUG, 139 "notification message ISAKMP-SA RESPONDER-LIFETIME, " 140 "doi=%d proto_id=%d spi=%s(size=%d).\n", 141 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); 142 143 /* TODO */ 144 #if 0 145 struct isakmp_pl_attr *attrpl; 146 int len = ntohs(notify->h.len) - (sizeof(*notify) + notify->spi_size); 147 148 attrpl = (struct isakmp_pl_attr *)((char *)(notify + 1) + notify->spi_size); 149 while (len > 0) { 150 } 151 #endif 152 153 racoon_free(spi); 154 return 0; 155} 156 157static int 158isakmp_ph2_responder_lifetime (phase2_handle_t *iph2, struct isakmp_pl_resp_lifetime *notify) 159{ 160 char *spi; 161 162 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { 163 plog(ASL_LEVEL_ERR, 164 "invalid spi_size in notification payload.\n"); 165 return -1; 166 } 167 spi = val2str((char *)(notify + 1), notify->spi_size); 168 169 plog(ASL_LEVEL_DEBUG, 170 "notification message IPSEC-SA RESPONDER-LIFETIME, " 171 "doi=%d proto_id=%d spi=%s(size=%d).\n", 172 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); 173 174 /* TODO */ 175 176 racoon_free(spi); 177 return 0; 178} 179 180/* %%% 181 * Information Exchange 182 */ 183/* 184 * receive Information 185 */ 186int 187isakmp_info_recv(phase1_handle_t *iph1, vchar_t *msg0) 188{ 189 vchar_t *msg = NULL; 190 vchar_t *pbuf = NULL; 191 u_int32_t msgid = 0; 192 int error = -1; 193 struct isakmp *isakmp; 194 struct isakmp_gen *gen; 195 struct isakmp_parse_t *pa; 196 void *p; 197 vchar_t *hash, *payload; 198 struct isakmp_gen *nd; 199 u_int8_t np; 200 int encrypted; 201 int flag = 0; 202 203 plog(ASL_LEVEL_DEBUG, "receive Information.\n"); 204 205 encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E); 206 msgid = ((struct isakmp *)msg0->v)->msgid; 207 208 /* Use new IV to decrypt Informational message. */ 209 if (encrypted) { 210 struct isakmp_ivm *ivm; 211 212 if (iph1->ivm == NULL) { 213 plog(ASL_LEVEL_ERR, "iph1->ivm == NULL\n"); 214 IPSECSESSIONTRACEREVENT(iph1->parent_session, 215 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, 216 CONSTSTR("Information message"), 217 CONSTSTR("Failed to process Information Message (no IV)")); 218 return -1; 219 } 220 221 /* compute IV */ 222 ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid); 223 if (ivm == NULL) { 224 plog(ASL_LEVEL_ERR, 225 "failed to compute IV\n"); 226 IPSECSESSIONTRACEREVENT(iph1->parent_session, 227 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, 228 CONSTSTR("Information message"), 229 CONSTSTR("Failed to process Information Message (can't compute IV)")); 230 return -1; 231 } 232 233 msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive); 234 oakley_delivm(ivm); 235 if (msg == NULL) { 236 plog(ASL_LEVEL_ERR, 237 "failed to decrypt packet\n"); 238 IPSECSESSIONTRACEREVENT(iph1->parent_session, 239 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, 240 CONSTSTR("Information message"), 241 CONSTSTR("Failed to decrypt Information message")); 242 return -1; 243 } 244 245 } else 246 msg = vdup(msg0); 247 248 /* Safety check */ 249 if (msg->l < sizeof(*isakmp) + sizeof(*gen)) { 250 plog(ASL_LEVEL_ERR, 251 "ignore information because the " 252 "message is way too short\n"); 253 goto end; 254 } 255 256 isakmp = (struct isakmp *)msg->v; 257 gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp)); 258 np = gen->np; 259 260 if (encrypted) { 261 if (isakmp->np != ISAKMP_NPTYPE_HASH) { 262 plog(ASL_LEVEL_ERR, 263 "ignore information because the " 264 "message has no hash payload.\n"); 265 goto end; 266 } 267 268 if (!FSM_STATE_IS_ESTABLISHED(iph1->status) && 269 (!iph1->approval || !iph1->skeyid_a)) { 270 plog(ASL_LEVEL_ERR, 271 "ignore information because ISAKMP-SA " 272 "has not been established yet.\n"); 273 goto end; 274 } 275 276 /* Safety check */ 277 if (msg->l < sizeof(*isakmp) + ntohs(gen->len) + sizeof(*nd)) { 278 plog(ASL_LEVEL_ERR, 279 "ignore information because the " 280 "message is too short\n"); 281 goto end; 282 } 283 284 p = (caddr_t) gen + sizeof(struct isakmp_gen); 285 nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len)); 286 287 /* nd length check */ 288 if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) + 289 ntohs(gen->len))) { 290 plog(ASL_LEVEL_ERR, 291 "too long payload length (broken message?)\n"); 292 goto end; 293 } 294 295 if (ntohs(nd->len) < sizeof(*nd)) { 296 plog(ASL_LEVEL_ERR, 297 "too short payload length (broken message?)\n"); 298 goto end; 299 } 300 301 payload = vmalloc(ntohs(nd->len)); 302 if (payload == NULL) { 303 plog(ASL_LEVEL_ERR, 304 "cannot allocate memory\n"); 305 goto end; 306 } 307 308 memcpy(payload->v, (caddr_t) nd, ntohs(nd->len)); 309 310 /* compute HASH */ 311 hash = oakley_compute_hash1(iph1, isakmp->msgid, payload); 312 if (hash == NULL) { 313 plog(ASL_LEVEL_ERR, 314 "cannot compute hash\n"); 315 316 vfree(payload); 317 goto end; 318 } 319 320 if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) { 321 plog(ASL_LEVEL_ERR, 322 "ignore information due to hash length mismatch\n"); 323 324 vfree(hash); 325 vfree(payload); 326 goto end; 327 } 328 329 if (memcmp(p, hash->v, hash->l) != 0) { 330 plog(ASL_LEVEL_ERR, 331 "ignore information due to hash mismatch\n"); 332 333 vfree(hash); 334 vfree(payload); 335 goto end; 336 } 337 338 plog(ASL_LEVEL_DEBUG, "hash validated.\n"); 339 340 vfree(hash); 341 vfree(payload); 342 } else { 343 /* make sure phase 1 was not yet at encrypted state */ 344 switch (iph1->etype) { 345 case ISAKMP_ETYPE_AGG: 346 // %%%%% should also check for unity/mode cfg - last pkt is encrypted in such cases 347 if (!FSM_STATE_IS_ESTABLISHED(iph1->status) && 348 ((iph1->side == INITIATOR && iph1->status == IKEV1_STATE_AGG_I_MSG3SENT) || 349 (iph1->side == RESPONDER && iph1->status == IKEV1_STATE_AGG_R_MSG3RCVD))) { 350 break; 351 } 352 case ISAKMP_ETYPE_IDENT: 353 if (!FSM_STATE_IS_ESTABLISHED(iph1->status) && 354 ((iph1->side == INITIATOR && (iph1->status == IKEV1_STATE_IDENT_I_MSG5SENT 355 || iph1->status == IKEV1_STATE_IDENT_I_MSG6RCVD)) || 356 (iph1->side == RESPONDER && (iph1->status == IKEV1_STATE_IDENT_R_MSG5RCVD)))) { 357 break; 358 } 359 /*FALLTHRU*/ 360 default: 361 plog(ASL_LEVEL_ERR, 362 "%s message must be encrypted\n", 363 s_isakmp_nptype(np)); 364 error = 0; 365 goto end; 366 } 367 } 368 369 if (!(pbuf = isakmp_parse(msg))) { 370 plog(ASL_LEVEL_ERR, 371 "failed to parse msg"); 372 error = -1; 373 goto end; 374 } 375 376 error = 0; 377 for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v; pa->type; pa++) { // Wcast-align fix (void*) - aligned buffer of aligned (unpacked) structs 378 switch (pa->type) { 379 case ISAKMP_NPTYPE_HASH: 380 /* Handled above */ 381 break; 382 case ISAKMP_NPTYPE_N: 383 error = isakmp_info_recv_n(iph1, 384 (struct isakmp_pl_n *)pa->ptr, 385 msgid, encrypted); 386 break; 387 case ISAKMP_NPTYPE_D: 388 error = isakmp_info_recv_d(iph1, 389 (struct isakmp_pl_d *)pa->ptr, 390 msgid, encrypted); 391 break; 392 case ISAKMP_NPTYPE_NONCE: 393 /* XXX to be 6.4.2 ike-01.txt */ 394 /* XXX IV is to be synchronized. */ 395 plog(ASL_LEVEL_ERR, 396 "ignore Acknowledged Informational\n"); 397 break; 398 default: 399 /* don't send information, see isakmp_ident_r1() */ 400 error = 0; 401 plog(ASL_LEVEL_ERR, 402 "reject the packet, " 403 "received unexpected payload type %s.\n", 404 s_isakmp_nptype(gen->np)); 405 } 406 if(error < 0) { 407 break; 408 } else { 409 flag |= error; 410 } 411 } 412 IPSECSESSIONTRACEREVENT(iph1->parent_session, 413 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC, 414 CONSTSTR("Information message"), 415 CONSTSTR(NULL)); 416 417end: 418 if (error) { 419 IPSECSESSIONTRACEREVENT(iph1->parent_session, 420 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL, 421 CONSTSTR("Information message"), 422 CONSTSTR("Failed to process Information Message")); 423 } 424 if (msg != NULL) 425 vfree(msg); 426 if (pbuf != NULL) 427 vfree(pbuf); 428 return error; 429} 430 431/* 432 * handling of Notification payload 433 */ 434static int 435isakmp_info_recv_n(phase1_handle_t *iph1, struct isakmp_pl_n *notify, u_int32_t msgid, int encrypted) 436{ 437 u_int type; 438 vchar_t *ndata; 439 char *nraw; 440 size_t l; 441 char *spi; 442 443 type = ntohs(notify->type); 444 445 switch (type) { 446 case ISAKMP_NTYPE_CONNECTED: 447 case ISAKMP_NTYPE_REPLAY_STATUS: 448#ifdef ENABLE_HYBRID 449 case ISAKMP_NTYPE_UNITY_HEARTBEAT: 450#endif 451 /* do something */ 452 break; 453 case ISAKMP_NTYPE_RESPONDER_LIFETIME: 454 if (encrypted) { 455 return(isakmp_ph1_responder_lifetime(iph1, 456 (struct isakmp_pl_resp_lifetime *)notify)); 457 } 458 break; 459 case ISAKMP_NTYPE_INITIAL_CONTACT: 460 if (encrypted) { 461 info_recv_initialcontact(iph1); 462 return 0; 463 } 464 break; 465#ifdef ENABLE_DPD 466 case ISAKMP_NTYPE_R_U_THERE: 467 if (encrypted) 468 return isakmp_info_recv_r_u(iph1, 469 (struct isakmp_pl_ru *)notify, msgid); 470 break; 471 case ISAKMP_NTYPE_R_U_THERE_ACK: 472 if (encrypted) 473 return isakmp_info_recv_r_u_ack(iph1, 474 (struct isakmp_pl_ru *)notify, msgid); 475 break; 476#endif 477#ifdef ENABLE_VPNCONTROL_PORT 478 case ISAKMP_NTYPE_LOAD_BALANCE: 479 isakmp_info_recv_lb(iph1, (struct isakmp_pl_lb *)notify, encrypted); 480 break; 481#endif 482 483 default: 484 { 485 /* XXX there is a potential of dos attack. */ 486 if(type >= ISAKMP_NTYPE_MINERROR && 487 type <= ISAKMP_NTYPE_MAXERROR) { 488 if (msgid == 0) { 489 /* don't think this realy deletes ph1 ? */ 490 plog(ASL_LEVEL_ERR, 491 "Delete Phase 1 handle.\n"); 492 return -1; 493 } else { 494 if (ike_session_getph2bymsgid(iph1, msgid) == NULL) { 495 plog(ASL_LEVEL_ERR, 496 "Fatal %s notify messsage, " 497 "Phase 1 should be deleted.\n", 498 s_isakmp_notify_msg(type)); 499 } else { 500 plog(ASL_LEVEL_ERR, 501 "Fatal %s notify messsage, " 502 "Phase 2 should be deleted.\n", 503 s_isakmp_notify_msg(type)); 504 } 505 } 506 } else { 507 plog(ASL_LEVEL_ERR, 508 "Unhandled notify message %s, " 509 "no Phase 2 handle found.\n", 510 s_isakmp_notify_msg(type)); 511 } 512 } 513 break; 514 } 515 516 /* get spi if specified and allocate */ 517 if(notify->spi_size > 0) { 518 if (ntohs(notify->h.len) < sizeof(*notify) + notify->spi_size) { 519 plog(ASL_LEVEL_ERR, 520 "Invalid spi_size in notification payload.\n"); 521 return -1; 522 } 523 spi = val2str((char *)(notify + 1), notify->spi_size); 524 525 plog(ASL_LEVEL_DEBUG, 526 "Notification message %d:%s, " 527 "doi=%d proto_id=%d spi=%s(size=%d).\n", 528 type, s_isakmp_notify_msg(type), 529 ntohl(notify->doi), notify->proto_id, spi, notify->spi_size); 530 531 racoon_free(spi); 532 } 533 534 /* Send the message data to the logs */ 535 if(type >= ISAKMP_NTYPE_MINERROR && 536 type <= ISAKMP_NTYPE_MAXERROR) { 537 l = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size; 538 if (l > 0) { 539 nraw = (char*)notify; 540 nraw += sizeof(*notify) + notify->spi_size; 541 if ((ndata = vmalloc(l)) != NULL) { 542 memcpy(ndata->v, nraw, ndata->l); 543 plog(ASL_LEVEL_ERR, 544 "Message: '%s'.\n", 545 binsanitize(ndata->v, ndata->l)); 546 vfree(ndata); 547 } else { 548 plog(ASL_LEVEL_ERR, 549 "Cannot allocate memory\n"); 550 } 551 } 552 } 553 return 0; 554} 555 556#ifdef ENABLE_VPNCONTROL_PORT 557static void 558isakmp_info_vpncontrol_notify_ike_failed (phase1_handle_t *iph1, int isakmp_info_initiator, int type, vchar_t *data) 559{ 560 u_int32_t address; 561 u_int32_t fail_reason; 562 563 /* notify the API that we have received the delete */ 564 if (iph1->remote->ss_family == AF_INET) 565 address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr; 566 else 567 address = 0; 568 569 if (isakmp_info_initiator == FROM_REMOTE) { 570 int premature = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_PREMATURE); 571 int expired = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_EXPIRED); 572 573 if (premature) { 574 fail_reason = VPNCTL_NTYPE_LOCAL_CERT_PREMATURE; 575 plog(ASL_LEVEL_NOTICE, ">>> Server reports client's certificate is pre-mature\n"); 576 } else if (expired) { 577 fail_reason = VPNCTL_NTYPE_LOCAL_CERT_EXPIRED; 578 plog(ASL_LEVEL_NOTICE, ">>> Server reports client's certificate is expired\n"); 579 } else { 580 fail_reason = type; 581 } 582 vpncontrol_notify_ike_failed(fail_reason, isakmp_info_initiator, address, 0, NULL); 583 return; 584 } else { 585 /* FROM_LOCAL */ 586 if (type == ISAKMP_INTERNAL_ERROR || 587 type <= ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS) { 588 int premature = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_PREMATURE); 589 int expired = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_EXPIRED); 590 int subjname = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_INVALID_SUBJNAME); 591 int subjaltname = oakley_find_status_in_certchain(iph1->cert_p, CERT_STATUS_INVALID_SUBJALTNAME); 592 593 if (premature) { 594 fail_reason = VPNCTL_NTYPE_PEER_CERT_PREMATURE; 595 plog(ASL_LEVEL_NOTICE, ">>> Server's certificate is pre-mature\n"); 596 } else if (expired) { 597 fail_reason = VPNCTL_NTYPE_PEER_CERT_EXPIRED; 598 plog(ASL_LEVEL_NOTICE, ">>> Server's certificate is expired\n"); 599 } else if (subjname) { 600 fail_reason = VPNCTL_NTYPE_PEER_CERT_INVALID_SUBJNAME; 601 plog(ASL_LEVEL_NOTICE, ">>> Server's certificate subject name not valid\n"); 602 } else if (subjaltname) { 603 fail_reason = VPNCTL_NTYPE_PEER_CERT_INVALID_SUBJALTNAME; 604 plog(ASL_LEVEL_NOTICE, ">>> Server's certificate subject alternate name not valid\n"); 605 } else { 606 fail_reason = type; 607 } 608 (void)vpncontrol_notify_ike_failed(fail_reason, isakmp_info_initiator, address, 609 (data ? data->l : 0), (u_int8_t *)(data ? data->v : NULL)); 610 return; 611 } 612 } 613} 614#endif /* ENABLE_VPNCONTROL_PORT */ 615 616/* 617 * handling of Deletion payload 618 */ 619static int 620isakmp_info_recv_d(phase1_handle_t *iph1, struct isakmp_pl_d *delete, u_int32_t msgid, int encrypted) 621{ 622 int tlen, num_spi; 623 phase1_handle_t *del_ph1; 624 union { 625 u_int32_t spi32; 626 u_int16_t spi16[2]; 627 } spi; 628 629 if (ntohl(delete->doi) != IPSEC_DOI) { 630 plog(ASL_LEVEL_ERR, 631 "delete payload with invalid doi:%d.\n", 632 ntohl(delete->doi)); 633#ifdef ENABLE_HYBRID 634 /* 635 * At deconnexion time, Cisco VPN client does this 636 * with a zero DOI. Don't give up in that situation. 637 */ 638 if (((iph1->mode_cfg->flags & 639 ISAKMP_CFG_VENDORID_UNITY) == 0) || (delete->doi != 0)) 640 return 0; 641#else 642 return 0; 643#endif 644 } 645 646 num_spi = ntohs(delete->num_spi); 647 tlen = ntohs(delete->h.len) - sizeof(struct isakmp_pl_d); 648 649 if (tlen != num_spi * delete->spi_size) { 650 plog(ASL_LEVEL_ERR, 651 "deletion payload with invalid length.\n"); 652 return 0; 653 } 654 655 plog(ASL_LEVEL_DEBUG, 656 "delete payload for protocol %s\n", 657 s_ipsecdoi_proto(delete->proto_id)); 658 659 if(!iph1->rmconf->weak_phase1_check && !encrypted) { 660 plog(ASL_LEVEL_WARNING, 661 "Ignoring unencrypted delete payload " 662 "(check the weak_phase1_check option)\n"); 663 return 0; 664 } 665 666 switch (delete->proto_id) { 667 case IPSECDOI_PROTO_ISAKMP: 668 if (delete->spi_size != sizeof(isakmp_index)) { 669 plog(ASL_LEVEL_ERR, 670 "delete payload with strange spi " 671 "size %d(proto_id:%d)\n", 672 delete->spi_size, delete->proto_id); 673 return 0; 674 } 675 676 del_ph1 = ike_session_getph1byindex(iph1->parent_session, (isakmp_index *)(delete + 1)); 677 if(del_ph1 != NULL){ 678 679 // hack: start a rekey now, if one was pending (only for client). 680 if (del_ph1->sce_rekey && 681 del_ph1->parent_session && 682 del_ph1->parent_session->is_client && 683 del_ph1->parent_session->established) { 684 isakmp_ph1rekeyexpire(del_ph1, FALSE); 685 } 686 687 if (del_ph1->scr) 688 SCHED_KILL(del_ph1->scr); 689 690 /* 691 * Do not delete IPsec SAs when receiving an IKE delete notification. 692 * Just delete the IKE SA. 693 */ 694#ifdef ENABLE_VPNCONTROL_PORT 695 if (del_ph1->started_by_api || (del_ph1->is_rekey && del_ph1->parent_session && del_ph1->parent_session->is_client)) { 696 if (ike_session_islast_ph1(del_ph1)) { 697 isakmp_info_vpncontrol_notify_ike_failed(del_ph1, FROM_REMOTE, VPNCTL_NTYPE_PH1_DELETE, NULL); 698 } 699 } 700#endif 701 if (del_ph1->rmconf->natt_multiple_user && 702 del_ph1->parent_session->is_l2tpvpn_ipsec) { 703 plog(ASL_LEVEL_DEBUG, "Ignoring IKE delete from peer for L2TP server\n"); 704 break; 705 } 706 isakmp_ph1expire(del_ph1); 707 } 708 break; 709 710 case IPSECDOI_PROTO_IPSEC_AH: 711 case IPSECDOI_PROTO_IPSEC_ESP: 712 if (delete->spi_size != sizeof(u_int32_t)) { 713 plog(ASL_LEVEL_ERR, 714 "delete payload with strange spi " 715 "size %d(proto_id:%d)\n", 716 delete->spi_size, delete->proto_id); 717 return 0; 718 } 719 if (iph1->rmconf->natt_multiple_user && 720 iph1->parent_session->is_l2tpvpn_ipsec) { 721 plog(ASL_LEVEL_DEBUG, "Ignoring SA delete from peer for L2TP server\n"); 722 break; 723 } 724 purge_ipsec_spi(iph1->remote, delete->proto_id, 725 ALIGNED_CAST(u_int32_t *)(delete + 1), num_spi, NULL, NULL); // Wcast-align fix (void*) - delete payload is aligned 726 break; 727 728 case IPSECDOI_PROTO_IPCOMP: 729 /* need to handle both 16bit/32bit SPI */ 730 memset(&spi, 0, sizeof(spi)); 731 if (delete->spi_size == sizeof(spi.spi16[1])) { 732 memcpy(&spi.spi16[1], delete + 1, 733 sizeof(spi.spi16[1])); 734 } else if (delete->spi_size == sizeof(spi.spi32)) 735 memcpy(&spi.spi32, delete + 1, sizeof(spi.spi32)); 736 else { 737 plog(ASL_LEVEL_ERR, 738 "delete payload with strange spi " 739 "size %d(proto_id:%d)\n", 740 delete->spi_size, delete->proto_id); 741 return 0; 742 } 743 purge_ipsec_spi(iph1->remote, delete->proto_id, 744 &spi.spi32, num_spi, NULL, NULL); 745 break; 746 747 default: 748 plog(ASL_LEVEL_ERR, 749 "deletion message received, " 750 "invalid proto_id: %d\n", 751 delete->proto_id); 752 return 0; 753 } 754 755 plog(ASL_LEVEL_DEBUG, "purged SAs.\n"); 756 757 return 0; 758} 759 760/* 761 * send Delete payload (for ISAKMP SA) in Informational exchange. 762 */ 763int 764isakmp_info_send_d1(phase1_handle_t *iph1) 765{ 766 struct isakmp_pl_d *d; 767 vchar_t *payload = NULL; 768 int tlen; 769 int error = 0; 770 771 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) 772 return 0; 773 774 /* create delete payload */ 775 776 /* send SPIs of inbound SAs. */ 777 /* XXX should send outbound SAs's ? */ 778 tlen = sizeof(*d) + sizeof(isakmp_index); 779 payload = vmalloc(tlen); 780 if (payload == NULL) { 781 plog(ASL_LEVEL_ERR, 782 "failed to get buffer for payload.\n"); 783 return errno; 784 } 785 786 d = (struct isakmp_pl_d *)payload->v; 787 d->h.np = ISAKMP_NPTYPE_NONE; 788 d->h.len = htons(tlen); 789 d->doi = htonl(IPSEC_DOI); 790 d->proto_id = IPSECDOI_PROTO_ISAKMP; 791 d->spi_size = sizeof(isakmp_index); 792 d->num_spi = htons(1); 793 memcpy(d + 1, &iph1->index, sizeof(isakmp_index)); 794 795 error = isakmp_info_send_common(iph1, payload, 796 ISAKMP_NPTYPE_D, 0); 797 vfree(payload); 798 if (error) { 799 IPSECSESSIONTRACEREVENT(iph1->parent_session, 800 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 801 CONSTSTR("Delete ISAKMP-SA"), 802 CONSTSTR("Failed to transmit Delete-ISAKMP-SA message")); 803 } else { 804 IPSECSESSIONTRACEREVENT(iph1->parent_session, 805 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, 806 CONSTSTR("Delete ISAKMP-SA"), 807 CONSTSTR(NULL)); 808 } 809 810 return error; 811} 812 813/* 814 * send Delete payload (for IPsec SA) in Informational exchange, based on 815 * pfkey msg. It sends always single SPI. 816 */ 817int 818isakmp_info_send_d2(phase2_handle_t *iph2) 819{ 820 phase1_handle_t *iph1; 821 struct saproto *pr; 822 struct isakmp_pl_d *d; 823 vchar_t *payload = NULL; 824 int tlen; 825 int error = 0; 826 u_int8_t *spi; 827 828 if (!FSM_STATE_IS_ESTABLISHED(iph2->status)) 829 return 0; 830 831 /* 832 * don't send delete information if there is no phase 1 handler. 833 * It's nonsensical to negotiate phase 1 to send the information. 834 */ 835 iph1 = ike_session_get_established_ph1(iph2->parent_session); 836 if (!iph1) { 837 iph1 = ike_session_getph1byaddr(iph2->parent_session, iph2->src, iph2->dst); 838 } 839 if (iph1 == NULL){ 840 IPSECSESSIONTRACEREVENT(iph2->parent_session, 841 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, 842 CONSTSTR("Information message"), 843 CONSTSTR("Failed to transmit Information message")); 844 IPSECSESSIONTRACEREVENT(iph2->parent_session, 845 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 846 CONSTSTR("Delete IPSEC-SA"), 847 CONSTSTR("Failed to transmit Delete-IPSEC-SA message")); 848 plog(ASL_LEVEL_DEBUG, 849 "No ph1 handler found, could not send DELETE_SA\n"); 850 return 0; 851 } 852 853 /* create delete payload */ 854 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 855 856 /* send SPIs of inbound SAs. */ 857 /* 858 * XXX should I send outbound SAs's ? 859 * I send inbound SAs's SPI only at the moment because I can't 860 * decode any more if peer send encoded packet without aware of 861 * deletion of SA. Outbound SAs don't come under the situation. 862 */ 863 tlen = sizeof(*d) + pr->spisize; 864 payload = vmalloc(tlen); 865 if (payload == NULL) { 866 IPSECSESSIONTRACEREVENT(iph2->parent_session, 867 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, 868 CONSTSTR("Information message"), 869 CONSTSTR("Failed to transmit Information message")); 870 IPSECSESSIONTRACEREVENT(iph2->parent_session, 871 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 872 CONSTSTR("Delete IPSEC-SA"), 873 CONSTSTR("Failed to transmit Delete-IPSEC-SA message")); 874 plog(ASL_LEVEL_ERR, 875 "failed to get buffer for payload.\n"); 876 return errno; 877 } 878 879 d = (struct isakmp_pl_d *)payload->v; 880 d->h.np = ISAKMP_NPTYPE_NONE; 881 d->h.len = htons(tlen); 882 d->doi = htonl(IPSEC_DOI); 883 d->proto_id = pr->proto_id; 884 d->spi_size = pr->spisize; 885 d->num_spi = htons(1); 886 /* 887 * XXX SPI bits are left-filled, for use with IPComp. 888 * we should be switching to variable-length spi field... 889 */ 890 spi = (u_int8_t *)&pr->spi; 891 spi += sizeof(pr->spi); 892 spi -= pr->spisize; 893 memcpy(d + 1, spi, pr->spisize); 894 895 error = isakmp_info_send_common(iph1, payload, 896 ISAKMP_NPTYPE_D, 0); 897 vfree(payload); 898 if (error) { 899 IPSECSESSIONTRACEREVENT(iph2->parent_session, 900 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 901 CONSTSTR("Delete IPSEC-SA"), 902 CONSTSTR("Failed to transmit Delete-IPSEC-SA")); 903 } else { 904 IPSECSESSIONTRACEREVENT(iph2->parent_session, 905 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, 906 CONSTSTR("Delete IPSEC-SA"), 907 CONSTSTR(NULL)); 908 } 909 } 910 911 return error; 912} 913 914/* 915 * send Notification payload (without ISAKMP SA) in an Informational exchange 916 */ 917int 918isakmp_info_send_nx(struct isakmp *isakmp, struct sockaddr_storage *remote, struct sockaddr_storage *local, 919 int type, vchar_t *data) 920{ 921 phase1_handle_t *iph1 = NULL; 922 struct remoteconf *rmconf; 923 vchar_t *payload = NULL; 924 int tlen; 925 int error = -1; 926 struct isakmp_pl_n *n; 927 int spisiz = 0; /* see below */ 928 ike_session_t *sess = ike_session_get_session(local, remote, FALSE, NULL); 929 930 /* search appropreate configuration */ 931 rmconf = getrmconf(remote); 932 if (rmconf == NULL) { 933 IPSECSESSIONTRACEREVENT(sess, 934 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, 935 CONSTSTR("Information message"), 936 CONSTSTR("Failed to transmit Information message (no remote configuration)")); 937 plog(ASL_LEVEL_ERR, 938 "no configuration found for peer address.\n"); 939 goto end; 940 } 941 942 /* add new entry to isakmp status table. */ 943 iph1 = ike_session_newph1(ISAKMP_VERSION_NUMBER_IKEV1); 944 if (iph1 == NULL) { 945 IPSECSESSIONTRACEREVENT(sess, 946 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, 947 CONSTSTR("Information message"), 948 CONSTSTR("Failed to transmit Information message (no new Phase 1)")); 949 plog(ASL_LEVEL_ERR, 950 "failed to allocate ph1"); 951 return -1; 952 } 953 954 memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t)); 955 isakmp_newcookie((char *)&iph1->index.r_ck, remote, local); 956 fsm_set_state(&iph1->status, IKEV1_STATE_INFO); 957 iph1->rmconf = rmconf; 958 retain_rmconf(iph1->rmconf); 959 iph1->side = INITIATOR; 960 iph1->version = isakmp->v; 961 iph1->flags = 0; 962 iph1->msgid = 0; /* XXX */ 963#ifdef ENABLE_HYBRID 964 if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) { 965 error = -1; 966 goto end; 967 } 968#endif 969#ifdef ENABLE_FRAG 970 iph1->frag = 0; 971 iph1->frag_chain = NULL; 972#endif 973 974 /* copy remote address */ 975 if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) { 976 IPSECSESSIONTRACEREVENT(sess, 977 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, 978 CONSTSTR("Information message"), 979 CONSTSTR("Failed to transmit Information Message (can't copy Phase 1 addresses)")); 980 plog(ASL_LEVEL_ERR, 981 "failed to copy ph1 addresses"); 982 error = -1; 983 iph1 = NULL; /* deleted in copy_ph1addresses */ 984 goto end; 985 } 986 987 tlen = sizeof(*n) + spisiz; 988 if (data) 989 tlen += data->l; 990 payload = vmalloc(tlen); 991 if (payload == NULL) { 992 IPSECSESSIONTRACEREVENT(sess, 993 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, 994 CONSTSTR("Information message"), 995 CONSTSTR("Failed to transmit Information Message (can't allocate payload)")); 996 plog(ASL_LEVEL_ERR, 997 "failed to get buffer to send.\n"); 998 error = -1; 999 goto end; 1000 } 1001 1002 n = (struct isakmp_pl_n *)payload->v; 1003 n->h.np = ISAKMP_NPTYPE_NONE; 1004 n->h.len = htons(tlen); 1005 n->doi = htonl(IPSEC_DOI); 1006 n->proto_id = IPSECDOI_KEY_IKE; 1007 n->spi_size = spisiz; 1008 n->type = htons(type); 1009 if (spisiz) 1010 memset(n + 1, 0, spisiz); /* XXX spisiz is always 0 */ 1011 if (data) 1012 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); 1013 1014#ifdef ENABLE_VPNCONTROL_PORT 1015 isakmp_info_vpncontrol_notify_ike_failed(iph1, FROM_LOCAL, type, data); 1016#endif 1017 if (ike_session_link_phase1(sess, iph1)) 1018 fatal_error(-1); 1019 1020 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); 1021 vfree(payload); 1022 if (error) { 1023 IPSECSESSIONTRACEREVENT(sess, 1024 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 1025 CONSTSTR("Without ISAKMP-SA"), 1026 CONSTSTR("Failed to transmit Without-ISAKMP-SA message")); 1027 } else { 1028 IPSECSESSIONTRACEREVENT(sess, 1029 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, 1030 CONSTSTR("Without ISAKMP-SA"), 1031 CONSTSTR(NULL)); 1032 } 1033 1034 end: 1035 if (iph1 != NULL) 1036 ike_session_unlink_phase1(iph1); 1037 1038 return error; 1039} 1040 1041/* 1042 * send Notification payload (with ISAKMP SA) in an Informational exchange 1043 */ 1044int 1045isakmp_info_send_n1(phase1_handle_t *iph1, int type, vchar_t *data) 1046{ 1047 vchar_t *payload = NULL; 1048 int tlen; 1049 int error = 0; 1050 struct isakmp_pl_n *n; 1051 int spisiz; 1052 1053 /* 1054 * note on SPI size: which description is correct? I have chosen 1055 * this to be 0. 1056 * 1057 * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by 1058 * Initiator/Responder cookie and SPI has no meaning, SPI size = 0. 1059 * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified 1060 * by cookie and SPI has no meaning, 0 <= SPI size <= 16. 1061 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16. 1062 */ 1063 if (type == ISAKMP_NTYPE_INITIAL_CONTACT || 1064 type == ISAKMP_NTYPE_LOAD_BALANCE) 1065 spisiz = sizeof(isakmp_index); 1066 else 1067 spisiz = 0; 1068 1069 tlen = sizeof(*n) + spisiz; 1070 if (data) 1071 tlen += data->l; 1072 payload = vmalloc(tlen); 1073 if (payload == NULL) { 1074 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1075 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 1076 CONSTSTR("ISAKMP-SA"), 1077 CONSTSTR("Failed to transmit ISAKMP-SA message (can't allocate payload)")); 1078 plog(ASL_LEVEL_ERR, 1079 "failed to get buffer to send.\n"); 1080 return errno; 1081 } 1082 1083 n = (struct isakmp_pl_n *)payload->v; 1084 n->h.np = ISAKMP_NPTYPE_NONE; 1085 n->h.len = htons(tlen); 1086 n->doi = htonl(iph1->rmconf->doitype); 1087 n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */ 1088 n->spi_size = spisiz; 1089 n->type = htons(type); 1090 if (spisiz) 1091 memcpy(n + 1, &iph1->index, sizeof(isakmp_index)); 1092 if (data) 1093 memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l); 1094 1095#ifdef ENABLE_VPNCONTROL_PORT 1096 isakmp_info_vpncontrol_notify_ike_failed(iph1, FROM_LOCAL, type, data); 1097#endif 1098 1099 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags); 1100 vfree(payload); 1101 if (error) { 1102 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1103 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 1104 CONSTSTR("ISAKMP-SA"), 1105 CONSTSTR("Can't transmit ISAKMP-SA message")); 1106 } else { 1107 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1108 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, 1109 CONSTSTR("ISAKMP-SA"), 1110 CONSTSTR(NULL)); 1111 } 1112 1113 return error; 1114} 1115 1116/* 1117 * send Notification payload (with IPsec SA) in an Informational exchange 1118 */ 1119int 1120isakmp_info_send_n2(phase2_handle_t *iph2, int type, vchar_t *data) 1121{ 1122 phase1_handle_t *iph1 = iph2->ph1; 1123 vchar_t *payload = NULL; 1124 int tlen; 1125 int error = 0; 1126 struct isakmp_pl_n *n; 1127 struct saproto *pr; 1128 1129 if (!iph2->approval) 1130 return EINVAL; 1131 1132 pr = iph2->approval->head; 1133 1134 /* XXX must be get proper spi */ 1135 tlen = sizeof(*n) + pr->spisize; 1136 if (data) 1137 tlen += data->l; 1138 payload = vmalloc(tlen); 1139 if (payload == NULL) { 1140 IPSECSESSIONTRACEREVENT(iph2->parent_session, 1141 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 1142 CONSTSTR("IPSEC-SA"), 1143 CONSTSTR("Failed to transmit IPSEC-SA message (can't allocate payload)")); 1144 plog(ASL_LEVEL_ERR, 1145 "failed to get buffer to send.\n"); 1146 return errno; 1147 } 1148 1149 n = (struct isakmp_pl_n *)payload->v; 1150 n->h.np = ISAKMP_NPTYPE_NONE; 1151 n->h.len = htons(tlen); 1152 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */ 1153 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ 1154 n->spi_size = pr->spisize; 1155 n->type = htons(type); 1156 memcpy(n + 1, &pr->spi, sizeof(u_int32_t)); // Wcast-align fix - copy instead of assign 1157 if (data) 1158 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); 1159 1160 iph2->flags |= ISAKMP_FLAG_E; /* XXX Should we do FLAG_A ? */ 1161 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags); 1162 vfree(payload); 1163 if (error) { 1164 IPSECSESSIONTRACEREVENT(iph2->parent_session, 1165 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 1166 CONSTSTR("IPSEC-SA"), 1167 CONSTSTR("Failed to transmit IPSEC-SA message")); 1168 } else { 1169 IPSECSESSIONTRACEREVENT(iph2->parent_session, 1170 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, 1171 CONSTSTR("IPSEC-SA"), 1172 CONSTSTR(NULL)); 1173 } 1174 1175 return error; 1176} 1177 1178/* 1179 * send Information 1180 * When ph1->skeyid_a == NULL, send message without encoding. 1181 */ 1182int 1183isakmp_info_send_common(phase1_handle_t *iph1, vchar_t *payload, u_int32_t np, int flags) 1184{ 1185 phase2_handle_t *iph2 = NULL; 1186 vchar_t *hash = NULL; 1187 struct isakmp *isakmp; 1188 struct isakmp_gen *gen; 1189 char *p; 1190 int tlen; 1191 int error = -1; 1192 1193 /* add new entry to isakmp status table */ 1194 iph2 = ike_session_newph2(ISAKMP_VERSION_NUMBER_IKEV1, PHASE2_TYPE_INFO); 1195 if (iph2 == NULL) { 1196 plog(ASL_LEVEL_ERR, 1197 "failed to allocate ph2"); 1198 goto end; 1199 } 1200 1201 iph2->dst = dupsaddr(iph1->remote); 1202 if (iph2->dst == NULL) { 1203 plog(ASL_LEVEL_ERR, 1204 "failed to duplicate remote address"); 1205 ike_session_delph2(iph2); 1206 goto end; 1207 } 1208 iph2->src = dupsaddr(iph1->local); 1209 if (iph2->src == NULL) { 1210 plog(ASL_LEVEL_ERR, 1211 "failed to duplicate local address"); 1212 ike_session_delph2(iph2); 1213 goto end; 1214 } 1215 switch (iph1->remote->ss_family) { 1216 case AF_INET: 1217#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) 1218 ((struct sockaddr_in *)iph2->dst)->sin_port = 0; 1219 ((struct sockaddr_in *)iph2->src)->sin_port = 0; 1220#endif 1221 break; 1222#ifdef INET6 1223 case AF_INET6: 1224#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) 1225 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0; 1226 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0; 1227#endif 1228 break; 1229#endif 1230 default: 1231 plog(ASL_LEVEL_ERR, 1232 "invalid family: %d\n", iph1->remote->ss_family); 1233 ike_session_delph2(iph2); 1234 goto end; 1235 } 1236 iph2->side = INITIATOR; 1237 fsm_set_state(&iph2->status, IKEV1_STATE_INFO); 1238 iph2->msgid = isakmp_newmsgid2(iph1); 1239 1240 /* get IV and HASH(1) if skeyid_a was generated. */ 1241 if (iph1->skeyid_a != NULL) { 1242 iph2->ivm = oakley_newiv2(iph1, iph2->msgid); 1243 if (iph2->ivm == NULL) { 1244 plog(ASL_LEVEL_ERR, 1245 "failed to generate IV"); 1246 ike_session_delph2(iph2); 1247 goto end; 1248 } 1249 1250 /* generate HASH(1) */ 1251 hash = oakley_compute_hash1(iph1, iph2->msgid, payload); 1252 if (hash == NULL) { 1253 plog(ASL_LEVEL_ERR, 1254 "failed to generate HASH"); 1255 ike_session_delph2(iph2); 1256 goto end; 1257 } 1258 1259 /* initialized total buffer length */ 1260 tlen = hash->l; 1261 tlen += sizeof(*gen); 1262 } else { 1263 /* IKE-SA is not established */ 1264 hash = NULL; 1265 1266 /* initialized total buffer length */ 1267 tlen = 0; 1268 } 1269 if ((flags & ISAKMP_FLAG_A) == 0) 1270 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E); 1271 else 1272 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); 1273 1274 ike_session_link_ph2_to_ph1(iph1, iph2); 1275 1276 tlen += sizeof(*isakmp) + payload->l; 1277 1278 /* create buffer for isakmp payload */ 1279 iph2->sendbuf = vmalloc(tlen); 1280 if (iph2->sendbuf == NULL) { 1281 plog(ASL_LEVEL_ERR, 1282 "failed to get buffer to send.\n"); 1283 goto err; 1284 } 1285 1286 /* create isakmp header */ 1287 isakmp = (struct isakmp *)iph2->sendbuf->v; 1288 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); 1289 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); 1290 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH; 1291 isakmp->v = iph1->version; 1292 isakmp->etype = ISAKMP_ETYPE_INFO; 1293 isakmp->flags = iph2->flags; 1294 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid)); 1295 isakmp->len = htonl(tlen); 1296 p = (char *)(isakmp + 1); 1297 1298 /* create HASH payload */ 1299 if (hash != NULL) { 1300 gen = (struct isakmp_gen *)p; 1301 gen->np = np & 0xff; 1302 gen->len = htons(sizeof(*gen) + hash->l); 1303 p += sizeof(*gen); 1304 memcpy(p, hash->v, hash->l); 1305 p += hash->l; 1306 } 1307 1308 /* add payload */ 1309 memcpy(p, payload->v, payload->l); 1310 p += payload->l; 1311 1312#ifdef HAVE_PRINT_ISAKMP_C 1313 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); 1314#endif 1315 1316 /* encoding */ 1317 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { 1318 vchar_t *tmp; 1319 1320 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive, 1321 iph2->ivm->iv); 1322 VPTRINIT(iph2->sendbuf); 1323 if (tmp == NULL) { 1324 plog(ASL_LEVEL_ERR, 1325 "failed to encrypt packet"); 1326 goto err; 1327 } 1328 iph2->sendbuf = tmp; 1329 } 1330 1331 /* HDR*, HASH(1), N */ 1332 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { 1333 plog(ASL_LEVEL_ERR, 1334 "failed to send packet"); 1335 VPTRINIT(iph2->sendbuf); 1336 goto err; 1337 } 1338 1339 plog(ASL_LEVEL_DEBUG, 1340 "sendto Information %s.\n", s_isakmp_nptype(np)); 1341 1342 /* 1343 * don't resend notify message because peer can use Acknowledged 1344 * Informational if peer requires the reply of the notify message. 1345 */ 1346 1347 /* XXX If Acknowledged Informational required, don't delete ph2handle */ 1348 error = 0; 1349 VPTRINIT(iph2->sendbuf); 1350 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1351 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC, 1352 CONSTSTR("Information message"), 1353 CONSTSTR(NULL)); 1354 1355 goto err; /* XXX */ 1356 1357end: 1358 if (error) { 1359 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1360 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL, 1361 CONSTSTR("Information message"), 1362 CONSTSTR("Failed to transmit Information message")); 1363 } 1364 if (hash) 1365 vfree(hash); 1366 return error; 1367 1368err: 1369 ike_session_unlink_phase2(iph2); 1370 goto end; 1371} 1372 1373/* 1374 * add a notify payload to buffer by reallocating buffer. 1375 * If buf == NULL, the function only create a notify payload. 1376 * 1377 * XXX Which is SPI to be included, inbound or outbound ? 1378 */ 1379vchar_t * 1380isakmp_add_pl_n(vchar_t *buf0, u_int8_t **np_p, int type, struct saproto *pr, vchar_t *data) 1381{ 1382 vchar_t *buf = NULL; 1383 struct isakmp_pl_n *n; 1384 int tlen; 1385 int oldlen = 0; 1386 1387 if (*np_p) 1388 **np_p = ISAKMP_NPTYPE_N; 1389 1390 tlen = sizeof(*n) + pr->spisize; 1391 1392 if (data) 1393 tlen += data->l; 1394 if (buf0) { 1395 oldlen = buf0->l; 1396 buf = vrealloc(buf0, buf0->l + tlen); 1397 } else 1398 buf = vmalloc(tlen); 1399 if (!buf) { 1400 plog(ASL_LEVEL_ERR, 1401 "failed to get a payload buffer.\n"); 1402 return NULL; 1403 } 1404 1405 n = (struct isakmp_pl_n *)(buf->v + oldlen); 1406 n->h.np = ISAKMP_NPTYPE_NONE; 1407 n->h.len = htons(tlen); 1408 n->doi = htonl(IPSEC_DOI); /* IPSEC DOI (1) */ 1409 n->proto_id = pr->proto_id; /* IPSEC AH/ESP/whatever*/ 1410 n->spi_size = pr->spisize; 1411 n->type = htons(type); 1412 memcpy(n + 1, &pr->spi, sizeof(u_int32_t)); // Wcast-align fix - copy instead of assign with cast 1413 if (data) 1414 memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l); 1415 1416 /* save the pointer of next payload type */ 1417 *np_p = &n->h.np; 1418 1419 return buf; 1420} 1421 1422 1423void 1424purge_ipsec_spi(struct sockaddr_storage *dst0, int proto, u_int32_t *spi /*network byteorder*/, size_t n, u_int32_t *inbound_spi, size_t *max_inbound_spi) 1425{ 1426 vchar_t *buf = NULL; 1427 struct sadb_msg *msg, *next, *end; 1428 struct sadb_sa *sa; 1429 struct sadb_lifetime *lt; 1430 struct sockaddr_storage *src, *dst; 1431 phase2_handle_t *iph2; 1432 u_int64_t created; 1433 size_t i, j = 0; 1434 caddr_t mhp[SADB_EXT_MAX + 1]; 1435 1436 buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto)); 1437 if (buf == NULL) { 1438 plog(ASL_LEVEL_DEBUG, 1439 "pfkey_dump_sadb returned nothing.\n"); 1440 return; 1441 } 1442 1443 msg = ALIGNED_CAST(struct sadb_msg *)buf->v; 1444 end = ALIGNED_CAST(struct sadb_msg *)(buf->v + buf->l); 1445 1446 while (msg < end) { 1447 if ((msg->sadb_msg_len << 3) < sizeof(*msg)) 1448 break; 1449 next = ALIGNED_CAST(struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); 1450 if (msg->sadb_msg_type != SADB_DUMP) { 1451 msg = next; 1452 continue; 1453 } 1454 1455 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { 1456 plog(ASL_LEVEL_ERR, 1457 "pfkey_check (%s)\n", ipsec_strerror()); 1458 msg = next; 1459 continue; 1460 } 1461 1462 sa = ALIGNED_CAST(struct sadb_sa *)(mhp[SADB_EXT_SA]); // Wcast-align fix (void*) - buffer of pointers to aligned structs 1463 if (!sa 1464 || !mhp[SADB_EXT_ADDRESS_SRC] 1465 || !mhp[SADB_EXT_ADDRESS_DST]) { 1466 msg = next; 1467 continue; 1468 } 1469 src = ALIGNED_CAST(struct sockaddr_storage*)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); // Wcast-align fix (void*) - buffer of pointers to aligned structs 1470 dst = ALIGNED_CAST(struct sockaddr_storage*)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1471 lt = ALIGNED_CAST(struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD]; 1472 if(lt != NULL) 1473 created = lt->sadb_lifetime_addtime; 1474 else 1475 created = 0; 1476 1477 if (sa->sadb_sa_state != SADB_SASTATE_MATURE 1478 && sa->sadb_sa_state != SADB_SASTATE_DYING) { 1479 msg = next; 1480 continue; 1481 } 1482 1483 /* XXX n^2 algorithm, inefficient */ 1484 1485 /* don't delete inbound SAs at the moment (just save them in inbound_spi) */ 1486 /* XXX should we remove SAs with opposite direction as well? */ 1487 if (CMPSADDR2(dst0, dst)) { 1488 msg = next; 1489 continue; 1490 } 1491 1492 for (i = 0; i < n; i++) { 1493 u_int32_t *i_spi; 1494 1495 if (spi[i] != sa->sadb_sa_spi) 1496 continue; 1497 1498 /* 1499 * delete a relative phase 2 handler. 1500 * continue to process if no relative phase 2 handler 1501 * exists. 1502 */ 1503 if (inbound_spi && max_inbound_spi && j < *max_inbound_spi) { 1504 i_spi = &inbound_spi[j]; 1505 } else { 1506 i_spi = NULL; 1507 } 1508 iph2 = ike_session_getph2bysaidx2(src, dst, proto, spi[i], i_spi); 1509 1510 pfkey_send_delete(lcconf->sock_pfkey, 1511 msg->sadb_msg_satype, 1512 IPSEC_MODE_ANY, 1513 src, dst, sa->sadb_sa_spi); 1514 1515 if(iph2 != NULL){ 1516 delete_spd(iph2); 1517 ike_session_unlink_phase2(iph2); 1518 if (i_spi) { 1519 j++; 1520 } 1521 } 1522 1523 plog(ASL_LEVEL_INFO, "Purged IPsec-SA proto_id=%s spi=%u.\n", 1524 s_ipsecdoi_proto(proto), 1525 ntohl(spi[i])); 1526 } 1527 1528 msg = next; 1529 } 1530 1531 if (max_inbound_spi) { 1532 *max_inbound_spi = j; 1533 } 1534 1535 if (buf) 1536 vfree(buf); 1537} 1538 1539/* 1540 * delete all phase2 sa relatived to the destination address. 1541 * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore 1542 * an INITIAL-CONTACT if we have contacted the peer. This matches the 1543 * Sun IKE behavior, and makes rekeying work much better when the peer 1544 * restarts. 1545 */ 1546void 1547info_recv_initialcontact(phase1_handle_t *iph1) 1548{ 1549 vchar_t *buf = NULL; 1550 struct sadb_msg *msg, *next, *end; 1551 struct sadb_sa *sa; 1552 struct sockaddr_storage *src, *dst; 1553 caddr_t mhp[SADB_EXT_MAX + 1]; 1554 int proto_id, i; 1555 phase2_handle_t *iph2; 1556#if 0 1557 char *loc, *rem; 1558#endif 1559 1560 if (f_local) 1561 return; 1562 1563 // TODO: make sure that is_rekey is cleared for this. and session indicates the same 1564#if 0 1565 loc = racoon_strdup(saddrwop2str(iph1->local)); 1566 rem = racoon_strdup(saddrwop2str(iph1->remote)); 1567 STRDUP_FATAL(loc); 1568 STRDUP_FATAL(rem); 1569 1570 /* 1571 * Purge all IPSEC-SAs for the peer. We can do this 1572 * the easy way (using a PF_KEY SADB_DELETE extension) 1573 * or we can do it the hard way. 1574 */ 1575 for (i = 0; i < pfkey_nsatypes; i++) { 1576 proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype); 1577 1578 plog(ASL_LEVEL_INFO, 1579 "purging %s SAs for %s -> %s\n", 1580 pfkey_satypes[i].ps_name, loc, rem); 1581 if (pfkey_send_delete_all(lcconf->sock_pfkey, 1582 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, 1583 iph1->local, iph1->remote) == -1) { 1584 plog(ASL_LEVEL_ERR, 1585 "delete_all %s -> %s failed for %s (%s)\n", 1586 loc, rem, 1587 pfkey_satypes[i].ps_name, ipsec_strerror()); 1588 goto the_hard_way; 1589 } 1590 1591 ike_session_deleteallph2(iph1->local, iph1->remote, proto_id); 1592 1593 plog(ASL_LEVEL_INFO, 1594 "purging %s SAs for %s -> %s\n", 1595 pfkey_satypes[i].ps_name, rem, loc); 1596 if (pfkey_send_delete_all(lcconf->sock_pfkey, 1597 pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY, 1598 iph1->remote, iph1->local) == -1) { 1599 plog(ASL_LEVEL_ERR, 1600 "delete_all %s -> %s failed for %s (%s)\n", 1601 rem, loc, 1602 pfkey_satypes[i].ps_name, ipsec_strerror()); 1603 goto the_hard_way; 1604 } 1605 1606 ike_session_deleteallph2(iph1->remote, iph1->local, proto_id); 1607 } 1608 1609 racoon_free(loc); 1610 racoon_free(rem); 1611 return; 1612 1613 the_hard_way: 1614 racoon_free(loc); 1615 racoon_free(rem); 1616#endif 1617 1618 buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC); 1619 if (buf == NULL) { 1620 plog(ASL_LEVEL_DEBUG, 1621 "pfkey_dump_sadb returned nothing.\n"); 1622 return; 1623 } 1624 1625 msg = ALIGNED_CAST(struct sadb_msg *)buf->v; 1626 end = ALIGNED_CAST(struct sadb_msg *)(buf->v + buf->l); 1627 1628 while (msg < end) { 1629 if ((msg->sadb_msg_len << 3) < sizeof(*msg)) 1630 break; 1631 next = ALIGNED_CAST(struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3)); 1632 if (msg->sadb_msg_type != SADB_DUMP) { 1633 msg = next; 1634 continue; 1635 } 1636 1637 if (pfkey_align(msg, mhp) || pfkey_check(mhp)) { 1638 plog(ASL_LEVEL_ERR, 1639 "pfkey_check (%s)\n", ipsec_strerror()); 1640 msg = next; 1641 continue; 1642 } 1643 1644 if (mhp[SADB_EXT_SA] == NULL 1645 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 1646 || mhp[SADB_EXT_ADDRESS_DST] == NULL) { 1647 msg = next; 1648 continue; 1649 } 1650 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA]; // Wcast-align fix (void*) - buffer of pointers to aligned structs 1651 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 1652 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1653 1654 if (sa->sadb_sa_state != SADB_SASTATE_MATURE 1655 && sa->sadb_sa_state != SADB_SASTATE_DYING) { 1656 msg = next; 1657 continue; 1658 } 1659 1660 /* 1661 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that 1662 * announces the sender of the message was rebooted. 1663 * it is interpreted to delete all SAs which source address 1664 * is the sender of the message. 1665 * racoon only deletes SA which is matched both the 1666 * source address and the destination accress. 1667 */ 1668#ifdef ENABLE_NATT 1669 /* 1670 * XXX RFC 3947 says that whe MUST NOT use IP+port to find old SAs 1671 * from this peer ! 1672 */ 1673 if(iph1->natt_flags & NAT_DETECTED){ 1674 if (CMPSADDR(iph1->local, src) == 0 && 1675 CMPSADDR(iph1->remote, dst) == 0) 1676 ; 1677 else if (CMPSADDR(iph1->remote, src) == 0 && 1678 CMPSADDR(iph1->local, dst) == 0) 1679 ; 1680 else { 1681 msg = next; 1682 continue; 1683 } 1684 } else 1685#endif 1686 /* If there is no NAT-T, we don't have to check addr + port... 1687 * XXX what about a configuration with a remote peers which is not 1688 * NATed, but which NATs some other peers ? 1689 * Here, the INITIAl-CONTACT would also flush all those NATed peers !! 1690 */ 1691 if (cmpsaddrwop(iph1->local, src) == 0 && 1692 cmpsaddrwop(iph1->remote, dst) == 0) 1693 ; 1694 else if (cmpsaddrwop(iph1->remote, src) == 0 && 1695 cmpsaddrwop(iph1->local, dst) == 0) 1696 ; 1697 else { 1698 msg = next; 1699 continue; 1700 } 1701 1702 /* 1703 * Make sure this is an SATYPE that we manage. 1704 * This is gross; too bad we couldn't do it the 1705 * easy way. 1706 */ 1707 for (i = 0; i < pfkey_nsatypes; i++) { 1708 if (pfkey_satypes[i].ps_satype == 1709 msg->sadb_msg_satype) 1710 break; 1711 } 1712 if (i == pfkey_nsatypes) { 1713 msg = next; 1714 continue; 1715 } 1716 1717 plog(ASL_LEVEL_INFO, 1718 "purging spi=%u.\n", ntohl(sa->sadb_sa_spi)); 1719 pfkey_send_delete(lcconf->sock_pfkey, 1720 msg->sadb_msg_satype, 1721 IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi); 1722 1723 /* 1724 * delete a relative phase 2 handler. 1725 * continue to process if no relative phase 2 handler 1726 * exists. 1727 */ 1728 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); 1729 iph2 = ike_session_getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); 1730 if (iph2) { 1731 delete_spd(iph2); 1732 ike_session_unlink_phase2(iph2); 1733 } 1734 1735 msg = next; 1736 } 1737 1738 vfree(buf); 1739} 1740 1741void 1742isakmp_check_notify(struct isakmp_gen *gen /* points to Notify payload */, phase1_handle_t *iph1) 1743{ 1744 struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen; 1745 1746 plog(ASL_LEVEL_DEBUG, 1747 "Notify Message received\n"); 1748 1749 switch (ntohs(notify->type)) { 1750 case ISAKMP_NTYPE_CONNECTED: 1751 case ISAKMP_NTYPE_RESPONDER_LIFETIME: 1752 case ISAKMP_NTYPE_REPLAY_STATUS: 1753 case ISAKMP_NTYPE_HEARTBEAT: 1754#ifdef ENABLE_HYBRID 1755 case ISAKMP_NTYPE_UNITY_HEARTBEAT: 1756#endif 1757 plog(ASL_LEVEL_WARNING, 1758 "Ignore %s notification.\n", 1759 s_isakmp_notify_msg(ntohs(notify->type))); 1760 break; 1761 case ISAKMP_NTYPE_INITIAL_CONTACT: 1762 plog(ASL_LEVEL_WARNING, 1763 "Ignore INITIAL-CONTACT notification, " 1764 "because it is only accepted after Phase 1.\n"); 1765 break; 1766 case ISAKMP_NTYPE_LOAD_BALANCE: 1767 plog(ASL_LEVEL_WARNING, 1768 "Ignore LOAD-BALANCE notification, " 1769 "because it is only accepted after Phase 1.\n"); 1770 break; 1771 default: 1772 isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); 1773 plog(ASL_LEVEL_ERR, 1774 "Received unknown notification type %s.\n", 1775 s_isakmp_notify_msg(ntohs(notify->type))); 1776 } 1777 1778 return; 1779} 1780 1781void 1782isakmp_check_ph2_notify(struct isakmp_gen *gen /* points to Notify payload */, phase2_handle_t *iph2) 1783{ 1784 struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen; 1785 1786 plog(ASL_LEVEL_DEBUG, 1787 "Phase 2 Notify Message received\n"); 1788 1789 switch (ntohs(notify->type)) { 1790 case ISAKMP_NTYPE_RESPONDER_LIFETIME: 1791 return((void)isakmp_ph2_responder_lifetime(iph2, 1792 (struct isakmp_pl_resp_lifetime *)notify)); 1793 break; 1794 case ISAKMP_NTYPE_CONNECTED: 1795 case ISAKMP_NTYPE_REPLAY_STATUS: 1796 case ISAKMP_NTYPE_HEARTBEAT: 1797#ifdef ENABLE_HYBRID 1798 case ISAKMP_NTYPE_UNITY_HEARTBEAT: 1799#endif 1800 plog(ASL_LEVEL_WARNING, 1801 "Ignore %s notification.\n", 1802 s_isakmp_notify_msg(ntohs(notify->type))); 1803 break; 1804 case ISAKMP_NTYPE_INITIAL_CONTACT: 1805 plog(ASL_LEVEL_WARNING, 1806 "Ignore INITIAL-CONTACT notification, " 1807 "because it is only accepted after Phase 1.\n"); 1808 break; 1809 case ISAKMP_NTYPE_LOAD_BALANCE: 1810 plog(ASL_LEVEL_WARNING, 1811 "Ignore LOAD-BALANCE notification, " 1812 "because it is only accepted after Phase 1.\n"); 1813 break; 1814 default: 1815 isakmp_info_send_n1(iph2->ph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL); 1816 plog(ASL_LEVEL_ERR, 1817 "Received unknown notification type %s.\n", 1818 s_isakmp_notify_msg(ntohs(notify->type))); 1819 } 1820 1821 return; 1822} 1823 1824#ifdef ENABLE_VPNCONTROL_PORT 1825static int 1826isakmp_info_recv_lb(phase1_handle_t *iph1, struct isakmp_pl_lb *n, int encrypted) 1827{ 1828 1829 if (iph1->side != INITIATOR) 1830 { 1831 plog(ASL_LEVEL_DEBUG, 1832 "LOAD-BALANCE notification ignored - we are not the initiator.\n"); 1833 return 0; 1834 } 1835 if (iph1->remote->ss_family != AF_INET) { 1836 plog(ASL_LEVEL_DEBUG, 1837 "LOAD-BALANCE notification ignored - only supported for IPv4.\n"); 1838 return 0; 1839 } 1840 if (!encrypted) { 1841 plog(ASL_LEVEL_DEBUG, 1842 "LOAD-BALANCE notification ignored - not protected.\n"); 1843 return 0; 1844 } 1845 if (ntohs(n->h.len) != sizeof(struct isakmp_pl_lb)) { 1846 plog(ASL_LEVEL_DEBUG, 1847 "Invalid length of payload\n"); 1848 return -1; 1849 } 1850 vpncontrol_notify_ike_failed(ISAKMP_NTYPE_LOAD_BALANCE, FROM_REMOTE, 1851 ((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr, 4, (u_int8_t*)(&(n->address))); 1852 1853 plog(ASL_LEVEL_NOTICE, 1854 "Received LOAD_BALANCE notification.\n"); 1855 1856 if (((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr != ntohl(n->address)) { 1857 plog(ASL_LEVEL_DEBUG, 1858 "Deleting old Phase 1 because of LOAD_BALANCE notification - redirect address=%x.\n", 1859 ntohl(n->address)); 1860 1861 if (FSM_STATE_IS_ESTABLISHED(iph1->status)) { 1862 isakmp_info_send_d1(iph1); 1863 } 1864 isakmp_ph1expire(iph1); 1865 } 1866 1867 return 0; 1868} 1869#endif 1870 1871#ifdef ENABLE_DPD 1872static int 1873isakmp_info_recv_r_u (phase1_handle_t *iph1, struct isakmp_pl_ru *ru, u_int32_t msgid) 1874{ 1875 struct isakmp_pl_ru *ru_ack; 1876 vchar_t *payload = NULL; 1877 int tlen; 1878 int error = 0; 1879 1880 plog(ASL_LEVEL_DEBUG, 1881 "DPD R-U-There received\n"); 1882 1883 /* XXX should compare cookies with iph1->index? 1884 Or is this already done by calling function? */ 1885 tlen = sizeof(*ru_ack); 1886 payload = vmalloc(tlen); 1887 if (payload == NULL) { 1888 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1889 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 1890 CONSTSTR("R-U-THERE? ACK"), 1891 CONSTSTR("Failed to transmit DPD response")); 1892 plog(ASL_LEVEL_ERR, 1893 "failed to get buffer to send.\n"); 1894 return errno; 1895 } 1896 1897 ru_ack = (struct isakmp_pl_ru *)payload->v; 1898 ru_ack->h.np = ISAKMP_NPTYPE_NONE; 1899 ru_ack->h.len = htons(tlen); 1900 ru_ack->doi = htonl(IPSEC_DOI); 1901 ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK); 1902 ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */ 1903 ru_ack->spi_size = sizeof(isakmp_index); 1904 memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t)); 1905 memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t)); 1906 ru_ack->data = ru->data; 1907 1908 /* XXX Should we do FLAG_A ? */ 1909 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 1910 ISAKMP_FLAG_E); 1911 vfree(payload); 1912 if (error) { 1913 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1914 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 1915 CONSTSTR("R-U-THERE? ACK"), 1916 CONSTSTR("Failed to transmit DPD ack")); 1917 } else { 1918 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1919 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, 1920 CONSTSTR("R-U-THERE? ACK"), 1921 CONSTSTR(NULL)); 1922 } 1923 1924 plog(ASL_LEVEL_DEBUG, "received a valid R-U-THERE, ACK sent\n"); 1925 1926 /* Should we mark tunnel as active ? */ 1927 return error; 1928} 1929 1930static int 1931isakmp_info_recv_r_u_ack (phase1_handle_t *iph1, struct isakmp_pl_ru *ru, u_int32_t msgid) 1932{ 1933 1934 plog(ASL_LEVEL_DEBUG, 1935 "DPD R-U-There-Ack received\n"); 1936 1937 /* XXX Maintain window of acceptable sequence numbers ? 1938 * => ru->data <= iph2->dpd_seq && 1939 * ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */ 1940 if (ntohl(ru->data) != iph1->dpd_seq) { 1941 plog(ASL_LEVEL_ERR, 1942 "Wrong DPD sequence number (%d, %d expected).\n", 1943 ntohl(ru->data), iph1->dpd_seq); 1944 return 0; 1945 } 1946 1947 if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) || 1948 memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) { 1949 plog(ASL_LEVEL_ERR, 1950 "Cookie mismatch in DPD ACK!.\n"); 1951 return 0; 1952 } 1953 1954 iph1->dpd_fails = 0; 1955 1956 iph1->dpd_seq++; 1957 1958 /* Useless ??? */ 1959 iph1->dpd_lastack = time(NULL); 1960 1961 SCHED_KILL(iph1->dpd_r_u); 1962 1963 isakmp_sched_r_u(iph1, 0); 1964 1965 if (iph1->side == INITIATOR) { 1966 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1967 IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RESP, 1968 CONSTSTR("Initiator DPD Response"), 1969 CONSTSTR(NULL)); 1970 } else { 1971 IPSECSESSIONTRACEREVENT(iph1->parent_session, 1972 IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RESP, 1973 CONSTSTR("Responder DPD Response"), 1974 CONSTSTR(NULL)); 1975 } 1976 plog(ASL_LEVEL_DEBUG, "received an R-U-THERE-ACK\n"); 1977 1978#ifdef ENABLE_VPNCONTROL_PORT 1979 vpncontrol_notify_peer_resp_ph1(1, iph1); 1980#endif /* ENABLE_VPNCONTROL_PORT */ 1981 1982 return 0; 1983} 1984 1985 1986/* 1987 * send Delete payload (for ISAKMP SA) in Informational exchange. 1988 */ 1989void 1990isakmp_info_send_r_u(void *arg) 1991{ 1992 phase1_handle_t *iph1 = arg; 1993 1994 /* create R-U-THERE payload */ 1995 struct isakmp_pl_ru *ru; 1996 vchar_t *payload = NULL; 1997 int tlen; 1998 int error = 0; 1999 2000 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) { 2001 plog(ASL_LEVEL_DEBUG, "DPD r-u send aborted, invalid Phase 1 status %d....\n", 2002 iph1->status); 2003 return; 2004 } 2005 2006 if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) { 2007 u_int32_t address; 2008 2009 IPSECSESSIONTRACEREVENT(iph1->parent_session, 2010 IPSECSESSIONEVENTCODE_IKEV1_DPD_MAX_RETRANSMIT, 2011 CONSTSTR("DPD maximum retransmits"), 2012 CONSTSTR("maxed-out of DPD requests without receiving an ack")); 2013 2014 if (iph1->remote->ss_family == AF_INET) 2015 address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr; 2016 else 2017 address = 0; 2018 (void)vpncontrol_notify_ike_failed(VPNCTL_NTYPE_PEER_DEAD, FROM_LOCAL, address, 0, NULL); 2019 2020 purge_remote(iph1); 2021 plog(ASL_LEVEL_DEBUG, 2022 "DPD: remote seems to be dead\n"); 2023 2024 /* Do not reschedule here: phase1 is deleted, 2025 * DPD will be reactivated when a new ph1 will be negociated 2026 */ 2027 return; 2028 } 2029 2030 tlen = sizeof(*ru); 2031 payload = vmalloc(tlen); 2032 if (payload == NULL) { 2033 IPSECSESSIONTRACEREVENT(iph1->parent_session, 2034 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 2035 CONSTSTR("R-U-THERE?"), 2036 CONSTSTR("Failed to transmit DPD request")); 2037 plog(ASL_LEVEL_ERR, 2038 "failed to get buffer for payload.\n"); 2039 return; 2040 } 2041 ru = (struct isakmp_pl_ru *)payload->v; 2042 ru->h.np = ISAKMP_NPTYPE_NONE; 2043 ru->h.len = htons(tlen); 2044 ru->doi = htonl(IPSEC_DOI); 2045 ru->type = htons(ISAKMP_NTYPE_R_U_THERE); 2046 ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/ 2047 ru->spi_size = sizeof(isakmp_index); 2048 2049 memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)); 2050 memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t)); 2051 2052 if (iph1->dpd_seq == 0){ 2053 /* generate a random seq which is not too big */ 2054 srand(time(NULL)); 2055 iph1->dpd_seq = rand() & 0x0fff; 2056 } 2057 2058 ru->data = htonl(iph1->dpd_seq); 2059 2060 error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0); 2061 vfree(payload); 2062 if (error) { 2063 IPSECSESSIONTRACEREVENT(iph1->parent_session, 2064 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_FAIL, 2065 CONSTSTR("R-U-THERE?"), 2066 CONSTSTR("Failed to transmit DPD request")); 2067 } else { 2068 IPSECSESSIONTRACEREVENT(iph1->parent_session, 2069 IPSECSESSIONEVENTCODE_IKEV1_INFO_NOTICE_TX_SUCC, 2070 CONSTSTR("R-U-THERE?"), 2071 CONSTSTR(NULL)); 2072 } 2073 2074 if (iph1->side == INITIATOR) { 2075 IPSECSESSIONTRACEREVENT(iph1->parent_session, 2076 iph1->dpd_fails? IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_RETRANSMIT : IPSECSESSIONEVENTCODE_IKEV1_DPD_INIT_REQ, 2077 CONSTSTR("Initiator DPD Request"), 2078 CONSTSTR(NULL)); 2079 } else { 2080 IPSECSESSIONTRACEREVENT(iph1->parent_session, 2081 iph1->dpd_fails? IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_RETRANSMIT : IPSECSESSIONEVENTCODE_IKEV1_DPD_RESP_REQ, 2082 CONSTSTR("Responder DPD Request"), 2083 CONSTSTR(NULL)); 2084 } 2085 plog(ASL_LEVEL_DEBUG, 2086 "DPD R-U-There sent (%d)\n", error); 2087 2088 /* will be decreased if ACK received... */ 2089 iph1->dpd_fails++; 2090 2091 /* Reschedule the r_u_there with a short delay, 2092 * will be deleted/rescheduled if ACK received before */ 2093 isakmp_sched_r_u(iph1, 1); 2094 2095 plog(ASL_LEVEL_DEBUG, 2096 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry); 2097} 2098 2099/* 2100 * monitor DPD (ALGORITHM_INBOUND_DETECT) Informational exchange. 2101 */ 2102static void 2103isakmp_info_monitor_r_u_algo_inbound_detect (phase1_handle_t *iph1) 2104{ 2105 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) { 2106 plog(ASL_LEVEL_DEBUG, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) aborted, invalid Phase 1 status %d....\n", 2107 iph1->status); 2108 return; 2109 } 2110 2111 plog(ASL_LEVEL_DEBUG, "DPD monitoring (for ALGORITHM_INBOUND_DETECT) ....\n"); 2112 2113 // check phase1 for ike packets received from peer 2114 if (iph1->peer_sent_ike) { 2115 // yes, reshedule check 2116 iph1->peer_sent_ike = 0; 2117 2118 /* ike packets received from peer... reschedule dpd */ 2119 isakmp_sched_r_u(iph1, 0); 2120 2121 plog(ASL_LEVEL_DEBUG, 2122 "ike packets received from peer... reschedule monitor.\n"); 2123 2124 return; 2125 } 2126 2127 // after ike packets, next we check if any data was received 2128 if (!iph1->parent_session->peer_sent_data_sc_dpd) { 2129 isakmp_info_send_r_u(iph1); 2130 } else { 2131 isakmp_sched_r_u(iph1, 0); 2132 2133 plog(ASL_LEVEL_DEBUG, 2134 "rescheduling DPD monitoring (for ALGORITHM_INBOUND_DETECT).\n"); 2135 } 2136 iph1->parent_session->peer_sent_data_sc_dpd = 0; 2137} 2138 2139/* 2140 * monitor DPD (ALGORITHM_BLACKHOLE_DETECT) Informational exchange. 2141 */ 2142static void 2143isakmp_info_monitor_r_u_algo_blackhole_detect (phase1_handle_t *iph1) 2144{ 2145 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) { 2146 plog(ASL_LEVEL_DEBUG, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) aborted, invalid Phase 1 status %d....\n", 2147 iph1->status); 2148 return; 2149 } 2150 2151 plog(ASL_LEVEL_DEBUG, "DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) ....\n"); 2152 2153 // check if data was sent but none was received 2154 if (iph1->parent_session->i_sent_data_sc_dpd && 2155 !iph1->parent_session->peer_sent_data_sc_dpd) { 2156 isakmp_info_send_r_u(iph1); 2157 } else { 2158 isakmp_sched_r_u(iph1, 0); 2159 2160 plog(ASL_LEVEL_DEBUG, 2161 "rescheduling DPD monitoring (for ALGORITHM_BLACKHOLE_DETECT) i = %d, peer %d.\n", 2162 iph1->parent_session->i_sent_data_sc_dpd, 2163 iph1->parent_session->peer_sent_data_sc_dpd); 2164 } 2165 iph1->parent_session->i_sent_data_sc_dpd = 0; 2166 iph1->parent_session->peer_sent_data_sc_dpd = 0; 2167} 2168 2169/* 2170 * monitor DPD Informational exchange. 2171 */ 2172static void 2173isakmp_info_monitor_r_u(void *arg) 2174{ 2175 phase1_handle_t *iph1 = arg; 2176 2177 if (iph1 && iph1->rmconf) { 2178 if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT) { 2179 isakmp_info_monitor_r_u_algo_inbound_detect(iph1); 2180 } else if (iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) { 2181 isakmp_info_monitor_r_u_algo_blackhole_detect(iph1); 2182 } else { 2183 plog(ASL_LEVEL_DEBUG, "DPD monitoring aborted, invalid algorithm %d....\n", 2184 iph1->rmconf->dpd_algo); 2185 } 2186 } 2187} 2188 2189/* Schedule a new R-U-THERE */ 2190int 2191isakmp_sched_r_u(phase1_handle_t *iph1, int retry) 2192{ 2193 if(iph1 == NULL || 2194 iph1->rmconf == NULL) 2195 return 1; 2196 2197 2198 if(iph1->dpd_support == 0 || 2199 iph1->rmconf->dpd_interval == 0) 2200 return 0; 2201 2202 if(retry) { 2203 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry, 2204 isakmp_info_send_r_u, iph1); 2205 } else { 2206 if (iph1->rmconf->dpd_algo == DPD_ALGO_INBOUND_DETECT || 2207 iph1->rmconf->dpd_algo == DPD_ALGO_BLACKHOLE_DETECT) { 2208 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval, 2209 isakmp_info_monitor_r_u, iph1); 2210 } else { 2211 iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_interval, 2212 isakmp_info_send_r_u, iph1); 2213 } 2214 } 2215 2216 return 0; 2217} 2218 2219/* 2220 * punts dpd for later because of some activity that: 2221 * 1) implicitly does dpd (e.g. phase2 exchanges), or 2222 * 2) indicates liveness (e.g. received ike packets). 2223 */ 2224void 2225isakmp_reschedule_info_monitor_if_pending (phase1_handle_t *iph1, char *reason) 2226{ 2227 if (!iph1 || 2228 !FSM_STATE_IS_ESTABLISHED(iph1->status) || 2229 !iph1->dpd_support || 2230 !iph1->rmconf->dpd_interval || 2231 iph1->rmconf->dpd_algo == DPD_ALGO_DEFAULT) { 2232 return; 2233 } 2234 2235 if (!iph1->peer_sent_ike) { 2236 SCHED_KILL(iph1->dpd_r_u); 2237 2238 isakmp_sched_r_u(iph1, 0); 2239 2240 plog(ASL_LEVEL_DEBUG, 2241 "%s... rescheduling send_r_u.\n", 2242 reason); 2243 } 2244 iph1->peer_sent_ike++; 2245} 2246#endif 2247