1 /* $NetBSD: isakmp_quick.c,v 1.11.4.1 2007/08/01 11:52:21 vanhu Exp $ */
3 /* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd Exp */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
40 #include <netinet/in.h>
46 #if TIME_WITH_SYS_TIME
47 # include <sys/time.h>
51 # include <sys/time.h>
60 #ifndef HAVE_NETINET6_IPSEC
61 #include <netinet/ipsec.h>
63 #include <netinet6/ipsec.h>
73 #include "localconf.h"
74 #include "remoteconf.h"
78 #include "isakmp_var.h"
80 #include "isakmp_inf.h"
81 #include "isakmp_quick.h"
83 #include "ipsec_doi.h"
84 #include "crypto_openssl.h"
87 #include "algorithm.h"
93 #include "nattraversal.h"
94 #include "ipsecSessionTracer.h"
95 #include "ipsecMessageTracer.h"
98 static vchar_t
*quick_ir1mx
__P((struct ph2handle
*, vchar_t
*, vchar_t
*));
99 static int get_sainfo_r
__P((struct ph2handle
*));
100 static int get_proposal_r
__P((struct ph2handle
*));
101 static int get_proposal_r_remote
__P((struct ph2handle
*, int));
107 * begin Quick Mode as initiator. send pfkey getspi message to kernel.
110 quick_i1prep(iph2
, msg
)
111 struct ph2handle
*iph2
;
112 vchar_t
*msg
; /* must be null pointer */
114 int error
= ISAKMP_INTERNAL_ERROR
;
117 if (iph2
->status
!= PHASE2ST_STATUS2
) {
118 plog(LLV_ERROR
, LOCATION
, NULL
,
119 "status mismatched %d.\n", iph2
->status
);
123 iph2
->msgid
= isakmp_newmsgid2(iph2
->ph1
);
124 if (iph2
->ivm
!= NULL
)
125 oakley_delivm(iph2
->ivm
);
126 iph2
->ivm
= oakley_newiv2(iph2
->ph1
, iph2
->msgid
);
127 if (iph2
->ivm
== NULL
)
130 iph2
->status
= PHASE2ST_GETSPISENT
;
132 /* don't anything if local test mode. */
138 /* send getspi message */
139 if (pk_sendgetspi(iph2
) < 0) {
140 plog(LLV_ERROR
, LOCATION
, NULL
,
141 "failed to send getspi message");
145 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
147 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
148 pfkey_timeover_stub
, iph2
);
158 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
161 quick_i1send(iph2
, msg
)
162 struct ph2handle
*iph2
;
163 vchar_t
*msg
; /* must be null pointer */
165 vchar_t
*body
= NULL
;
166 vchar_t
*hash
= NULL
;
168 vchar_t
*natoa_i
= NULL
;
169 vchar_t
*natoa_r
= NULL
;
170 #endif /* ENABLE_NATT */
172 struct isakmp_gen
*gen
;
175 int error
= ISAKMP_INTERNAL_ERROR
;
176 int pfsgroup
, idci
, idcr
;
178 struct ipsecdoi_id_b
*id
, *id_p
;
182 plog(LLV_ERROR
, LOCATION
, NULL
,
183 "msg has to be NULL in this function.\n");
186 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
187 plog(LLV_ERROR
, LOCATION
, NULL
,
188 "status mismatched %d.\n", iph2
->status
);
192 /* create SA payload for my proposal */
193 if (ipsecdoi_setph2proposal(iph2
) < 0) {
194 plog(LLV_ERROR
, LOCATION
, NULL
,
195 "failed to set proposal");
199 /* generate NONCE value */
200 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
201 if (iph2
->nonce
== NULL
) {
202 plog(LLV_ERROR
, LOCATION
, NULL
,
203 "failed to generate NONCE");
208 * DH value calculation is kicked out into cfparse.y.
209 * because pfs group can not be negotiated, it's only to be checked
212 /* generate KE value if need */
213 pfsgroup
= iph2
->proposal
->pfs_group
;
215 /* DH group settting if PFS is required. */
216 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
217 plog(LLV_ERROR
, LOCATION
, NULL
,
218 "failed to set DH value.\n");
221 if (oakley_dh_generate(iph2
->pfsgrp
,
222 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
223 plog(LLV_ERROR
, LOCATION
, NULL
,
224 "failed to generate DH");
229 /* generate ID value */
230 if (ipsecdoi_setid2(iph2
) < 0) {
231 plog(LLV_ERROR
, LOCATION
, NULL
,
232 "failed to get ID.\n");
235 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDci:\n");
236 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
237 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDcr:\n");
238 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
241 * we do not attach IDci nor IDcr, under the following condition:
242 * - all proposals are transport mode
244 * - id payload suggests to encrypt all the traffic (no specific
247 id
= (struct ipsecdoi_id_b
*)iph2
->id
->v
;
248 id_p
= (struct ipsecdoi_id_b
*)iph2
->id_p
->v
;
249 if (id
->proto_id
== 0
250 && id_p
->proto_id
== 0
251 && iph2
->ph1
->rmconf
->support_proxy
== 0
252 && ipsecdoi_transportmode(iph2
->proposal
)) {
257 /* create SA;NONCE payload, and KE if need, and IDii, IDir. */
258 tlen
= + sizeof(*gen
) + iph2
->sa
->l
259 + sizeof(*gen
) + iph2
->nonce
->l
;
261 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
263 tlen
+= sizeof(*gen
) + iph2
->id
->l
;
265 tlen
+= sizeof(*gen
) + iph2
->id_p
->l
;
269 * RFC3947 5.2. if we propose UDP-Encapsulated-Transport
270 * we should send NAT-OA
272 if (ipsecdoi_any_transportmode(iph2
->proposal
)
273 && (iph2
->ph1
->natt_flags
& NAT_DETECTED
)) {
274 natoa_type
= create_natoa_payloads(iph2
, &natoa_i
, &natoa_r
);
275 if (natoa_type
== -1) {
276 plog(LLV_ERROR
, LOCATION
, NULL
,
277 "failed to generate NAT-OA payload.\n");
279 } else if (natoa_type
!= 0) {
280 tlen
+= sizeof(*gen
) + natoa_i
->l
;
281 tlen
+= sizeof(*gen
) + natoa_r
->l
;
283 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiator send NAT-OAi:\n");
284 plogdump(LLV_DEBUG
, natoa_i
->v
, natoa_i
->l
);
285 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiator send NAT-OAr:\n");
286 plogdump(LLV_DEBUG
, natoa_r
->v
, natoa_r
->l
);
291 body
= vmalloc(tlen
);
293 plog(LLV_ERROR
, LOCATION
, NULL
,
294 "failed to get buffer to send.\n");
301 p
= set_isakmp_payload(p
, iph2
->sa
, ISAKMP_NPTYPE_NONCE
);
303 /* add NONCE payload */
305 np
= ISAKMP_NPTYPE_KE
;
306 else if (idci
|| idcr
)
307 np
= ISAKMP_NPTYPE_ID
;
309 np
= (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
310 p
= set_isakmp_payload(p
, iph2
->nonce
, np
);
312 /* add KE payload if need. */
313 np
= (idci
|| idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
315 p
= set_isakmp_payload(p
, iph2
->dhpub
, np
);
318 np
= (idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
320 p
= set_isakmp_payload(p
, iph2
->id
, np
);
324 p
= set_isakmp_payload(p
, iph2
->id_p
, natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
328 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
329 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
332 /* generate HASH(1) */
333 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, body
);
335 plog(LLV_ERROR
, LOCATION
, NULL
,
336 "failed to compute HASH");
340 /* send isakmp payload */
341 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
342 if (iph2
->sendbuf
== NULL
) {
343 plog(LLV_ERROR
, LOCATION
, NULL
,
344 "failed to get send buffer");
348 /* send the packet, add to the schedule to resend */
349 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
350 if (isakmp_ph2resend(iph2
) == -1) {
351 plog(LLV_ERROR
, LOCATION
, NULL
,
352 "failed to send packet");
356 /* change status of isakmp status entry */
357 iph2
->status
= PHASE2ST_MSG1SENT
;
361 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
362 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
363 CONSTSTR("Initiator, Quick-Mode message 1"),
368 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
369 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
370 CONSTSTR("Initiator, Quick-Mode Message 1"),
371 CONSTSTR("Failed to transmit Quick-Mode Message 1"));
382 #endif /* ENABLE_NATT */
388 * receive from responder
389 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
392 quick_i2recv(iph2
, msg0
)
393 struct ph2handle
*iph2
;
397 vchar_t
*hbuf
= NULL
; /* for hash computing. */
398 vchar_t
*pbuf
= NULL
; /* for payload parsing */
399 struct isakmp_parse_t
*pa
;
400 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
401 struct isakmp_pl_hash
*hash
= NULL
;
405 int error
= ISAKMP_INTERNAL_ERROR
;
406 struct sockaddr
*natoa_i
= NULL
;
407 struct sockaddr
*natoa_r
= NULL
;
410 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
411 plog(LLV_ERROR
, LOCATION
, NULL
,
412 "status mismatched %d.\n", iph2
->status
);
417 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
418 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
419 "Packet wasn't encrypted.\n");
422 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
424 plog(LLV_ERROR
, LOCATION
, NULL
,
425 "failed to decrypt");
429 /* create buffer for validating HASH(2) */
432 * 1. the first one must be HASH
433 * 2. the second one must be SA (added in isakmp-oakley-05!)
434 * 3. two IDs must be considered as IDci, then IDcr
436 pbuf
= isakmp_parse(msg
);
438 plog(LLV_ERROR
, LOCATION
, NULL
,
439 "failed to parse msg");
442 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
444 /* HASH payload is fixed postion */
445 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
446 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
447 "received invalid next payload type %d, "
449 pa
->type
, ISAKMP_NPTYPE_HASH
);
452 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
456 * this restriction was introduced in isakmp-oakley-05.
457 * we do not check this for backward compatibility.
458 * TODO: command line/config file option to enable/disable this code
460 /* HASH payload is fixed postion */
461 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
462 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
463 "received invalid next payload type %d, "
465 pa
->type
, ISAKMP_NPTYPE_HASH
);
468 /* allocate buffer for computing HASH(2) */
469 tlen
= iph2
->nonce
->l
470 + ntohl(isakmp
->len
) - sizeof(*isakmp
);
471 hbuf
= vmalloc(tlen
);
473 plog(LLV_ERROR
, LOCATION
, NULL
,
474 "failed to get hash buffer.\n");
477 p
= hbuf
->v
+ iph2
->nonce
->l
; /* retain the space for Ni_b */
480 * parse the payloads.
481 * copy non-HASH payloads into hbuf, so that we can validate HASH.
484 f_id
= 0; /* flag to use checking ID */
485 tlen
= 0; /* count payload length except of HASH payload. */
486 for (; pa
->type
; pa
++) {
488 /* copy to buffer for HASH */
489 /* Don't modify the payload */
490 memcpy(p
, pa
->ptr
, pa
->len
);
493 case ISAKMP_NPTYPE_SA
:
494 if (iph2
->sa_ret
!= NULL
) {
495 plog(LLV_ERROR
, LOCATION
, NULL
,
496 "Ignored, multiple SA "
497 "isn't supported.\n");
500 if (isakmp_p2ph(&iph2
->sa_ret
, pa
->ptr
) < 0) {
501 plog(LLV_ERROR
, LOCATION
, NULL
,
502 "failed to process SA payload");
507 case ISAKMP_NPTYPE_NONCE
:
508 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0) {
509 plog(LLV_ERROR
, LOCATION
, NULL
,
510 "failed to process NONCE payload");
515 case ISAKMP_NPTYPE_KE
:
516 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0) {
517 plog(LLV_ERROR
, LOCATION
, NULL
,
518 "failed to process KE payload");
523 case ISAKMP_NPTYPE_ID
:
536 /* These ids may not match when natt is used with some devices.
537 * RFC 2407 says that the protocol and port fields should be ignored
538 * if they are zero, therefore they need to be checked individually.
540 struct ipsecdoi_id_b
*id_ptr
= (struct ipsecdoi_id_b
*)vp
->v
;
541 struct ipsecdoi_pl_id
*idp_ptr
= (struct ipsecdoi_pl_id
*)pa
->ptr
;
543 if (id_ptr
->type
!= idp_ptr
->b
.type
544 || (idp_ptr
->b
.proto_id
!= 0 && idp_ptr
->b
.proto_id
!= id_ptr
->proto_id
)
545 || (idp_ptr
->b
.port
!= 0 && idp_ptr
->b
.port
!= id_ptr
->port
)
546 || memcmp(vp
->v
+ sizeof(struct ipsecdoi_id_b
), (caddr_t
)pa
->ptr
+ sizeof(struct ipsecdoi_pl_id
),
547 vp
->l
- sizeof(struct ipsecdoi_id_b
))) {
548 // to support servers that use our external nat address as our ID
549 if (iph2
->ph1
->natt_flags
& NAT_DETECTED
) {
550 plog(LLV_WARNING
, LOCATION
, NULL
,
551 "mismatched ID was returned - ignored because nat traversal is being used.\n");
552 /* If I'm behind a nat and the ID is type address - save the address
553 * and port for when the peer rekeys.
555 if (f_id
== 0 && (iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
)) {
556 if (lcconf
->ext_nat_id
)
557 vfree(lcconf
->ext_nat_id
);
558 lcconf
->ext_nat_id
= vmalloc(ntohs(idp_ptr
->h
.len
) - sizeof(struct isakmp_gen
));
559 if (lcconf
->ext_nat_id
== NULL
) {
560 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating external nat id.\n");
563 memcpy(lcconf
->ext_nat_id
->v
, &(idp_ptr
->b
), lcconf
->ext_nat_id
->l
);
564 if (iph2
->ext_nat_id
)
565 vfree(iph2
->ext_nat_id
);
566 iph2
->ext_nat_id
= vdup(lcconf
->ext_nat_id
);
567 if (iph2
->ext_nat_id
== NULL
) {
568 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating ph2's external nat id.\n");
571 plog(LLV_DEBUG
, LOCATION
, NULL
, "external nat address saved.\n");
572 plogdump(LLV_DEBUG
, iph2
->ext_nat_id
->v
, iph2
->ext_nat_id
->l
);
573 } else if (f_id
&& (iph2
->ph1
->natt_flags
& NAT_DETECTED_PEER
)) {
574 if (iph2
->ext_nat_id_p
)
575 vfree(iph2
->ext_nat_id_p
);
576 iph2
->ext_nat_id_p
= vmalloc(ntohs(idp_ptr
->h
.len
) - sizeof(struct isakmp_gen
));
577 if (iph2
->ext_nat_id_p
== NULL
) {
578 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating peers ph2's external nat id.\n");
581 memcpy(iph2
->ext_nat_id_p
->v
, &(idp_ptr
->b
), iph2
->ext_nat_id_p
->l
);
582 plog(LLV_DEBUG
, LOCATION
, NULL
, "peer's external nat address saved.\n");
583 plogdump(LLV_DEBUG
, iph2
->ext_nat_id_p
->v
, iph2
->ext_nat_id_p
->l
);
586 plog(LLV_ERROR
, LOCATION
, NULL
, "mismatched ID was returned.\n");
587 error
= ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED
;
596 case ISAKMP_NPTYPE_N
:
597 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
601 case ISAKMP_NPTYPE_NATOA_DRAFT
:
602 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
603 case ISAKMP_NPTYPE_NATOA_RFC
:
606 struct sockaddr
*daddr
;
608 isakmp_p2ph(&vp
, pa
->ptr
);
611 daddr
= process_natoa_payload(vp
);
613 if (natoa_i
== NULL
) {
615 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiaor rcvd NAT-OA i: %s\n",
617 } else if (natoa_r
== NULL
) {
619 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiator rcvd NAT-OA r: %s\n",
633 /* don't send information, see ident_r1recv() */
634 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
635 "ignore the packet, "
636 "received unexpecting payload type %d.\n",
643 /* compute true length of payload. */
647 /* payload existency check */
648 if (hash
== NULL
|| iph2
->sa_ret
== NULL
|| iph2
->nonce_p
== NULL
) {
649 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
650 "few isakmp message received.\n");
654 /* Fixed buffer for calculating HASH */
655 memcpy(hbuf
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
656 plog(LLV_DEBUG
, LOCATION
, NULL
,
657 "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n",
658 hbuf
->l
, tlen
+ iph2
->nonce
->l
);
659 /* adjust buffer length for HASH */
660 hbuf
->l
= iph2
->nonce
->l
+ tlen
;
662 /* validate HASH(2) */
665 vchar_t
*my_hash
= NULL
;
668 r_hash
= (char *)hash
+ sizeof(*hash
);
670 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(2) received:");
671 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
673 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
674 if (my_hash
== NULL
) {
675 plog(LLV_ERROR
, LOCATION
, NULL
,
676 "failed to compute HASH");
680 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
684 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
685 "HASH(2) mismatch.\n");
686 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
691 /* validity check SA payload sent from responder */
692 if (ipsecdoi_checkph2proposal(iph2
) < 0) {
693 plog(LLV_ERROR
, LOCATION
, NULL
,
694 "failed to validate SA proposal");
695 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
699 /* change status of isakmp status entry */
700 iph2
->status
= PHASE2ST_STATUS6
;
704 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
705 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
706 CONSTSTR("Initiator, Quick-Mode message 2"),
711 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
712 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
713 CONSTSTR("Initiator, Quick-Mode Message 2"),
714 CONSTSTR("Failed to process Quick-Mode Message 2 "));
725 racoon_free(natoa_i
);
728 racoon_free(natoa_r
);
733 VPTRINIT(iph2
->sa_ret
);
734 VPTRINIT(iph2
->nonce_p
);
735 VPTRINIT(iph2
->dhpub_p
);
737 VPTRINIT(iph2
->id_p
);
748 quick_i2send(iph2
, msg0
)
749 struct ph2handle
*iph2
;
754 vchar_t
*hash
= NULL
;
757 int error
= ISAKMP_INTERNAL_ERROR
;
758 int packet_error
= -1;
761 if (iph2
->status
!= PHASE2ST_STATUS6
) {
762 plog(LLV_ERROR
, LOCATION
, NULL
,
763 "status mismatched %d.\n", iph2
->status
);
767 /* generate HASH(3) */
771 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) generate\n");
773 tmp
= vmalloc(iph2
->nonce
->l
+ iph2
->nonce_p
->l
);
775 plog(LLV_ERROR
, LOCATION
, NULL
,
776 "failed to get hash buffer.\n");
779 memcpy(tmp
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
780 memcpy(tmp
->v
+ iph2
->nonce
->l
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
782 hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
786 plog(LLV_ERROR
, LOCATION
, NULL
,
787 "failed to compute HASH");
792 /* create buffer for isakmp payload */
793 tlen
= sizeof(struct isakmp
)
794 + sizeof(struct isakmp_gen
) + hash
->l
;
797 plog(LLV_ERROR
, LOCATION
, NULL
,
798 "failed to get buffer to send.\n");
802 /* create isakmp header */
803 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
805 plog(LLV_ERROR
, LOCATION
, NULL
,
806 "failed to create ISAKMP header");
810 /* add HASH(3) payload */
811 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_NONE
);
813 #ifdef HAVE_PRINT_ISAKMP_C
814 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
818 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
819 if (iph2
->sendbuf
== NULL
) {
820 plog(LLV_ERROR
, LOCATION
, NULL
,
821 "failed to encrypt packet");
825 /* if there is commit bit, need resending */
826 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
827 /* send the packet, add to the schedule to resend */
828 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
829 if (isakmp_ph2resend(iph2
) == -1) {
830 plog(LLV_ERROR
, LOCATION
, NULL
,
831 "failed to send packet, commit-bit");
835 /* send the packet */
836 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0) {
837 plog(LLV_ERROR
, LOCATION
, NULL
,
838 "failed to send packet");
843 /* the sending message is added to the received-list. */
844 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
,
846 PH2_NON_ESP_EXTRA_LEN(iph2
)) == -1) {
847 plog(LLV_ERROR
, LOCATION
, NULL
,
848 "failed to add a response packet to the tree.\n");
852 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
853 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
854 CONSTSTR("Initiator, Quick-Mode message 3"),
858 /* compute both of KEYMATs */
859 if (oakley_compute_keymat(iph2
, INITIATOR
) < 0) {
860 plog(LLV_ERROR
, LOCATION
, NULL
,
861 "failed to compute KEYMAT");
865 iph2
->status
= PHASE2ST_ADDSA
;
867 /* don't anything if local test mode. */
873 /* if there is commit bit don't set up SA now. */
874 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
875 iph2
->status
= PHASE2ST_COMMIT
;
880 /* Do UPDATE for initiator */
881 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
882 if (pk_sendupdate(iph2
) < 0) {
883 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
886 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
888 /* Do ADD for responder */
889 if (pk_sendadd(iph2
) < 0) {
890 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
893 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
899 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
900 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
901 CONSTSTR("Initiator, Quick-Mode Message 3"),
902 CONSTSTR("Failed to transmit Quick-Mode Message 3"));
915 * receive from responder
916 * HDR#*, HASH(4), notify
919 quick_i3recv(iph2
, msg0
)
920 struct ph2handle
*iph2
;
924 vchar_t
*pbuf
= NULL
; /* for payload parsing */
925 struct isakmp_parse_t
*pa
;
926 struct isakmp_pl_hash
*hash
= NULL
;
927 vchar_t
*notify
= NULL
;
928 int error
= ISAKMP_INTERNAL_ERROR
;
929 int packet_error
= -1;
932 if (iph2
->status
!= PHASE2ST_COMMIT
) {
933 plog(LLV_ERROR
, LOCATION
, NULL
,
934 "status mismatched %d.\n", iph2
->status
);
939 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
940 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
941 "Packet wasn't encrypted.\n");
944 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
946 plog(LLV_ERROR
, LOCATION
, NULL
,
947 "failed to decrypt packet");
951 /* validate the type of next payload */
952 pbuf
= isakmp_parse(msg
);
954 plog(LLV_ERROR
, LOCATION
, NULL
,
955 "failed to parse msg");
959 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
960 pa
->type
!= ISAKMP_NPTYPE_NONE
;
964 case ISAKMP_NPTYPE_HASH
:
965 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
967 case ISAKMP_NPTYPE_N
:
968 if (notify
!= NULL
) {
969 plog(LLV_WARNING
, LOCATION
, NULL
,
970 "Ignoring multiple notifications\n");
973 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
974 notify
= vmalloc(pa
->len
);
975 if (notify
== NULL
) {
976 plog(LLV_ERROR
, LOCATION
, NULL
,
977 "failed to get notify buffer.\n");
980 memcpy(notify
->v
, pa
->ptr
, notify
->l
);
983 /* don't send information, see ident_r1recv() */
984 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
985 "ignore the packet, "
986 "received unexpecting payload type %d.\n",
992 /* payload existency check */
994 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
995 "few isakmp message received.\n");
999 /* validate HASH(4) */
1002 vchar_t
*my_hash
= NULL
;
1003 vchar_t
*tmp
= NULL
;
1006 r_hash
= (char *)hash
+ sizeof(*hash
);
1008 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) validate:");
1009 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1011 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
1013 if (my_hash
== NULL
) {
1014 plog(LLV_ERROR
, LOCATION
, NULL
,
1015 "failed to compute HASH");
1019 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1023 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
1024 "HASH(4) mismatch.\n");
1025 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1030 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1031 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
1032 CONSTSTR("Initiator, Quick-Mode message 4"),
1036 iph2
->status
= PHASE2ST_ADDSA
;
1037 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
1039 /* don't anything if local test mode. */
1045 /* Do UPDATE for initiator */
1046 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
1047 if (pk_sendupdate(iph2
) < 0) {
1048 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
1051 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
1053 /* Do ADD for responder */
1054 if (pk_sendadd(iph2
) < 0) {
1055 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
1058 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
1064 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1065 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
1066 CONSTSTR("Initiator, Quick-Mode Message 4"),
1067 CONSTSTR("Failed to process Quick-Mode Message 4"));
1080 * receive from initiator
1081 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
1084 quick_r1recv(iph2
, msg0
)
1085 struct ph2handle
*iph2
;
1088 vchar_t
*msg
= NULL
;
1089 vchar_t
*hbuf
= NULL
; /* for hash computing. */
1090 vchar_t
*pbuf
= NULL
; /* for payload parsing */
1091 struct isakmp_parse_t
*pa
;
1092 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
1093 struct isakmp_pl_hash
*hash
= NULL
;
1096 int f_id_order
; /* for ID payload detection */
1097 int error
= ISAKMP_INTERNAL_ERROR
;
1098 struct sockaddr
*natoa_i
= NULL
;
1099 struct sockaddr
*natoa_r
= NULL
;
1101 /* validity check */
1102 if (iph2
->status
!= PHASE2ST_START
) {
1103 plog(LLV_ERROR
, LOCATION
, NULL
,
1104 "status mismatched %d.\n", iph2
->status
);
1109 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1110 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1111 "Packet wasn't encrypted.\n");
1112 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1115 /* decrypt packet */
1116 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
1118 plog(LLV_ERROR
, LOCATION
, NULL
,
1119 "failed to decrypt packet");
1123 /* create buffer for using to validate HASH(1) */
1126 * 1. the first one must be HASH
1127 * 2. the second one must be SA (added in isakmp-oakley-05!)
1128 * 3. two IDs must be considered as IDci, then IDcr
1130 pbuf
= isakmp_parse(msg
);
1132 plog(LLV_ERROR
, LOCATION
, NULL
,
1133 "failed to parse msg");
1136 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1138 /* HASH payload is fixed postion */
1139 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
1140 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1141 "received invalid next payload type %d, "
1143 pa
->type
, ISAKMP_NPTYPE_HASH
);
1144 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
1147 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1151 * this restriction was introduced in isakmp-oakley-05.
1152 * we do not check this for backward compatibility.
1153 * TODO: command line/config file option to enable/disable this code
1155 /* HASH payload is fixed postion */
1156 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
1157 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
1158 "received invalid next payload type %d, "
1160 pa
->type
, ISAKMP_NPTYPE_SA
);
1161 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
1164 /* allocate buffer for computing HASH(1) */
1165 tlen
= ntohl(isakmp
->len
) - sizeof(*isakmp
);
1166 hbuf
= vmalloc(tlen
);
1168 plog(LLV_ERROR
, LOCATION
, NULL
,
1169 "failed to get hash buffer.\n");
1175 * parse the payloads.
1176 * copy non-HASH payloads into hbuf, so that we can validate HASH.
1178 iph2
->sa
= NULL
; /* we don't support multi SAs. */
1179 iph2
->nonce_p
= NULL
;
1180 iph2
->dhpub_p
= NULL
;
1183 tlen
= 0; /* count payload length except of HASH payload. */
1186 * IDi2 MUST be immediatelly followed by IDr2. We allowed the
1187 * illegal case, but logged. First ID payload is to be IDi2.
1188 * And next ID payload is to be IDr2.
1192 for (; pa
->type
; pa
++) {
1194 /* copy to buffer for HASH */
1195 /* Don't modify the payload */
1196 memcpy(p
, pa
->ptr
, pa
->len
);
1198 if (pa
->type
!= ISAKMP_NPTYPE_ID
)
1202 case ISAKMP_NPTYPE_SA
:
1203 if (iph2
->sa
!= NULL
) {
1204 plog(LLV_ERROR
, LOCATION
, NULL
,
1205 "Multi SAs isn't supported.\n");
1208 if (isakmp_p2ph(&iph2
->sa
, pa
->ptr
) < 0) {
1209 plog(LLV_ERROR
, LOCATION
, NULL
,
1210 "failed to process SA payload");
1215 case ISAKMP_NPTYPE_NONCE
:
1216 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0) {
1217 plog(LLV_ERROR
, LOCATION
, NULL
,
1218 "failed to process NONCE payload");
1223 case ISAKMP_NPTYPE_KE
:
1224 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0) {
1225 plog(LLV_ERROR
, LOCATION
, NULL
,
1226 "failed to process KE payload");
1231 case ISAKMP_NPTYPE_ID
:
1232 if (iph2
->id_p
== NULL
) {
1236 if (isakmp_p2ph(&iph2
->id_p
, pa
->ptr
) < 0) {
1237 plog(LLV_ERROR
, LOCATION
, NULL
,
1238 "failed to process IDci2 payload");
1242 } else if (iph2
->id
== NULL
) {
1244 if (f_id_order
== 0) {
1245 plog(LLV_ERROR
, LOCATION
, NULL
,
1246 "IDr2 payload is not "
1247 "immediatelly followed "
1248 "by IDi2. We allowed.\n");
1249 /* XXX we allowed in this case. */
1252 if (isakmp_p2ph(&iph2
->id
, pa
->ptr
) < 0) {
1253 plog(LLV_ERROR
, LOCATION
, NULL
,
1254 "failed to process IDcr2 payload");
1258 plog(LLV_ERROR
, LOCATION
, NULL
,
1259 "received too many ID payloads.\n");
1260 plogdump(LLV_ERROR
, iph2
->id
->v
, iph2
->id
->l
);
1261 error
= ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1266 case ISAKMP_NPTYPE_N
:
1267 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
1271 case ISAKMP_NPTYPE_NATOA_DRAFT
:
1272 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
1273 case ISAKMP_NPTYPE_NATOA_RFC
:
1276 struct sockaddr
*daddr
;
1278 isakmp_p2ph(&vp
, pa
->ptr
);
1281 daddr
= process_natoa_payload(vp
);
1283 if (natoa_i
== NULL
) {
1285 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder rcvd NAT-OA i: %s\n",
1286 saddr2str(natoa_i
));
1287 } else if (natoa_r
== NULL
) {
1289 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder rcvd NAT-OA r: %s\n",
1290 saddr2str(natoa_r
));
1303 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1304 "ignore the packet, "
1305 "received unexpected payload type %d.\n",
1307 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1313 /* compute true length of payload. */
1317 /* payload existency check */
1318 if (hash
== NULL
|| iph2
->sa
== NULL
|| iph2
->nonce_p
== NULL
) {
1319 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1320 "expected isakmp payloads missing.\n");
1321 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1326 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDci2:");
1327 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
1330 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDcr2:");
1331 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
1334 /* adjust buffer length for HASH */
1337 /* validate HASH(1) */
1340 vchar_t
*my_hash
= NULL
;
1343 r_hash
= (caddr_t
)hash
+ sizeof(*hash
);
1345 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(1) validate:");
1346 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1348 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
1349 if (my_hash
== NULL
) {
1350 plog(LLV_ERROR
, LOCATION
, NULL
,
1351 "failed to compute HASH");
1355 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1359 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
1360 "HASH(1) mismatch.\n");
1361 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1367 error
= get_sainfo_r(iph2
);
1369 plog(LLV_ERROR
, LOCATION
, NULL
,
1370 "failed to get sainfo.\n");
1374 /* check the existence of ID payload and create responder's proposal */
1375 error
= get_proposal_r(iph2
);
1378 /* generate a policy template from peer's proposal */
1379 if (set_proposal_from_proposal(iph2
)) {
1380 plog(LLV_ERROR
, LOCATION
, NULL
,
1381 "failed to generate a proposal template "
1382 "from client's proposal.\n");
1383 return ISAKMP_INTERNAL_ERROR
;
1387 /* select single proposal or reject it. */
1388 if (ipsecdoi_selectph2proposal(iph2
) < 0) {
1389 plog(LLV_ERROR
, LOCATION
, NULL
,
1390 "failed to select proposal.\n");
1391 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1396 plog(LLV_ERROR
, LOCATION
, NULL
,
1397 "failed to get proposal for responder.\n");
1401 /* check KE and attribute of PFS */
1402 if (iph2
->dhpub_p
!= NULL
&& iph2
->approval
->pfs_group
== 0) {
1403 plog(LLV_ERROR
, LOCATION
, NULL
,
1404 "no PFS is specified, but peer sends KE.\n");
1405 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1408 if (iph2
->dhpub_p
== NULL
&& iph2
->approval
->pfs_group
!= 0) {
1409 plog(LLV_ERROR
, LOCATION
, NULL
,
1410 "PFS is specified, but peer doesn't sends KE.\n");
1411 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1415 ike_session_update_mode(iph2
); /* update the mode, now that we have a proposal */
1418 * save the packet from the initiator in order to resend the
1419 * responder's first packet against this packet.
1421 iph2
->msg1
= vdup(msg0
);
1423 /* change status of isakmp status entry */
1424 iph2
->status
= PHASE2ST_STATUS2
;
1428 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1429 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
1430 CONSTSTR("Responder, Quick-Mode message 1"),
1435 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1436 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
1437 CONSTSTR("Responder, Quick-Mode Message 1"),
1438 CONSTSTR("Failed to process Quick-Mode Message 1"));
1449 racoon_free(natoa_i
);
1452 racoon_free(natoa_r
);
1458 VPTRINIT(iph2
->nonce_p
);
1459 VPTRINIT(iph2
->dhpub_p
);
1461 VPTRINIT(iph2
->id_p
);
1468 * call pfkey_getspi.
1471 quick_r1prep(iph2
, msg
)
1472 struct ph2handle
*iph2
;
1475 int error
= ISAKMP_INTERNAL_ERROR
;
1477 /* validity check */
1478 if (iph2
->status
!= PHASE2ST_STATUS2
) {
1479 plog(LLV_ERROR
, LOCATION
, NULL
,
1480 "status mismatched %d.\n", iph2
->status
);
1484 iph2
->status
= PHASE2ST_GETSPISENT
;
1486 /* send getspi message */
1487 if (pk_sendgetspi(iph2
) < 0) {
1488 plog(LLV_ERROR
, LOCATION
, NULL
,
1489 "failed to send getspi");
1493 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
1495 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
1496 pfkey_timeover_stub
, iph2
);
1506 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
1509 quick_r2send(iph2
, msg
)
1510 struct ph2handle
*iph2
;
1513 vchar_t
*body
= NULL
;
1514 vchar_t
*hash
= NULL
;
1515 vchar_t
*natoa_i
= NULL
;
1516 vchar_t
*natoa_r
= NULL
;
1518 struct isakmp_gen
*gen
;
1521 int error
= ISAKMP_INTERNAL_ERROR
;
1523 u_int8_t
*np_p
= NULL
;
1525 /* validity check */
1527 plog(LLV_ERROR
, LOCATION
, NULL
,
1528 "msg has to be NULL in this function.\n");
1531 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
1532 plog(LLV_ERROR
, LOCATION
, NULL
,
1533 "status mismatched %d.\n", iph2
->status
);
1537 /* update responders SPI */
1538 if (ipsecdoi_updatespi(iph2
) < 0) {
1539 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to update spi.\n");
1543 /* generate NONCE value */
1544 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
1545 if (iph2
->nonce
== NULL
) {
1546 plog(LLV_ERROR
, LOCATION
, NULL
,
1547 "failed to generate NONCE");
1551 /* generate KE value if need */
1552 pfsgroup
= iph2
->approval
->pfs_group
;
1553 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0) {
1554 /* DH group settting if PFS is required. */
1555 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
1556 plog(LLV_ERROR
, LOCATION
, NULL
,
1557 "failed to set DH value.\n");
1560 /* generate DH public value */
1561 if (oakley_dh_generate(iph2
->pfsgrp
,
1562 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
1563 plog(LLV_ERROR
, LOCATION
, NULL
,
1564 "failed to generate DH public");
1569 /* create SA;NONCE payload, and KE and ID if need */
1570 tlen
= sizeof(*gen
) + iph2
->sa_ret
->l
1571 + sizeof(*gen
) + iph2
->nonce
->l
;
1572 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0)
1573 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
1574 if (iph2
->id_p
!= NULL
)
1575 tlen
+= (sizeof(*gen
) + iph2
->id_p
->l
1576 + sizeof(*gen
) + iph2
->id
->l
);
1580 * RFC3947 5.2. if we chose UDP-Encapsulated-Transport
1581 * we should send NAT-OA
1583 if (ipsecdoi_any_transportmode(iph2
->approval
)
1584 && (iph2
->ph1
->natt_flags
& NAT_DETECTED
)) {
1585 natoa_type
= create_natoa_payloads(iph2
, &natoa_i
, &natoa_r
);
1586 if (natoa_type
== -1) {
1587 plog(LLV_ERROR
, LOCATION
, NULL
,
1588 "failed to create NATOA payloads");
1591 else if (natoa_type
!= 0) {
1592 tlen
+= sizeof(*gen
) + natoa_i
->l
;
1593 tlen
+= sizeof(*gen
) + natoa_r
->l
;
1595 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder send NAT-OAi:\n");
1596 plogdump(LLV_DEBUG
, natoa_i
->v
, natoa_i
->l
);
1597 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder send NAT-OAr:\n");
1598 plogdump(LLV_DEBUG
, natoa_r
->v
, natoa_r
->l
);
1603 plog(LLV_DEBUG
, LOCATION
, NULL
, "Approved SA\n");
1604 printsaprop0(LLV_DEBUG
, iph2
->approval
);
1606 body
= vmalloc(tlen
);
1608 plog(LLV_ERROR
, LOCATION
, NULL
,
1609 "failed to get buffer to send.\n");
1614 /* make SA payload */
1615 p
= set_isakmp_payload(body
->v
, iph2
->sa_ret
, ISAKMP_NPTYPE_NONCE
);
1617 /* add NONCE payload */
1618 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1619 p
= set_isakmp_payload(p
, iph2
->nonce
,
1620 (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0)
1622 : (iph2
->id_p
!= NULL
1624 : (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
)));
1626 /* add KE payload if need. */
1627 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0) {
1628 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1629 p
= set_isakmp_payload(p
, iph2
->dhpub
,
1630 (iph2
->id_p
== NULL
) ? (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
) : ISAKMP_NPTYPE_ID
);
1633 /* add ID payloads received. */
1634 if (iph2
->id_p
!= NULL
) {
1636 p
= set_isakmp_payload(p
, iph2
->id_p
, ISAKMP_NPTYPE_ID
);
1637 plog(LLV_DEBUG
, LOCATION
, NULL
, "sending IDci2:\n");
1638 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
1640 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1641 p
= set_isakmp_payload(p
, iph2
->id
, (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
));
1642 plog(LLV_DEBUG
, LOCATION
, NULL
, "sending IDcr2:\n");
1643 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
1646 /* add a RESPONDER-LIFETIME notify payload if needed */
1648 vchar_t
*data
= NULL
;
1649 struct saprop
*pp
= iph2
->approval
;
1652 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_SEC
) {
1653 u_int32_t v
= htonl((u_int32_t
)pp
->lifetime
);
1654 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1655 IPSECDOI_ATTR_SA_LD_TYPE_SEC
);
1657 plog(LLV_ERROR
, LOCATION
, NULL
,
1658 "failed to add RESPONDER-LIFETIME notify (type) payload");
1661 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1662 (caddr_t
)&v
, sizeof(v
));
1664 plog(LLV_ERROR
, LOCATION
, NULL
,
1665 "failed to add RESPONDER-LIFETIME notify (value) payload");
1669 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_KB
) {
1670 u_int32_t v
= htonl((u_int32_t
)pp
->lifebyte
);
1671 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1672 IPSECDOI_ATTR_SA_LD_TYPE_KB
);
1674 plog(LLV_ERROR
, LOCATION
, NULL
,
1675 "failed to add RESPONDER-LIFETIME notify (type) payload");
1678 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1679 (caddr_t
)&v
, sizeof(v
));
1681 plog(LLV_ERROR
, LOCATION
, NULL
,
1682 "failed to add RESPONDER-LIFETIME notify (value) payload");
1688 * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1689 * in the case of SA bundle ?
1692 for (pr
= pp
->head
; pr
; pr
= pr
->next
) {
1693 body
= isakmp_add_pl_n(body
, &np_p
,
1694 ISAKMP_NTYPE_RESPONDER_LIFETIME
, pr
, data
);
1696 plog(LLV_ERROR
, LOCATION
, NULL
,
1697 "invalid RESPONDER-LIFETIME payload");
1699 return error
; /* XXX */
1708 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
1709 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
1712 /* generate HASH(2) */
1716 tmp
= vmalloc(iph2
->nonce_p
->l
+ body
->l
);
1718 plog(LLV_ERROR
, LOCATION
, NULL
,
1719 "failed to get hash buffer.\n");
1722 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1723 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, body
->v
, body
->l
);
1725 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, tmp
);
1729 plog(LLV_ERROR
, LOCATION
, NULL
,
1730 "failed to compute HASH");
1735 /* send isakmp payload */
1736 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
1737 if (iph2
->sendbuf
== NULL
) {
1738 plog(LLV_ERROR
, LOCATION
, NULL
,
1739 "failed to get send buffer");
1743 /* send the packet, add to the schedule to resend */
1744 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
1745 if (isakmp_ph2resend(iph2
) == -1) {
1746 plog(LLV_ERROR
, LOCATION
, NULL
,
1747 "failed to send packet");
1751 /* the sending message is added to the received-list. */
1752 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, iph2
->msg1
,
1753 PH2_NON_ESP_EXTRA_LEN(iph2
)) == -1) {
1754 plog(LLV_ERROR
, LOCATION
, NULL
,
1755 "failed to add a response packet to the tree.\n");
1759 /* change status of isakmp status entry */
1760 iph2
->status
= PHASE2ST_MSG1SENT
;
1764 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1765 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
1766 CONSTSTR("Responder, Quick-Mode message 2"),
1771 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1772 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
1773 CONSTSTR("Responder, Quick-Mode Message 2"),
1774 CONSTSTR("Failed to transmit Quick-Mode Message 2"));
1789 * receive from initiator
1793 quick_r3recv(iph2
, msg0
)
1794 struct ph2handle
*iph2
;
1797 vchar_t
*msg
= NULL
;
1798 vchar_t
*pbuf
= NULL
; /* for payload parsing */
1799 struct isakmp_parse_t
*pa
;
1800 struct isakmp_pl_hash
*hash
= NULL
;
1801 int error
= ISAKMP_INTERNAL_ERROR
;
1803 /* validity check */
1804 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
1805 plog(LLV_ERROR
, LOCATION
, NULL
,
1806 "status mismatched %d.\n", iph2
->status
);
1810 /* decrypt packet */
1811 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1812 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1813 "Packet wasn't encrypted.\n");
1816 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
1818 plog(LLV_ERROR
, LOCATION
, NULL
,
1819 "failed to decrypt packet");
1823 /* validate the type of next payload */
1824 pbuf
= isakmp_parse(msg
);
1826 plog(LLV_ERROR
, LOCATION
, NULL
,
1827 "failed to parse msg");
1831 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1832 pa
->type
!= ISAKMP_NPTYPE_NONE
;
1836 case ISAKMP_NPTYPE_HASH
:
1837 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1839 case ISAKMP_NPTYPE_N
:
1840 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
1843 /* don't send information, see ident_r1recv() */
1844 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1845 "ignore the packet, "
1846 "received unexpecting payload type %d.\n",
1852 /* payload existency check */
1854 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1855 "few isakmp message received.\n");
1859 /* validate HASH(3) */
1860 /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1863 vchar_t
*my_hash
= NULL
;
1864 vchar_t
*tmp
= NULL
;
1867 r_hash
= (char *)hash
+ sizeof(*hash
);
1869 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) validate:");
1870 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1872 tmp
= vmalloc(iph2
->nonce_p
->l
+ iph2
->nonce
->l
);
1874 plog(LLV_ERROR
, LOCATION
, NULL
,
1875 "failed to get hash buffer.\n");
1878 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1879 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, iph2
->nonce
->v
, iph2
->nonce
->l
);
1881 my_hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
1883 if (my_hash
== NULL
) {
1884 plog(LLV_ERROR
, LOCATION
, NULL
,
1885 "failed to compute HASH");
1889 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1893 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1894 "HASH(3) mismatch.\n");
1895 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1900 /* if there is commit bit, don't set up SA now. */
1901 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
1902 iph2
->status
= PHASE2ST_COMMIT
;
1904 iph2
->status
= PHASE2ST_STATUS6
;
1908 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1909 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
1910 CONSTSTR("Responder, Quick-Mode message 3"),
1915 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1916 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
1917 CONSTSTR("Responder, Quick-Mode Message 3"),
1918 CONSTSTR("Failed to process Quick-Mode Message 3"));
1930 * HDR#*, HASH(4), notify
1933 quick_r3send(iph2
, msg0
)
1934 struct ph2handle
*iph2
;
1937 vchar_t
*buf
= NULL
;
1938 vchar_t
*myhash
= NULL
;
1939 struct isakmp_pl_n
*n
;
1940 vchar_t
*notify
= NULL
;
1943 int error
= ISAKMP_INTERNAL_ERROR
;
1945 /* validity check */
1946 if (iph2
->status
!= PHASE2ST_COMMIT
) {
1947 plog(LLV_ERROR
, LOCATION
, NULL
,
1948 "status mismatched %d.\n", iph2
->status
);
1952 /* generate HASH(4) */
1953 /* XXX What can I do in the case of multiple different SA */
1954 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) generate\n");
1956 /* XXX What should I do if there are multiple SAs ? */
1957 tlen
= sizeof(struct isakmp_pl_n
) + iph2
->approval
->head
->spisize
;
1958 notify
= vmalloc(tlen
);
1959 if (notify
== NULL
) {
1960 plog(LLV_ERROR
, LOCATION
, NULL
,
1961 "failed to get notify buffer.\n");
1964 n
= (struct isakmp_pl_n
*)notify
->v
;
1965 n
->h
.np
= ISAKMP_NPTYPE_NONE
;
1966 n
->h
.len
= htons(tlen
);
1967 n
->doi
= htonl(IPSEC_DOI
);
1968 n
->proto_id
= iph2
->approval
->head
->proto_id
;
1969 n
->spi_size
= sizeof(iph2
->approval
->head
->spisize
);
1970 n
->type
= htons(ISAKMP_NTYPE_CONNECTED
);
1971 memcpy(n
+ 1, &iph2
->approval
->head
->spi
, iph2
->approval
->head
->spisize
);
1973 myhash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
1974 if (myhash
== NULL
) {
1975 plog(LLV_ERROR
, LOCATION
, NULL
,
1976 "failed to compute HASH");
1980 /* create buffer for isakmp payload */
1981 tlen
= sizeof(struct isakmp
)
1982 + sizeof(struct isakmp_gen
) + myhash
->l
1984 buf
= vmalloc(tlen
);
1986 plog(LLV_ERROR
, LOCATION
, NULL
,
1987 "failed to get buffer to send.\n");
1991 /* create isakmp header */
1992 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
1994 plog(LLV_ERROR
, LOCATION
, NULL
,
1995 "failed to set ISAKMP header");
1999 /* add HASH(4) payload */
2000 p
= set_isakmp_payload(p
, myhash
, ISAKMP_NPTYPE_N
);
2002 /* add notify payload */
2003 memcpy(p
, notify
->v
, notify
->l
);
2005 #ifdef HAVE_PRINT_ISAKMP_C
2006 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
2010 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
2011 if (iph2
->sendbuf
== NULL
) {
2012 plog(LLV_ERROR
, LOCATION
, NULL
,
2013 "failed to encrypt packet");
2017 /* send the packet */
2018 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0) {
2019 plog(LLV_ERROR
, LOCATION
, NULL
,
2020 "failed to send packet");
2024 /* the sending message is added to the received-list. */
2025 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, msg0
,
2026 PH2_NON_ESP_EXTRA_LEN(iph2
)) == -1) {
2027 plog(LLV_ERROR
, LOCATION
, NULL
,
2028 "failed to add a response packet to the tree.\n");
2032 iph2
->status
= PHASE2ST_COMMIT
;
2036 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
2037 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
2038 CONSTSTR("Responder, Quick-Mode message 4"),
2043 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
2044 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
2045 CONSTSTR("Responder, Quick-Mode Message 4"),
2046 CONSTSTR("Failed to transmit Quick-Mode Message 4"));
2063 quick_r3prep(iph2
, msg0
)
2064 struct ph2handle
*iph2
;
2067 vchar_t
*msg
= NULL
;
2068 int error
= ISAKMP_INTERNAL_ERROR
;
2070 /* validity check */
2071 if (iph2
->status
!= PHASE2ST_STATUS6
) {
2072 plog(LLV_ERROR
, LOCATION
, NULL
,
2073 "status mismatched %d.\n", iph2
->status
);
2077 /* compute both of KEYMATs */
2078 if (oakley_compute_keymat(iph2
, RESPONDER
) < 0) {
2079 plog(LLV_ERROR
, LOCATION
, NULL
,
2080 "failed to compute KEYMAT");
2084 iph2
->status
= PHASE2ST_ADDSA
;
2085 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
2087 /* don't anything if local test mode. */
2093 /* Do UPDATE as responder */
2094 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
2095 if (pk_sendupdate(iph2
) < 0) {
2096 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
2099 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
2101 /* Do ADD for responder */
2102 if (pk_sendadd(iph2
) < 0) {
2103 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
2106 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
2109 * set policies into SPD if the policy is generated
2110 * from peer's policy.
2112 if (iph2
->spidx_gen
) {
2114 struct policyindex
*spidx
;
2115 struct sockaddr_storage addr
;
2117 struct sockaddr
*src
= iph2
->src
;
2118 struct sockaddr
*dst
= iph2
->dst
;
2120 /* make inbound policy */
2123 if (pk_sendspdupdate2(iph2
) < 0) {
2124 plog(LLV_ERROR
, LOCATION
, NULL
,
2125 "pfkey spdupdate2(inbound) failed.\n");
2128 plog(LLV_DEBUG
, LOCATION
, NULL
,
2129 "pfkey spdupdate2(inbound) sent.\n");
2131 spidx
= (struct policyindex
*)iph2
->spidx_gen
;
2132 #ifdef HAVE_POLICY_FWD
2133 /* make forward policy if required */
2134 if (tunnel_mode_prop(iph2
->approval
)) {
2135 spidx
->dir
= IPSEC_DIR_FWD
;
2136 if (pk_sendspdupdate2(iph2
) < 0) {
2137 plog(LLV_ERROR
, LOCATION
, NULL
,
2138 "pfkey spdupdate2(forward) failed.\n");
2141 plog(LLV_DEBUG
, LOCATION
, NULL
,
2142 "pfkey spdupdate2(forward) sent.\n");
2146 /* make outbound policy */
2149 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
2151 spidx
->src
= spidx
->dst
;
2153 pref
= spidx
->prefs
;
2154 spidx
->prefs
= spidx
->prefd
;
2155 spidx
->prefd
= pref
;
2157 if (pk_sendspdupdate2(iph2
) < 0) {
2158 plog(LLV_ERROR
, LOCATION
, NULL
,
2159 "pfkey spdupdate2(outbound) failed.\n");
2162 plog(LLV_DEBUG
, LOCATION
, NULL
,
2163 "pfkey spdupdate2(outbound) sent.\n");
2165 /* spidx_gen is unnecessary any more */
2166 delsp_bothdir((struct policyindex
*)iph2
->spidx_gen
);
2167 racoon_free(iph2
->spidx_gen
);
2168 iph2
->spidx_gen
= NULL
;
2169 iph2
->generated_spidx
=1;
2182 * create HASH, body (SA, NONCE) payload with isakmp header.
2185 quick_ir1mx(iph2
, body
, hash
)
2186 struct ph2handle
*iph2
;
2187 vchar_t
*body
, *hash
;
2189 struct isakmp
*isakmp
;
2190 vchar_t
*buf
= NULL
, *new = NULL
;
2193 struct isakmp_gen
*gen
;
2194 int error
= ISAKMP_INTERNAL_ERROR
;
2196 /* create buffer for isakmp payload */
2197 tlen
= sizeof(*isakmp
)
2198 + sizeof(*gen
) + hash
->l
2200 buf
= vmalloc(tlen
);
2202 plog(LLV_ERROR
, LOCATION
, NULL
,
2203 "failed to get buffer to send.\n");
2207 /* re-set encryption flag, for serurity. */
2208 iph2
->flags
|= ISAKMP_FLAG_E
;
2210 /* set isakmp header */
2211 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
2213 plog(LLV_ERROR
, LOCATION
, NULL
,
2214 "failed to set ISAKMP header");
2218 /* add HASH payload */
2219 /* XXX is next type always SA ? */
2220 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_SA
);
2222 /* add body payload */
2223 memcpy(p
, body
->v
, body
->l
);
2225 #ifdef HAVE_PRINT_ISAKMP_C
2226 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
2230 new = oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
2232 plog(LLV_ERROR
, LOCATION
, NULL
,
2233 "failed to encrypt packet");
2244 if (error
&& buf
!= NULL
) {
2253 * get remote's sainfo.
2254 * NOTE: this function is for responder.
2258 struct ph2handle
*iph2
;
2260 vchar_t
*idsrc
= NULL
, *iddst
= NULL
;
2262 int error
= ISAKMP_INTERNAL_ERROR
;
2263 struct sainfo
*anonymous
= NULL
;
2265 if (iph2
->id
== NULL
) {
2266 switch (iph2
->src
->sa_family
) {
2268 prefixlen
= sizeof(struct in_addr
) << 3;
2271 prefixlen
= sizeof(struct in6_addr
) << 3;
2274 plog(LLV_ERROR
, LOCATION
, NULL
,
2275 "invalid family: %d\n", iph2
->src
->sa_family
);
2278 idsrc
= ipsecdoi_sockaddr2id(iph2
->src
, prefixlen
,
2281 idsrc
= vdup(iph2
->id
);
2283 if (idsrc
== NULL
) {
2284 plog(LLV_ERROR
, LOCATION
, NULL
,
2285 "failed to set ID for source.\n");
2289 if (iph2
->id_p
== NULL
) {
2290 switch (iph2
->dst
->sa_family
) {
2292 prefixlen
= sizeof(struct in_addr
) << 3;
2295 prefixlen
= sizeof(struct in6_addr
) << 3;
2298 plog(LLV_ERROR
, LOCATION
, NULL
,
2299 "invalid family: %d\n", iph2
->dst
->sa_family
);
2302 iddst
= ipsecdoi_sockaddr2id(iph2
->dst
, prefixlen
,
2305 iddst
= vdup(iph2
->id_p
);
2307 if (iddst
== NULL
) {
2308 plog(LLV_ERROR
, LOCATION
, NULL
,
2309 "failed to set ID for destination.\n");
2313 iph2
->sainfo
= getsainfo(idsrc
, iddst
, iph2
->ph1
->id_p
, 0);
2314 // track anonymous sainfo, because we'll try to find a better sainfo if this is a client
2315 if (iph2
->sainfo
&& iph2
->sainfo
->idsrc
== NULL
)
2316 anonymous
= iph2
->sainfo
;
2318 if (iph2
->sainfo
== NULL
||
2319 (anonymous
&& iph2
->parent_session
&& iph2
->parent_session
->is_client
)) {
2320 if ((iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) && lcconf
->ext_nat_id
!= NULL
)
2321 iph2
->sainfo
= getsainfo(idsrc
, iddst
, iph2
->ph1
->id_p
, 1);
2323 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2324 "get_sainfo_r case 1.\n");
2326 // still no sainfo (or anonymous): for client, fallback to sainfo used by a previous established phase2
2327 if (iph2
->sainfo
== NULL
||
2328 (iph2
->sainfo
->idsrc
== NULL
&& iph2
->parent_session
&& iph2
->parent_session
->is_client
)) {
2329 ike_session_get_sainfo_r(iph2
);
2331 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2332 "get_sainfo_r case 2.\n");
2334 // still no sainfo (or anonymous): fallback to sainfo picked by dst id
2335 if ((iph2
->sainfo
== NULL
|| iph2
->sainfo
->idsrc
== NULL
) && iph2
->id_p
) {
2336 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2337 "get_sainfo_r about to try dst id only.\n");
2338 iph2
->sainfo
= getsainfo_by_dst_id(iph2
->id_p
, iph2
->ph1
->id_p
);
2340 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2341 "get_sainfo_r case 3.\n");
2342 if (iph2
->sainfo
->idsrc
== NULL
)
2343 anonymous
= iph2
->sainfo
;
2348 if (iph2
->sainfo
== NULL
) {
2349 if (anonymous
== NULL
) {
2350 plog(LLV_ERROR
, LOCATION
, NULL
,
2351 "failed to get sainfo.\n");
2354 iph2
->sainfo
= anonymous
;
2357 if (link_sainfo_to_ph2(iph2
->sainfo
) != 0) {
2358 plog(LLV_ERROR
, LOCATION
, NULL
,
2359 "failed to link sainfo\n");
2360 iph2
->sainfo
= NULL
;
2365 #ifdef ENABLE_HYBRID
2366 /* xauth group inclusion check */
2367 if (iph2
->sainfo
->group
!= NULL
)
2368 if(group_check(iph2
->ph1
,&iph2
->sainfo
->group
->v
,1)) {
2369 plog(LLV_ERROR
, LOCATION
, NULL
,
2370 "failed to group check");
2375 plog(LLV_DEBUG
, LOCATION
, NULL
,
2376 "selected sainfo: %s\n", sainfo2str(iph2
->sainfo
));
2389 get_proposal_r(iph2
)
2390 struct ph2handle
*iph2
;
2392 int error
= get_proposal_r_remote(iph2
, 0);
2393 if (error
!= -2 && error
!= 0 &&
2394 (((iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) && lcconf
->ext_nat_id
!= NULL
) ||
2395 (iph2
->parent_session
&& iph2
->parent_session
->is_client
))) {
2396 if (iph2
->parent_session
&& iph2
->parent_session
->is_client
)
2397 error
= ike_session_get_proposal_r(iph2
);
2398 if (error
!= -2 && error
!= 0)
2399 error
= get_proposal_r_remote(iph2
, 1);
2405 * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
2406 * are IP address and same address family.
2407 * Then get remote's policy from SPD copied from kernel.
2408 * If the type of ID payload is address or subnet type, then the index is
2409 * made from the payload. If there is no ID payload, or the type of ID
2410 * payload is NOT address type, then the index is made from the address
2412 * NOTE: This function is only for responder.
2415 get_proposal_r_remote(iph2
, ignore_id
)
2416 struct ph2handle
*iph2
;
2419 struct policyindex spidx
;
2420 struct secpolicy
*sp_in
, *sp_out
;
2421 int idi2type
= 0; /* switch whether copy IDs into id[src,dst]. */
2422 int error
= ISAKMP_INTERNAL_ERROR
;
2423 int generated_policy_exit_early
= 1;
2425 /* check the existence of ID payload */
2426 if ((iph2
->id_p
!= NULL
&& iph2
->id
== NULL
)
2427 || (iph2
->id_p
== NULL
&& iph2
->id
!= NULL
)) {
2428 plog(LLV_ERROR
, LOCATION
, NULL
,
2429 "Both IDs wasn't found in payload.\n");
2430 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2433 /* make sure if id[src,dst] is null (if use_remote_addr == 0). */
2434 if (!ignore_id
&& (iph2
->src_id
|| iph2
->dst_id
)) {
2435 plog(LLV_ERROR
, LOCATION
, NULL
,
2436 "Why do ID[src,dst] exist already.\n");
2437 return ISAKMP_INTERNAL_ERROR
;
2440 plog(LLV_DEBUG
, LOCATION
, NULL
,
2441 "%s: ignore_id %x.\n", __FUNCTION__
, ignore_id
);
2443 memset(&spidx
, 0, sizeof(spidx
));
2445 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
2447 /* make a spidx; a key to search SPD */
2448 spidx
.dir
= IPSEC_DIR_INBOUND
;
2452 * make destination address in spidx from either ID payload
2453 * or phase 1 address into a address in spidx.
2454 * If behind a nat - use phase1 address because server's
2455 * use the nat's address in the ID payload.
2457 if (iph2
->id
!= NULL
2459 && (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
2460 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
2461 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2462 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
2463 /* get a destination address of a policy */
2464 error
= ipsecdoi_id2sockaddr(iph2
->id
,
2465 (struct sockaddr
*)&spidx
.dst
,
2466 &spidx
.prefd
, &spidx
.ul_proto
);
2472 * get scopeid from the SA address.
2473 * note that the phase 1 source address is used as
2474 * a destination address to search for a inbound policy entry
2475 * because rcoon is responder.
2477 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
) {
2478 error
= setscopeid((struct sockaddr
*)&spidx
.dst
,
2485 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
2486 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
)
2487 idi2type
= _XIDT(iph2
->id
);
2491 plog(LLV_DEBUG
, LOCATION
, NULL
,
2492 "get a destination address of SP index "
2493 "from phase1 address "
2494 "due to no ID payloads found "
2495 "OR because ID type is not address.\n");
2498 * copy the SOURCE address of IKE into the DESTINATION address
2499 * of the key to search the SPD because the direction of policy
2502 memcpy(&spidx
.dst
, iph2
->src
, sysdep_sa_len(iph2
->src
));
2503 switch (spidx
.dst
.ss_family
) {
2506 struct sockaddr_in
*s
= (struct sockaddr_in
*)&spidx
.dst
;
2507 spidx
.prefd
= sizeof(struct in_addr
) << 3;
2508 s
->sin_port
= htons(0);
2513 spidx
.prefd
= sizeof(struct in6_addr
) << 3;
2522 /* make source address in spidx */
2523 if (iph2
->id_p
!= NULL
2525 && (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR
2526 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
2527 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2528 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
2529 /* get a source address of inbound SA */
2530 error
= ipsecdoi_id2sockaddr(iph2
->id_p
,
2531 (struct sockaddr
*)&spidx
.src
,
2532 &spidx
.prefs
, &spidx
.ul_proto
);
2538 * get scopeid from the SA address.
2539 * for more detail, see above of this function.
2541 if (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
) {
2542 error
= setscopeid((struct sockaddr
*)&spidx
.src
,
2549 /* make id[src,dst] if both ID types are IP address and same */
2550 if (_XIDT(iph2
->id_p
) == idi2type
2551 && spidx
.dst
.ss_family
== spidx
.src
.ss_family
) {
2552 iph2
->src_id
= dupsaddr((struct sockaddr
*)&spidx
.dst
);
2553 if (iph2
->src_id
== NULL
) {
2554 plog(LLV_ERROR
, LOCATION
, NULL
,
2555 "buffer allocation failed.\n");
2556 return ISAKMP_INTERNAL_ERROR
;
2558 iph2
->dst_id
= dupsaddr((struct sockaddr
*)&spidx
.src
);
2559 if (iph2
->dst_id
== NULL
) {
2560 plog(LLV_ERROR
, LOCATION
, NULL
,
2561 "buffer allocation failed.\n");
2562 return ISAKMP_INTERNAL_ERROR
;
2567 plog(LLV_DEBUG
, LOCATION
, NULL
,
2568 "get a source address of SP index "
2569 "from phase1 address "
2570 "due to no ID payloads found "
2571 "OR because ID type is not address.\n");
2573 /* see above comment. */
2574 memcpy(&spidx
.src
, iph2
->dst
, sysdep_sa_len(iph2
->dst
));
2575 switch (spidx
.src
.ss_family
) {
2578 struct sockaddr_in
*s
= (struct sockaddr_in
*)&spidx
.src
;
2579 spidx
.prefs
= sizeof(struct in_addr
) << 3;
2580 s
->sin_port
= htons(0);
2585 spidx
.prefs
= sizeof(struct in6_addr
) << 3;
2596 plog(LLV_DEBUG
, LOCATION
, NULL
,
2597 "get a src address from ID payload "
2598 "%s prefixlen=%u ul_proto=%u\n",
2599 saddr2str((struct sockaddr
*)&spidx
.src
),
2600 spidx
.prefs
, spidx
.ul_proto
);
2601 plog(LLV_DEBUG
, LOCATION
, NULL
,
2602 "get dst address from ID payload "
2603 "%s prefixlen=%u ul_proto=%u\n",
2604 saddr2str((struct sockaddr
*)&spidx
.dst
),
2605 spidx
.prefd
, spidx
.ul_proto
);
2608 * convert the ul_proto if it is 0
2609 * because 0 in ID payload means a wild card.
2611 if (spidx
.ul_proto
== 0)
2612 spidx
.ul_proto
= IPSEC_ULPROTO_ANY
;
2614 /* get inbound policy */
2615 sp_in
= getsp_r(&spidx
, iph2
);
2616 if (sp_in
== NULL
|| sp_in
->policy
== IPSEC_POLICY_GENERATE
) {
2617 if (iph2
->ph1
->rmconf
->gen_policy
) {
2619 plog(LLV_INFO
, LOCATION
, NULL
,
2620 "Update the generated policy : %s\n",
2623 plog(LLV_INFO
, LOCATION
, NULL
,
2625 "try to generate the policy : %s\n",
2627 iph2
->spidx_gen
= racoon_malloc(sizeof(spidx
));
2628 if (!iph2
->spidx_gen
) {
2629 plog(LLV_ERROR
, LOCATION
, NULL
,
2630 "buffer allocation failed.\n");
2631 return ISAKMP_INTERNAL_ERROR
;
2633 memcpy(iph2
->spidx_gen
, &spidx
, sizeof(spidx
));
2634 generated_policy_exit_early
= 1; /* special value */
2636 plog(LLV_ERROR
, LOCATION
, NULL
,
2637 "no policy found: %s\n", spidx2str(&spidx
));
2638 return ISAKMP_INTERNAL_ERROR
;
2642 /* get outbound policy */
2644 struct sockaddr_storage addr
;
2647 spidx
.dir
= IPSEC_DIR_OUTBOUND
;
2649 spidx
.src
= spidx
.dst
;
2652 spidx
.prefs
= spidx
.prefd
;
2655 sp_out
= getsp_r(&spidx
, iph2
);
2657 plog(LLV_WARNING
, LOCATION
, NULL
,
2658 "no outbound policy found: %s\n",
2663 iph2
->spid
= sp_out
->id
;
2668 plog(LLV_DEBUG
, LOCATION
, NULL
,
2669 "suitable SP found:%s\n", spidx2str(&spidx
));
2671 if (generated_policy_exit_early
) {
2676 * In the responder side, the inbound policy should be using IPsec.
2677 * outbound policy is not checked currently.
2679 if (sp_in
->policy
!= IPSEC_POLICY_IPSEC
) {
2680 plog(LLV_ERROR
, LOCATION
, NULL
,
2681 "policy found, but no IPsec required: %s\n",
2683 return ISAKMP_INTERNAL_ERROR
;
2686 /* set new proposal derived from a policy into the iph2->proposal. */
2687 if (set_proposal_from_policy(iph2
, sp_in
, sp_out
) < 0) {
2688 plog(LLV_ERROR
, LOCATION
, NULL
,
2689 "failed to create saprop.\n");
2690 return ISAKMP_INTERNAL_ERROR
;