1 /* $Id: pfkey.c,v 1.31.2.10 2005/10/03 14:52:19 manubsd Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
33 #include "racoon_types.h"
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
48 #include <netinet/udp.h>
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>
57 #include <net/route.h>
58 #include <net/pfkeyv2.h>
60 #include <netinet/in.h>
61 #ifndef HAVE_NETINET6_IPSEC
62 #include <netinet/ipsec.h>
64 #include <netinet6/ipsec.h>
76 #include "ike_session.h"
79 #include "localconf.h"
80 #include "remoteconf.h"
81 #include "isakmp_var.h"
83 #include "isakmp_inf.h"
84 #include "ipsec_doi.h"
89 #include "algorithm.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"
105 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
106 #define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC
110 static u_int
ipsecdoi2pfkey_aalg (u_int
);
111 static u_int
ipsecdoi2pfkey_ealg (u_int
);
112 static u_int
ipsecdoi2pfkey_calg (u_int
);
113 static u_int
ipsecdoi2pfkey_alg (u_int
, u_int
);
114 static u_int
keylen_aalg (u_int
);
115 static u_int
keylen_ealg (u_int
, int);
117 static int pk_recvgetspi (caddr_t
*);
118 static int pk_recvupdate (caddr_t
*);
119 static int pk_recvadd (caddr_t
*);
120 static int pk_recvdelete (caddr_t
*);
121 static int pk_recvacquire (caddr_t
*);
122 static int pk_recvexpire (caddr_t
*);
123 static int pk_recvflush (caddr_t
*);
124 static int getsadbpolicy (caddr_t
*, int *, int, phase2_handle_t
*);
125 static int pk_recvspdupdate (caddr_t
*);
126 static int pk_recvspdadd (caddr_t
*);
127 static int pk_recvspddelete (caddr_t
*);
128 static int pk_recvspdexpire (caddr_t
*);
129 static int pk_recvspdget (caddr_t
*);
130 static int pk_recvspddump (caddr_t
*);
131 static int pk_recvspdflush (caddr_t
*);
132 static int pk_recvgetsastat (caddr_t
*);
133 static struct sadb_msg
*pk_recv (int, ssize_t
*);
135 static int (*pkrecvf
[]) (caddr_t
*) = {
143 NULL
, /* SABD_REGISTER */
146 NULL
, /* SADB_DUMP */
147 NULL
, /* SADB_X_PROMISC */
148 NULL
, /* SADB_X_PCHANGE */
153 NULL
, /* SADB_X_SPDACQUIRE */
156 NULL
, /* SADB_X_SPDSETIDX */
158 NULL
, /* SADB_X_SPDDELETE2 */
159 pk_recvgetsastat
, /* SADB_GETSASTAT */
160 NULL
, /* SADB_X_SPDENABLE */
161 NULL
, /* SADB_X_SPDDISNABLE */
162 NULL
, /* SADB_MIGRATE */
164 #warning "SADB extra message?"
168 static int addnewsp (caddr_t
*);
170 /* cope with old kame headers - ugly */
171 #ifndef SADB_X_AALG_MD5
172 #define SADB_X_AALG_MD5 SADB_AALG_MD5
174 #ifndef SADB_X_AALG_SHA
175 #define SADB_X_AALG_SHA SADB_AALG_SHA
177 #ifndef SADB_X_AALG_NULL
178 #define SADB_X_AALG_NULL SADB_AALG_NULL
181 #ifndef SADB_X_EALG_BLOWFISHCBC
182 #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
184 #ifndef SADB_X_EALG_CAST128CBC
185 #define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
187 #ifndef SADB_X_EALG_RC5CBC
188 #ifdef SADB_EALG_RC5CBC
189 #define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
195 struct sadb_msg
*msg
;
197 caddr_t mhp
[SADB_EXT_MAX
+ 1];
200 // Special debug use only - creates large logs
201 // plogdump(ASL_LEVEL_DEBUG, msg, msg->sadb_msg_len << 3, "get pfkey %s message\n",
202 // s_pfkey_type(msg->sadb_msg_type));
205 /* check pfkey message. */
206 if (pfkey_align(msg
, mhp
)) {
208 "libipsec failed pfkey align (%s)\n",
212 if (pfkey_check(mhp
)) {
214 "libipsec failed pfkey check (%s)\n",
218 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
220 if (msg
->sadb_msg_errno
) {
223 /* when SPD is empty, treat the state as no error. */
224 if (msg
->sadb_msg_type
== SADB_X_SPDDUMP
&&
225 msg
->sadb_msg_errno
== ENOENT
)
226 pri
= ASL_LEVEL_NOTICE
;
231 "pfkey %s failed: %s\n",
232 s_pfkey_type(msg
->sadb_msg_type
),
233 strerror(msg
->sadb_msg_errno
));
238 if (msg
->sadb_msg_type
>= ARRAYLEN(pkrecvf
)) {
240 "unknown PF_KEY message type=%u\n",
245 if (pkrecvf
[msg
->sadb_msg_type
] == NULL
) {
246 plog(ASL_LEVEL_NOTICE
,
247 "unsupported PF_KEY message %s\n",
248 s_pfkey_type(msg
->sadb_msg_type
));
252 if ((pkrecvf
[msg
->sadb_msg_type
])(mhp
) < 0)
263 * PF_KEY packet handler
268 //%%%%%%%%%%%%%%%%%% need to handle errors encountered here - this no longer returns a result
270 pfkey_handler(void *unused
)
272 struct sadb_msg
*msg
;
275 if (slept_at
|| woke_at
) {
276 plog(ASL_LEVEL_DEBUG
,
277 "ignoring pfkey port until power-mgmt event is handled.\n");
281 /* receive pfkey message. */
283 msg
= (struct sadb_msg
*)pk_recv(lcconf
->sock_pfkey
, &len
);
288 "failed to recv from pfkey (%s)\n",
292 /* short message - msg not ready */
293 plog(ASL_LEVEL_NOTICE
, "recv short message from pfkey\n");
303 struct saved_msg_elem
*elem
;
304 struct saved_msg_elem
*elem_tmp
= NULL
;
306 if (slept_at
|| woke_at
) {
307 plog(ASL_LEVEL_NOTICE
,
308 "ignoring (saved) pfkey messages until power-mgmt event is handled.\n");
312 TAILQ_FOREACH_SAFE(elem
, &lcconf
->saved_msg_queue
, chain
, elem_tmp
) {
313 pfkey_process((struct sadb_msg
*)elem
->msg
);
314 TAILQ_REMOVE(&lcconf
->saved_msg_queue
, elem
, chain
);
322 struct sadb_msg
*msg
;
324 struct saved_msg_elem
*elem
;
326 elem
= (struct saved_msg_elem
*)racoon_calloc(sizeof(struct saved_msg_elem
), 1);
330 TAILQ_INSERT_TAIL(&lcconf
->saved_msg_queue
, elem
, chain
);
338 pfkey_dump_sadb(satype
)
343 pid_t pid
= getpid();
344 struct sadb_msg
*msg
= NULL
;
348 if ((s
= pfkey_open()) < 0) {
350 "libipsec failed pfkey open: %s\n",
355 plog(ASL_LEVEL_DEBUG
, "call pfkey_send_dump\n");
356 if (pfkey_send_dump(s
, satype
) < 0) {
358 "libipsec failed dump: %s\n", ipsec_strerror());
365 msg
= pk_recv(s
, &len
);
374 * for multi-processor system this had to be added because the messages can
375 * be interleaved - they won't all be dump messages
377 if (msg
->sadb_msg_type
!= SADB_DUMP
) { /* save for later processing */
383 // ignore dump messages that aren't racoon's
384 if (msg
->sadb_msg_pid
!= pid
)
387 ml
= msg
->sadb_msg_len
<< 3;
388 bl
= buf
? buf
->l
: 0;
389 buf
= vrealloc(buf
, bl
+ ml
);
392 "failed to reallocate buffer to dump.\n");
395 memcpy(buf
->v
+ bl
, msg
, ml
);
397 if (msg
->sadb_msg_seq
== 0)
416 * These are the SATYPEs that we manage. We register to get
417 * PF_KEY messages related to these SATYPEs, and we also use
418 * this list to determine which SATYPEs to delete SAs for when
419 * we receive an INITIAL-CONTACT.
421 const struct pfkey_satype pfkey_satypes
[] = {
422 { SADB_SATYPE_AH
, "AH" },
423 { SADB_SATYPE_ESP
, "ESP" },
424 { SADB_X_SATYPE_IPCOMP
, "IPCOMP" },
426 const int pfkey_nsatypes
=
427 sizeof(pfkey_satypes
) / sizeof(pfkey_satypes
[0]);
430 * PF_KEY initialization
435 int i
, reg_fail
, sock
;
437 if ((lcconf
->sock_pfkey
= pfkey_open()) < 0) {
439 "libipsec failed pfkey open (%s)\n", ipsec_strerror());
443 for (i
= 0, reg_fail
= 0; i
< pfkey_nsatypes
; i
++) {
444 plog(ASL_LEVEL_DEBUG
,
445 "call pfkey_send_register for %s\n",
446 pfkey_satypes
[i
].ps_name
);
447 if (pfkey_send_register(lcconf
->sock_pfkey
,
448 pfkey_satypes
[i
].ps_satype
) < 0 ||
449 pfkey_recv_register(lcconf
->sock_pfkey
) < 0) {
450 plog(ASL_LEVEL_WARNING
,
451 "failed to register %s (%s)\n",
452 pfkey_satypes
[i
].ps_name
,
458 if (reg_fail
== pfkey_nsatypes
) {
460 "failed to regist any protocol.\n");
461 close(lcconf
->sock_pfkey
);
466 lcconf
->pfkey_source
= dispatch_source_create(DISPATCH_SOURCE_TYPE_READ
, lcconf
->sock_pfkey
, 0, dispatch_get_main_queue());
467 if (lcconf
->pfkey_source
== NULL
) {
468 plog(ASL_LEVEL_ERR
, "could not create pfkey socket source.");
471 dispatch_source_set_event_handler_f(lcconf
->pfkey_source
, pfkey_handler
);
472 sock
= lcconf
->sock_pfkey
;
473 dispatch_source_set_cancel_handler(lcconf
->pfkey_source
,
475 pfkey_close_sock(sock
);
477 dispatch_resume(lcconf
->pfkey_source
);
479 if (pfkey_send_spddump(lcconf
->sock_pfkey
) < 0) {
481 "libipsec sending spddump failed: %s\n",
487 if (pfkey_promisc_toggle(1) < 0) {
499 dispatch_source_cancel(lcconf
->pfkey_source
);
500 lcconf
->pfkey_source
= NULL
;
503 /* %%% for conversion */
504 /* IPSECDOI_ATTR_AUTH -> SADB_AALG */
506 ipsecdoi2pfkey_aalg(hashtype
)
510 case IPSECDOI_ATTR_AUTH_HMAC_MD5
:
511 case IPSECDOI_ATTR_AUTH_HMAC_MD5_96
:
512 return SADB_AALG_MD5HMAC
;
513 case IPSECDOI_ATTR_AUTH_HMAC_SHA1
:
514 case IPSECDOI_ATTR_AUTH_HMAC_SHA1_96
:
515 return SADB_AALG_SHA1HMAC
;
516 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256
:
517 #if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC)
518 return SADB_X_AALG_SHA2_256
;
520 return SADB_X_AALG_SHA2_256HMAC
;
522 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384
:
523 #if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC)
524 return SADB_X_AALG_SHA2_384
;
526 return SADB_X_AALG_SHA2_384HMAC
;
528 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512
:
529 #if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC)
530 return SADB_X_AALG_SHA2_512
;
532 return SADB_X_AALG_SHA2_512HMAC
;
534 case IPSECDOI_ATTR_AUTH_KPDK
: /* need special care */
535 return SADB_AALG_NONE
;
538 case IPSECDOI_ATTR_AUTH_DES_MAC
:
540 "Not supported hash type: %u\n", hashtype
);
543 case 0: /* reserved */
545 return SADB_AALG_NONE
;
548 "Invalid hash type: %u\n", hashtype
);
554 /* IPSECDOI_ESP -> SADB_EALG */
556 ipsecdoi2pfkey_ealg(t_id
)
560 case IPSECDOI_ESP_DES_IV64
: /* sa_flags |= SADB_X_EXT_OLD */
561 return SADB_EALG_DESCBC
;
562 case IPSECDOI_ESP_DES
:
563 return SADB_EALG_DESCBC
;
564 case IPSECDOI_ESP_3DES
:
565 return SADB_EALG_3DESCBC
;
566 #ifdef SADB_X_EALG_RC5CBC
567 case IPSECDOI_ESP_RC5
:
568 return SADB_X_EALG_RC5CBC
;
570 case IPSECDOI_ESP_CAST
:
571 return SADB_X_EALG_CAST128CBC
;
572 case IPSECDOI_ESP_BLOWFISH
:
573 return SADB_X_EALG_BLOWFISHCBC
;
574 case IPSECDOI_ESP_DES_IV32
: /* flags |= (SADB_X_EXT_OLD|
576 return SADB_EALG_DESCBC
;
577 case IPSECDOI_ESP_NULL
:
578 return SADB_EALG_NULL
;
579 #ifdef SADB_X_EALG_AESCBC
580 case IPSECDOI_ESP_AES
:
581 return SADB_X_EALG_AESCBC
;
583 #ifdef SADB_X_EALG_TWOFISHCBC
584 case IPSECDOI_ESP_TWOFISH
:
585 return SADB_X_EALG_TWOFISHCBC
;
589 case IPSECDOI_ESP_3IDEA
:
590 case IPSECDOI_ESP_IDEA
:
591 case IPSECDOI_ESP_RC4
:
593 "Not supported transform: %u\n", t_id
);
596 case 0: /* reserved */
599 "Invalid transform id: %u\n", t_id
);
605 /* IPCOMP -> SADB_CALG */
607 ipsecdoi2pfkey_calg(t_id
)
611 case IPSECDOI_IPCOMP_OUI
:
612 return SADB_X_CALG_OUI
;
613 case IPSECDOI_IPCOMP_DEFLATE
:
614 return SADB_X_CALG_DEFLATE
;
615 case IPSECDOI_IPCOMP_LZS
:
616 return SADB_X_CALG_LZS
;
618 case 0: /* reserved */
621 "Invalid transform id: %u\n", t_id
);
627 /* IPSECDOI_PROTO -> SADB_SATYPE */
629 ipsecdoi2pfkey_proto(proto
)
633 case IPSECDOI_PROTO_IPSEC_AH
:
634 return SADB_SATYPE_AH
;
635 case IPSECDOI_PROTO_IPSEC_ESP
:
636 return SADB_SATYPE_ESP
;
637 case IPSECDOI_PROTO_IPCOMP
:
638 return SADB_X_SATYPE_IPCOMP
;
642 "Invalid ipsec_doi proto: %u\n", proto
);
649 ipsecdoi2pfkey_alg(algclass
, type
)
650 u_int algclass
, type
;
653 case IPSECDOI_ATTR_AUTH
:
654 return ipsecdoi2pfkey_aalg(type
);
655 case IPSECDOI_PROTO_IPSEC_ESP
:
656 return ipsecdoi2pfkey_ealg(type
);
657 case IPSECDOI_PROTO_IPCOMP
:
658 return ipsecdoi2pfkey_calg(type
);
661 "Invalid ipsec_doi algclass: %u\n", algclass
);
667 /* SADB_SATYPE -> IPSECDOI_PROTO */
669 pfkey2ipsecdoi_proto(satype
)
674 return IPSECDOI_PROTO_IPSEC_AH
;
675 case SADB_SATYPE_ESP
:
676 return IPSECDOI_PROTO_IPSEC_ESP
;
677 case SADB_X_SATYPE_IPCOMP
:
678 return IPSECDOI_PROTO_IPCOMP
;
682 "Invalid pfkey proto: %u\n", satype
);
688 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
690 ipsecdoi2pfkey_mode(mode
)
694 case IPSECDOI_ATTR_ENC_MODE_TUNNEL
:
696 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC
:
697 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT
:
699 return IPSEC_MODE_TUNNEL
;
700 case IPSECDOI_ATTR_ENC_MODE_TRNS
:
702 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC
:
703 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT
:
705 return IPSEC_MODE_TRANSPORT
;
707 plog(ASL_LEVEL_ERR
, "Invalid mode type: %u\n", mode
);
713 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
715 pfkey2ipsecdoi_mode(mode
)
719 case IPSEC_MODE_TUNNEL
:
720 return IPSECDOI_ATTR_ENC_MODE_TUNNEL
;
721 case IPSEC_MODE_TRANSPORT
:
722 return IPSECDOI_ATTR_ENC_MODE_TRNS
;
724 return IPSECDOI_ATTR_ENC_MODE_ANY
;
726 plog(ASL_LEVEL_ERR
, "Invalid mode type: %u\n", mode
);
732 /* default key length for encryption algorithm */
734 keylen_aalg(hashtype
)
740 return SADB_AALG_NONE
;
742 res
= alg_ipsec_hmacdef_hashlen(hashtype
);
745 "invalid hmac algorithm %u.\n", hashtype
);
751 /* default key length for encryption algorithm */
753 keylen_ealg(enctype
, encklen
)
759 res
= alg_ipsec_encdef_keylen(enctype
, encklen
);
762 "invalid encryption algorithm %u.\n", enctype
);
769 pfkey_convertfromipsecdoi(iph2
, proto_id
, t_id
, hashtype
,
770 e_type
, e_keylen
, a_type
, a_keylen
, flags
)
771 phase2_handle_t
*iph2
;
783 case IPSECDOI_PROTO_IPSEC_ESP
:
784 if ((*e_type
= ipsecdoi2pfkey_ealg(t_id
)) == ~0)
786 if ((*e_keylen
= keylen_ealg(t_id
, *e_keylen
)) == ~0)
790 if ((*a_type
= ipsecdoi2pfkey_aalg(hashtype
)) == ~0)
792 if ((*a_keylen
= keylen_aalg(hashtype
)) == ~0)
796 if (*e_type
== SADB_EALG_NONE
) {
797 plog(ASL_LEVEL_ERR
, "no ESP algorithm.\n");
802 case IPSECDOI_PROTO_IPSEC_AH
:
803 if ((*a_type
= ipsecdoi2pfkey_aalg(hashtype
)) == ~0)
805 if ((*a_keylen
= keylen_aalg(hashtype
)) == ~0)
809 if (t_id
== IPSECDOI_ATTR_AUTH_HMAC_MD5
810 && hashtype
== IPSECDOI_ATTR_AUTH_KPDK
) {
811 /* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
812 *a_type
= SADB_X_AALG_MD5
;
813 *flags
|= SADB_X_EXT_OLD
;
815 *e_type
= SADB_EALG_NONE
;
817 if (*a_type
== SADB_AALG_NONE
) {
818 plog(ASL_LEVEL_ERR
, "no AH algorithm.\n");
823 case IPSECDOI_PROTO_IPCOMP
:
824 if ((*e_type
= ipsecdoi2pfkey_calg(t_id
)) == ~0)
828 *flags
= SADB_X_EXT_RAWCPI
;
830 *a_type
= SADB_AALG_NONE
;
832 if (*e_type
== SADB_X_CALG_NONE
) {
833 plog(ASL_LEVEL_ERR
, "no IPCOMP algorithm.\n");
839 plog(ASL_LEVEL_ERR
, "unknown IPsec protocol.\n");
850 /* called from scheduler */
852 pfkey_timeover_stub(p
)
856 pfkey_timeover((phase2_handle_t
*)p
);
861 phase2_handle_t
*iph2
;
864 "%s give up to get IPsec-SA due to time up to wait.\n",
865 saddrwop2str((struct sockaddr
*)iph2
->dst
));
866 SCHED_KILL(iph2
->sce
);
868 /* If initiator side, send error to kernel by SADB_ACQUIRE. */
869 if (iph2
->side
== INITIATOR
)
870 pk_sendeacquire(iph2
);
872 ike_session_unlink_phase2(iph2
);
878 /* send getspi message per ipsec protocol per remote address */
880 * the local address and remote address in ph1handle are dealed
881 * with destination address and source address respectively.
882 * Because SPI is decided by responder.
886 phase2_handle_t
*iph2
;
888 struct sockaddr_storage
*src
= NULL
, *dst
= NULL
;
892 u_int32_t minspi
, maxspi
;
895 if (iph2
->side
== INITIATOR
) {
897 proxy
= iph2
->ph1
->rmconf
->support_proxy
;
900 if (iph2
->sainfo
&& iph2
->sainfo
->id_i
)
904 /* for mobile IPv6 */
905 if (proxy
&& iph2
->src_id
&& iph2
->dst_id
&&
906 ipsecdoi_transportmode(pp
)) {
914 for (pr
= pp
->head
; pr
!= NULL
; pr
= pr
->next
) {
917 satype
= ipsecdoi2pfkey_proto(pr
->proto_id
);
920 "invalid proto_id %d\n", pr
->proto_id
);
923 /* this works around a bug in Linux kernel where it allocates 4 byte
925 else if (satype
== SADB_X_SATYPE_IPCOMP
) {
933 mode
= ipsecdoi2pfkey_mode(pr
->encmode
);
936 "invalid encmode %d\n", pr
->encmode
);
940 plog(ASL_LEVEL_DEBUG
, "call pfkey_send_getspi\n");
941 if (pfkey_send_getspi(
948 pr
->reqid_in
, 0, 0, iph2
->seq
, 0) < 0) {
950 "ipseclib failed send getspi (%s)\n",
955 plog(ASL_LEVEL_DEBUG
,
956 "pfkey GETSPI sent: %s\n",
957 sadbsecas2str(dst
, src
, satype
, 0, mode
));
964 * receive GETSPI from kernel.
970 struct sadb_msg
*msg
;
972 phase2_handle_t
*iph2
;
973 struct sockaddr_storage
*dst
;
975 int allspiok
, notfound
;
980 if (mhp
[SADB_EXT_SA
] == NULL
981 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
) {
983 "Inappropriate sadb getspi message passed.\n");
986 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
987 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
988 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]); /* note SA dir */
990 /* the message has to be processed or not ? */
991 if (msg
->sadb_msg_pid
!= getpid()) {
992 plog(ASL_LEVEL_DEBUG
,
993 "%s message is not interesting "
994 "because pid %d is not mine.\n",
995 s_pfkey_type(msg
->sadb_msg_type
),
1000 iph2
= ike_session_getph2byseq(msg
->sadb_msg_seq
);
1002 plog(ASL_LEVEL_DEBUG
,
1003 "Seq %d of %s message not interesting.\n",
1005 s_pfkey_type(msg
->sadb_msg_type
));
1009 if (iph2
->is_dying
) {
1011 "Status mismatch Phase 2 dying (db:%d)\n",
1016 switch (iph2
->version
) {
1017 case ISAKMP_VERSION_NUMBER_IKEV1
:
1018 if (iph2
->status
!= IKEV1_STATE_QUICK_I_GETSPISENT
&&
1019 iph2
->status
!= IKEV1_STATE_QUICK_R_GETSPISENT
) {
1020 plog(ASL_LEVEL_ERR
, "Status mismatch (db:%d)\n", iph2
->status
);
1023 // check the underlying iph2->ph1
1025 if (!ike_session_update_ph2_ph1bind(iph2
)) {
1027 "Can't proceed with getspi for %s. no suitable ISAKMP-SA found \n",
1028 saddrwop2str((struct sockaddr
*)iph2
->dst
));
1029 ike_session_unlink_phase2(iph2
);
1035 plog(ASL_LEVEL_ERR
, "Internal error: invalid IKE major version %d\n", iph2
->version
);
1039 /* set SPI, and check to get all spi whether or not */
1042 proto_id
= pfkey2ipsecdoi_proto(msg
->sadb_msg_satype
);
1043 pp
= iph2
->side
== INITIATOR
? iph2
->proposal
: iph2
->approval
;
1045 for (pr
= pp
->head
; pr
!= NULL
; pr
= pr
->next
) {
1046 if (pr
->proto_id
== proto_id
&& pr
->spi
== 0) {
1047 pr
->spi
= sa
->sadb_sa_spi
;
1049 plog(ASL_LEVEL_DEBUG
,
1050 "pfkey GETSPI succeeded: %s\n",
1051 sadbsecas2str(iph2
->dst
, iph2
->src
,
1052 msg
->sadb_msg_satype
,
1054 ipsecdoi2pfkey_mode(pr
->encmode
)));
1057 allspiok
= 0; /* not get all spi */
1062 "Get spi for unknown address %s\n",
1063 saddrwop2str((struct sockaddr
*)iph2
->dst
));
1064 ike_session_unlink_phase2(iph2
);
1069 switch (iph2
->version
) {
1070 case ISAKMP_VERSION_NUMBER_IKEV1
:
1071 if (isakmp_post_getspi(iph2
) < 0) {
1072 plog(ASL_LEVEL_ERR
, "IKEv1 post getspi failed.\n");
1073 ike_session_unlink_phase2(iph2
);
1088 phase2_handle_t
*iph2
;
1091 struct sockaddr_storage
*src
= NULL
, *dst
= NULL
;
1092 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
1094 u_int64_t lifebyte
= 0;
1095 u_int wsize
= 4; /* XXX static size of window */
1097 struct ph2natt natt
;
1101 if (iph2
->approval
== NULL
) {
1103 "No approved SAs found.\n");
1106 if (iph2
->side
== INITIATOR
)
1107 proxy
= iph2
->ph1
->rmconf
->support_proxy
;
1108 else if (iph2
->sainfo
&& iph2
->sainfo
->id_i
)
1111 /* for mobile IPv6 */
1112 if (proxy
&& iph2
->src_id
&& iph2
->dst_id
&&
1113 ipsecdoi_transportmode(iph2
->approval
)) {
1121 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1122 /* validity check */
1123 satype
= ipsecdoi2pfkey_proto(pr
->proto_id
);
1126 "Invalid proto_id %d\n", pr
->proto_id
);
1129 else if (satype
== SADB_X_SATYPE_IPCOMP
) {
1130 /* IPCOMP has no replay window */
1133 #ifdef ENABLE_SAMODE_UNSPECIFIED
1134 mode
= IPSEC_MODE_ANY
;
1136 mode
= ipsecdoi2pfkey_mode(pr
->encmode
);
1139 "Invalid encmode %d\n", pr
->encmode
);
1144 /* set algorithm type and key length */
1145 e_keylen
= pr
->head
->encklen
;
1146 authtype
= pr
->head
->authtype
;
1148 if (pfkey_convertfromipsecdoi(
1154 &a_type
, &a_keylen
, &flags
) < 0)
1158 lifebyte
= iph2
->approval
->lifebyte
* 1024,
1164 //plog(ASL_LEVEL_DEBUG, "call pfkey_send_update\n");
1165 plog(ASL_LEVEL_DEBUG
, "call pfkey_send_update: e_type %d, e_klen %d, a_type %d, a_klen %d\n",
1166 e_type
, e_keylen
, a_type
, a_keylen
);
1167 if (pr
->udp_encap
) {
1168 memset (&natt
, 0, sizeof (natt
));
1169 natt
.sport
= extract_port (iph2
->ph1
->remote
);
1170 flags
|= SADB_X_EXT_NATT
;
1171 if (iph2
->ph1
->rmconf
->natt_multiple_user
== TRUE
&&
1172 mode
== IPSEC_MODE_TRANSPORT
&&
1173 src
->ss_family
== AF_INET
) {
1174 flags
|= SADB_X_EXT_NATT_MULTIPLEUSERS
;
1175 if (iph2
->ph1
->natt_flags
& NAT_DETECTED_PEER
) {
1176 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1177 flags
|= SADB_X_EXT_NATT_DETECTED_PEER
;
1179 } else if (iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) {
1180 if (iph2
->ph1
->rmconf
->natt_keepalive
== TRUE
)
1181 flags
|= SADB_X_EXT_NATT_KEEPALIVE
;
1183 if (iph2
->ph1
->natt_flags
& NAT_DETECTED_PEER
) {
1184 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1185 flags
|= SADB_X_EXT_NATT_DETECTED_PEER
;
1189 memset (&natt
, 0, sizeof (natt
));
1192 if (pfkey_send_update(
1202 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1203 0, lifebyte
, iph2
->approval
->lifetime
, 0,
1204 iph2
->seq
, natt
.sport
, 0) < 0) {
1206 "libipsec failed send update (%s)\n",
1211 plog(ASL_LEVEL_DEBUG
, "call pfkey_send_update\n");
1212 if (pfkey_send_update(
1222 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1223 0, lifebyte
, iph2
->approval
->lifetime
, 0,
1224 iph2
->seq
, 0, 0) < 0) {
1226 "libipsec failed send update (%s)\n",
1230 #endif /* ENABLE_NATT */
1242 struct sadb_msg
*msg
;
1244 struct sockaddr_storage
*src
, *dst
;
1245 phase2_handle_t
*iph2
;
1246 u_int proto_id
, encmode
, sa_mode
;
1250 /* ignore this message because of local test mode. */
1256 || mhp
[SADB_EXT_SA
] == NULL
1257 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
1258 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
) {
1260 "inappropriate sadb update message passed.\n");
1263 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1264 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1265 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1266 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
1268 sa_mode
= mhp
[SADB_X_EXT_SA2
] == NULL
1270 : (ALIGNED_CAST(struct sadb_x_sa2
*)mhp
[SADB_X_EXT_SA2
])->sadb_x_sa2_mode
;
1272 /* the message has to be processed or not ? */
1273 if (msg
->sadb_msg_pid
!= getpid()) {
1274 plog(ASL_LEVEL_DEBUG
,
1275 "%s message is not interesting "
1276 "because pid %d is not mine.\n",
1277 s_pfkey_type(msg
->sadb_msg_type
),
1282 iph2
= ike_session_getph2byseq(msg
->sadb_msg_seq
);
1284 plog(ASL_LEVEL_DEBUG
,
1285 "Seq %d of %s message not interesting.\n",
1287 s_pfkey_type(msg
->sadb_msg_type
));
1291 if (iph2
->is_dying
) {
1293 "Status mismatch Phase 2 dying (db:%d)\n",
1297 if (iph2
->status
!= IKEV1_STATE_QUICK_I_ADDSA
&&
1298 iph2
->status
!= IKEV1_STATE_QUICK_R_ADDSA
) {
1300 "Status mismatch (db:%d)\n",
1305 /* check to complete all keys ? */
1306 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1307 proto_id
= pfkey2ipsecdoi_proto(msg
->sadb_msg_satype
);
1308 if (proto_id
== ~0) {
1310 "invalid proto_id %d\n", msg
->sadb_msg_satype
);
1313 encmode
= pfkey2ipsecdoi_mode(sa_mode
);
1314 if (encmode
== ~0) {
1316 "invalid encmode %d\n", sa_mode
);
1320 if (pr
->proto_id
== proto_id
1321 && pr
->spi
== sa
->sadb_sa_spi
) {
1323 plog(ASL_LEVEL_DEBUG
,
1324 "pfkey UPDATE succeeded: %s\n",
1325 sadbsecas2str(iph2
->dst
, iph2
->src
,
1326 msg
->sadb_msg_satype
,
1330 plog(ASL_LEVEL_NOTICE
,
1331 "IPsec-SA established (update): satype=%u spi=%#x mode=%u\n",
1332 msg
->sadb_msg_satype
, ntohl(sa
->sadb_sa_spi
), sa_mode
);
1333 plog(ASL_LEVEL_DEBUG
,
1334 "IPsec-SA established (update): %s\n",
1335 sadbsecas2str(iph2
->dst
, iph2
->src
,
1336 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
,
1347 /* turn off the timer for calling pfkey_timeover() */
1348 SCHED_KILL(iph2
->sce
);
1351 fsm_set_state(&iph2
->status
, IKEV1_STATE_PHASE2_ESTABLISHED
);
1353 if (iph2
->side
== INITIATOR
) {
1354 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1355 IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC
,
1356 CONSTSTR("Initiator, Quick-Mode"),
1359 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1360 IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC
,
1361 CONSTSTR("Responder, Quick-Mode"),
1365 ike_session_ph2_established(iph2
);
1367 IPSECLOGASLMSG("IPSec Phase 2 established (Initiated by %s).\n",
1368 (iph2
->side
== INITIATOR
)? "me" : "peer");
1371 gettimeofday(&iph2
->end
, NULL
);
1372 plog(ASL_LEVEL_NOTICE
, "%s(%s): %8.6f",
1373 "Phase 2", "quick", timedelta(&iph2
->start
, &iph2
->end
));
1378 iph2
->ph1
->ph2cnt
++;
1380 /* turn off schedule */
1382 SCHED_KILL(iph2
->scr
);
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.
1388 ike_session_unbindph12(iph2
); //%%%%% fix this
1390 iph2
->sce
= sched_new(iph2
->approval
->lifetime
,
1391 isakmp_ph2expire_stub
, iph2
);
1393 plog(ASL_LEVEL_DEBUG
, "===\n");
1402 phase2_handle_t
*iph2
;
1405 struct sockaddr_storage
*src
= NULL
, *dst
= NULL
;
1406 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
1408 u_int64_t lifebyte
= 0;
1409 u_int wsize
= 4; /* XXX static size of window */
1411 struct ph2natt natt
;
1415 if (iph2
->approval
== NULL
) {
1417 "no approvaled SAs found.\n");
1420 if (iph2
->side
== INITIATOR
)
1421 proxy
= iph2
->ph1
->rmconf
->support_proxy
;
1422 else if (iph2
->sainfo
&& iph2
->sainfo
->id_i
)
1425 /* for mobile IPv6 */
1426 if (proxy
&& iph2
->src_id
&& iph2
->dst_id
&&
1427 ipsecdoi_transportmode(iph2
->approval
)) {
1435 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1436 /* validity check */
1437 satype
= ipsecdoi2pfkey_proto(pr
->proto_id
);
1440 "invalid proto_id %d\n", pr
->proto_id
);
1443 else if (satype
== SADB_X_SATYPE_IPCOMP
) {
1444 /* no replay window for IPCOMP */
1447 #ifdef ENABLE_SAMODE_UNSPECIFIED
1448 mode
= IPSEC_MODE_ANY
;
1450 mode
= ipsecdoi2pfkey_mode(pr
->encmode
);
1453 "invalid encmode %d\n", pr
->encmode
);
1458 /* set algorithm type and key length */
1459 e_keylen
= pr
->head
->encklen
;
1460 authtype
= pr
->head
->authtype
;
1462 if (pfkey_convertfromipsecdoi(
1468 &a_type
, &a_keylen
, &flags
) < 0)
1472 lifebyte
= iph2
->approval
->lifebyte
* 1024,
1478 //plog(ASL_LEVEL_DEBUG, "call pfkey_send_add\n");
1479 plog(ASL_LEVEL_DEBUG
, "call pfkey_send_add: e_type %d, e_klen %d, a_type %d, a_klen %d\n",
1480 e_type
, e_keylen
, a_type
, a_keylen
);
1482 if (pr
->udp_encap
) {
1483 memset (&natt
, 0, sizeof (natt
));
1484 natt
.dport
= extract_port (iph2
->ph1
->remote
);
1485 flags
|= SADB_X_EXT_NATT
;
1486 if (iph2
->ph1
->rmconf
->natt_multiple_user
== TRUE
&&
1487 mode
== IPSEC_MODE_TRANSPORT
&&
1488 src
->ss_family
== AF_INET
) {
1489 flags
|= SADB_X_EXT_NATT_MULTIPLEUSERS
;
1490 if (iph2
->ph1
->natt_flags
& NAT_DETECTED_PEER
) {
1491 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1492 flags
|= SADB_X_EXT_NATT_DETECTED_PEER
;
1494 } else if (iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) {
1495 if (iph2
->ph1
->rmconf
->natt_keepalive
== TRUE
)
1496 flags
|= SADB_X_EXT_NATT_KEEPALIVE
;
1498 if (iph2
->ph1
->natt_flags
& NAT_DETECTED_PEER
) {
1499 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1500 flags
|= SADB_X_EXT_NATT_DETECTED_PEER
;
1504 memset (&natt
, 0, sizeof (natt
));
1506 /* Remove port information, that SA doesn't use it */
1521 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1522 0, lifebyte
, iph2
->approval
->lifetime
, 0,
1523 iph2
->seq
,natt
.dport
, 0) < 0) {
1525 "libipsec failed send add (%s)\n",
1530 plog(ASL_LEVEL_DEBUG
, "call pfkey_send_add\n");
1532 /* Remove port information, it is not used without NAT-T */
1546 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1547 0, lifebyte
, iph2
->approval
->lifetime
, 0,
1548 iph2
->seq
, 0, 0) < 0) {
1550 "libipsec failed send add (%s)\n",
1554 #endif /* ENABLE_NATT */
1564 struct sadb_msg
*msg
;
1566 struct sockaddr_storage
*src
, *dst
;
1567 phase2_handle_t
*iph2
;
1570 /* ignore this message because of local test mode. */
1576 || mhp
[SADB_EXT_SA
] == NULL
1577 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
1578 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
) {
1580 "inappropriate sadb add message passed.\n");
1583 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1584 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1585 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1586 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
1588 sa_mode
= mhp
[SADB_X_EXT_SA2
] == NULL
1590 : (ALIGNED_CAST(struct sadb_x_sa2
*)mhp
[SADB_X_EXT_SA2
])->sadb_x_sa2_mode
;
1592 /* the message has to be processed or not ? */
1593 if (msg
->sadb_msg_pid
!= getpid()) {
1594 plog(ASL_LEVEL_DEBUG
,
1595 "%s message is not interesting "
1596 "because pid %d is not mine.\n",
1597 s_pfkey_type(msg
->sadb_msg_type
),
1602 iph2
= ike_session_getph2byseq(msg
->sadb_msg_seq
);
1604 plog(ASL_LEVEL_DEBUG
,
1605 "seq %d of %s message not interesting.\n",
1607 s_pfkey_type(msg
->sadb_msg_type
));
1611 * NOTE don't update any status of phase2 handle
1612 * because they must be updated by SADB_UPDATE message
1615 plog(ASL_LEVEL_NOTICE
,
1616 "IPsec-SA established (add): satype=%u spi=%#x mode=%u\n",
1617 msg
->sadb_msg_satype
, ntohl(sa
->sadb_sa_spi
), sa_mode
);
1618 plog(ASL_LEVEL_DEBUG
,
1619 "IPsec-SA established (add): %s\n",
1620 sadbsecas2str(iph2
->src
, iph2
->dst
,
1621 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
, sa_mode
));
1623 ike_session_cleanup_other_established_ph2s(iph2
->parent_session
, iph2
);
1625 #ifdef ENABLE_VPNCONTROL_PORT
1627 vpncontrol_notify_phase_change(0, FROM_LOCAL
, NULL
, iph2
);
1631 plog(ASL_LEVEL_DEBUG
, "===\n");
1639 struct sadb_msg
*msg
;
1641 struct sockaddr_storage
*src
, *dst
;
1642 phase2_handle_t
*iph2
;
1643 u_int proto_id
, sa_mode
;
1647 || mhp
[SADB_EXT_SA
] == NULL
1648 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
1649 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
1650 || (mhp
[SADB_EXT_LIFETIME_HARD
] != NULL
1651 && mhp
[SADB_EXT_LIFETIME_SOFT
] != NULL
)) {
1653 "inappropriate sadb expire message passed.\n");
1656 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1657 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
1658 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1659 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1661 sa_mode
= mhp
[SADB_X_EXT_SA2
] == NULL
1663 : (ALIGNED_CAST(struct sadb_x_sa2
*)mhp
[SADB_X_EXT_SA2
])->sadb_x_sa2_mode
;
1665 proto_id
= pfkey2ipsecdoi_proto(msg
->sadb_msg_satype
);
1666 if (proto_id
== ~0) {
1668 "invalid proto_id %d\n", msg
->sadb_msg_satype
);
1672 plog(ASL_LEVEL_NOTICE
,
1673 "IPsec-SA expired: satype=%u spi=%#x mode=%u\n",
1674 msg
->sadb_msg_satype
, ntohl(sa
->sadb_sa_spi
), sa_mode
);
1675 plog(ASL_LEVEL_DEBUG
,
1676 "IPsec-SA expired: %s\n",
1677 sadbsecas2str(src
, dst
,
1678 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
, sa_mode
));
1680 iph2
= ike_session_getph2bysaidx(src
, dst
, proto_id
, sa
->sadb_sa_spi
);
1683 * Ignore it because two expire messages are come up.
1684 * phase2 handler has been deleted already when 2nd message
1687 plog(ASL_LEVEL_DEBUG
,
1688 "no such a SA found: %s\n",
1689 sadbsecas2str(src
, dst
,
1690 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
,
1694 if (iph2
->is_dying
|| !FSM_STATE_IS_ESTABLISHED(iph2
->status
)) {
1696 * If the status is not equal to PHASE2ST_ESTABLISHED,
1697 * racoon ignores this expire message. There are two reason.
1698 * One is that the phase 2 probably starts because there is
1699 * a potential that racoon receives the acquire message
1700 * without receiving a expire message. Another is that racoon
1701 * may receive the multiple expire messages from the kernel.
1703 plog(ASL_LEVEL_WARNING
,
1704 "The expire message is received but the handler %s (status = 0x%x).\n",
1705 iph2
->is_dying
? "is dying" : "has not been established", iph2
->status
);
1709 /* turn off the timer for calling isakmp_ph2expire() */
1710 SCHED_KILL(iph2
->sce
);
1712 fsm_set_state(&iph2
->status
, IKEV1_STATE_PHASE2_EXPIRED
);
1714 /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */
1715 /* allocate buffer for status management of pfkey message */
1716 if (iph2
->side
== INITIATOR
&&
1717 !ike_session_has_other_established_ph2(iph2
->parent_session
, iph2
) &&
1718 !ike_session_drop_rekey(iph2
->parent_session
, IKE_SESSION_REKEY_TYPE_PH2
)) {
1720 ike_session_initph2(iph2
);
1722 /* start isakmp initiation by using ident exchange */
1723 if (isakmp_post_acquire(iph2
) < 0) {
1725 "failed to begin ipsec sa "
1726 "re-negotiation.\n");
1727 ike_session_unlink_phase2(iph2
);
1736 /* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
1737 /* RESPONDER always delete ph2handle, keep silent. RESPONDER doesn't
1738 * manage IPsec SA, so delete the list */
1739 ike_session_unlink_phase2(iph2
);
1748 struct sadb_msg
*msg
;
1749 struct sadb_x_policy
*xpl
;
1750 struct secpolicy
*sp_out
= NULL
, *sp_in
= NULL
;
1751 phase2_handle_t
*iph2
;
1752 struct sockaddr_storage
*src
, *dst
;
1753 ike_session_t
*session
= NULL
;
1754 struct remoteconf
*rmconf
;
1756 /* ignore this message because of local test mode. */
1762 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
1763 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
1764 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
1766 "inappropriate sadb acquire message passed.\n");
1769 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1770 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
1771 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1772 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1774 /* ignore if type is not IPSEC_POLICY_IPSEC */
1775 if (xpl
->sadb_x_policy_type
!= IPSEC_POLICY_IPSEC
) {
1776 plog(ASL_LEVEL_DEBUG
,
1777 "ignore ACQUIRE message. type is not IPsec.\n");
1781 /* ignore it if src is multicast address */
1783 struct sockaddr_storage
*sa
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1785 if ((sa
->ss_family
== AF_INET
1786 && IN_MULTICAST(ntohl(((struct sockaddr_in
*)sa
)->sin_addr
.s_addr
)))
1788 || (sa
->ss_family
== AF_INET6
1789 && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6
*)sa
)->sin6_addr
))
1792 plog(ASL_LEVEL_DEBUG
,
1793 "ignore due to multicast address: %s.\n",
1794 saddrwop2str((struct sockaddr
*)sa
));
1799 /* ignore, if we do not listen on source address */
1802 * - if we'll contact peer from address we do not listen -
1803 * we will be unable to complete negotiation;
1804 * - if we'll negotiate using address we're listening -
1805 * remote peer will send packets to address different
1806 * than one in the policy, so kernel will drop them;
1807 * => therefore this acquire is not for us! --Aidas
1809 // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1810 struct sockaddr_storage
*sa
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1814 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
1815 str
= saddr2str((struct sockaddr
*)p
->addr
);
1816 plog(ASL_LEVEL_DEBUG
,
1817 "checking listen addrs: %s", str
);
1819 if (!cmpsaddrwop(p
->addr
, sa
)) {
1826 plog(ASL_LEVEL_DEBUG
,
1827 "ignore because do not listen on source address : %s.\n",
1828 saddrwop2str((struct sockaddr
*)sa
));
1834 * If there is a phase 2 handler against the policy identifier in
1835 * the acquire message, and if
1836 * 1. its state is less than PHASE2ST_ESTABLISHED, then racoon
1837 * should ignore such a acquire message because the phase 2
1838 * is just negotiating.
1839 * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
1840 * has to process such a acquire message because racoon may
1841 * have lost the expire message.
1843 iph2
= ike_session_getph2byid(src
, dst
, xpl
->sadb_x_policy_id
);
1845 session
= iph2
->parent_session
;
1846 if (!FSM_STATE_IS_ESTABLISHED(iph2
->status
)) {
1847 plog(ASL_LEVEL_DEBUG
,
1848 "ignore the acquire because ph2 found\n");
1851 if (FSM_STATE_IS_EXPIRED(iph2
->status
))
1856 /* search for proper policyindex */
1857 sp_out
= getspbyspid(xpl
->sadb_x_policy_id
);
1858 if (sp_out
== NULL
) {
1859 plog(ASL_LEVEL_ERR
, "no policy found: id:%d.\n",
1860 xpl
->sadb_x_policy_id
);
1863 plog(ASL_LEVEL_DEBUG
,
1864 "suitable outbound SP found: %s.\n", spidx2str(&sp_out
->spidx
));
1866 /* get inbound policy */
1868 struct policyindex spidx
;
1870 spidx
.dir
= IPSEC_DIR_INBOUND
;
1871 memcpy(&spidx
.src
, &sp_out
->spidx
.dst
, sizeof(spidx
.src
));
1872 memcpy(&spidx
.dst
, &sp_out
->spidx
.src
, sizeof(spidx
.dst
));
1873 spidx
.prefs
= sp_out
->spidx
.prefd
;
1874 spidx
.prefd
= sp_out
->spidx
.prefs
;
1875 spidx
.ul_proto
= sp_out
->spidx
.ul_proto
;
1877 sp_in
= getsp(&spidx
);
1879 plog(ASL_LEVEL_DEBUG
,
1880 "Suitable inbound SP found: %s.\n",
1881 spidx2str(&sp_in
->spidx
));
1883 plog(ASL_LEVEL_NOTICE
,
1884 "No in-bound policy found: %s\n",
1889 /* allocate a phase 2 */
1890 rmconf
= getrmconf(dst
);
1891 if (rmconf
== NULL
) {
1892 plog(ASL_LEVEL_ERR
, "No configuration found for %s.\n",
1893 saddrwop2str((struct sockaddr
*)dst
));
1897 iph2
= ike_session_newph2(rmconf
->ike_version
, PHASE2_TYPE_SA
);
1900 "Failed to allocate Phase 2 entry.\n");
1903 plog(ASL_LEVEL_DEBUG
, "Got new Phase 2 version %d\n", iph2
->version
);
1904 iph2
->version
= rmconf
->ike_version
;
1905 iph2
->side
= INITIATOR
;
1906 iph2
->spid
= xpl
->sadb_x_policy_id
;
1908 iph2
->satype
= msg
->sadb_msg_satype
;
1909 iph2
->seq
= msg
->sadb_msg_seq
;
1910 vpncontrol_set_nat64_prefix(&iph2
->nat64_prefix
);
1911 /* set end addresses of SA */
1912 // Wcast_align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1913 iph2
->src
= dupsaddr(ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]));
1914 if (iph2
->src
== NULL
) {
1915 ike_session_delph2(iph2
);
1918 iph2
->dst
= dupsaddr(ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]));
1919 if (iph2
->dst
== NULL
) {
1920 ike_session_delph2(iph2
);
1924 if (iph2
->version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
1925 fsm_set_state(&iph2
->status
, IKEV1_STATE_QUICK_I_START
);
1928 plog(ASL_LEVEL_DEBUG
,
1929 "new acquire %s\n", spidx2str(&sp_out
->spidx
));
1933 vchar_t
*idsrc
, *iddst
;
1935 idsrc
= ipsecdoi_sockaddr2id(&sp_out
->spidx
.src
,
1936 sp_out
->spidx
.prefs
, sp_out
->spidx
.ul_proto
);
1937 if (idsrc
== NULL
) {
1939 "failed to get ID for %s\n",
1940 spidx2str(&sp_out
->spidx
));
1941 ike_session_delph2(iph2
);
1944 iddst
= ipsecdoi_sockaddr2id(&sp_out
->spidx
.dst
,
1945 sp_out
->spidx
.prefd
, sp_out
->spidx
.ul_proto
);
1946 if (iddst
== NULL
) {
1948 "failed to get ID for %s\n",
1949 spidx2str(&sp_out
->spidx
));
1951 ike_session_delph2(iph2
);
1954 iph2
->sainfo
= getsainfo(idsrc
, iddst
, NULL
, 0);
1957 if (iph2
->sainfo
== NULL
) {
1959 "failed to get sainfo.\n");
1960 ike_session_delph2(iph2
);
1962 /* XXX should use the algorithm list from register message */
1965 retain_sainfo(iph2
->sainfo
);
1967 if (set_proposal_from_policy(iph2
, sp_out
, sp_in
) < 0) {
1969 "failed to create saprop.\n");
1970 ike_session_delph2(iph2
);
1974 if (session
== NULL
)
1975 session
= ike_session_get_session(iph2
->src
, iph2
->dst
, 1, NULL
);
1976 if (session
== NULL
)
1979 if (ike_session_link_phase2(session
, iph2
))
1980 fatal_error(-1); //????? fix ???
1982 /* start isakmp initiation by using ident exchange */
1983 /* XXX should be looped if there are multiple phase 2 handler. */
1984 if (isakmp_post_acquire(iph2
) < 0) {
1986 "failed to begin ipsec sa negotiation.\n");
1990 #if !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1991 if ( lcconf
->vt
== NULL
){
1992 if (!(lcconf
->vt
= vproc_transaction_begin(NULL
)))
1994 "vproc_transaction_begin returns NULL.\n");
1996 #endif // !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
2002 ike_session_unlink_phase2(iph2
);
2010 struct sadb_msg
*msg
;
2012 struct sockaddr_storage
*src
, *dst
;
2013 phase2_handle_t
*iph2
= NULL
;
2016 /* ignore this message because of local test mode. */
2022 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2023 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
) {
2025 "inappropriate sadb delete message passed.\n");
2028 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2029 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
2030 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
2031 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
2033 /* the message has to be processed or not ? */
2034 if (msg
->sadb_msg_pid
== getpid()) {
2035 plog(ASL_LEVEL_DEBUG
,
2036 "%s message is not interesting "
2037 "because the message was originated by me.\n",
2038 s_pfkey_type(msg
->sadb_msg_type
));
2042 proto_id
= pfkey2ipsecdoi_proto(msg
->sadb_msg_satype
);
2043 if (proto_id
== ~0) {
2045 "invalid proto_id %d\n", msg
->sadb_msg_satype
);
2049 plog(ASL_LEVEL_DEBUG
, "SADB delete message: proto-id %d\n", proto_id
);
2050 plog(ASL_LEVEL_DEBUG
, "src: %s\n", saddr2str((struct sockaddr
*)src
));
2051 plog(ASL_LEVEL_DEBUG
, "dst: %s\n", saddr2str((struct sockaddr
*)dst
));
2054 ike_session_deleteallph2(src
, dst
, proto_id
);
2055 ike_session_deleteallph1(src
, dst
);
2059 iph2
= ike_session_getph2bysaidx(src
, dst
, proto_id
, sa
->sadb_sa_spi
);
2063 "no iph2 found: %s\n",
2064 sadbsecas2str(src
, dst
, msg
->sadb_msg_satype
,
2065 sa
->sadb_sa_spi
, IPSEC_MODE_ANY
));
2070 "pfkey DELETE received: %s\n",
2071 sadbsecas2str(iph2
->src
, iph2
->dst
,
2072 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
, IPSEC_MODE_ANY
));
2074 /* send delete information */
2076 /* 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. */
2077 /*if (FSM_STATE_IS_ESTABLISHED(iph2->status))
2078 isakmp_info_send_d2(iph2);
2080 ike_session_cleanup_ph1s_by_ph2(iph2);
2081 ike_session_unlink_phase2(iph2);*/
2091 if (mhp
[0] == NULL
) {
2093 "inappropriate sadb flush message passed.\n");
2097 ike_session_flush_all_phase2(false);
2098 ike_session_flush_all_phase1(false);
2104 getsadbpolicy(policy0
, policylen0
, type
, iph2
)
2106 int *policylen0
, type
;
2107 phase2_handle_t
*iph2
;
2109 struct policyindex
*spidx
= iph2
->spidx_gen
;
2110 struct sadb_x_policy
*xpl
;
2111 struct sadb_x_ipsecrequest
*xisr
;
2118 /* get policy buffer size */
2119 policylen
= sizeof(struct sadb_x_policy
);
2120 if (type
!= SADB_X_SPDDELETE
) {
2121 for (pr
= iph2
->approval
->head
; pr
; pr
= pr
->next
) {
2122 xisrlen
= sizeof(*xisr
);
2123 if (pr
->encmode
== IPSECDOI_ATTR_ENC_MODE_TUNNEL
) {
2124 xisrlen
+= (sysdep_sa_len((struct sockaddr
*)iph2
->src
)
2125 + sysdep_sa_len((struct sockaddr
*)iph2
->dst
));
2128 policylen
+= PFKEY_ALIGN8(xisrlen
);
2132 /* make policy structure */
2133 policy
= racoon_malloc(policylen
);
2136 "buffer allocation failed.\n");
2140 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)policy
;
2141 xpl
->sadb_x_policy_len
= PFKEY_UNIT64(policylen
);
2142 xpl
->sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
2143 xpl
->sadb_x_policy_type
= IPSEC_POLICY_IPSEC
;
2144 xpl
->sadb_x_policy_dir
= spidx
->dir
;
2145 xpl
->sadb_x_policy_id
= 0;
2146 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2147 xpl
->sadb_x_policy_priority
= PRIORITY_DEFAULT
;
2150 /* no need to append policy information any more if type is SPDDELETE */
2151 if (type
== SADB_X_SPDDELETE
)
2154 xisr
= (struct sadb_x_ipsecrequest
*)(xpl
+ 1);
2156 for (pr
= iph2
->approval
->head
; pr
; pr
= pr
->next
) {
2158 satype
= doi2ipproto(pr
->proto_id
);
2161 "invalid proto_id %d\n", pr
->proto_id
);
2164 mode
= ipsecdoi2pfkey_mode(pr
->encmode
);
2167 "invalid encmode %d\n", pr
->encmode
);
2172 * the policy level cannot be unique because the policy
2173 * is defined later than SA, so req_id cannot be bound to SA.
2175 xisr
->sadb_x_ipsecrequest_proto
= satype
;
2176 xisr
->sadb_x_ipsecrequest_mode
= mode
;
2177 xisr
->sadb_x_ipsecrequest_level
= IPSEC_LEVEL_REQUIRE
;
2178 xisr
->sadb_x_ipsecrequest_reqid
= 0;
2179 p
= (caddr_t
)(xisr
+ 1);
2181 xisrlen
= sizeof(*xisr
);
2183 if (pr
->encmode
== IPSECDOI_ATTR_ENC_MODE_TUNNEL
) {
2184 int src_len
, dst_len
;
2186 src_len
= sysdep_sa_len((struct sockaddr
*)iph2
->src
);
2187 dst_len
= sysdep_sa_len((struct sockaddr
*)iph2
->dst
);
2188 xisrlen
+= src_len
+ dst_len
;
2190 memcpy(p
, iph2
->src
, src_len
);
2193 memcpy(p
, iph2
->dst
, dst_len
);
2197 xisr
->sadb_x_ipsecrequest_len
= PFKEY_ALIGN8(xisrlen
);
2202 *policylen0
= policylen
;
2208 racoon_free(policy
);
2214 pk_sendspdupdate2(iph2
)
2215 phase2_handle_t
*iph2
;
2217 struct policyindex
*spidx
= iph2
->spidx_gen
;
2218 caddr_t policy
= NULL
;
2220 u_int64_t ltime
, vtime
;
2222 ltime
= iph2
->approval
->lifetime
;
2225 if (getsadbpolicy(&policy
, &policylen
, SADB_X_SPDUPDATE
, iph2
)) {
2227 "getting sadb policy failed.\n");
2231 if (pfkey_send_spdupdate2(
2239 policy
, policylen
, 0) < 0) {
2241 "libipsec failed send spdupdate2 (%s)\n",
2245 plog(ASL_LEVEL_DEBUG
, "call pfkey_send_spdupdate2\n");
2249 racoon_free(policy
);
2255 pk_recvspdupdate(mhp
)
2258 struct sadb_address
*saddr
, *daddr
;
2259 struct sadb_x_policy
*xpl
;
2260 struct policyindex spidx
;
2261 struct secpolicy
*sp
;
2265 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2266 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2267 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2269 "inappropriate sadb spdupdate message passed.\n");
2272 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
2273 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2274 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2276 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2277 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2280 saddr
->sadb_address_prefixlen
,
2281 daddr
->sadb_address_prefixlen
,
2282 saddr
->sadb_address_proto
,
2283 xpl
->sadb_x_policy_priority
,
2286 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2289 saddr
->sadb_address_prefixlen
,
2290 daddr
->sadb_address_prefixlen
,
2291 saddr
->sadb_address_proto
,
2298 "such policy does not already exist: \"%s\"\n",
2305 if (addnewsp(mhp
) < 0)
2312 * this function has to be used by responder side.
2315 pk_sendspdadd2(iph2
)
2316 phase2_handle_t
*iph2
;
2318 struct policyindex
*spidx
= iph2
->spidx_gen
;
2319 caddr_t policy
= NULL
;
2321 u_int64_t ltime
, vtime
;
2323 ltime
= iph2
->approval
->lifetime
;
2326 if (getsadbpolicy(&policy
, &policylen
, SADB_X_SPDADD
, iph2
)) {
2328 "getting sadb policy failed.\n");
2332 if (pfkey_send_spdadd2(
2340 policy
, policylen
, 0) < 0) {
2342 "libipsec failed send spdadd2 (%s)\n",
2346 plog(ASL_LEVEL_DEBUG
, "call pfkey_send_spdadd2\n");
2350 racoon_free(policy
);
2359 struct sadb_address
*saddr
, *daddr
;
2360 struct sadb_x_policy
*xpl
;
2361 struct policyindex spidx
;
2362 struct secpolicy
*sp
;
2366 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2367 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2368 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2370 "inappropriate sadb spdadd message passed.\n");
2373 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
2374 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2375 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2377 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2378 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2381 saddr
->sadb_address_prefixlen
,
2382 daddr
->sadb_address_prefixlen
,
2383 saddr
->sadb_address_proto
,
2384 xpl
->sadb_x_policy_priority
,
2387 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2390 saddr
->sadb_address_prefixlen
,
2391 daddr
->sadb_address_prefixlen
,
2392 saddr
->sadb_address_proto
,
2399 "such policy already exists. "
2400 "anyway replace it: %s\n",
2406 if (addnewsp(mhp
) < 0)
2413 * this function has to be used by responder side.
2416 pk_sendspddelete(iph2
)
2417 phase2_handle_t
*iph2
;
2419 struct policyindex
*spidx
= iph2
->spidx_gen
;
2420 caddr_t policy
= NULL
;
2423 if (getsadbpolicy(&policy
, &policylen
, SADB_X_SPDDELETE
, iph2
)) {
2425 "getting sadb policy failed.\n");
2429 if (pfkey_send_spddelete(
2436 policy
, policylen
, 0) < 0) {
2438 "libipsec failed send spddelete (%s)\n",
2442 plog(ASL_LEVEL_DEBUG
, "call pfkey_send_spddelete\n");
2446 racoon_free(policy
);
2452 pk_recvspddelete(mhp
)
2455 struct sadb_address
*saddr
, *daddr
;
2456 struct sadb_x_policy
*xpl
;
2457 struct policyindex spidx
;
2458 struct secpolicy
*sp
;
2462 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2463 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2464 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2466 "inappropriate sadb spddelete message passed.\n");
2469 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
2470 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2471 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2473 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2474 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2477 saddr
->sadb_address_prefixlen
,
2478 daddr
->sadb_address_prefixlen
,
2479 saddr
->sadb_address_proto
,
2480 xpl
->sadb_x_policy_priority
,
2483 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2486 saddr
->sadb_address_prefixlen
,
2487 daddr
->sadb_address_prefixlen
,
2488 saddr
->sadb_address_proto
,
2495 "no policy found: %s\n",
2500 ike_session_purgephXbyspid(xpl
->sadb_x_policy_id
, true);
2509 pk_recvspdexpire(mhp
)
2512 struct sadb_address
*saddr
, *daddr
;
2513 struct sadb_x_policy
*xpl
;
2514 struct policyindex spidx
;
2515 struct secpolicy
*sp
;
2519 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2520 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2521 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2523 "inappropriate sadb spdexpire message passed.\n");
2526 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
2527 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2528 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2530 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2531 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2534 saddr
->sadb_address_prefixlen
,
2535 daddr
->sadb_address_prefixlen
,
2536 saddr
->sadb_address_proto
,
2537 xpl
->sadb_x_policy_priority
,
2540 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2543 saddr
->sadb_address_prefixlen
,
2544 daddr
->sadb_address_prefixlen
,
2545 saddr
->sadb_address_proto
,
2552 "no policy found: %s\n",
2557 ike_session_purgephXbyspid(xpl
->sadb_x_policy_id
, false);
2570 if (mhp
[0] == NULL
) {
2572 "inappropriate sadb spdget message passed.\n");
2583 struct sadb_msg
*msg
;
2584 struct sadb_address
*saddr
, *daddr
;
2585 struct sadb_x_policy
*xpl
;
2586 struct policyindex spidx
;
2587 struct secpolicy
*sp
;
2590 if (mhp
[0] == NULL
) {
2592 "inappropriate sadb spddump message passed.\n");
2595 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2597 saddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_SRC
];
2598 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2599 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2601 if (saddr
== NULL
|| daddr
== NULL
|| xpl
== NULL
) {
2603 "inappropriate sadb spddump message passed.\n");
2607 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2608 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2611 saddr
->sadb_address_prefixlen
,
2612 daddr
->sadb_address_prefixlen
,
2613 saddr
->sadb_address_proto
,
2614 xpl
->sadb_x_policy_priority
,
2617 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2620 saddr
->sadb_address_prefixlen
,
2621 daddr
->sadb_address_prefixlen
,
2622 saddr
->sadb_address_proto
,
2629 "such policy already exists. "
2630 "anyway replace it: %s\n",
2636 if (addnewsp(mhp
) < 0)
2643 pk_recvspdflush(mhp
)
2647 if (mhp
[0] == NULL
) {
2649 "inappropriate sadb spdflush message passed.\n");
2653 ike_session_flush_all_phase2(false);
2654 ike_session_flush_all_phase1(false);
2661 * send error against acquire message to kenrel.
2664 pk_sendeacquire(iph2
)
2665 phase2_handle_t
*iph2
;
2667 struct sadb_msg
*newmsg
;
2670 len
= sizeof(struct sadb_msg
);
2671 newmsg
= racoon_calloc(1, len
);
2672 if (newmsg
== NULL
) {
2674 "failed to get buffer to send acquire.\n");
2678 memset(newmsg
, 0, len
);
2679 newmsg
->sadb_msg_version
= PF_KEY_V2
;
2680 newmsg
->sadb_msg_type
= SADB_ACQUIRE
;
2681 newmsg
->sadb_msg_errno
= ENOENT
; /* XXX */
2682 newmsg
->sadb_msg_satype
= iph2
->satype
;
2683 newmsg
->sadb_msg_len
= PFKEY_UNIT64(len
);
2684 newmsg
->sadb_msg_reserved
= 0;
2685 newmsg
->sadb_msg_seq
= iph2
->seq
;
2686 newmsg
->sadb_msg_pid
= (u_int32_t
)getpid();
2689 len
= pfkey_send(lcconf
->sock_pfkey
, newmsg
, len
);
2691 racoon_free(newmsg
);
2697 pk_sendget_inbound_sastats(ike_session_t
*session
)
2699 u_int32_t max_stats
;
2703 plog(ASL_LEVEL_DEBUG
, "invalid args in %s \n", __FUNCTION__
);
2707 session
->traffic_monitor
.num_in_curr_req
= 0;
2708 bzero(session
->traffic_monitor
.in_curr_req
, sizeof(session
->traffic_monitor
.in_curr_req
));
2709 max_stats
= (sizeof(session
->traffic_monitor
.in_curr_req
) / sizeof(session
->traffic_monitor
.in_curr_req
[0]));
2712 if ((session
->traffic_monitor
.num_in_curr_req
= ike_session_get_sas_for_stats(session
,
2715 session
->traffic_monitor
.in_curr_req
,
2717 u_int64_t session_ids
[] = {(u_int64_t
)session
, 0};
2719 //plog(ASL_LEVEL_DEBUG, "about to call %s\n", __FUNCTION__);
2721 if (pfkey_send_getsastats(lcconf
->sock_pfkey
,
2726 session
->traffic_monitor
.in_curr_req
,
2727 session
->traffic_monitor
.num_in_curr_req
) < 0) {
2730 //plog(ASL_LEVEL_DEBUG, "%s successful\n", __FUNCTION__);
2732 return session
->traffic_monitor
.num_in_curr_req
;
2738 pk_sendget_outbound_sastats(ike_session_t
*session
)
2740 u_int32_t max_stats
;
2744 plog(ASL_LEVEL_DEBUG
, "invalid args in %s \n", __FUNCTION__
);
2748 session
->traffic_monitor
.num_out_curr_req
= 0;
2749 bzero(session
->traffic_monitor
.out_curr_req
, sizeof(session
->traffic_monitor
.out_curr_req
));
2750 max_stats
= (sizeof(session
->traffic_monitor
.out_curr_req
) / sizeof(session
->traffic_monitor
.out_curr_req
[0]));
2753 if ((session
->traffic_monitor
.num_out_curr_req
= ike_session_get_sas_for_stats(session
,
2756 session
->traffic_monitor
.out_curr_req
,
2758 u_int64_t session_ids
[] = {(u_int64_t
)session
, 0};
2760 //plog(ASL_LEVEL_DEBUG, "about to call %s\n", __FUNCTION__);
2762 if (pfkey_send_getsastats(lcconf
->sock_pfkey
,
2767 session
->traffic_monitor
.out_curr_req
,
2768 session
->traffic_monitor
.num_out_curr_req
) < 0) {
2771 //plog(ASL_LEVEL_DEBUG, "%s successful\n", __FUNCTION__);
2773 return session
->traffic_monitor
.num_out_curr_req
;
2779 * receive GETSPDSTAT from kernel.
2782 pk_recvgetsastat(mhp
)
2785 struct sadb_msg
*msg
;
2786 struct sadb_session_id
*session_id
;
2787 struct sadb_sastat
*stat_resp
;
2788 ike_session_t
*session
;
2790 /* validity check */
2791 if (mhp
[0] == NULL
||
2792 mhp
[SADB_EXT_SESSION_ID
] == NULL
||
2793 mhp
[SADB_EXT_SASTAT
] == NULL
) {
2795 "inappropriate sadb getsastat response.\n");
2798 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to structs in an aligned buffer
2799 session_id
= ALIGNED_CAST(struct sadb_session_id
*)mhp
[SADB_EXT_SESSION_ID
];
2800 stat_resp
= ALIGNED_CAST(struct sadb_sastat
*)mhp
[SADB_EXT_SASTAT
];
2802 /* the message has to be processed or not ? */
2803 if (msg
->sadb_msg_pid
!= getpid()) {
2804 plog(ASL_LEVEL_DEBUG
,
2805 "%s message is not interesting "
2806 "because pid %d is not mine.\n",
2807 s_pfkey_type(msg
->sadb_msg_type
),
2811 if (!session_id
->sadb_session_id_v
[0]) {
2812 plog(ASL_LEVEL_DEBUG
,
2813 "%s message is bad "
2814 "because session-id[0] is invalid.\n",
2815 s_pfkey_type(msg
->sadb_msg_type
));
2818 session
= ALIGNED_CAST(__typeof__(session
))session_id
->sadb_session_id_v
[0];
2820 if (!stat_resp
->sadb_sastat_list_len
) {
2821 plog(ASL_LEVEL_DEBUG
,
2822 "%s message is bad "
2823 "because it has no sastats.\n",
2824 s_pfkey_type(msg
->sadb_msg_type
));
2828 ike_session_update_traffic_idle_status(session
,
2829 stat_resp
->sadb_sastat_dir
,
2830 (struct sastat
*)(stat_resp
+ 1),
2831 stat_resp
->sadb_sastat_list_len
);
2836 * check if the algorithm is supported or not.
2841 pk_checkalg(class, calg
, keylen
)
2842 int class, calg
, keylen
;
2846 struct sadb_alg alg0
;
2848 switch (algclass2doi(class)) {
2849 case IPSECDOI_PROTO_IPSEC_ESP
:
2850 sup
= SADB_EXT_SUPPORTED_ENCRYPT
;
2852 case IPSECDOI_ATTR_AUTH
:
2853 sup
= SADB_EXT_SUPPORTED_AUTH
;
2855 case IPSECDOI_PROTO_IPCOMP
:
2859 "invalid algorithm class.\n");
2862 alg
= ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg
));
2867 if (ipsec_get_keylen(sup
, alg
, &alg0
)) {
2869 "%s.\n", ipsec_strerror());
2872 keylen
= alg0
.sadb_alg_minbits
;
2875 error
= ipsec_check_keylen(sup
, alg
, keylen
);
2878 "%s.\n", ipsec_strerror());
2884 * differences with pfkey_recv() in libipsec/pfkey.c:
2885 * - never performs busy wait loop.
2886 * - returns NULL and set *lenp to negative on fatal failures
2887 * - returns NULL and set *lenp to non-negative on non-fatal failures
2888 * - returns non-NULL on success
2890 static struct sadb_msg
*
2895 struct sadb_msg
*newmsg
;
2897 socklen_t optlen
= sizeof(reallen
);
2899 if (getsockopt(so
, SOL_SOCKET
, SO_NREAD
, &reallen
, &optlen
) < 0)
2900 return NULL
; /*fatal*/
2905 if ((newmsg
= racoon_calloc(1, reallen
)) == NULL
)
2908 while ((*lenp
= recv(so
, (caddr_t
)newmsg
, reallen
, 0)) < 0) {
2911 plog(ASL_LEVEL_ERR
, "failed to recv pfkey message: %s\n", strerror(errno
));
2915 racoon_free(newmsg
);
2916 return NULL
; /*fatal*/
2917 } else if (*lenp
!= reallen
|| *lenp
< sizeof(struct sadb_msg
)) {
2918 racoon_free(newmsg
);
2929 return eay_random();
2936 struct secpolicy
*new;
2937 struct sadb_address
*saddr
, *daddr
;
2938 struct sadb_x_policy
*xpl
;
2941 if (mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2942 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2943 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2945 "inappropriate sadb spd management message passed.\n");
2949 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
2950 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2951 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2956 "failed to allocate buffer\n");
2960 new->spidx
.dir
= xpl
->sadb_x_policy_dir
;
2961 new->id
= xpl
->sadb_x_policy_id
;
2962 new->policy
= xpl
->sadb_x_policy_type
;
2966 switch (xpl
->sadb_x_policy_type
) {
2967 case IPSEC_POLICY_DISCARD
:
2968 case IPSEC_POLICY_GENERATE
:
2969 case IPSEC_POLICY_NONE
:
2970 case IPSEC_POLICY_ENTRUST
:
2971 case IPSEC_POLICY_BYPASS
:
2974 case IPSEC_POLICY_IPSEC
:
2977 struct sadb_x_ipsecrequest
*xisr
;
2978 struct ipsecrequest
**p_isr
= &new->req
;
2980 /* validity check */
2981 if (PFKEY_EXTLEN(xpl
) < sizeof(*xpl
)) {
2983 "invalid msg length.\n");
2987 tlen
= PFKEY_EXTLEN(xpl
) - sizeof(*xpl
);
2988 xisr
= (struct sadb_x_ipsecrequest
*)(xpl
+ 1);
2993 if (xisr
->sadb_x_ipsecrequest_len
< sizeof(*xisr
)) {
2995 "invalid msg length.\n");
2999 /* allocate request buffer */
3000 *p_isr
= newipsecreq();
3001 if (*p_isr
== NULL
) {
3003 "failed to get new ipsecreq.\n");
3008 (*p_isr
)->next
= NULL
;
3010 switch (xisr
->sadb_x_ipsecrequest_proto
) {
3013 case IPPROTO_IPCOMP
:
3017 "invalid proto type: %u\n",
3018 xisr
->sadb_x_ipsecrequest_proto
);
3021 (*p_isr
)->saidx
.proto
= xisr
->sadb_x_ipsecrequest_proto
;
3023 switch (xisr
->sadb_x_ipsecrequest_mode
) {
3024 case IPSEC_MODE_TRANSPORT
:
3025 case IPSEC_MODE_TUNNEL
:
3027 case IPSEC_MODE_ANY
:
3030 "invalid mode: %u\n",
3031 xisr
->sadb_x_ipsecrequest_mode
);
3034 (*p_isr
)->saidx
.mode
= xisr
->sadb_x_ipsecrequest_mode
;
3036 switch (xisr
->sadb_x_ipsecrequest_level
) {
3037 case IPSEC_LEVEL_DEFAULT
:
3038 case IPSEC_LEVEL_USE
:
3039 case IPSEC_LEVEL_REQUIRE
:
3041 case IPSEC_LEVEL_UNIQUE
:
3042 (*p_isr
)->saidx
.reqid
=
3043 xisr
->sadb_x_ipsecrequest_reqid
;
3048 "invalid level: %u\n",
3049 xisr
->sadb_x_ipsecrequest_level
);
3052 (*p_isr
)->level
= xisr
->sadb_x_ipsecrequest_level
;
3054 /* set IP addresses if there */
3055 if (xisr
->sadb_x_ipsecrequest_len
> sizeof(*xisr
)) {
3056 struct sockaddr
*paddr
;
3058 paddr
= (struct sockaddr
*)(xisr
+ 1);
3059 bcopy(paddr
, &(*p_isr
)->saidx
.src
,
3060 sysdep_sa_len(paddr
));
3062 paddr
= (struct sockaddr
*)((caddr_t
)paddr
3063 + sysdep_sa_len(paddr
));
3064 bcopy(paddr
, &(*p_isr
)->saidx
.dst
,
3065 sysdep_sa_len(paddr
));
3070 /* initialization for the next. */
3071 p_isr
= &(*p_isr
)->next
;
3072 tlen
-= xisr
->sadb_x_ipsecrequest_len
;
3074 /* validity check */
3077 "becoming tlen < 0\n");
3080 xisr
= ALIGNED_CAST(struct sadb_x_ipsecrequest
*)((caddr_t
)xisr
3081 + xisr
->sadb_x_ipsecrequest_len
);
3087 "invalid policy type.\n");
3092 #ifdef HAVE_PFKEY_POLICY_PRIORITY
3093 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
3096 saddr
->sadb_address_prefixlen
,
3097 daddr
->sadb_address_prefixlen
,
3098 saddr
->sadb_address_proto
,
3099 xpl
->sadb_x_policy_priority
,
3102 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
3105 saddr
->sadb_address_prefixlen
,
3106 daddr
->sadb_address_prefixlen
,
3107 saddr
->sadb_address_proto
,
3116 /* proto/mode/src->dst spi */
3118 sadbsecas2str(src
, dst
, proto
, spi
, mode
)
3119 struct sockaddr_storage
*src
, *dst
;
3124 static char buf
[256];
3125 u_int doi_proto
, doi_mode
= 0;
3129 doi_proto
= pfkey2ipsecdoi_proto(proto
);
3130 if (doi_proto
== ~0)
3133 doi_mode
= pfkey2ipsecdoi_mode(mode
);
3138 blen
= sizeof(buf
) - 1;
3141 i
= snprintf(p
, blen
, "%s%s%s ",
3142 s_ipsecdoi_proto(doi_proto
),
3144 mode
? s_ipsecdoi_encmode(doi_mode
) : "");
3145 if (i
< 0 || i
>= blen
)
3150 i
= snprintf(p
, blen
, "%s->", saddr2str((struct sockaddr
*)src
));
3151 if (i
< 0 || i
>= blen
)
3156 i
= snprintf(p
, blen
, "%s ", saddr2str((struct sockaddr
*)dst
));
3157 if (i
< 0 || i
>= blen
)
3163 snprintf(p
, blen
, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi
),
3164 (unsigned long)ntohl(spi
));