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