1/* $Id: pfkey.c,v 1.31.2.10 2005/10/03 14:52:19 manubsd Exp $ */ 2 3/* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include "config.h" 33#include "racoon_types.h" 34 35#include <stdlib.h> 36#include <string.h> 37#include <stdio.h> 38#include <netdb.h> 39#include <errno.h> 40#ifdef HAVE_UNISTD_H 41#include <unistd.h> 42#endif 43#include <netdb.h> 44#include <netinet/in.h> 45#include <arpa/inet.h> 46 47#ifdef ENABLE_NATT 48#include <netinet/udp.h> 49#endif 50 51#include <sys/types.h> 52#include <sys/param.h> 53#include <sys/socket.h> 54#include <sys/queue.h> 55#include <sys/sysctl.h> 56 57#include <net/route.h> 58#include <net/pfkeyv2.h> 59 60#include <netinet/in.h> 61#ifndef HAVE_NETINET6_IPSEC 62#include <netinet/ipsec.h> 63#else 64#include <netinet6/ipsec.h> 65#endif 66 67#include "libpfkey.h" 68 69#include "var.h" 70#include "misc.h" 71#include "vmbuf.h" 72#include "plog.h" 73#include "sockmisc.h" 74#include "debug.h" 75#include "fsm.h" 76#include "ike_session.h" 77 78#include "schedule.h" 79#include "localconf.h" 80#include "remoteconf.h" 81#include "isakmp_var.h" 82#include "isakmp.h" 83#include "isakmp_inf.h" 84#include "ipsec_doi.h" 85#include "oakley.h" 86#include "pfkey.h" 87#include "handler.h" 88#include "policy.h" 89#include "algorithm.h" 90#include "sainfo.h" 91#include "proposal.h" 92#include "strnames.h" 93#include "gcmalloc.h" 94#include "nattraversal.h" 95#include "crypto_openssl.h" 96#include "grabmyaddr.h" 97#include "vpn_control.h" 98#include "vpn_control_var.h" 99#include "ike_session.h" 100#include "ipsecSessionTracer.h" 101#include "ipsecMessageTracer.h" 102#include "power_mgmt.h" 103#include "session.h" 104 105#if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC) 106#define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC 107#endif 108 109/* prototype */ 110static u_int ipsecdoi2pfkey_aalg (u_int); 111static u_int ipsecdoi2pfkey_ealg (u_int); 112static u_int ipsecdoi2pfkey_calg (u_int); 113static u_int ipsecdoi2pfkey_alg (u_int, u_int); 114static u_int keylen_aalg (u_int); 115static u_int keylen_ealg (u_int, int); 116 117static int pk_recvgetspi (caddr_t *); 118static int pk_recvupdate (caddr_t *); 119static int pk_recvadd (caddr_t *); 120static int pk_recvdelete (caddr_t *); 121static int pk_recvacquire (caddr_t *); 122static int pk_recvexpire (caddr_t *); 123static int pk_recvflush (caddr_t *); 124static int getsadbpolicy (caddr_t *, int *, int, phase2_handle_t *); 125static int pk_recvspdupdate (caddr_t *); 126static int pk_recvspdadd (caddr_t *); 127static int pk_recvspddelete (caddr_t *); 128static int pk_recvspdexpire (caddr_t *); 129static int pk_recvspdget (caddr_t *); 130static int pk_recvspddump (caddr_t *); 131static int pk_recvspdflush (caddr_t *); 132static int pk_recvgetsastat (caddr_t *); 133static struct sadb_msg *pk_recv (int, ssize_t *); 134 135static int (*pkrecvf[]) (caddr_t *) = { 136NULL, 137pk_recvgetspi, 138pk_recvupdate, 139pk_recvadd, 140pk_recvdelete, 141NULL, /* SADB_GET */ 142pk_recvacquire, 143NULL, /* SABD_REGISTER */ 144pk_recvexpire, 145pk_recvflush, 146NULL, /* SADB_DUMP */ 147NULL, /* SADB_X_PROMISC */ 148NULL, /* SADB_X_PCHANGE */ 149pk_recvspdupdate, 150pk_recvspdadd, 151pk_recvspddelete, 152pk_recvspdget, 153NULL, /* SADB_X_SPDACQUIRE */ 154pk_recvspddump, 155pk_recvspdflush, 156NULL, /* SADB_X_SPDSETIDX */ 157pk_recvspdexpire, 158NULL, /* SADB_X_SPDDELETE2 */ 159pk_recvgetsastat, /* SADB_GETSASTAT */ 160NULL, /* SADB_X_NAT_T_NEW_MAPPING */ 161NULL, /* SADB_X_MIGRATE */ 162#if (SADB_MAX > 25) 163#error "SADB extra message?" 164#endif 165}; 166 167static int addnewsp (caddr_t *); 168 169/* cope with old kame headers - ugly */ 170#ifndef SADB_X_AALG_MD5 171#define SADB_X_AALG_MD5 SADB_AALG_MD5 172#endif 173#ifndef SADB_X_AALG_SHA 174#define SADB_X_AALG_SHA SADB_AALG_SHA 175#endif 176#ifndef SADB_X_AALG_NULL 177#define SADB_X_AALG_NULL SADB_AALG_NULL 178#endif 179 180#ifndef SADB_X_EALG_BLOWFISHCBC 181#define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC 182#endif 183#ifndef SADB_X_EALG_CAST128CBC 184#define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC 185#endif 186#ifndef SADB_X_EALG_RC5CBC 187#ifdef SADB_EALG_RC5CBC 188#define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC 189#endif 190#endif 191 192int 193pfkey_process(msg) 194 struct sadb_msg *msg; 195{ 196 caddr_t mhp[SADB_EXT_MAX + 1]; 197 int error = -1; 198 199 // Special debug use only - creates large logs 200 // plogdump(ASL_LEVEL_DEBUG, msg, msg->sadb_msg_len << 3, "get pfkey %s message\n", 201 // s_pfkey_type(msg->sadb_msg_type)); 202 203 /* validity check */ 204 /* check pfkey message. */ 205 if (pfkey_align(msg, mhp)) { 206 plog(ASL_LEVEL_ERR, 207 "libipsec failed pfkey align (%s)\n", 208 ipsec_strerror()); 209 goto end; 210 } 211 if (pfkey_check(mhp)) { 212 plog(ASL_LEVEL_ERR, 213 "libipsec failed pfkey check (%s)\n", 214 ipsec_strerror()); 215 goto end; 216 } 217 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 218 219 if (msg->sadb_msg_errno) { 220 int pri; 221 222 /* when SPD is empty, treat the state as no error. */ 223 if (msg->sadb_msg_type == SADB_X_SPDDUMP && 224 msg->sadb_msg_errno == ENOENT) 225 pri = ASL_LEVEL_DEBUG; 226 else 227 pri = ASL_LEVEL_ERR; 228 229 plog(pri, 230 "pfkey %s failed: %s\n", 231 s_pfkey_type(msg->sadb_msg_type), 232 strerror(msg->sadb_msg_errno)); 233 goto end; 234 } 235 236 /* safety check */ 237 if (msg->sadb_msg_type >= ARRAYLEN(pkrecvf)) { 238 plog(ASL_LEVEL_ERR, 239 "unknown PF_KEY message type=%u\n", 240 msg->sadb_msg_type); 241 goto end; 242 } 243 244 if (pkrecvf[msg->sadb_msg_type] == NULL) { 245 plog(ASL_LEVEL_INFO, 246 "unsupported PF_KEY message %s\n", 247 s_pfkey_type(msg->sadb_msg_type)); 248 goto end; 249 } 250 251 if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0) 252 goto end; 253 254 error = 0; 255end: 256 if (msg) 257 racoon_free(msg); 258 return(error); 259} 260 261/* 262 * PF_KEY packet handler 263 * 0: success 264 * -1: fail 265 */ 266 267//%%%%%%%%%%%%%%%%%% need to handle errors encountered here - this no longer returns a result 268void 269pfkey_handler(void *unused) 270{ 271 struct sadb_msg *msg; 272 ssize_t len; 273 274 if (slept_at || woke_at) { 275 plog(ASL_LEVEL_DEBUG, 276 "ignoring pfkey port until power-mgmt event is handled.\n"); 277 return; 278 } 279 280 /* receive pfkey message. */ 281 len = 0; 282 msg = (struct sadb_msg *)pk_recv(lcconf->sock_pfkey, &len); 283 284 if (msg == NULL) { 285 if (len < 0) { 286 plog(ASL_LEVEL_ERR, 287 "failed to recv from pfkey (%s)\n", 288 strerror(errno)); 289 return; 290 } else { 291 /* short message - msg not ready */ 292 plog(ASL_LEVEL_DEBUG, "recv short message from pfkey\n"); 293 return; 294 } 295 } 296 pfkey_process(msg); 297} 298 299void 300pfkey_post_handler() 301{ 302 struct saved_msg_elem *elem; 303 struct saved_msg_elem *elem_tmp = NULL; 304 305 if (slept_at || woke_at) { 306 plog(ASL_LEVEL_DEBUG, 307 "ignoring (saved) pfkey messages until power-mgmt event is handled.\n"); 308 return; 309 } 310 311 TAILQ_FOREACH_SAFE(elem, &lcconf->saved_msg_queue, chain, elem_tmp) { 312 pfkey_process((struct sadb_msg *)elem->msg); 313 TAILQ_REMOVE(&lcconf->saved_msg_queue, elem, chain); 314 racoon_free(elem); 315 316 } 317} 318 319int 320pfkey_save_msg(msg) 321 struct sadb_msg *msg; 322{ 323 struct saved_msg_elem *elem; 324 325 elem = (struct saved_msg_elem *)racoon_calloc(sizeof(struct saved_msg_elem), 1); 326 if (elem == NULL) 327 return -1; 328 elem->msg = msg; 329 TAILQ_INSERT_TAIL(&lcconf->saved_msg_queue, elem, chain); 330 return 0; 331} 332 333/* 334 * dump SADB 335 */ 336vchar_t * 337pfkey_dump_sadb(satype) 338 int satype; 339{ 340 int s = -1; 341 vchar_t *buf = NULL; 342 pid_t pid = getpid(); 343 struct sadb_msg *msg = NULL; 344 size_t bl, ml; 345 ssize_t len; 346 347 if ((s = pfkey_open()) < 0) { 348 plog(ASL_LEVEL_ERR, 349 "libipsec failed pfkey open: %s\n", 350 ipsec_strerror()); 351 return NULL; 352 } 353 354 plog(ASL_LEVEL_DEBUG, "call pfkey_send_dump\n"); 355 if (pfkey_send_dump(s, satype) < 0) { 356 plog(ASL_LEVEL_ERR, 357 "libipsec failed dump: %s\n", ipsec_strerror()); 358 goto fail; 359 } 360 361 while (1) { 362 if (msg) 363 racoon_free(msg); 364 msg = pk_recv(s, &len); 365 if (msg == NULL) { 366 if (len < 0) 367 goto done; 368 else 369 continue; 370 } 371 372 /* 373 * for multi-processor system this had to be added because the messages can 374 * be interleaved - they won't all be dump messages 375 */ 376 if (msg->sadb_msg_type != SADB_DUMP) { /* save for later processing */ 377 pfkey_save_msg(msg); 378 msg = NULL; 379 continue; 380 } 381 382 // ignore dump messages that aren't racoon's 383 if (msg->sadb_msg_pid != pid) 384 continue; 385 386 ml = msg->sadb_msg_len << 3; 387 bl = buf ? buf->l : 0; 388 buf = vrealloc(buf, bl + ml); 389 if (buf == NULL) { 390 plog(ASL_LEVEL_ERR, 391 "failed to reallocate buffer to dump.\n"); 392 goto fail; 393 } 394 memcpy(buf->v + bl, msg, ml); 395 396 if (msg->sadb_msg_seq == 0) 397 break; 398 } 399 goto done; 400 401fail: 402 if (buf) 403 vfree(buf); 404 buf = NULL; 405done: 406 if (msg) 407 racoon_free(msg); 408 if (s >= 0) 409 pfkey_close_sock(s); 410 return buf; 411} 412 413 414/* 415 * These are the SATYPEs that we manage. We register to get 416 * PF_KEY messages related to these SATYPEs, and we also use 417 * this list to determine which SATYPEs to delete SAs for when 418 * we receive an INITIAL-CONTACT. 419 */ 420const struct pfkey_satype pfkey_satypes[] = { 421 { SADB_SATYPE_AH, "AH" }, 422 { SADB_SATYPE_ESP, "ESP" }, 423 { SADB_X_SATYPE_IPCOMP, "IPCOMP" }, 424}; 425const int pfkey_nsatypes = 426 sizeof(pfkey_satypes) / sizeof(pfkey_satypes[0]); 427 428/* 429 * PF_KEY initialization 430 */ 431int 432pfkey_init(void) 433{ 434 int i, reg_fail, sock; 435 436 if ((lcconf->sock_pfkey = pfkey_open()) < 0) { 437 plog(ASL_LEVEL_ERR, 438 "libipsec failed pfkey open (%s)\n", ipsec_strerror()); 439 return -1; 440 } 441 442 for (i = 0, reg_fail = 0; i < pfkey_nsatypes; i++) { 443 plog(ASL_LEVEL_DEBUG, 444 "call pfkey_send_register for %s\n", 445 pfkey_satypes[i].ps_name); 446 if (pfkey_send_register(lcconf->sock_pfkey, 447 pfkey_satypes[i].ps_satype) < 0 || 448 pfkey_recv_register(lcconf->sock_pfkey) < 0) { 449 plog(ASL_LEVEL_WARNING, 450 "failed to register %s (%s)\n", 451 pfkey_satypes[i].ps_name, 452 ipsec_strerror()); 453 reg_fail++; 454 } 455 } 456 457 if (reg_fail == pfkey_nsatypes) { 458 plog(ASL_LEVEL_ERR, 459 "failed to regist any protocol.\n"); 460 close(lcconf->sock_pfkey); 461 return -1; 462 } 463 initsp(); 464 465 lcconf->pfkey_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, lcconf->sock_pfkey, 0, dispatch_get_main_queue()); 466 if (lcconf->pfkey_source == NULL) { 467 plog(ASL_LEVEL_ERR, "could not create pfkey socket source."); 468 return -1; 469 } 470 dispatch_source_set_event_handler_f(lcconf->pfkey_source, pfkey_handler); 471 sock = lcconf->sock_pfkey; 472 dispatch_source_set_cancel_handler(lcconf->pfkey_source, 473 ^{ 474 pfkey_close_sock(sock); 475 }); 476 dispatch_resume(lcconf->pfkey_source); 477 478 if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) { 479 plog(ASL_LEVEL_ERR, 480 "libipsec sending spddump failed: %s\n", 481 ipsec_strerror()); 482 pfkey_close(); 483 return -1; 484 } 485#if 0 486 if (pfkey_promisc_toggle(1) < 0) { 487 pfkey_close(); 488 return -1; 489 } 490#endif 491 492 return 0; 493} 494 495void 496pfkey_close(void) 497{ 498 dispatch_source_cancel(lcconf->pfkey_source); 499 lcconf->pfkey_source = NULL; 500} 501 502/* %%% for conversion */ 503/* IPSECDOI_ATTR_AUTH -> SADB_AALG */ 504static u_int 505ipsecdoi2pfkey_aalg(hashtype) 506 u_int hashtype; 507{ 508 switch (hashtype) { 509 case IPSECDOI_ATTR_AUTH_HMAC_MD5: 510 case IPSECDOI_ATTR_AUTH_HMAC_MD5_96: 511 return SADB_AALG_MD5HMAC; 512 case IPSECDOI_ATTR_AUTH_HMAC_SHA1: 513 case IPSECDOI_ATTR_AUTH_HMAC_SHA1_96: 514 return SADB_AALG_SHA1HMAC; 515 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256: 516#if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC) 517 return SADB_X_AALG_SHA2_256; 518#else 519 return SADB_X_AALG_SHA2_256HMAC; 520#endif 521 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384: 522#if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC) 523 return SADB_X_AALG_SHA2_384; 524#else 525 return SADB_X_AALG_SHA2_384HMAC; 526#endif 527 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512: 528#if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC) 529 return SADB_X_AALG_SHA2_512; 530#else 531 return SADB_X_AALG_SHA2_512HMAC; 532#endif 533 case IPSECDOI_ATTR_AUTH_KPDK: /* need special care */ 534 return SADB_AALG_NONE; 535 536 /* not supported */ 537 case IPSECDOI_ATTR_AUTH_DES_MAC: 538 plog(ASL_LEVEL_ERR, 539 "Not supported hash type: %u\n", hashtype); 540 return ~0; 541 542 case 0: /* reserved */ 543 default: 544 return SADB_AALG_NONE; 545 546 plog(ASL_LEVEL_ERR, 547 "Invalid hash type: %u\n", hashtype); 548 return ~0; 549 } 550 /*NOTREACHED*/ 551} 552 553/* IPSECDOI_ESP -> SADB_EALG */ 554static u_int 555ipsecdoi2pfkey_ealg(t_id) 556 u_int t_id; 557{ 558 switch (t_id) { 559 case IPSECDOI_ESP_DES_IV64: /* sa_flags |= SADB_X_EXT_OLD */ 560 return SADB_EALG_DESCBC; 561 case IPSECDOI_ESP_DES: 562 return SADB_EALG_DESCBC; 563 case IPSECDOI_ESP_3DES: 564 return SADB_EALG_3DESCBC; 565#ifdef SADB_X_EALG_RC5CBC 566 case IPSECDOI_ESP_RC5: 567 return SADB_X_EALG_RC5CBC; 568#endif 569 case IPSECDOI_ESP_CAST: 570 return SADB_X_EALG_CAST128CBC; 571 case IPSECDOI_ESP_BLOWFISH: 572 return SADB_X_EALG_BLOWFISHCBC; 573 case IPSECDOI_ESP_DES_IV32: /* flags |= (SADB_X_EXT_OLD| 574 SADB_X_EXT_IV4B)*/ 575 return SADB_EALG_DESCBC; 576 case IPSECDOI_ESP_NULL: 577 return SADB_EALG_NULL; 578#ifdef SADB_X_EALG_AESCBC 579 case IPSECDOI_ESP_AES: 580 return SADB_X_EALG_AESCBC; 581#endif 582#ifdef SADB_X_EALG_TWOFISHCBC 583 case IPSECDOI_ESP_TWOFISH: 584 return SADB_X_EALG_TWOFISHCBC; 585#endif 586 587 /* not supported */ 588 case IPSECDOI_ESP_3IDEA: 589 case IPSECDOI_ESP_IDEA: 590 case IPSECDOI_ESP_RC4: 591 plog(ASL_LEVEL_ERR, 592 "Not supported transform: %u\n", t_id); 593 return ~0; 594 595 case 0: /* reserved */ 596 default: 597 plog(ASL_LEVEL_ERR, 598 "Invalid transform id: %u\n", t_id); 599 return ~0; 600 } 601 /*NOTREACHED*/ 602} 603 604/* IPCOMP -> SADB_CALG */ 605static u_int 606ipsecdoi2pfkey_calg(t_id) 607 u_int t_id; 608{ 609 switch (t_id) { 610 case IPSECDOI_IPCOMP_OUI: 611 return SADB_X_CALG_OUI; 612 case IPSECDOI_IPCOMP_DEFLATE: 613 return SADB_X_CALG_DEFLATE; 614 case IPSECDOI_IPCOMP_LZS: 615 return SADB_X_CALG_LZS; 616 617 case 0: /* reserved */ 618 default: 619 plog(ASL_LEVEL_ERR, 620 "Invalid transform id: %u\n", t_id); 621 return ~0; 622 } 623 /*NOTREACHED*/ 624} 625 626/* IPSECDOI_PROTO -> SADB_SATYPE */ 627u_int 628ipsecdoi2pfkey_proto(proto) 629 u_int proto; 630{ 631 switch (proto) { 632 case IPSECDOI_PROTO_IPSEC_AH: 633 return SADB_SATYPE_AH; 634 case IPSECDOI_PROTO_IPSEC_ESP: 635 return SADB_SATYPE_ESP; 636 case IPSECDOI_PROTO_IPCOMP: 637 return SADB_X_SATYPE_IPCOMP; 638 639 default: 640 plog(ASL_LEVEL_ERR, 641 "Invalid ipsec_doi proto: %u\n", proto); 642 return ~0; 643 } 644 /*NOTREACHED*/ 645} 646 647static u_int 648ipsecdoi2pfkey_alg(algclass, type) 649 u_int algclass, type; 650{ 651 switch (algclass) { 652 case IPSECDOI_ATTR_AUTH: 653 return ipsecdoi2pfkey_aalg(type); 654 case IPSECDOI_PROTO_IPSEC_ESP: 655 return ipsecdoi2pfkey_ealg(type); 656 case IPSECDOI_PROTO_IPCOMP: 657 return ipsecdoi2pfkey_calg(type); 658 default: 659 plog(ASL_LEVEL_ERR, 660 "Invalid ipsec_doi algclass: %u\n", algclass); 661 return ~0; 662 } 663 /*NOTREACHED*/ 664} 665 666/* SADB_SATYPE -> IPSECDOI_PROTO */ 667u_int 668pfkey2ipsecdoi_proto(satype) 669 u_int satype; 670{ 671 switch (satype) { 672 case SADB_SATYPE_AH: 673 return IPSECDOI_PROTO_IPSEC_AH; 674 case SADB_SATYPE_ESP: 675 return IPSECDOI_PROTO_IPSEC_ESP; 676 case SADB_X_SATYPE_IPCOMP: 677 return IPSECDOI_PROTO_IPCOMP; 678 679 default: 680 plog(ASL_LEVEL_ERR, 681 "Invalid pfkey proto: %u\n", satype); 682 return ~0; 683 } 684 /*NOTREACHED*/ 685} 686 687/* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */ 688u_int 689ipsecdoi2pfkey_mode(mode) 690 u_int mode; 691{ 692 switch (mode) { 693 case IPSECDOI_ATTR_ENC_MODE_TUNNEL: 694#ifdef ENABLE_NATT 695 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC: 696 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT: 697#endif 698 return IPSEC_MODE_TUNNEL; 699 case IPSECDOI_ATTR_ENC_MODE_TRNS: 700#ifdef ENABLE_NATT 701 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC: 702 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT: 703#endif 704 return IPSEC_MODE_TRANSPORT; 705 default: 706 plog(ASL_LEVEL_ERR, "Invalid mode type: %u\n", mode); 707 return ~0; 708 } 709 /*NOTREACHED*/ 710} 711 712/* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */ 713u_int 714pfkey2ipsecdoi_mode(mode) 715 u_int mode; 716{ 717 switch (mode) { 718 case IPSEC_MODE_TUNNEL: 719 return IPSECDOI_ATTR_ENC_MODE_TUNNEL; 720 case IPSEC_MODE_TRANSPORT: 721 return IPSECDOI_ATTR_ENC_MODE_TRNS; 722 case IPSEC_MODE_ANY: 723 return IPSECDOI_ATTR_ENC_MODE_ANY; 724 default: 725 plog(ASL_LEVEL_ERR, "Invalid mode type: %u\n", mode); 726 return ~0; 727 } 728 /*NOTREACHED*/ 729} 730 731/* default key length for encryption algorithm */ 732static u_int 733keylen_aalg(hashtype) 734 u_int hashtype; 735{ 736 int res; 737 738 if (hashtype == 0) 739 return SADB_AALG_NONE; 740 741 res = alg_ipsec_hmacdef_hashlen(hashtype); 742 if (res == -1) { 743 plog(ASL_LEVEL_ERR, 744 "invalid hmac algorithm %u.\n", hashtype); 745 return ~0; 746 } 747 return res; 748} 749 750/* default key length for encryption algorithm */ 751static u_int 752keylen_ealg(enctype, encklen) 753 u_int enctype; 754 int encklen; 755{ 756 int res; 757 758 res = alg_ipsec_encdef_keylen(enctype, encklen); 759 if (res == -1) { 760 plog(ASL_LEVEL_ERR, 761 "invalid encryption algorithm %u.\n", enctype); 762 return ~0; 763 } 764 return res; 765} 766 767int 768pfkey_convertfromipsecdoi(iph2, proto_id, t_id, hashtype, 769 e_type, e_keylen, a_type, a_keylen, flags) 770 phase2_handle_t *iph2; 771 u_int proto_id; 772 u_int t_id; 773 u_int hashtype; 774 u_int *e_type; 775 u_int *e_keylen; 776 u_int *a_type; 777 u_int *a_keylen; 778 u_int *flags; 779{ 780 *flags = 0; 781 switch (proto_id) { 782 case IPSECDOI_PROTO_IPSEC_ESP: 783 if ((*e_type = ipsecdoi2pfkey_ealg(t_id)) == ~0) 784 goto bad; 785 if ((*e_keylen = keylen_ealg(t_id, *e_keylen)) == ~0) 786 goto bad; 787 *e_keylen >>= 3; 788 789 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0) 790 goto bad; 791 if ((*a_keylen = keylen_aalg(hashtype)) == ~0) 792 goto bad; 793 *a_keylen >>= 3; 794 795 if (*e_type == SADB_EALG_NONE) { 796 plog(ASL_LEVEL_ERR, "no ESP algorithm.\n"); 797 goto bad; 798 } 799 break; 800 801 case IPSECDOI_PROTO_IPSEC_AH: 802 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0) 803 goto bad; 804 if ((*a_keylen = keylen_aalg(hashtype)) == ~0) 805 goto bad; 806 *a_keylen >>= 3; 807 808 if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5 809 && hashtype == IPSECDOI_ATTR_AUTH_KPDK) { 810 /* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */ 811 *a_type = SADB_X_AALG_MD5; 812 *flags |= SADB_X_EXT_OLD; 813 } 814 *e_type = SADB_EALG_NONE; 815 *e_keylen = 0; 816 if (*a_type == SADB_AALG_NONE) { 817 plog(ASL_LEVEL_ERR, "no AH algorithm.\n"); 818 goto bad; 819 } 820 break; 821 822 case IPSECDOI_PROTO_IPCOMP: 823 if ((*e_type = ipsecdoi2pfkey_calg(t_id)) == ~0) 824 goto bad; 825 *e_keylen = 0; 826 827 *flags = SADB_X_EXT_RAWCPI; 828 829 *a_type = SADB_AALG_NONE; 830 *a_keylen = 0; 831 if (*e_type == SADB_X_CALG_NONE) { 832 plog(ASL_LEVEL_ERR, "no IPCOMP algorithm.\n"); 833 goto bad; 834 } 835 break; 836 837 default: 838 plog(ASL_LEVEL_ERR, "unknown IPsec protocol.\n"); 839 goto bad; 840 } 841 842 return 0; 843 844 bad: 845 errno = EINVAL; 846 return -1; 847} 848 849/* called from scheduler */ 850void 851pfkey_timeover_stub(p) 852 void *p; 853{ 854 855 pfkey_timeover((phase2_handle_t *)p); 856} 857 858void 859pfkey_timeover(iph2) 860 phase2_handle_t *iph2; 861{ 862 plog(ASL_LEVEL_ERR, 863 "%s give up to get IPsec-SA due to time up to wait.\n", 864 saddrwop2str((struct sockaddr *)iph2->dst)); 865 SCHED_KILL(iph2->sce); 866 867 /* If initiator side, send error to kernel by SADB_ACQUIRE. */ 868 if (iph2->side == INITIATOR) 869 pk_sendeacquire(iph2); 870 871 ike_session_unlink_phase2(iph2); 872 873 return; 874} 875 876/*%%%*/ 877/* send getspi message per ipsec protocol per remote address */ 878/* 879 * the local address and remote address in ph1handle are dealed 880 * with destination address and source address respectively. 881 * Because SPI is decided by responder. 882 */ 883int 884pk_sendgetspi(iph2) 885 phase2_handle_t *iph2; 886{ 887 struct sockaddr_storage *src = NULL, *dst = NULL; 888 u_int satype, mode; 889 struct saprop *pp; 890 struct saproto *pr; 891 u_int32_t minspi, maxspi; 892 int proxy = 0; 893 894 if (iph2->side == INITIATOR) { 895 pp = iph2->proposal; 896 proxy = iph2->ph1->rmconf->support_proxy; 897 } else { 898 pp = iph2->approval; 899 if (iph2->sainfo && iph2->sainfo->id_i) 900 proxy = 1; 901 } 902 903 /* for mobile IPv6 */ 904 if (proxy && iph2->src_id && iph2->dst_id && 905 ipsecdoi_transportmode(pp)) { 906 src = iph2->src_id; 907 dst = iph2->dst_id; 908 } else { 909 src = iph2->src; 910 dst = iph2->dst; 911 } 912 913 for (pr = pp->head; pr != NULL; pr = pr->next) { 914 915 /* validity check */ 916 satype = ipsecdoi2pfkey_proto(pr->proto_id); 917 if (satype == ~0) { 918 plog(ASL_LEVEL_ERR, 919 "invalid proto_id %d\n", pr->proto_id); 920 return -1; 921 } 922 /* this works around a bug in Linux kernel where it allocates 4 byte 923 spi's for IPCOMP */ 924 else if (satype == SADB_X_SATYPE_IPCOMP) { 925 minspi = 0x100; 926 maxspi = 0xffff; 927 } 928 else { 929 minspi = 0; 930 maxspi = 0; 931 } 932 mode = ipsecdoi2pfkey_mode(pr->encmode); 933 if (mode == ~0) { 934 plog(ASL_LEVEL_ERR, 935 "invalid encmode %d\n", pr->encmode); 936 return -1; 937 } 938 939 plog(ASL_LEVEL_DEBUG, "call pfkey_send_getspi\n"); 940 if (pfkey_send_getspi( 941 lcconf->sock_pfkey, 942 satype, 943 mode, 944 dst, /* src of SA */ 945 src, /* dst of SA */ 946 minspi, maxspi, 947 pr->reqid_in, 0, 0, iph2->seq, 0) < 0) { 948 plog(ASL_LEVEL_ERR, 949 "ipseclib failed send getspi (%s)\n", 950 ipsec_strerror()); 951 return -1; 952 } 953 954 plog(ASL_LEVEL_DEBUG, 955 "pfkey GETSPI sent: %s\n", 956 sadbsecas2str(dst, src, satype, 0, mode)); 957 } 958 959 return 0; 960} 961 962/* 963 * receive GETSPI from kernel. 964 */ 965static int 966pk_recvgetspi(mhp) 967 caddr_t *mhp; 968{ 969 struct sadb_msg *msg; 970 struct sadb_sa *sa; 971 phase2_handle_t *iph2; 972 struct sockaddr_storage *dst; 973 int proto_id; 974 int allspiok, notfound; 975 struct saprop *pp; 976 struct saproto *pr; 977 978 /* validity check */ 979 if (mhp[SADB_EXT_SA] == NULL 980 || mhp[SADB_EXT_ADDRESS_DST] == NULL) { 981 plog(ASL_LEVEL_ERR, 982 "Inappropriate sadb getspi message passed.\n"); 983 return -1; 984 } 985 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 986 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA]; 987 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */ 988 989 /* the message has to be processed or not ? */ 990 if (msg->sadb_msg_pid != getpid()) { 991 plog(ASL_LEVEL_DEBUG, 992 "%s message is not interesting " 993 "because pid %d is not mine.\n", 994 s_pfkey_type(msg->sadb_msg_type), 995 msg->sadb_msg_pid); 996 return -1; 997 } 998 999 iph2 = ike_session_getph2byseq(msg->sadb_msg_seq); 1000 if (iph2 == NULL) { 1001 plog(ASL_LEVEL_DEBUG, 1002 "Seq %d of %s message not interesting.\n", 1003 msg->sadb_msg_seq, 1004 s_pfkey_type(msg->sadb_msg_type)); 1005 return -1; 1006 } 1007 1008 if (iph2->is_dying) { 1009 plog(ASL_LEVEL_ERR, 1010 "Status mismatch Phase 2 dying (db:%d)\n", 1011 iph2->status); 1012 return -1; 1013 } 1014 1015 switch (iph2->version) { 1016 case ISAKMP_VERSION_NUMBER_IKEV1: 1017 if (iph2->status != IKEV1_STATE_QUICK_I_GETSPISENT && 1018 iph2->status != IKEV1_STATE_QUICK_R_GETSPISENT) { 1019 plog(ASL_LEVEL_ERR, "Status mismatch (db:%d)\n", iph2->status); 1020 return -1; 1021 } 1022 // check the underlying iph2->ph1 1023 if (!iph2->ph1) { 1024 if (!ike_session_update_ph2_ph1bind(iph2)) { 1025 plog(ASL_LEVEL_ERR, 1026 "Can't proceed with getspi for %s. no suitable ISAKMP-SA found \n", 1027 saddrwop2str((struct sockaddr *)iph2->dst)); 1028 ike_session_unlink_phase2(iph2); 1029 return -1; 1030 } 1031 } 1032 break; 1033 default: 1034 plog(ASL_LEVEL_ERR, "Internal error: invalid IKE major version %d\n", iph2->version); 1035 return -1; 1036 } 1037 1038 /* set SPI, and check to get all spi whether or not */ 1039 allspiok = 1; 1040 notfound = 1; 1041 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); 1042 pp = iph2->side == INITIATOR ? iph2->proposal : iph2->approval; 1043 1044 for (pr = pp->head; pr != NULL; pr = pr->next) { 1045 if (pr->proto_id == proto_id && pr->spi == 0) { 1046 pr->spi = sa->sadb_sa_spi; 1047 notfound = 0; 1048 plog(ASL_LEVEL_DEBUG, 1049 "pfkey GETSPI succeeded: %s\n", 1050 sadbsecas2str(iph2->dst, iph2->src, 1051 msg->sadb_msg_satype, 1052 sa->sadb_sa_spi, 1053 ipsecdoi2pfkey_mode(pr->encmode))); 1054 } 1055 if (pr->spi == 0) 1056 allspiok = 0; /* not get all spi */ 1057 } 1058 1059 if (notfound) { 1060 plog(ASL_LEVEL_ERR, 1061 "Get spi for unknown address %s\n", 1062 saddrwop2str((struct sockaddr *)iph2->dst)); 1063 ike_session_unlink_phase2(iph2); 1064 return -1; 1065 } 1066 1067 if (allspiok) { 1068 switch (iph2->version) { 1069 case ISAKMP_VERSION_NUMBER_IKEV1: 1070 if (isakmp_post_getspi(iph2) < 0) { 1071 plog(ASL_LEVEL_ERR, "IKEv1 post getspi failed.\n"); 1072 ike_session_unlink_phase2(iph2); 1073 iph2 = NULL; 1074 return -1; 1075 } 1076 break; 1077 } 1078 } 1079 return 0; 1080} 1081 1082/* 1083 * set inbound SA 1084 */ 1085int 1086pk_sendupdate(iph2) 1087 phase2_handle_t *iph2; 1088{ 1089 struct saproto *pr; 1090 struct sockaddr_storage *src = NULL, *dst = NULL; 1091 u_int e_type, e_keylen, a_type, a_keylen, flags; 1092 u_int satype, mode; 1093 u_int64_t lifebyte = 0; 1094 u_int wsize = 4; /* XXX static size of window */ 1095 int proxy = 0; 1096 struct ph2natt natt; 1097 int authtype; 1098 1099 /* sanity check */ 1100 if (iph2->approval == NULL) { 1101 plog(ASL_LEVEL_ERR, 1102 "No approved SAs found.\n"); 1103 } 1104 1105 if (iph2->side == INITIATOR) 1106 proxy = iph2->ph1->rmconf->support_proxy; 1107 else if (iph2->sainfo && iph2->sainfo->id_i) 1108 proxy = 1; 1109 1110 /* for mobile IPv6 */ 1111 if (proxy && iph2->src_id && iph2->dst_id && 1112 ipsecdoi_transportmode(iph2->approval)) { 1113 src = iph2->src_id; 1114 dst = iph2->dst_id; 1115 } else { 1116 src = iph2->src; 1117 dst = iph2->dst; 1118 } 1119 1120 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 1121 /* validity check */ 1122 satype = ipsecdoi2pfkey_proto(pr->proto_id); 1123 if (satype == ~0) { 1124 plog(ASL_LEVEL_ERR, 1125 "Invalid proto_id %d\n", pr->proto_id); 1126 return -1; 1127 } 1128 else if (satype == SADB_X_SATYPE_IPCOMP) { 1129 /* IPCOMP has no replay window */ 1130 wsize = 0; 1131 } 1132#ifdef ENABLE_SAMODE_UNSPECIFIED 1133 mode = IPSEC_MODE_ANY; 1134#else 1135 mode = ipsecdoi2pfkey_mode(pr->encmode); 1136 if (mode == ~0) { 1137 plog(ASL_LEVEL_ERR, 1138 "Invalid encmode %d\n", pr->encmode); 1139 return -1; 1140 } 1141#endif 1142 1143 /* set algorithm type and key length */ 1144 e_keylen = pr->head->encklen; 1145 authtype = pr->head->authtype; 1146 a_keylen = 0; 1147 if (pfkey_convertfromipsecdoi( 1148 iph2, 1149 pr->proto_id, 1150 pr->head->trns_id, 1151 authtype, 1152 &e_type, &e_keylen, 1153 &a_type, &a_keylen, &flags) < 0) 1154 return -1; 1155 1156#if 0 1157 lifebyte = iph2->approval->lifebyte * 1024, 1158#else 1159 lifebyte = 0; 1160#endif 1161 1162#ifdef ENABLE_NATT 1163 //plog(ASL_LEVEL_DEBUG, "call pfkey_send_update\n"); 1164 plog(ASL_LEVEL_DEBUG, "call pfkey_send_update: e_type %d, e_klen %d, a_type %d, a_klen %d\n", 1165 e_type, e_keylen, a_type, a_keylen); 1166 if (pr->udp_encap) { 1167 memset (&natt, 0, sizeof (natt)); 1168 natt.sport = extract_port (iph2->ph1->remote); 1169 flags |= SADB_X_EXT_NATT; 1170 if (iph2->ph1->rmconf->natt_multiple_user == TRUE && 1171 mode == IPSEC_MODE_TRANSPORT && 1172 src->ss_family == AF_INET) { 1173 flags |= SADB_X_EXT_NATT_MULTIPLEUSERS; 1174 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) { 1175 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE 1176 flags |= SADB_X_EXT_NATT_DETECTED_PEER; 1177 } 1178 } else if (iph2->ph1->natt_flags & NAT_DETECTED_ME) { 1179 if (iph2->ph1->rmconf->natt_keepalive == TRUE) 1180 flags |= SADB_X_EXT_NATT_KEEPALIVE; 1181 } else { 1182 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) { 1183 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE 1184 flags |= SADB_X_EXT_NATT_DETECTED_PEER; 1185 } 1186 } 1187 } else { 1188 memset (&natt, 0, sizeof (natt)); 1189 } 1190 1191 if (pfkey_send_update( 1192 lcconf->sock_pfkey, 1193 satype, 1194 mode, 1195 dst, 1196 src, 1197 pr->spi, 1198 pr->reqid_in, 1199 wsize, 1200 pr->keymat->v, 1201 e_type, e_keylen, a_type, a_keylen, flags, 1202 0, lifebyte, iph2->approval->lifetime, 0, 1203 iph2->seq, natt.sport, 0) < 0) { 1204 plog(ASL_LEVEL_ERR, 1205 "libipsec failed send update (%s)\n", 1206 ipsec_strerror()); 1207 return -1; 1208 } 1209#else 1210 plog(ASL_LEVEL_DEBUG, "call pfkey_send_update\n"); 1211 if (pfkey_send_update( 1212 lcconf->sock_pfkey, 1213 satype, 1214 mode, 1215 dst, 1216 src, 1217 pr->spi, 1218 pr->reqid_in, 1219 wsize, 1220 pr->keymat->v, 1221 e_type, e_keylen, a_type, a_keylen, flags, 1222 0, lifebyte, iph2->approval->lifetime, 0, 1223 iph2->seq, 0, 0) < 0) { 1224 plog(ASL_LEVEL_ERR, 1225 "libipsec failed send update (%s)\n", 1226 ipsec_strerror()); 1227 return -1; 1228 } 1229#endif /* ENABLE_NATT */ 1230 1231 1232 } 1233 1234 return 0; 1235} 1236 1237static int 1238pk_recvupdate(mhp) 1239 caddr_t *mhp; 1240{ 1241 struct sadb_msg *msg; 1242 struct sadb_sa *sa; 1243 struct sockaddr_storage *src, *dst; 1244 phase2_handle_t *iph2; 1245 u_int proto_id, encmode, sa_mode; 1246 int incomplete = 0; 1247 struct saproto *pr; 1248 1249 /* ignore this message because of local test mode. */ 1250 if (f_local) 1251 return 0; 1252 1253 /* sanity check */ 1254 if (mhp[0] == NULL 1255 || mhp[SADB_EXT_SA] == NULL 1256 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 1257 || mhp[SADB_EXT_ADDRESS_DST] == NULL) { 1258 plog(ASL_LEVEL_ERR, 1259 "inappropriate sadb update message passed.\n"); 1260 return -1; 1261 } 1262 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 1263 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 1264 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1265 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA]; 1266 1267 sa_mode = mhp[SADB_X_EXT_SA2] == NULL 1268 ? IPSEC_MODE_ANY 1269 : (ALIGNED_CAST(struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode; 1270 1271 /* the message has to be processed or not ? */ 1272 if (msg->sadb_msg_pid != getpid()) { 1273 plog(ASL_LEVEL_DEBUG, 1274 "%s message is not interesting " 1275 "because pid %d is not mine.\n", 1276 s_pfkey_type(msg->sadb_msg_type), 1277 msg->sadb_msg_pid); 1278 return -1; 1279 } 1280 1281 iph2 = ike_session_getph2byseq(msg->sadb_msg_seq); 1282 if (iph2 == NULL) { 1283 plog(ASL_LEVEL_DEBUG, 1284 "Seq %d of %s message not interesting.\n", 1285 msg->sadb_msg_seq, 1286 s_pfkey_type(msg->sadb_msg_type)); 1287 return -1; 1288 } 1289 1290 if (iph2->is_dying) { 1291 plog(ASL_LEVEL_ERR, 1292 "Status mismatch Phase 2 dying (db:%d)\n", 1293 iph2->status); 1294 return -1; 1295 } 1296 if (iph2->status != IKEV1_STATE_QUICK_I_ADDSA && 1297 iph2->status != IKEV1_STATE_QUICK_R_ADDSA) { 1298 plog(ASL_LEVEL_ERR, 1299 "Status mismatch (db:%d)\n", 1300 iph2->status); 1301 return -1; 1302 } 1303 1304 /* check to complete all keys ? */ 1305 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 1306 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); 1307 if (proto_id == ~0) { 1308 plog(ASL_LEVEL_ERR, 1309 "invalid proto_id %d\n", msg->sadb_msg_satype); 1310 return -1; 1311 } 1312 encmode = pfkey2ipsecdoi_mode(sa_mode); 1313 if (encmode == ~0) { 1314 plog(ASL_LEVEL_ERR, 1315 "invalid encmode %d\n", sa_mode); 1316 return -1; 1317 } 1318 1319 if (pr->proto_id == proto_id 1320 && pr->spi == sa->sadb_sa_spi) { 1321 pr->ok = 1; 1322 plog(ASL_LEVEL_DEBUG, 1323 "pfkey UPDATE succeeded: %s\n", 1324 sadbsecas2str(iph2->dst, iph2->src, 1325 msg->sadb_msg_satype, 1326 sa->sadb_sa_spi, 1327 sa_mode)); 1328 1329 plog(ASL_LEVEL_INFO, 1330 "IPsec-SA established: %s\n", 1331 sadbsecas2str(iph2->dst, iph2->src, 1332 msg->sadb_msg_satype, sa->sadb_sa_spi, 1333 sa_mode)); 1334 } 1335 1336 if (pr->ok == 0) 1337 incomplete = 1; 1338 } 1339 1340 if (incomplete) 1341 return 0; 1342 1343 /* turn off the timer for calling pfkey_timeover() */ 1344 SCHED_KILL(iph2->sce); 1345 1346 /* update status */ 1347 fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_ESTABLISHED); 1348 1349 if (iph2->side == INITIATOR) { 1350 IPSECSESSIONTRACEREVENT(iph2->parent_session, 1351 IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC, 1352 CONSTSTR("Initiator, Quick-Mode"), 1353 CONSTSTR(NULL)); 1354 } else { 1355 IPSECSESSIONTRACEREVENT(iph2->parent_session, 1356 IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC, 1357 CONSTSTR("Responder, Quick-Mode"), 1358 CONSTSTR(NULL)); 1359 } 1360 1361 ike_session_ph2_established(iph2); 1362 1363 IPSECLOGASLMSG("IPSec Phase 2 established (Initiated by %s).\n", 1364 (iph2->side == INITIATOR)? "me" : "peer"); 1365 1366#ifdef ENABLE_STATS 1367 gettimeofday(&iph2->end, NULL); 1368 plog(ASL_LEVEL_NOTICE, "%s(%s): %8.6f", 1369 "Phase 2", "quick", timedelta(&iph2->start, &iph2->end)); 1370#endif 1371 1372 /* count up */ 1373 if (iph2->ph1) 1374 iph2->ph1->ph2cnt++; 1375 1376 /* turn off schedule */ 1377 if (iph2->scr) 1378 SCHED_KILL(iph2->scr); 1379 1380 /* 1381 * since we are going to reuse the phase2 handler, we need to 1382 * remain it and refresh all the references between ph1 and ph2 to use. 1383 */ 1384 ike_session_unbindph12(iph2); //%%%%% fix this 1385 1386 iph2->sce = sched_new(iph2->approval->lifetime, 1387 isakmp_ph2expire_stub, iph2); 1388 1389 plog(ASL_LEVEL_DEBUG, "===\n"); 1390 return 0; 1391} 1392 1393/* 1394 * set outbound SA 1395 */ 1396int 1397pk_sendadd(iph2) 1398 phase2_handle_t *iph2; 1399{ 1400 struct saproto *pr; 1401 struct sockaddr_storage *src = NULL, *dst = NULL; 1402 u_int e_type, e_keylen, a_type, a_keylen, flags; 1403 u_int satype, mode; 1404 u_int64_t lifebyte = 0; 1405 u_int wsize = 4; /* XXX static size of window */ 1406 int proxy = 0; 1407 struct ph2natt natt; 1408 int authtype; 1409 1410 /* sanity check */ 1411 if (iph2->approval == NULL) { 1412 plog(ASL_LEVEL_ERR, 1413 "no approvaled SAs found.\n"); 1414 } 1415 1416 if (iph2->side == INITIATOR) 1417 proxy = iph2->ph1->rmconf->support_proxy; 1418 else if (iph2->sainfo && iph2->sainfo->id_i) 1419 proxy = 1; 1420 1421 /* for mobile IPv6 */ 1422 if (proxy && iph2->src_id && iph2->dst_id && 1423 ipsecdoi_transportmode(iph2->approval)) { 1424 src = iph2->src_id; 1425 dst = iph2->dst_id; 1426 } else { 1427 src = iph2->src; 1428 dst = iph2->dst; 1429 } 1430 1431 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 1432 /* validity check */ 1433 satype = ipsecdoi2pfkey_proto(pr->proto_id); 1434 if (satype == ~0) { 1435 plog(ASL_LEVEL_ERR, 1436 "invalid proto_id %d\n", pr->proto_id); 1437 return -1; 1438 } 1439 else if (satype == SADB_X_SATYPE_IPCOMP) { 1440 /* no replay window for IPCOMP */ 1441 wsize = 0; 1442 } 1443#ifdef ENABLE_SAMODE_UNSPECIFIED 1444 mode = IPSEC_MODE_ANY; 1445#else 1446 mode = ipsecdoi2pfkey_mode(pr->encmode); 1447 if (mode == ~0) { 1448 plog(ASL_LEVEL_ERR, 1449 "invalid encmode %d\n", pr->encmode); 1450 return -1; 1451 } 1452#endif 1453 1454 /* set algorithm type and key length */ 1455 e_keylen = pr->head->encklen; 1456 authtype = pr->head->authtype; 1457 a_keylen = 0; 1458 if (pfkey_convertfromipsecdoi( 1459 iph2, 1460 pr->proto_id, 1461 pr->head->trns_id, 1462 authtype, 1463 &e_type, &e_keylen, 1464 &a_type, &a_keylen, &flags) < 0) 1465 return -1; 1466 1467#if 0 1468 lifebyte = iph2->approval->lifebyte * 1024, 1469#else 1470 lifebyte = 0; 1471#endif 1472 1473#ifdef ENABLE_NATT 1474 //plog(ASL_LEVEL_DEBUG, "call pfkey_send_add\n"); 1475 plog(ASL_LEVEL_DEBUG, "call pfkey_send_add: e_type %d, e_klen %d, a_type %d, a_klen %d\n", 1476 e_type, e_keylen, a_type, a_keylen); 1477 1478 if (pr->udp_encap) { 1479 memset (&natt, 0, sizeof (natt)); 1480 natt.dport = extract_port (iph2->ph1->remote); 1481 flags |= SADB_X_EXT_NATT; 1482 if (iph2->ph1->rmconf->natt_multiple_user == TRUE && 1483 mode == IPSEC_MODE_TRANSPORT && 1484 src->ss_family == AF_INET) { 1485 flags |= SADB_X_EXT_NATT_MULTIPLEUSERS; 1486 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) { 1487 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE 1488 flags |= SADB_X_EXT_NATT_DETECTED_PEER; 1489 } 1490 } else if (iph2->ph1->natt_flags & NAT_DETECTED_ME) { 1491 if (iph2->ph1->rmconf->natt_keepalive == TRUE) 1492 flags |= SADB_X_EXT_NATT_KEEPALIVE; 1493 } else { 1494 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) { 1495 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE 1496 flags |= SADB_X_EXT_NATT_DETECTED_PEER; 1497 } 1498 } 1499 } else { 1500 memset (&natt, 0, sizeof (natt)); 1501 1502 /* Remove port information, that SA doesn't use it */ 1503 //set_port(src, 0); 1504 //set_port(dst, 0); 1505 } 1506 1507 if (pfkey_send_add( 1508 lcconf->sock_pfkey, 1509 satype, 1510 mode, 1511 src, 1512 dst, 1513 pr->spi_p, 1514 pr->reqid_out, 1515 wsize, 1516 pr->keymat_p->v, 1517 e_type, e_keylen, a_type, a_keylen, flags, 1518 0, lifebyte, iph2->approval->lifetime, 0, 1519 iph2->seq,natt.dport, 0) < 0) { 1520 plog(ASL_LEVEL_ERR, 1521 "libipsec failed send add (%s)\n", 1522 ipsec_strerror()); 1523 return -1; 1524 } 1525#else 1526 plog(ASL_LEVEL_DEBUG, "call pfkey_send_add\n"); 1527 1528 /* Remove port information, it is not used without NAT-T */ 1529 //set_port(src, 0); 1530 //set_port(dst, 0); 1531 1532 if (pfkey_send_add( 1533 lcconf->sock_pfkey, 1534 satype, 1535 mode, 1536 src, 1537 dst, 1538 pr->spi_p, 1539 pr->reqid_out, 1540 wsize, 1541 pr->keymat_p->v, 1542 e_type, e_keylen, a_type, a_keylen, flags, 1543 0, lifebyte, iph2->approval->lifetime, 0, 1544 iph2->seq, 0, 0) < 0) { 1545 plog(ASL_LEVEL_ERR, 1546 "libipsec failed send add (%s)\n", 1547 ipsec_strerror()); 1548 return -1; 1549 } 1550#endif /* ENABLE_NATT */ 1551 } 1552 1553 return 0; 1554} 1555 1556static int 1557pk_recvadd(mhp) 1558 caddr_t *mhp; 1559{ 1560 struct sadb_msg *msg; 1561 struct sadb_sa *sa; 1562 struct sockaddr_storage *src, *dst; 1563 phase2_handle_t *iph2; 1564 u_int sa_mode; 1565 1566 /* ignore this message because of local test mode. */ 1567 if (f_local) 1568 return 0; 1569 1570 /* sanity check */ 1571 if (mhp[0] == NULL 1572 || mhp[SADB_EXT_SA] == NULL 1573 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 1574 || mhp[SADB_EXT_ADDRESS_DST] == NULL) { 1575 plog(ASL_LEVEL_ERR, 1576 "inappropriate sadb add message passed.\n"); 1577 return -1; 1578 } 1579 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 1580 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 1581 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1582 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA]; 1583 1584 sa_mode = mhp[SADB_X_EXT_SA2] == NULL 1585 ? IPSEC_MODE_ANY 1586 : (ALIGNED_CAST(struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode; 1587 1588 /* the message has to be processed or not ? */ 1589 if (msg->sadb_msg_pid != getpid()) { 1590 plog(ASL_LEVEL_DEBUG, 1591 "%s message is not interesting " 1592 "because pid %d is not mine.\n", 1593 s_pfkey_type(msg->sadb_msg_type), 1594 msg->sadb_msg_pid); 1595 return -1; 1596 } 1597 1598 iph2 = ike_session_getph2byseq(msg->sadb_msg_seq); 1599 if (iph2 == NULL) { 1600 plog(ASL_LEVEL_DEBUG, 1601 "seq %d of %s message not interesting.\n", 1602 msg->sadb_msg_seq, 1603 s_pfkey_type(msg->sadb_msg_type)); 1604 return -1; 1605 } 1606 /* 1607 * NOTE don't update any status of phase2 handle 1608 * because they must be updated by SADB_UPDATE message 1609 */ 1610 1611 plog(ASL_LEVEL_INFO, 1612 "IPsec-SA established: %s\n", 1613 sadbsecas2str(iph2->src, iph2->dst, 1614 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode)); 1615 1616 ike_session_cleanup_other_established_ph2s(iph2->parent_session, iph2); 1617 1618#ifdef ENABLE_VPNCONTROL_PORT 1619 { 1620 u_int32_t address; 1621 1622 if (iph2->dst->ss_family == AF_INET) 1623 address = ((struct sockaddr_in *)iph2->dst)->sin_addr.s_addr; 1624 else 1625 address = 0; 1626 vpncontrol_notify_phase_change(0, FROM_LOCAL, NULL, iph2); 1627 } 1628#endif 1629 1630 plog(ASL_LEVEL_DEBUG, "===\n"); 1631 return 0; 1632} 1633 1634static int 1635pk_recvexpire(mhp) 1636 caddr_t *mhp; 1637{ 1638 struct sadb_msg *msg; 1639 struct sadb_sa *sa; 1640 struct sockaddr_storage *src, *dst; 1641 phase2_handle_t *iph2; 1642 u_int proto_id, sa_mode; 1643 1644 /* sanity check */ 1645 if (mhp[0] == NULL 1646 || mhp[SADB_EXT_SA] == NULL 1647 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 1648 || mhp[SADB_EXT_ADDRESS_DST] == NULL 1649 || (mhp[SADB_EXT_LIFETIME_HARD] != NULL 1650 && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) { 1651 plog(ASL_LEVEL_ERR, 1652 "inappropriate sadb expire message passed.\n"); 1653 return -1; 1654 } 1655 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 1656 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA]; 1657 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 1658 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1659 1660 sa_mode = mhp[SADB_X_EXT_SA2] == NULL 1661 ? IPSEC_MODE_ANY 1662 : (ALIGNED_CAST(struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode; 1663 1664 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); 1665 if (proto_id == ~0) { 1666 plog(ASL_LEVEL_ERR, 1667 "invalid proto_id %d\n", msg->sadb_msg_satype); 1668 return -1; 1669 } 1670 1671 plog(ASL_LEVEL_INFO, 1672 "IPsec-SA expired: %s\n", 1673 sadbsecas2str(src, dst, 1674 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode)); 1675 1676 iph2 = ike_session_getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); 1677 if (iph2 == NULL) { 1678 /* 1679 * Ignore it because two expire messages are come up. 1680 * phase2 handler has been deleted already when 2nd message 1681 * is received. 1682 */ 1683 plog(ASL_LEVEL_DEBUG, 1684 "no such a SA found: %s\n", 1685 sadbsecas2str(src, dst, 1686 msg->sadb_msg_satype, sa->sadb_sa_spi, 1687 sa_mode)); 1688 return 0; 1689 } 1690 if (iph2->is_dying || !FSM_STATE_IS_ESTABLISHED(iph2->status)) { 1691 /* 1692 * If the status is not equal to PHASE2ST_ESTABLISHED, 1693 * racoon ignores this expire message. There are two reason. 1694 * One is that the phase 2 probably starts because there is 1695 * a potential that racoon receives the acquire message 1696 * without receiving a expire message. Another is that racoon 1697 * may receive the multiple expire messages from the kernel. 1698 */ 1699 plog(ASL_LEVEL_WARNING, 1700 "The expire message is received but the handler %s (status = 0x%x).\n", 1701 iph2->is_dying ? "is dying" : "has not been established", iph2->status); 1702 return 0; 1703 } 1704 1705 /* turn off the timer for calling isakmp_ph2expire() */ 1706 SCHED_KILL(iph2->sce); 1707 1708 fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED); 1709 1710 /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */ 1711 /* allocate buffer for status management of pfkey message */ 1712 if (iph2->side == INITIATOR && 1713 !ike_session_has_other_established_ph2(iph2->parent_session, iph2) && 1714 !ike_session_drop_rekey(iph2->parent_session, IKE_SESSION_REKEY_TYPE_PH2)) { 1715 1716 ike_session_initph2(iph2); 1717 1718 /* start isakmp initiation by using ident exchange */ 1719 if (isakmp_post_acquire(iph2) < 0) { 1720 plog(ASL_LEVEL_ERR, 1721 "failed to begin ipsec sa " 1722 "re-negotiation.\n"); 1723 ike_session_unlink_phase2(iph2); 1724 return -1; 1725 } 1726 1727 return 0; 1728 /*NOTREACHED*/ 1729 } 1730 1731 1732 /* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */ 1733 /* RESPONDER always delete ph2handle, keep silent. RESPONDER doesn't 1734 * manage IPsec SA, so delete the list */ 1735 ike_session_unlink_phase2(iph2); 1736 1737 return 0; 1738} 1739 1740static int 1741pk_recvacquire(mhp) 1742 caddr_t *mhp; 1743{ 1744 struct sadb_msg *msg; 1745 struct sadb_x_policy *xpl; 1746 struct secpolicy *sp_out = NULL, *sp_in = NULL; 1747 phase2_handle_t *iph2; 1748 struct sockaddr_storage *src, *dst; 1749 ike_session_t *session = NULL; 1750 struct remoteconf *rmconf; 1751 1752 /* ignore this message because of local test mode. */ 1753 if (f_local) 1754 return 0; 1755 1756 /* sanity check */ 1757 if (mhp[0] == NULL 1758 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 1759 || mhp[SADB_EXT_ADDRESS_DST] == NULL 1760 || mhp[SADB_X_EXT_POLICY] == NULL) { 1761 plog(ASL_LEVEL_ERR, 1762 "inappropriate sadb acquire message passed.\n"); 1763 return -1; 1764 } 1765 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 1766 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; 1767 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 1768 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1769 1770 /* ignore if type is not IPSEC_POLICY_IPSEC */ 1771 if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) { 1772 plog(ASL_LEVEL_DEBUG, 1773 "ignore ACQUIRE message. type is not IPsec.\n"); 1774 return 0; 1775 } 1776 1777 /* ignore it if src is multicast address */ 1778 { 1779 struct sockaddr_storage *sa = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 1780 1781 if ((sa->ss_family == AF_INET 1782 && IN_MULTICAST(ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr))) 1783#ifdef INET6 1784 || (sa->ss_family == AF_INET6 1785 && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sa)->sin6_addr)) 1786#endif 1787 ) { 1788 plog(ASL_LEVEL_DEBUG, 1789 "ignore due to multicast address: %s.\n", 1790 saddrwop2str((struct sockaddr *)sa)); 1791 return 0; 1792 } 1793 } 1794 1795 /* ignore, if we do not listen on source address */ 1796 { 1797 /* reasons behind: 1798 * - if we'll contact peer from address we do not listen - 1799 * we will be unable to complete negotiation; 1800 * - if we'll negotiate using address we're listening - 1801 * remote peer will send packets to address different 1802 * than one in the policy, so kernel will drop them; 1803 * => therefore this acquire is not for us! --Aidas 1804 */ 1805 // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 1806 struct sockaddr_storage *sa = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 1807 struct myaddrs *p; 1808 int do_listen = 0; 1809 char * str; 1810 for (p = lcconf->myaddrs; p; p = p->next) { 1811 str = saddr2str((struct sockaddr *)p->addr); 1812 plog(ASL_LEVEL_DEBUG, 1813 "checking listen addrs: %s", str); 1814 1815 if (!cmpsaddrwop(p->addr, sa)) { 1816 do_listen = 1; 1817 break; 1818 } 1819 } 1820 1821 if (!do_listen) { 1822 plog(ASL_LEVEL_DEBUG, 1823 "ignore because do not listen on source address : %s.\n", 1824 saddrwop2str((struct sockaddr *)sa)); 1825 return 0; 1826 } 1827 } 1828 1829 /* 1830 * If there is a phase 2 handler against the policy identifier in 1831 * the acquire message, and if 1832 * 1. its state is less than PHASE2ST_ESTABLISHED, then racoon 1833 * should ignore such a acquire message because the phase 2 1834 * is just negotiating. 1835 * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon 1836 * has to process such a acquire message because racoon may 1837 * have lost the expire message. 1838 */ 1839 iph2 = ike_session_getph2byid(src, dst, xpl->sadb_x_policy_id); 1840 if (iph2 != NULL) { 1841 session = iph2->parent_session; 1842 if (!FSM_STATE_IS_ESTABLISHED(iph2->status)) { 1843 plog(ASL_LEVEL_DEBUG, 1844 "ignore the acquire because ph2 found\n"); 1845 return -1; 1846 } 1847 if (FSM_STATE_IS_EXPIRED(iph2->status)) 1848 iph2 = NULL; 1849 /*FALLTHROUGH*/ 1850 } 1851 1852 /* search for proper policyindex */ 1853 sp_out = getspbyspid(xpl->sadb_x_policy_id); 1854 if (sp_out == NULL) { 1855 plog(ASL_LEVEL_ERR, "no policy found: id:%d.\n", 1856 xpl->sadb_x_policy_id); 1857 return -1; 1858 } 1859 plog(ASL_LEVEL_DEBUG, 1860 "suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx)); 1861 1862 /* get inbound policy */ 1863 { 1864 struct policyindex spidx; 1865 1866 spidx.dir = IPSEC_DIR_INBOUND; 1867 memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src)); 1868 memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst)); 1869 spidx.prefs = sp_out->spidx.prefd; 1870 spidx.prefd = sp_out->spidx.prefs; 1871 spidx.ul_proto = sp_out->spidx.ul_proto; 1872 1873 sp_in = getsp(&spidx); 1874 if (sp_in) { 1875 plog(ASL_LEVEL_DEBUG, 1876 "Suitable inbound SP found: %s.\n", 1877 spidx2str(&sp_in->spidx)); 1878 } else { 1879 plog(ASL_LEVEL_NOTICE, 1880 "No in-bound policy found: %s\n", 1881 spidx2str(&spidx)); 1882 } 1883 } 1884 1885 /* allocate a phase 2 */ 1886 rmconf = getrmconf(dst); 1887 if (rmconf == NULL) { 1888 plog(ASL_LEVEL_ERR, "No configuration found for %s.\n", 1889 saddrwop2str((struct sockaddr *)dst)); 1890 return -1; 1891 } 1892 1893 iph2 = ike_session_newph2(rmconf->ike_version, PHASE2_TYPE_SA); 1894 if (iph2 == NULL) { 1895 plog(ASL_LEVEL_ERR, 1896 "Failed to allocate Phase 2 entry.\n"); 1897 return -1; 1898 } 1899 plog(ASL_LEVEL_DEBUG, "Got new Phase 2 version %d\n", iph2->version); 1900 iph2->version = rmconf->ike_version; 1901 iph2->side = INITIATOR; 1902 iph2->spid = xpl->sadb_x_policy_id; 1903 1904 iph2->satype = msg->sadb_msg_satype; 1905 iph2->seq = msg->sadb_msg_seq; 1906 /* set end addresses of SA */ 1907 // Wcast_align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 1908 iph2->src = dupsaddr(ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC])); 1909 if (iph2->src == NULL) { 1910 ike_session_delph2(iph2); 1911 return -1; 1912 } 1913 iph2->dst = dupsaddr(ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST])); 1914 if (iph2->dst == NULL) { 1915 ike_session_delph2(iph2); 1916 return -1; 1917 } 1918 1919 if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV1) { 1920 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_START); 1921 } 1922 1923 plog(ASL_LEVEL_DEBUG, 1924 "new acquire %s\n", spidx2str(&sp_out->spidx)); 1925 1926 /* get sainfo */ 1927 { 1928 vchar_t *idsrc, *iddst; 1929 1930 idsrc = ipsecdoi_sockaddr2id(&sp_out->spidx.src, 1931 sp_out->spidx.prefs, sp_out->spidx.ul_proto); 1932 if (idsrc == NULL) { 1933 plog(ASL_LEVEL_ERR, 1934 "failed to get ID for %s\n", 1935 spidx2str(&sp_out->spidx)); 1936 ike_session_delph2(iph2); 1937 return -1; 1938 } 1939 iddst = ipsecdoi_sockaddr2id(&sp_out->spidx.dst, 1940 sp_out->spidx.prefd, sp_out->spidx.ul_proto); 1941 if (iddst == NULL) { 1942 plog(ASL_LEVEL_ERR, 1943 "failed to get ID for %s\n", 1944 spidx2str(&sp_out->spidx)); 1945 vfree(idsrc); 1946 ike_session_delph2(iph2); 1947 return -1; 1948 } 1949 iph2->sainfo = getsainfo(idsrc, iddst, NULL, 0); 1950 vfree(idsrc); 1951 vfree(iddst); 1952 if (iph2->sainfo == NULL) { 1953 plog(ASL_LEVEL_ERR, 1954 "failed to get sainfo.\n"); 1955 ike_session_delph2(iph2); 1956 return -1; 1957 /* XXX should use the algorithm list from register message */ 1958 } 1959 } 1960 retain_sainfo(iph2->sainfo); 1961 1962 if (set_proposal_from_policy(iph2, sp_out, sp_in) < 0) { 1963 plog(ASL_LEVEL_ERR, 1964 "failed to create saprop.\n"); 1965 ike_session_delph2(iph2); 1966 return -1; 1967 } 1968 1969 if (session == NULL) 1970 session = ike_session_get_session(iph2->src, iph2->dst, 1, NULL); 1971 if (session == NULL) 1972 fatal_error(-1); 1973 1974 if (ike_session_link_phase2(session, iph2)) 1975 fatal_error(-1); //????? fix ??? 1976 1977 /* start isakmp initiation by using ident exchange */ 1978 /* XXX should be looped if there are multiple phase 2 handler. */ 1979 if (isakmp_post_acquire(iph2) < 0) { 1980 plog(ASL_LEVEL_ERR, 1981 "failed to begin ipsec sa negotiation.\n"); 1982 goto err; 1983 } 1984 1985#if !TARGET_OS_EMBEDDED 1986 if ( lcconf->vt == NULL){ 1987 if (!(lcconf->vt = vproc_transaction_begin(NULL))) 1988 plog(ASL_LEVEL_ERR, 1989 "vproc_transaction_begin returns NULL.\n"); 1990 } 1991#endif 1992 1993 1994 return 0; 1995 1996err: 1997 ike_session_unlink_phase2(iph2); 1998 return -1; 1999} 2000 2001static int 2002pk_recvdelete(mhp) 2003 caddr_t *mhp; 2004{ 2005 struct sadb_msg *msg; 2006 struct sadb_sa *sa; 2007 struct sockaddr_storage *src, *dst; 2008 phase2_handle_t *iph2 = NULL; 2009 u_int proto_id; 2010 2011 /* ignore this message because of local test mode. */ 2012 if (f_local) 2013 return 0; 2014 2015 /* sanity check */ 2016 if (mhp[0] == NULL 2017 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 2018 || mhp[SADB_EXT_ADDRESS_DST] == NULL) { 2019 plog(ASL_LEVEL_ERR, 2020 "inappropriate sadb delete message passed.\n"); 2021 return -1; 2022 } 2023 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 2024 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA]; 2025 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); 2026 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); 2027 2028 /* the message has to be processed or not ? */ 2029 if (msg->sadb_msg_pid == getpid()) { 2030 plog(ASL_LEVEL_DEBUG, 2031 "%s message is not interesting " 2032 "because the message was originated by me.\n", 2033 s_pfkey_type(msg->sadb_msg_type)); 2034 return -1; 2035 } 2036 2037 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); 2038 if (proto_id == ~0) { 2039 plog(ASL_LEVEL_ERR, 2040 "invalid proto_id %d\n", msg->sadb_msg_satype); 2041 return -1; 2042 } 2043 2044 plog(ASL_LEVEL_DEBUG, "SADB delete message: proto-id %d\n", proto_id); 2045 plog(ASL_LEVEL_DEBUG, "src: %s\n", saddr2str((struct sockaddr *)src)); 2046 plog(ASL_LEVEL_DEBUG, "dst: %s\n", saddr2str((struct sockaddr *)dst)); 2047 2048 if (!sa) { 2049 ike_session_deleteallph2(src, dst, proto_id); 2050 ike_session_deleteallph1(src, dst); 2051 return 0; 2052 } 2053 2054 iph2 = ike_session_getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi); 2055 if (iph2 == NULL) { 2056 /* ignore */ 2057 plog(ASL_LEVEL_ERR, 2058 "no iph2 found: %s\n", 2059 sadbsecas2str(src, dst, msg->sadb_msg_satype, 2060 sa->sadb_sa_spi, IPSEC_MODE_ANY)); 2061 return 0; 2062 } 2063 2064 plog(ASL_LEVEL_ERR, 2065 "pfkey DELETE received: %s\n", 2066 sadbsecas2str(iph2->src, iph2->dst, 2067 msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY)); 2068 2069 /* send delete information */ 2070 2071 /* TODO: Look into handling this properly. Currently, if we get here, we can end up sending delete messages to the server for their own SAs, which is rejected. */ 2072 /*if (FSM_STATE_IS_ESTABLISHED(iph2->status)) 2073 isakmp_info_send_d2(iph2); 2074 2075 ike_session_cleanup_ph1s_by_ph2(iph2); 2076 ike_session_unlink_phase2(iph2);*/ 2077 2078 return 0; 2079} 2080 2081static int 2082pk_recvflush(mhp) 2083 caddr_t *mhp; 2084{ 2085 /* sanity check */ 2086 if (mhp[0] == NULL) { 2087 plog(ASL_LEVEL_ERR, 2088 "inappropriate sadb flush message passed.\n"); 2089 return -1; 2090 } 2091 2092 ike_session_flush_all_phase2(false); 2093 ike_session_flush_all_phase1(false); 2094 2095 return 0; 2096} 2097 2098static int 2099getsadbpolicy(policy0, policylen0, type, iph2) 2100 caddr_t *policy0; 2101 int *policylen0, type; 2102 phase2_handle_t *iph2; 2103{ 2104 struct policyindex *spidx = iph2->spidx_gen; 2105 struct sadb_x_policy *xpl; 2106 struct sadb_x_ipsecrequest *xisr; 2107 struct saproto *pr; 2108 caddr_t policy, p; 2109 int policylen; 2110 int xisrlen; 2111 u_int satype, mode; 2112 2113 /* get policy buffer size */ 2114 policylen = sizeof(struct sadb_x_policy); 2115 if (type != SADB_X_SPDDELETE) { 2116 for (pr = iph2->approval->head; pr; pr = pr->next) { 2117 xisrlen = sizeof(*xisr); 2118 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) { 2119 xisrlen += (sysdep_sa_len((struct sockaddr *)iph2->src) 2120 + sysdep_sa_len((struct sockaddr *)iph2->dst)); 2121 } 2122 2123 policylen += PFKEY_ALIGN8(xisrlen); 2124 } 2125 } 2126 2127 /* make policy structure */ 2128 policy = racoon_malloc(policylen); 2129 if (!policy) { 2130 plog(ASL_LEVEL_ERR, 2131 "buffer allocation failed.\n"); 2132 return -1; 2133 } 2134 2135 xpl = ALIGNED_CAST(struct sadb_x_policy *)policy; 2136 xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen); 2137 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; 2138 xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC; 2139 xpl->sadb_x_policy_dir = spidx->dir; 2140 xpl->sadb_x_policy_id = 0; 2141#ifdef HAVE_PFKEY_POLICY_PRIORITY 2142 xpl->sadb_x_policy_priority = PRIORITY_DEFAULT; 2143#endif 2144 2145 /* no need to append policy information any more if type is SPDDELETE */ 2146 if (type == SADB_X_SPDDELETE) 2147 goto end; 2148 2149 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1); 2150 2151 for (pr = iph2->approval->head; pr; pr = pr->next) { 2152 2153 satype = doi2ipproto(pr->proto_id); 2154 if (satype == ~0) { 2155 plog(ASL_LEVEL_ERR, 2156 "invalid proto_id %d\n", pr->proto_id); 2157 goto err; 2158 } 2159 mode = ipsecdoi2pfkey_mode(pr->encmode); 2160 if (mode == ~0) { 2161 plog(ASL_LEVEL_ERR, 2162 "invalid encmode %d\n", pr->encmode); 2163 goto err; 2164 } 2165 2166 /* 2167 * the policy level cannot be unique because the policy 2168 * is defined later than SA, so req_id cannot be bound to SA. 2169 */ 2170 xisr->sadb_x_ipsecrequest_proto = satype; 2171 xisr->sadb_x_ipsecrequest_mode = mode; 2172 xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE; 2173 xisr->sadb_x_ipsecrequest_reqid = 0; 2174 p = (caddr_t)(xisr + 1); 2175 2176 xisrlen = sizeof(*xisr); 2177 2178 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) { 2179 int src_len, dst_len; 2180 2181 src_len = sysdep_sa_len((struct sockaddr *)iph2->src); 2182 dst_len = sysdep_sa_len((struct sockaddr *)iph2->dst); 2183 xisrlen += src_len + dst_len; 2184 2185 memcpy(p, iph2->src, src_len); 2186 p += src_len; 2187 2188 memcpy(p, iph2->dst, dst_len); 2189 p += dst_len; 2190 } 2191 2192 xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen); 2193 } 2194 2195end: 2196 *policy0 = policy; 2197 *policylen0 = policylen; 2198 2199 return 0; 2200 2201err: 2202 if (policy) 2203 racoon_free(policy); 2204 2205 return -1; 2206} 2207 2208int 2209pk_sendspdupdate2(iph2) 2210 phase2_handle_t *iph2; 2211{ 2212 struct policyindex *spidx = iph2->spidx_gen; 2213 caddr_t policy = NULL; 2214 int policylen = 0; 2215 u_int64_t ltime, vtime; 2216 2217 ltime = iph2->approval->lifetime; 2218 vtime = 0; 2219 2220 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) { 2221 plog(ASL_LEVEL_ERR, 2222 "getting sadb policy failed.\n"); 2223 return -1; 2224 } 2225 2226 if (pfkey_send_spdupdate2( 2227 lcconf->sock_pfkey, 2228 &spidx->src, 2229 spidx->prefs, 2230 &spidx->dst, 2231 spidx->prefd, 2232 spidx->ul_proto, 2233 ltime, vtime, 2234 policy, policylen, 0) < 0) { 2235 plog(ASL_LEVEL_ERR, 2236 "libipsec failed send spdupdate2 (%s)\n", 2237 ipsec_strerror()); 2238 goto end; 2239 } 2240 plog(ASL_LEVEL_DEBUG, "call pfkey_send_spdupdate2\n"); 2241 2242end: 2243 if (policy) 2244 racoon_free(policy); 2245 2246 return 0; 2247} 2248 2249static int 2250pk_recvspdupdate(mhp) 2251 caddr_t *mhp; 2252{ 2253 struct sadb_address *saddr, *daddr; 2254 struct sadb_x_policy *xpl; 2255 struct policyindex spidx; 2256 struct secpolicy *sp; 2257 2258 /* sanity check */ 2259 if (mhp[0] == NULL 2260 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 2261 || mhp[SADB_EXT_ADDRESS_DST] == NULL 2262 || mhp[SADB_X_EXT_POLICY] == NULL) { 2263 plog(ASL_LEVEL_ERR, 2264 "inappropriate sadb spdupdate message passed.\n"); 2265 return -1; 2266 } 2267 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 2268 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; 2269 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; 2270 2271#ifdef HAVE_PFKEY_POLICY_PRIORITY 2272 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2273 saddr + 1, 2274 daddr + 1, 2275 saddr->sadb_address_prefixlen, 2276 daddr->sadb_address_prefixlen, 2277 saddr->sadb_address_proto, 2278 xpl->sadb_x_policy_priority, 2279 &spidx); 2280#else 2281 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2282 saddr + 1, 2283 daddr + 1, 2284 saddr->sadb_address_prefixlen, 2285 daddr->sadb_address_prefixlen, 2286 saddr->sadb_address_proto, 2287 &spidx); 2288#endif 2289 2290 sp = getsp(&spidx); 2291 if (sp == NULL) { 2292 plog(ASL_LEVEL_ERR, 2293 "such policy does not already exist: \"%s\"\n", 2294 spidx2str(&spidx)); 2295 } else { 2296 remsp(sp); 2297 delsp(sp); 2298 } 2299 2300 if (addnewsp(mhp) < 0) 2301 return -1; 2302 2303 return 0; 2304} 2305 2306/* 2307 * this function has to be used by responder side. 2308 */ 2309int 2310pk_sendspdadd2(iph2) 2311 phase2_handle_t *iph2; 2312{ 2313 struct policyindex *spidx = iph2->spidx_gen; 2314 caddr_t policy = NULL; 2315 int policylen = 0; 2316 u_int64_t ltime, vtime; 2317 2318 ltime = iph2->approval->lifetime; 2319 vtime = 0; 2320 2321 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) { 2322 plog(ASL_LEVEL_ERR, 2323 "getting sadb policy failed.\n"); 2324 return -1; 2325 } 2326 2327 if (pfkey_send_spdadd2( 2328 lcconf->sock_pfkey, 2329 &spidx->src, 2330 spidx->prefs, 2331 &spidx->dst, 2332 spidx->prefd, 2333 spidx->ul_proto, 2334 ltime, vtime, 2335 policy, policylen, 0) < 0) { 2336 plog(ASL_LEVEL_ERR, 2337 "libipsec failed send spdadd2 (%s)\n", 2338 ipsec_strerror()); 2339 goto end; 2340 } 2341 plog(ASL_LEVEL_DEBUG, "call pfkey_send_spdadd2\n"); 2342 2343end: 2344 if (policy) 2345 racoon_free(policy); 2346 2347 return 0; 2348} 2349 2350static int 2351pk_recvspdadd(mhp) 2352 caddr_t *mhp; 2353{ 2354 struct sadb_address *saddr, *daddr; 2355 struct sadb_x_policy *xpl; 2356 struct policyindex spidx; 2357 struct secpolicy *sp; 2358 2359 /* sanity check */ 2360 if (mhp[0] == NULL 2361 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 2362 || mhp[SADB_EXT_ADDRESS_DST] == NULL 2363 || mhp[SADB_X_EXT_POLICY] == NULL) { 2364 plog(ASL_LEVEL_ERR, 2365 "inappropriate sadb spdadd message passed.\n"); 2366 return -1; 2367 } 2368 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 2369 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; 2370 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; 2371 2372#ifdef HAVE_PFKEY_POLICY_PRIORITY 2373 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2374 saddr + 1, 2375 daddr + 1, 2376 saddr->sadb_address_prefixlen, 2377 daddr->sadb_address_prefixlen, 2378 saddr->sadb_address_proto, 2379 xpl->sadb_x_policy_priority, 2380 &spidx); 2381#else 2382 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2383 saddr + 1, 2384 daddr + 1, 2385 saddr->sadb_address_prefixlen, 2386 daddr->sadb_address_prefixlen, 2387 saddr->sadb_address_proto, 2388 &spidx); 2389#endif 2390 2391 sp = getsp(&spidx); 2392 if (sp != NULL) { 2393 plog(ASL_LEVEL_ERR, 2394 "such policy already exists. " 2395 "anyway replace it: %s\n", 2396 spidx2str(&spidx)); 2397 remsp(sp); 2398 delsp(sp); 2399 } 2400 2401 if (addnewsp(mhp) < 0) 2402 return -1; 2403 2404 return 0; 2405} 2406 2407/* 2408 * this function has to be used by responder side. 2409 */ 2410int 2411pk_sendspddelete(iph2) 2412 phase2_handle_t *iph2; 2413{ 2414 struct policyindex *spidx = iph2->spidx_gen; 2415 caddr_t policy = NULL; 2416 int policylen; 2417 2418 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) { 2419 plog(ASL_LEVEL_ERR, 2420 "getting sadb policy failed.\n"); 2421 return -1; 2422 } 2423 2424 if (pfkey_send_spddelete( 2425 lcconf->sock_pfkey, 2426 &spidx->src, 2427 spidx->prefs, 2428 &spidx->dst, 2429 spidx->prefd, 2430 spidx->ul_proto, 2431 policy, policylen, 0) < 0) { 2432 plog(ASL_LEVEL_ERR, 2433 "libipsec failed send spddelete (%s)\n", 2434 ipsec_strerror()); 2435 goto end; 2436 } 2437 plog(ASL_LEVEL_DEBUG, "call pfkey_send_spddelete\n"); 2438 2439end: 2440 if (policy) 2441 racoon_free(policy); 2442 2443 return 0; 2444} 2445 2446static int 2447pk_recvspddelete(mhp) 2448 caddr_t *mhp; 2449{ 2450 struct sadb_address *saddr, *daddr; 2451 struct sadb_x_policy *xpl; 2452 struct policyindex spidx; 2453 struct secpolicy *sp; 2454 2455 /* sanity check */ 2456 if (mhp[0] == NULL 2457 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 2458 || mhp[SADB_EXT_ADDRESS_DST] == NULL 2459 || mhp[SADB_X_EXT_POLICY] == NULL) { 2460 plog(ASL_LEVEL_ERR, 2461 "inappropriate sadb spddelete message passed.\n"); 2462 return -1; 2463 } 2464 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 2465 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; 2466 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; 2467 2468#ifdef HAVE_PFKEY_POLICY_PRIORITY 2469 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2470 saddr + 1, 2471 daddr + 1, 2472 saddr->sadb_address_prefixlen, 2473 daddr->sadb_address_prefixlen, 2474 saddr->sadb_address_proto, 2475 xpl->sadb_x_policy_priority, 2476 &spidx); 2477#else 2478 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2479 saddr + 1, 2480 daddr + 1, 2481 saddr->sadb_address_prefixlen, 2482 daddr->sadb_address_prefixlen, 2483 saddr->sadb_address_proto, 2484 &spidx); 2485#endif 2486 2487 sp = getsp(&spidx); 2488 if (sp == NULL) { 2489 plog(ASL_LEVEL_ERR, 2490 "no policy found: %s\n", 2491 spidx2str(&spidx)); 2492 return -1; 2493 } 2494 2495 ike_session_purgephXbyspid(xpl->sadb_x_policy_id, true); 2496 2497 remsp(sp); 2498 delsp(sp); 2499 2500 return 0; 2501} 2502 2503static int 2504pk_recvspdexpire(mhp) 2505 caddr_t *mhp; 2506{ 2507 struct sadb_address *saddr, *daddr; 2508 struct sadb_x_policy *xpl; 2509 struct policyindex spidx; 2510 struct secpolicy *sp; 2511 2512 /* sanity check */ 2513 if (mhp[0] == NULL 2514 || mhp[SADB_EXT_ADDRESS_SRC] == NULL 2515 || mhp[SADB_EXT_ADDRESS_DST] == NULL 2516 || mhp[SADB_X_EXT_POLICY] == NULL) { 2517 plog(ASL_LEVEL_ERR, 2518 "inappropriate sadb spdexpire message passed.\n"); 2519 return -1; 2520 } 2521 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 2522 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; 2523 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; 2524 2525#ifdef HAVE_PFKEY_POLICY_PRIORITY 2526 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2527 saddr + 1, 2528 daddr + 1, 2529 saddr->sadb_address_prefixlen, 2530 daddr->sadb_address_prefixlen, 2531 saddr->sadb_address_proto, 2532 xpl->sadb_x_policy_priority, 2533 &spidx); 2534#else 2535 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2536 saddr + 1, 2537 daddr + 1, 2538 saddr->sadb_address_prefixlen, 2539 daddr->sadb_address_prefixlen, 2540 saddr->sadb_address_proto, 2541 &spidx); 2542#endif 2543 2544 sp = getsp(&spidx); 2545 if (sp == NULL) { 2546 plog(ASL_LEVEL_ERR, 2547 "no policy found: %s\n", 2548 spidx2str(&spidx)); 2549 return -1; 2550 } 2551 2552 ike_session_purgephXbyspid(xpl->sadb_x_policy_id, false); 2553 2554 remsp(sp); 2555 delsp(sp); 2556 2557 return 0; 2558} 2559 2560static int 2561pk_recvspdget(mhp) 2562 caddr_t *mhp; 2563{ 2564 /* sanity check */ 2565 if (mhp[0] == NULL) { 2566 plog(ASL_LEVEL_ERR, 2567 "inappropriate sadb spdget message passed.\n"); 2568 return -1; 2569 } 2570 2571 return 0; 2572} 2573 2574static int 2575pk_recvspddump(mhp) 2576 caddr_t *mhp; 2577{ 2578 struct sadb_msg *msg; 2579 struct sadb_address *saddr, *daddr; 2580 struct sadb_x_policy *xpl; 2581 struct policyindex spidx; 2582 struct secpolicy *sp; 2583 2584 /* sanity check */ 2585 if (mhp[0] == NULL) { 2586 plog(ASL_LEVEL_ERR, 2587 "inappropriate sadb spddump message passed.\n"); 2588 return -1; 2589 } 2590 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 2591 2592 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; 2593 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; 2594 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; 2595 2596 if (saddr == NULL || daddr == NULL || xpl == NULL) { 2597 plog(ASL_LEVEL_ERR, 2598 "inappropriate sadb spddump message passed.\n"); 2599 return -1; 2600 } 2601 2602#ifdef HAVE_PFKEY_POLICY_PRIORITY 2603 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2604 saddr + 1, 2605 daddr + 1, 2606 saddr->sadb_address_prefixlen, 2607 daddr->sadb_address_prefixlen, 2608 saddr->sadb_address_proto, 2609 xpl->sadb_x_policy_priority, 2610 &spidx); 2611#else 2612 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 2613 saddr + 1, 2614 daddr + 1, 2615 saddr->sadb_address_prefixlen, 2616 daddr->sadb_address_prefixlen, 2617 saddr->sadb_address_proto, 2618 &spidx); 2619#endif 2620 2621 sp = getsp(&spidx); 2622 if (sp != NULL) { 2623 plog(ASL_LEVEL_ERR, 2624 "such policy already exists. " 2625 "anyway replace it: %s\n", 2626 spidx2str(&spidx)); 2627 remsp(sp); 2628 delsp(sp); 2629 } 2630 2631 if (addnewsp(mhp) < 0) 2632 return -1; 2633 2634 return 0; 2635} 2636 2637static int 2638pk_recvspdflush(mhp) 2639 caddr_t *mhp; 2640{ 2641 /* sanity check */ 2642 if (mhp[0] == NULL) { 2643 plog(ASL_LEVEL_ERR, 2644 "inappropriate sadb spdflush message passed.\n"); 2645 return -1; 2646 } 2647 2648 ike_session_flush_all_phase2(false); 2649 ike_session_flush_all_phase1(false); 2650 flushsp(); 2651 2652 return 0; 2653} 2654 2655/* 2656 * send error against acquire message to kenrel. 2657 */ 2658int 2659pk_sendeacquire(iph2) 2660 phase2_handle_t *iph2; 2661{ 2662 struct sadb_msg *newmsg; 2663 int len; 2664 2665 len = sizeof(struct sadb_msg); 2666 newmsg = racoon_calloc(1, len); 2667 if (newmsg == NULL) { 2668 plog(ASL_LEVEL_ERR, 2669 "failed to get buffer to send acquire.\n"); 2670 return -1; 2671 } 2672 2673 memset(newmsg, 0, len); 2674 newmsg->sadb_msg_version = PF_KEY_V2; 2675 newmsg->sadb_msg_type = SADB_ACQUIRE; 2676 newmsg->sadb_msg_errno = ENOENT; /* XXX */ 2677 newmsg->sadb_msg_satype = iph2->satype; 2678 newmsg->sadb_msg_len = PFKEY_UNIT64(len); 2679 newmsg->sadb_msg_reserved = 0; 2680 newmsg->sadb_msg_seq = iph2->seq; 2681 newmsg->sadb_msg_pid = (u_int32_t)getpid(); 2682 2683 /* send message */ 2684 len = pfkey_send(lcconf->sock_pfkey, newmsg, len); 2685 2686 racoon_free(newmsg); 2687 2688 return 0; 2689} 2690 2691int 2692pk_sendget_inbound_sastats(ike_session_t *session) 2693{ 2694 u_int32_t max_stats; 2695 u_int32_t seq; 2696 2697 if (!session) { 2698 plog(ASL_LEVEL_DEBUG, "invalid args in %s \n", __FUNCTION__); 2699 return -1; 2700 } 2701 2702 session->traffic_monitor.num_in_curr_req = 0; 2703 bzero(session->traffic_monitor.in_curr_req, sizeof(session->traffic_monitor.in_curr_req)); 2704 max_stats = (sizeof(session->traffic_monitor.in_curr_req) / sizeof(session->traffic_monitor.in_curr_req[0])); 2705 2706 // get list of SAs 2707 if ((session->traffic_monitor.num_in_curr_req = ike_session_get_sas_for_stats(session, 2708 IPSEC_DIR_INBOUND, 2709 &seq, 2710 session->traffic_monitor.in_curr_req, 2711 max_stats))) { 2712 u_int64_t session_ids[] = {(u_int64_t)session, 0}; 2713 2714 //plog(ASL_LEVEL_DEBUG, "about to call %s\n", __FUNCTION__); 2715 2716 if (pfkey_send_getsastats(lcconf->sock_pfkey, 2717 seq, 2718 session_ids, 2719 1, 2720 IPSEC_DIR_INBOUND, 2721 session->traffic_monitor.in_curr_req, 2722 session->traffic_monitor.num_in_curr_req) < 0) { 2723 return -1; 2724 } 2725 //plog(ASL_LEVEL_DEBUG, "%s successful\n", __FUNCTION__); 2726 2727 return session->traffic_monitor.num_in_curr_req; 2728 } 2729 return 0; 2730} 2731 2732int 2733pk_sendget_outbound_sastats(ike_session_t *session) 2734{ 2735 u_int32_t max_stats; 2736 u_int32_t seq; 2737 2738 if (!session) { 2739 plog(ASL_LEVEL_DEBUG, "invalid args in %s \n", __FUNCTION__); 2740 return -1; 2741 } 2742 2743 session->traffic_monitor.num_out_curr_req = 0; 2744 bzero(session->traffic_monitor.out_curr_req, sizeof(session->traffic_monitor.out_curr_req)); 2745 max_stats = (sizeof(session->traffic_monitor.out_curr_req) / sizeof(session->traffic_monitor.out_curr_req[0])); 2746 2747 // get list of SAs 2748 if ((session->traffic_monitor.num_out_curr_req = ike_session_get_sas_for_stats(session, 2749 IPSEC_DIR_OUTBOUND, 2750 &seq, 2751 session->traffic_monitor.out_curr_req, 2752 max_stats))) { 2753 u_int64_t session_ids[] = {(u_int64_t)session, 0}; 2754 2755 //plog(ASL_LEVEL_DEBUG, "about to call %s\n", __FUNCTION__); 2756 2757 if (pfkey_send_getsastats(lcconf->sock_pfkey, 2758 seq, 2759 session_ids, 2760 1, 2761 IPSEC_DIR_OUTBOUND, 2762 session->traffic_monitor.out_curr_req, 2763 session->traffic_monitor.num_out_curr_req) < 0) { 2764 return -1; 2765 } 2766 //plog(ASL_LEVEL_DEBUG, "%s successful\n", __FUNCTION__); 2767 2768 return session->traffic_monitor.num_out_curr_req; 2769 } 2770 return 0; 2771} 2772 2773/* 2774 * receive GETSPDSTAT from kernel. 2775 */ 2776static int 2777pk_recvgetsastat(mhp) 2778caddr_t *mhp; 2779{ 2780 struct sadb_msg *msg; 2781 struct sadb_session_id *session_id; 2782 struct sadb_sastat *stat_resp; 2783 ike_session_t *session; 2784 2785 /* validity check */ 2786 if (mhp[0] == NULL || 2787 mhp[SADB_EXT_SESSION_ID] == NULL || 2788 mhp[SADB_EXT_SASTAT] == NULL) { 2789 plog(ASL_LEVEL_ERR, 2790 "inappropriate sadb getsastat response.\n"); 2791 return -1; 2792 } 2793 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to structs in an aligned buffer 2794 session_id = ALIGNED_CAST(struct sadb_session_id *)mhp[SADB_EXT_SESSION_ID]; 2795 stat_resp = ALIGNED_CAST(struct sadb_sastat *)mhp[SADB_EXT_SASTAT]; 2796 2797 /* the message has to be processed or not ? */ 2798 if (msg->sadb_msg_pid != getpid()) { 2799 plog(ASL_LEVEL_DEBUG, 2800 "%s message is not interesting " 2801 "because pid %d is not mine.\n", 2802 s_pfkey_type(msg->sadb_msg_type), 2803 msg->sadb_msg_pid); 2804 return -1; 2805 } 2806 if (!session_id->sadb_session_id_v[0]) { 2807 plog(ASL_LEVEL_DEBUG, 2808 "%s message is bad " 2809 "because session-id[0] is invalid.\n", 2810 s_pfkey_type(msg->sadb_msg_type)); 2811 return -1; 2812 } 2813 session = ALIGNED_CAST(__typeof__(session))session_id->sadb_session_id_v[0]; 2814 2815 if (!stat_resp->sadb_sastat_list_len) { 2816 plog(ASL_LEVEL_DEBUG, 2817 "%s message is bad " 2818 "because it has no sastats.\n", 2819 s_pfkey_type(msg->sadb_msg_type)); 2820 return -1; 2821 } 2822 2823 ike_session_update_traffic_idle_status(session, 2824 stat_resp->sadb_sastat_dir, 2825 (struct sastat *)(stat_resp + 1), 2826 stat_resp->sadb_sastat_list_len); 2827 return 0; 2828} 2829 2830/* 2831 * check if the algorithm is supported or not. 2832 * OUT 0: ok 2833 * -1: ng 2834 */ 2835int 2836pk_checkalg(class, calg, keylen) 2837 int class, calg, keylen; 2838{ 2839 int sup, error; 2840 u_int alg; 2841 struct sadb_alg alg0; 2842 2843 switch (algclass2doi(class)) { 2844 case IPSECDOI_PROTO_IPSEC_ESP: 2845 sup = SADB_EXT_SUPPORTED_ENCRYPT; 2846 break; 2847 case IPSECDOI_ATTR_AUTH: 2848 sup = SADB_EXT_SUPPORTED_AUTH; 2849 break; 2850 case IPSECDOI_PROTO_IPCOMP: 2851 return 0; 2852 default: 2853 plog(ASL_LEVEL_ERR, 2854 "invalid algorithm class.\n"); 2855 return -1; 2856 } 2857 alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg)); 2858 if (alg == ~0) 2859 return -1; 2860 2861 if (keylen == 0) { 2862 if (ipsec_get_keylen(sup, alg, &alg0)) { 2863 plog(ASL_LEVEL_ERR, 2864 "%s.\n", ipsec_strerror()); 2865 return -1; 2866 } 2867 keylen = alg0.sadb_alg_minbits; 2868 } 2869 2870 error = ipsec_check_keylen(sup, alg, keylen); 2871 if (error) 2872 plog(ASL_LEVEL_ERR, 2873 "%s.\n", ipsec_strerror()); 2874 2875 return error; 2876} 2877 2878/* 2879 * differences with pfkey_recv() in libipsec/pfkey.c: 2880 * - never performs busy wait loop. 2881 * - returns NULL and set *lenp to negative on fatal failures 2882 * - returns NULL and set *lenp to non-negative on non-fatal failures 2883 * - returns non-NULL on success 2884 */ 2885static struct sadb_msg * 2886pk_recv(so, lenp) 2887 int so; 2888 ssize_t *lenp; 2889{ 2890 struct sadb_msg *newmsg; 2891 int reallen = 0; 2892 socklen_t optlen = sizeof(reallen); 2893 2894 if (getsockopt(so, SOL_SOCKET, SO_NREAD, &reallen, &optlen) < 0) 2895 return NULL; /*fatal*/ 2896 2897 if (reallen == 0) 2898 return NULL; 2899 2900 if ((newmsg = racoon_calloc(1, reallen)) == NULL) 2901 return NULL; 2902 2903 while ((*lenp = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) { 2904 if (errno == EINTR) 2905 continue; 2906 plog(ASL_LEVEL_ERR, "failed to recv pfkey message: %s\n", strerror(errno)); 2907 break; 2908 } 2909 if (*lenp < 0) { 2910 racoon_free(newmsg); 2911 return NULL; /*fatal*/ 2912 } else if (*lenp != reallen || *lenp < sizeof(struct sadb_msg)) { 2913 racoon_free(newmsg); 2914 return NULL; 2915 } 2916 2917 return newmsg; 2918} 2919 2920/* see handler.h */ 2921u_int32_t 2922pk_getseq() 2923{ 2924 return eay_random(); 2925} 2926 2927static int 2928addnewsp(mhp) 2929 caddr_t *mhp; 2930{ 2931 struct secpolicy *new; 2932 struct sadb_address *saddr, *daddr; 2933 struct sadb_x_policy *xpl; 2934 2935 /* sanity check */ 2936 if (mhp[SADB_EXT_ADDRESS_SRC] == NULL 2937 || mhp[SADB_EXT_ADDRESS_DST] == NULL 2938 || mhp[SADB_X_EXT_POLICY] == NULL) { 2939 plog(ASL_LEVEL_ERR, 2940 "inappropriate sadb spd management message passed.\n"); 2941 return -1; 2942 } 2943 2944 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer 2945 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; 2946 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY]; 2947 2948 new = newsp(); 2949 if (new == NULL) { 2950 plog(ASL_LEVEL_ERR, 2951 "failed to allocate buffer\n"); 2952 return -1; 2953 } 2954 2955 new->spidx.dir = xpl->sadb_x_policy_dir; 2956 new->id = xpl->sadb_x_policy_id; 2957 new->policy = xpl->sadb_x_policy_type; 2958 new->req = NULL; 2959 2960 /* check policy */ 2961 switch (xpl->sadb_x_policy_type) { 2962 case IPSEC_POLICY_DISCARD: 2963 case IPSEC_POLICY_GENERATE: 2964 case IPSEC_POLICY_NONE: 2965 case IPSEC_POLICY_ENTRUST: 2966 case IPSEC_POLICY_BYPASS: 2967 break; 2968 2969 case IPSEC_POLICY_IPSEC: 2970 { 2971 int tlen; 2972 struct sadb_x_ipsecrequest *xisr; 2973 struct ipsecrequest **p_isr = &new->req; 2974 2975 /* validity check */ 2976 if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) { 2977 plog(ASL_LEVEL_ERR, 2978 "invalid msg length.\n"); 2979 return -1; 2980 } 2981 2982 tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl); 2983 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1); 2984 2985 while (tlen > 0) { 2986 2987 /* length check */ 2988 if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) { 2989 plog(ASL_LEVEL_ERR, 2990 "invalid msg length.\n"); 2991 return -1; 2992 } 2993 2994 /* allocate request buffer */ 2995 *p_isr = newipsecreq(); 2996 if (*p_isr == NULL) { 2997 plog(ASL_LEVEL_ERR, 2998 "failed to get new ipsecreq.\n"); 2999 return -1; 3000 } 3001 3002 /* set values */ 3003 (*p_isr)->next = NULL; 3004 3005 switch (xisr->sadb_x_ipsecrequest_proto) { 3006 case IPPROTO_ESP: 3007 case IPPROTO_AH: 3008 case IPPROTO_IPCOMP: 3009 break; 3010 default: 3011 plog(ASL_LEVEL_ERR, 3012 "invalid proto type: %u\n", 3013 xisr->sadb_x_ipsecrequest_proto); 3014 return -1; 3015 } 3016 (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto; 3017 3018 switch (xisr->sadb_x_ipsecrequest_mode) { 3019 case IPSEC_MODE_TRANSPORT: 3020 case IPSEC_MODE_TUNNEL: 3021 break; 3022 case IPSEC_MODE_ANY: 3023 default: 3024 plog(ASL_LEVEL_ERR, 3025 "invalid mode: %u\n", 3026 xisr->sadb_x_ipsecrequest_mode); 3027 return -1; 3028 } 3029 (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode; 3030 3031 switch (xisr->sadb_x_ipsecrequest_level) { 3032 case IPSEC_LEVEL_DEFAULT: 3033 case IPSEC_LEVEL_USE: 3034 case IPSEC_LEVEL_REQUIRE: 3035 break; 3036 case IPSEC_LEVEL_UNIQUE: 3037 (*p_isr)->saidx.reqid = 3038 xisr->sadb_x_ipsecrequest_reqid; 3039 break; 3040 3041 default: 3042 plog(ASL_LEVEL_ERR, 3043 "invalid level: %u\n", 3044 xisr->sadb_x_ipsecrequest_level); 3045 return -1; 3046 } 3047 (*p_isr)->level = xisr->sadb_x_ipsecrequest_level; 3048 3049 /* set IP addresses if there */ 3050 if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { 3051 struct sockaddr *paddr; 3052 3053 paddr = (struct sockaddr *)(xisr + 1); 3054 bcopy(paddr, &(*p_isr)->saidx.src, 3055 sysdep_sa_len(paddr)); 3056 3057 paddr = (struct sockaddr *)((caddr_t)paddr 3058 + sysdep_sa_len(paddr)); 3059 bcopy(paddr, &(*p_isr)->saidx.dst, 3060 sysdep_sa_len(paddr)); 3061 } 3062 3063 (*p_isr)->sp = new; 3064 3065 /* initialization for the next. */ 3066 p_isr = &(*p_isr)->next; 3067 tlen -= xisr->sadb_x_ipsecrequest_len; 3068 3069 /* validity check */ 3070 if (tlen < 0) { 3071 plog(ASL_LEVEL_ERR, 3072 "becoming tlen < 0\n"); 3073 } 3074 3075 xisr = ALIGNED_CAST(struct sadb_x_ipsecrequest *)((caddr_t)xisr 3076 + xisr->sadb_x_ipsecrequest_len); 3077 } 3078 } 3079 break; 3080 default: 3081 plog(ASL_LEVEL_ERR, 3082 "invalid policy type.\n"); 3083 return -1; 3084 } 3085 3086#ifdef HAVE_PFKEY_POLICY_PRIORITY 3087 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 3088 saddr + 1, 3089 daddr + 1, 3090 saddr->sadb_address_prefixlen, 3091 daddr->sadb_address_prefixlen, 3092 saddr->sadb_address_proto, 3093 xpl->sadb_x_policy_priority, 3094 &new->spidx); 3095#else 3096 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir, 3097 saddr + 1, 3098 daddr + 1, 3099 saddr->sadb_address_prefixlen, 3100 daddr->sadb_address_prefixlen, 3101 saddr->sadb_address_proto, 3102 &new->spidx); 3103#endif 3104 3105 inssp(new); 3106 3107 return 0; 3108} 3109 3110/* proto/mode/src->dst spi */ 3111const char * 3112sadbsecas2str(src, dst, proto, spi, mode) 3113 struct sockaddr_storage *src, *dst; 3114 int proto; 3115 u_int32_t spi; 3116 int mode; 3117{ 3118 static char buf[256]; 3119 u_int doi_proto, doi_mode = 0; 3120 char *p; 3121 int blen, i; 3122 3123 doi_proto = pfkey2ipsecdoi_proto(proto); 3124 if (doi_proto == ~0) 3125 return NULL; 3126 if (mode) { 3127 doi_mode = pfkey2ipsecdoi_mode(mode); 3128 if (doi_mode == ~0) 3129 return NULL; 3130 } 3131 3132 blen = sizeof(buf) - 1; 3133 p = buf; 3134 3135 i = snprintf(p, blen, "%s%s%s ", 3136 s_ipsecdoi_proto(doi_proto), 3137 mode ? "/" : "", 3138 mode ? s_ipsecdoi_encmode(doi_mode) : ""); 3139 if (i < 0 || i >= blen) 3140 return NULL; 3141 p += i; 3142 blen -= i; 3143 3144 i = snprintf(p, blen, "%s->", saddr2str((struct sockaddr *)src)); 3145 if (i < 0 || i >= blen) 3146 return NULL; 3147 p += i; 3148 blen -= i; 3149 3150 i = snprintf(p, blen, "%s ", saddr2str((struct sockaddr *)dst)); 3151 if (i < 0 || i >= blen) 3152 return NULL; 3153 p += i; 3154 blen -= i; 3155 3156 if (spi) { 3157 snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi), 3158 (unsigned long)ntohl(spi)); 3159 } 3160 3161 return buf; 3162} 3163