1 /* $Id: proposal.c,v 1.13.8.5 2005/07/28 05:05:52 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
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/queue.h>
39 #include <netinet/in.h>
40 #ifdef HAVE_NETINET6_IPSEC
41 # include <netinet6/ipsec.h>
43 # include <netinet/ipsec.h>
60 #include "isakmp_var.h"
62 #include "ipsec_doi.h"
63 #include "algorithm.h"
66 #include "localconf.h"
67 #include "remoteconf.h"
73 #include "nattraversal.h"
77 * modules for ipsec sa spec
84 new = racoon_calloc(1, sizeof(*new));
96 new = racoon_calloc(1, sizeof(*new));
103 /* set saprop to last part of the prop tree */
106 struct saprop
**head
;
116 for (p
= *head
; p
->next
; p
= p
->next
)
123 /* set saproto to the end of the proto tree in saprop */
131 for (p
= pp
->head
; p
&& p
->next
; p
= p
->next
)
141 /* set saproto to the top of the proto tree in saprop */
143 inssaprotorev(pp
, new)
147 new->next
= pp
->head
;
158 new = racoon_calloc(1, sizeof(*new));
165 /* set saproto to last part of the proto tree in saprop */
173 for (tr
= pr
->head
; tr
&& tr
->next
; tr
= tr
->next
)
184 satrns_remove_from_list(struct satrns
**listptr
, struct satrns
*trns
)
187 struct satrns
**ptr
= listptr
;
199 ptr
= &((*ptr
)->next
);
206 saprop_udp_encap (struct saproto
*pr
)
208 switch (pr
->encmode
) {
209 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC
:
210 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT
:
211 pr
->encmode
= IPSECDOI_ATTR_ENC_MODE_TUNNEL
;
214 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC
:
215 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT
:
216 pr
->encmode
= IPSECDOI_ATTR_ENC_MODE_TRNS
;
223 saprop_adjust_encmode (struct saproto
*pr2
, struct saproto
*pr1
)
227 if (natt_udp_encap(pr2
->encmode
)) {
229 saprop_udp_encap(pr2
);
230 plog(ASL_LEVEL_INFO
, "Adjusting my encmode %s(%d)->%s(%d)\n",
231 s_ipsecdoi_encmode(prev
),
233 s_ipsecdoi_encmode(pr2
->encmode
),
236 if (natt_udp_encap(pr1
->encmode
)) {
238 saprop_udp_encap(pr1
);
239 plog(ASL_LEVEL_INFO
, "Adjusting peer's encmode %s(%d)->%s(%d)\n",
240 s_ipsecdoi_encmode(prev
),
242 s_ipsecdoi_encmode(pr1
->encmode
),
246 #endif // ENABLE_NATT
249 * take a single match between saprop. allocate a new proposal and return it
250 * for future use (like picking single proposal from a bundle).
251 * pp1: peer's proposal.
253 * NOTE: In the case of initiator, must be ensured that there is no
254 * modification of the proposal by calling cmp_aproppair_i() before
256 * XXX cannot understand the comment!
259 cmpsaprop_alloc(ph1
, pp1
, pp2
, side
)
260 phase1_handle_t
*ph1
;
261 const struct saprop
*pp1
, *pp2
;
264 struct saprop
*newpp
= NULL
;
265 struct saproto
*pr1
, *pr2
, *newpr
= NULL
;
266 struct satrns
*tr1
, *tr2
, *newtr
;
267 const int ordermatters
= 0;
274 "failed to allocate saprop.\n");
277 newpp
->prop_no
= pp1
->prop_no
;
279 /* see proposal.h about lifetime/key length and PFS selection. */
281 /* check time/bytes lifetime and PFS */
282 switch (ph1
->rmconf
->pcheck_level
) {
283 case PROP_CHECK_OBEY
:
284 newpp
->lifetime
= pp1
->lifetime
;
285 newpp
->lifebyte
= pp1
->lifebyte
;
286 newpp
->pfs_group
= pp1
->pfs_group
;
289 case PROP_CHECK_STRICT
:
290 if (pp1
->lifetime
> pp2
->lifetime
) {
292 "long lifetime proposed: "
294 (int)pp2
->lifetime
, (int)pp1
->lifetime
);
297 if (pp1
->lifebyte
> pp2
->lifebyte
) {
299 "long lifebyte proposed: "
301 pp2
->lifebyte
, pp1
->lifebyte
);
304 newpp
->lifetime
= pp1
->lifetime
;
305 newpp
->lifebyte
= pp1
->lifebyte
;
308 if (pp2
->pfs_group
!= 0 && pp1
->pfs_group
!= pp2
->pfs_group
) {
310 "pfs group mismatched: "
312 pp2
->pfs_group
, pp1
->pfs_group
);
315 newpp
->pfs_group
= pp1
->pfs_group
;
318 case PROP_CHECK_CLAIM
:
320 if (pp1
->lifetime
<= pp2
->lifetime
) {
321 newpp
->lifetime
= pp1
->lifetime
;
323 newpp
->lifetime
= pp2
->lifetime
;
324 newpp
->claim
|= IPSECDOI_ATTR_SA_LD_TYPE_SEC
;
325 plog(ASL_LEVEL_NOTICE
,
328 (int)pp2
->lifetime
, (int)pp1
->lifetime
);
332 if (pp1
->lifebyte
> pp2
->lifebyte
) {
333 newpp
->lifebyte
= pp2
->lifebyte
;
334 newpp
->claim
|= IPSECDOI_ATTR_SA_LD_TYPE_SEC
;
335 plog(ASL_LEVEL_NOTICE
,
338 pp2
->lifebyte
, pp1
->lifebyte
);
340 newpp
->lifebyte
= pp1
->lifebyte
;
345 case PROP_CHECK_EXACT
:
346 if (pp1
->lifetime
!= pp2
->lifetime
) {
348 "lifetime mismatched: "
350 (int)pp2
->lifetime
, (int)pp1
->lifetime
);
354 if (pp1
->lifebyte
!= pp2
->lifebyte
) {
356 "lifebyte mismatched: "
358 pp2
->lifebyte
, pp1
->lifebyte
);
361 if (pp1
->pfs_group
!= pp2
->pfs_group
) {
363 "pfs group mismatched: "
365 pp2
->pfs_group
, pp1
->pfs_group
);
368 newpp
->lifetime
= pp1
->lifetime
;
369 newpp
->lifebyte
= pp1
->lifebyte
;
370 newpp
->pfs_group
= pp1
->pfs_group
;
375 "invalid pcheck_level why?.\n");
380 for (pr1
= pp1
->head
; pr1
; pr1
= pr1
->next
)
382 for (pr2
= pp2
->head
; pr2
; pr2
= pr2
->next
)
387 /* check protocol order */
394 * XXX does not work if we have multiple proposals
395 * with the same proto_id
401 for (pr1
= pp1
->head
; pr1
; pr1
= pr1
->next
) {
402 if (pr1
->proto_id
== pr2
->proto_id
)
409 for (pr2
= pp2
->head
; pr2
; pr2
= pr2
->next
) {
410 if (pr2
->proto_id
== pr1
->proto_id
)
419 if (pr1
->proto_id
!= pr2
->proto_id
) {
421 "proto_id mismatched: "
423 s_ipsecdoi_proto(pr2
->proto_id
),
424 s_ipsecdoi_proto(pr1
->proto_id
));
428 if (pr1
->spisize
== pr2
->spisize
)
430 else if (pr1
->proto_id
== IPSECDOI_PROTO_IPCOMP
) {
432 * draft-shacham-ippcp-rfc2393bis-05.txt:
433 * need to accept 16bit and 32bit SPI (CPI) for IPComp.
435 if (pr1
->spisize
== sizeof(u_int16_t
) &&
436 pr2
->spisize
== sizeof(u_int32_t
)) {
438 } else if (pr2
->spisize
== sizeof(u_int16_t
) &&
439 pr1
->spisize
== sizeof(u_int32_t
)) {
444 "IPComp SPI size promoted "
445 "from 16bit to 32bit\n");
450 "spisize mismatched: "
452 (int)pr2
->spisize
, (int)pr1
->spisize
);
457 if (ph1
->natt_flags
& NAT_DETECTED
) {
458 saprop_adjust_encmode(pr2
, pr1
);
462 if (pr1
->encmode
!= pr2
->encmode
) {
464 "encmode mismatched: "
466 s_ipsecdoi_encmode(pr2
->encmode
),
467 s_ipsecdoi_encmode(pr1
->encmode
));
471 for (tr1
= pr1
->head
; tr1
; tr1
= tr1
->next
) {
472 for (tr2
= pr2
->head
; tr2
; tr2
= tr2
->next
) {
473 if (cmpsatrns(pr1
->proto_id
, tr1
, tr2
) == 0)
481 newpr
= newsaproto();
484 "failed to allocate saproto.\n");
487 newpr
->proto_id
= pr1
->proto_id
;
488 newpr
->spisize
= pr1
->spisize
;
489 newpr
->encmode
= pr1
->encmode
;
490 newpr
->spi
= pr2
->spi
; /* copy my SPI */
491 newpr
->spi_p
= pr1
->spi
; /* copy peer's SPI */
492 newpr
->reqid_in
= pr2
->reqid_in
;
493 newpr
->reqid_out
= pr2
->reqid_out
;
495 newpr
->udp_encap
= pr1
->udp_encap
| pr2
->udp_encap
;
501 "failed to allocate satrns.\n");
505 newtr
->trns_no
= tr1
->trns_no
;
506 newtr
->trns_id
= tr1
->trns_id
;
507 newtr
->encklen
= tr1
->encklen
;
508 newtr
->authtype
= tr1
->authtype
;
510 inssatrns(newpr
, newtr
);
511 inssaproto(newpp
, newpr
);
517 /* XXX should check if we have visited all items or not */
531 /* should be matched all protocols in a proposal */
532 if (pr1
!= NULL
|| pr2
!= NULL
)
542 /* take a single match between saprop. returns 0 if pp1 equals to pp2. */
545 const struct saprop
*pp1
, *pp2
;
547 if (pp1
->pfs_group
!= pp2
->pfs_group
) {
548 plog(ASL_LEVEL_WARNING
,
549 "pfs_group mismatch. mine:%d peer:%d\n",
550 pp1
->pfs_group
, pp2
->pfs_group
);
554 if (pp1
->lifetime
> pp2
->lifetime
) {
555 plog(ASL_LEVEL_WARNING
,
556 "less lifetime proposed. mine:%d peer:%d\n",
557 (int)pp1
->lifetime
, (int)pp2
->lifetime
);
560 if (pp1
->lifebyte
> pp2
->lifebyte
) {
561 plog(ASL_LEVEL_WARNING
,
562 "less lifebyte proposed. mine:%d peer:%d\n",
563 pp1
->lifebyte
, pp2
->lifebyte
);
571 * take a single match between satrns. returns 0 if tr1 equals to tr2.
576 cmpsatrns(proto_id
, tr1
, tr2
)
578 const struct satrns
*tr1
, *tr2
;
580 if (tr1
->trns_id
!= tr2
->trns_id
) {
581 plog(ASL_LEVEL_DEBUG
,
582 "trns_id mismatched: "
584 s_ipsecdoi_trns(proto_id
, tr2
->trns_id
),
585 s_ipsecdoi_trns(proto_id
, tr1
->trns_id
));
589 if (tr1
->authtype
!= tr2
->authtype
) {
590 plog(ASL_LEVEL_DEBUG
,
591 "authtype mismatched: "
593 s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH
, tr2
->authtype
),
594 s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH
, tr1
->authtype
));
599 * At this moment for interoperability, the responder obey
600 * the initiator. It should be defined a notify message.
602 if (tr1
->encklen
> tr2
->encklen
) {
603 plog(ASL_LEVEL_WARNING
,
604 "less key length proposed, "
605 "mine:%d peer:%d. Use initiaotr's one.\n",
606 tr2
->encklen
, tr1
->encklen
);
614 set_satrnsbysainfo(struct saproto
*pr
, struct sainfo
*sainfo
, u_int8_t ike_version
, int pfs_group
)
616 struct sainfoalg
*a
, *b
;
617 struct satrns
*newtr
;
620 switch (pr
->proto_id
) {
621 case IPSECDOI_PROTO_IPSEC_AH
:
622 if (sainfo
->algs
[algclass_ipsec_auth
] == NULL
) {
624 "no auth algorithm found\n");
628 for (a
= sainfo
->algs
[algclass_ipsec_auth
]; a
; a
= a
->next
) {
630 if (a
->alg
== IPSECDOI_ATTR_AUTH_NONE
)
633 /* allocate satrns */
637 "failed to allocate satrns.\n");
641 newtr
->trns_no
= t
++;
642 newtr
->trns_id
= ipsecdoi_authalg2trnsid(a
->alg
); // IKEv1 only
643 newtr
->authtype
= a
->alg
;
645 inssatrns(pr
, newtr
);
648 case IPSECDOI_PROTO_IPSEC_ESP
:
649 if (sainfo
->algs
[algclass_ipsec_enc
] == NULL
) {
651 "no encryption algorithm found\n");
655 if (ike_version
== ISAKMP_VERSION_NUMBER_IKEV1
) {
656 for (a
= sainfo
->algs
[algclass_ipsec_enc
]; a
; a
= a
->next
) {
657 for (b
= sainfo
->algs
[algclass_ipsec_auth
]; b
; b
= b
->next
) {
658 /* allocate satrns */
662 "failed to allocate satrns.\n");
666 newtr
->trns_no
= t
++;
667 newtr
->trns_id
= a
->alg
;
668 newtr
->encklen
= a
->encklen
;
669 newtr
->authtype
= b
->alg
;
671 inssatrns(pr
, newtr
);
676 case IPSECDOI_PROTO_IPCOMP
:
677 if (sainfo
->algs
[algclass_ipsec_comp
] == NULL
) {
679 "no ipcomp algorithm found\n");
683 for (a
= sainfo
->algs
[algclass_ipsec_comp
]; a
; a
= a
->next
) {
685 /* allocate satrns */
689 "failed to allocate satrns.\n");
693 newtr
->trns_no
= t
++;
694 newtr
->trns_id
= a
->alg
;
695 newtr
->authtype
= IPSECDOI_ATTR_AUTH_NONE
; /*no auth*/
697 inssatrns(pr
, newtr
);
702 "unknown proto_id (%d).\n", pr
->proto_id
);
706 /* no proposal found */
707 if (pr
->head
== NULL
) {
708 plog(ASL_LEVEL_ERR
, "no algorithms found.\n");
715 flushsatrns(pr
->head
);
721 struct prop_pair
*p0
;
723 struct prop_pair
*p
, *t
;
724 struct saprop
*newpp
;
725 struct saproto
*newpr
;
726 struct satrns
*newtr
;
732 /* allocate ipsec a sa proposal */
736 "failed to allocate saprop.\n");
739 newpp
->prop_no
= p0
->prop
->p_no
;
740 /* lifetime & lifebyte must be updated later */
742 for (p
= p0
; p
; p
= p
->next
) {
744 /* allocate ipsec sa protocol */
745 newpr
= newsaproto();
748 "failed to allocate saproto.\n");
753 /* XXX should be handled isakmp cookie */
754 if (sizeof(newpr
->spi
) < p
->prop
->spi_size
) {
756 "invalid spi size %d.\n", p
->prop
->spi_size
);
762 * XXX SPI bits are left-filled, for use with IPComp.
763 * we should be switching to variable-length spi field...
765 newpr
->proto_id
= p
->prop
->proto_id
;
766 newpr
->spisize
= p
->prop
->spi_size
;
767 memset(&newpr
->spi
, 0, sizeof(newpr
->spi
));
768 spi
= (u_int8_t
*)&newpr
->spi
;
769 spi
+= sizeof(newpr
->spi
);
770 spi
-= p
->prop
->spi_size
;
771 memcpy(spi
, p
->prop
+ 1, p
->prop
->spi_size
);
773 newpr
->reqid_out
= 0;
775 for (t
= p
; t
; t
= t
->tnext
) {
777 plog(ASL_LEVEL_DEBUG
,
778 "prop#=%d prot-id=%s spi-size=%d "
779 "#trns=%d trns#=%d trns-id=%s\n",
781 s_ipsecdoi_proto(t
->prop
->proto_id
),
782 t
->prop
->spi_size
, t
->prop
->num_t
,
784 s_ipsecdoi_trns(t
->prop
->proto_id
,
787 /* allocate ipsec sa transform */
791 "failed to allocate satrns.\n");
796 if (ipsecdoi_t2satrns(t
->trns
,
797 newpp
, newpr
, newtr
) < 0) {
804 inssatrns(newpr
, newtr
);
808 * If the peer does not specify encryption mode, use
809 * transport mode by default. This is to conform to
810 * draft-shacham-ippcp-rfc2393bis-08.txt (explicitly specifies
811 * that unspecified == transport), as well as RFC2407
812 * (unspecified == implementation dependent default).
814 if (newpr
->encmode
== 0)
815 newpr
->encmode
= IPSECDOI_ATTR_ENC_MODE_TRNS
;
817 inssaproto(newpp
, newpr
);
831 struct saprop
*p
, *save
;
833 for (p
= head
; p
!= NULL
; p
= save
) {
835 flushsaproto(p
->head
);
844 struct saproto
*head
;
846 struct saproto
*p
, *save
;
848 for (p
= head
; p
!= NULL
; p
= save
) {
850 flushsatrns(p
->head
);
863 struct satrns
*p
, *save
;
865 for (p
= head
; p
!= NULL
; p
= save
) {
874 * print multiple proposals
879 const struct saprop
*pp
;
881 const struct saprop
*p
;
888 for (p
= pp
; p
; p
= p
->next
) {
889 printsaprop0(pri
, p
);
896 * print one proposal.
899 printsaprop0(pri
, pp
)
901 const struct saprop
*pp
;
903 const struct saproto
*p
;
908 for (p
= pp
->head
; p
; p
= p
->next
) {
909 printsaproto(pri
, p
);
916 printsaproto(pri
, pr
)
918 const struct saproto
*pr
;
926 " (proto_id=%s spisize=%d spi=%08lx spi_p=%08lx "
927 "encmode=%s reqid=%d:%d)\n",
928 s_ipsecdoi_proto(pr
->proto_id
),
930 (unsigned long)ntohl(pr
->spi
),
931 (unsigned long)ntohl(pr
->spi_p
),
932 s_ipsecdoi_attr_v(IPSECDOI_ATTR_ENC_MODE
, pr
->encmode
),
933 (int)pr
->reqid_in
, (int)pr
->reqid_out
);
935 for (tr
= pr
->head
; tr
; tr
= tr
->next
) {
936 printsatrns(pri
, pr
->proto_id
, tr
);
943 printsatrns(pri
, proto_id
, tr
)
946 const struct satrns
*tr
;
952 case IPSECDOI_PROTO_IPSEC_AH
:
954 " (trns_id=%s authtype=%s)\n",
955 s_ipsecdoi_trns(proto_id
, tr
->trns_id
),
956 s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH
, tr
->authtype
));
958 case IPSECDOI_PROTO_IPSEC_ESP
:
960 " (trns_id=%s encklen=%d authtype=%s)\n",
961 s_ipsecdoi_trns(proto_id
, tr
->trns_id
),
963 s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH
, tr
->authtype
));
965 case IPSECDOI_PROTO_IPCOMP
:
968 s_ipsecdoi_trns(proto_id
, tr
->trns_id
));
972 "(unknown proto_id %d)\n", proto_id
);
979 print_proppair0(pri
, p
, level
)
986 memset(spc
, ' ', sizeof(spc
));
987 spc
[sizeof(spc
) - 1] = '\0';
993 "%s%p: next=%p tnext=%p\n", spc
, p
, p
->next
, p
->tnext
);
995 print_proppair0(pri
, p
->next
, level
+ 1);
997 print_proppair0(pri
, p
->tnext
, level
+ 1);
1001 print_proppair(pri
, p
)
1003 struct prop_pair
*p
;
1005 print_proppair0(pri
, p
, 1);
1009 set_proposal_from_policy(iph2
, sp_main
, sp_sub
)
1010 phase2_handle_t
*iph2
;
1011 struct secpolicy
*sp_main
, *sp_sub
;
1013 struct saprop
*newpp
;
1014 struct ipsecrequest
*req
;
1015 int encmodesv
= IPSEC_MODE_TRANSPORT
; /* use only when complex_bundle */
1017 newpp
= newsaprop();
1018 if (newpp
== NULL
) {
1020 "failed to allocate saprop.\n");
1024 newpp
->lifetime
= iph2
->sainfo
->lifetime
;
1025 newpp
->lifebyte
= iph2
->sainfo
->lifebyte
;
1026 newpp
->pfs_group
= iph2
->sainfo
->pfs_group
;
1028 //%%%% to do - verify DH group is OK - tried that here and iphone failed to connect
1030 if (lcconf
->complex_bundle
)
1034 * decide the encryption mode of this SA bundle.
1035 * the mode becomes tunnel mode when there is even one policy
1036 * of tunnel mode in the SPD. otherwise the mode becomes
1039 encmodesv
= IPSEC_MODE_TRANSPORT
;
1040 for (req
= sp_main
->req
; req
; req
= req
->next
) {
1041 if (req
->saidx
.mode
== IPSEC_MODE_TUNNEL
) {
1042 encmodesv
= pfkey2ipsecdoi_mode(req
->saidx
.mode
);
1044 if (iph2
->ph1
&& (iph2
->ph1
->natt_flags
& NAT_DETECTED
))
1045 encmodesv
+= iph2
->ph1
->natt_options
->mode_udp_diff
;
1052 for (req
= sp_main
->req
; req
; req
= req
->next
) {
1053 struct saproto
*newpr
;
1054 caddr_t paddr
= NULL
;
1057 * check if SA bundle ?
1058 * nested SAs negotiation is NOT supported.
1059 * me +--- SA1 ---+ peer1
1060 * me +--- SA2 --------------+ peer2
1062 if (req
->saidx
.src
.ss_len
&& req
->saidx
.dst
.ss_len
) {
1063 /* check the end of ip addresses of SA */
1064 if (iph2
->side
== INITIATOR
)
1065 paddr
= (caddr_t
)&req
->saidx
.dst
;
1067 paddr
= (caddr_t
)&req
->saidx
.src
;
1070 /* allocate ipsec sa protocol */
1071 newpr
= newsaproto();
1072 if (newpr
== NULL
) {
1074 "failed to allocate saproto.\n");
1078 newpr
->proto_id
= ipproto2doi(req
->saidx
.proto
);
1079 if (newpr
->proto_id
== IPSECDOI_PROTO_IPCOMP
)
1083 if (lcconf
->complex_bundle
) {
1084 encmodesv
= newpr
->encmode
= pfkey2ipsecdoi_mode(req
->saidx
.mode
);
1086 if (iph2
->ph1
&& (iph2
->ph1
->natt_flags
& NAT_DETECTED
))
1087 newpr
->encmode
+= iph2
->ph1
->natt_options
->mode_udp_diff
;
1091 encmodesv
= newpr
->encmode
= encmodesv
;
1092 if (iph2
->side
== INITIATOR
)
1093 newpr
->reqid_out
= req
->saidx
.reqid
;
1095 newpr
->reqid_in
= req
->saidx
.reqid
;
1097 if (set_satrnsbysainfo(newpr
, iph2
->sainfo
, iph2
->version
, newpp
->pfs_group
) < 0) {
1099 "failed to get algorithms.\n");
1104 /* set new saproto */
1105 inssaprotorev(newpp
, newpr
);
1108 /* get reqid_in from inbound policy */
1115 if (iph2
->side
== INITIATOR
)
1116 pr
->reqid_in
= req
->saidx
.reqid
;
1118 pr
->reqid_out
= req
->saidx
.reqid
;
1123 plog(ASL_LEVEL_NOTICE
,
1124 "There is a difference "
1125 "between the in/out bound policies in SPD.\n");
1129 iph2
->proposal
= newpp
;
1131 ike_session_update_mode(iph2
);
1133 printsaprop0(ASL_LEVEL_DEBUG
, newpp
);
1143 * generate a policy from peer's proposal.
1144 * this function unconditionally chooses the first proposal the in SA payload
1148 set_proposal_from_proposal(iph2
)
1149 phase2_handle_t
*iph2
;
1151 struct saprop
*newpp
= NULL
, *pp0
, *pp_peer
= NULL
;
1152 struct saproto
*newpr
= NULL
, *pr
;
1153 struct prop_pair
**pair
= NULL
;
1157 /* get proposal pair */
1158 if (iph2
->version
== ISAKMP_VERSION_NUMBER_IKEV1
)
1159 pair
= get_proppair(iph2
->sa
, IPSECDOI_TYPE_PH2
);
1165 * make my proposal according as the client proposal.
1166 * XXX assumed there is only one proposal even if it's the SA bundle.
1168 for (i
= 0; i
< MAXPROPPAIRLEN
; i
++) {
1169 if (pair
[i
] == NULL
)
1172 if (pp_peer
!= NULL
)
1173 flushsaprop(pp_peer
);
1175 pp_peer
= aproppair2saprop(pair
[i
]);
1176 if (pp_peer
== NULL
)
1182 "failed to allocate saprop.\n");
1186 pp0
->lifetime
= iph2
->sainfo
->lifetime
;
1187 pp0
->lifebyte
= iph2
->sainfo
->lifebyte
;
1188 pp0
->pfs_group
= iph2
->sainfo
->pfs_group
;
1190 if (pp_peer
->next
!= NULL
) {
1192 "pp_peer is inconsistency, ignore it.\n");
1196 for (pr
= pp_peer
->head
; pr
; pr
= pr
->next
) {
1198 newpr
= newsaproto();
1199 if (newpr
== NULL
) {
1201 "failed to allocate saproto.\n");
1205 newpr
->proto_id
= pr
->proto_id
;
1206 newpr
->spisize
= pr
->spisize
;
1207 newpr
->encmode
= pr
->encmode
;
1209 newpr
->spi_p
= pr
->spi
; /* copy peer's SPI */
1210 newpr
->reqid_in
= 0;
1211 newpr
->reqid_out
= 0;
1213 if (set_satrnsbysainfo(newpr
, iph2
->sainfo
, iph2
->version
, 0) < 0) {
1215 "failed to get algorithms.\n");
1220 inssaproto(pp0
, newpr
);
1223 inssaprop(&newpp
, pp0
);
1226 plog(ASL_LEVEL_DEBUG
, "make a proposal from peer's:\n");
1227 printsaprop0(ASL_LEVEL_DEBUG
, newpp
);
1229 iph2
->proposal
= newpp
;
1231 ike_session_update_mode(iph2
);
1240 flushsaprop(pp_peer
);
1242 free_proppair(pair
);
1252 for (pr
= p
->head
; pr
; pr
= pr
->next
)
1253 if (pr
->encmode
== IPSECDOI_ATTR_ENC_MODE_TUNNEL
)
1259 dupsatrns_1(struct satrns
*tr
)
1261 struct satrns
*newtr
;
1263 newtr
= racoon_calloc(1, sizeof(*newtr
));
1266 newtr
->trns_no
= tr
->trns_no
;
1267 newtr
->trns_id
= tr
->trns_id
;
1268 newtr
->encklen
= tr
->encklen
;
1269 newtr
->authtype
= tr
->authtype
;
1275 dupsatrns(newpr
, head
)
1276 struct saproto
*newpr
;
1277 struct satrns
*head
;
1279 struct satrns
*p
, *newtr
;
1281 for (p
= head
; p
!= NULL
; p
= p
->next
) {
1282 newtr
= newsatrns();
1284 newtr
->trns_no
= p
->trns_no
;
1285 newtr
->trns_id
= p
->trns_id
;
1286 newtr
->encklen
= p
->encklen
;
1287 newtr
->authtype
= p
->authtype
;
1288 inssatrns(newpr
, newtr
);
1299 dupsaproto(newpp
, head
, ignore_spis
)
1300 struct saprop
*newpp
;
1301 struct saproto
*head
;
1304 struct saproto
*p
, *newpr
;
1306 for (p
= head
; p
!= NULL
; p
= p
->next
) {
1307 newpr
= newsaproto();
1309 newpr
->proto_id
= p
->proto_id
;
1310 newpr
->spisize
= p
->spisize
;
1311 newpr
->encmode
= p
->encmode
;
1312 newpr
->udp_encap
= p
->udp_encap
;
1314 newpr
->spi
= p
->spi
;
1315 newpr
->spi_p
= p
->spi_p
;
1316 newpr
->reqid_in
= p
->reqid_in
;
1317 newpr
->reqid_out
= p
->reqid_out
;
1319 dupsatrns(newpr
, p
->head
);
1320 inssaproto(newpp
, newpr
);
1331 dupsaprop(head
, ignore_spis
)
1332 struct saprop
*head
;
1335 struct saprop
*p
, *newpp
;
1337 for (p
= head
, newpp
= NULL
; p
!= NULL
; p
= p
->next
) {
1338 struct saprop
*tmp
= newsaprop();
1340 tmp
->prop_no
= p
->prop_no
;
1341 tmp
->lifetime
= p
->lifetime
;
1342 tmp
->lifebyte
= p
->lifebyte
;
1343 tmp
->pfs_group
= p
->pfs_group
;
1344 tmp
->claim
= p
->claim
;
1345 dupsaproto(tmp
, p
->head
, ignore_spis
);
1346 inssaprop(&newpp
, tmp
);