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"
97 #include <Security/SecDH.h>
101 static vchar_t
*quick_ir1mx
__P((struct ph2handle
*, vchar_t
*, vchar_t
*));
102 static int get_sainfo_r
__P((struct ph2handle
*));
103 static int get_proposal_r
__P((struct ph2handle
*));
104 static int get_proposal_r_remote
__P((struct ph2handle
*, int));
110 * begin Quick Mode as initiator. send pfkey getspi message to kernel.
113 quick_i1prep(iph2
, msg
)
114 struct ph2handle
*iph2
;
115 vchar_t
*msg
; /* must be null pointer */
117 int error
= ISAKMP_INTERNAL_ERROR
;
120 if (iph2
->status
!= PHASE2ST_STATUS2
) {
121 plog(LLV_ERROR
, LOCATION
, NULL
,
122 "status mismatched %d.\n", iph2
->status
);
126 iph2
->msgid
= isakmp_newmsgid2(iph2
->ph1
);
127 if (iph2
->ivm
!= NULL
)
128 oakley_delivm(iph2
->ivm
);
129 iph2
->ivm
= oakley_newiv2(iph2
->ph1
, iph2
->msgid
);
130 if (iph2
->ivm
== NULL
)
133 iph2
->status
= PHASE2ST_GETSPISENT
;
135 /* don't anything if local test mode. */
141 /* send getspi message */
142 if (pk_sendgetspi(iph2
) < 0) {
143 plog(LLV_ERROR
, LOCATION
, NULL
,
144 "failed to send getspi message");
148 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
150 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
151 pfkey_timeover_stub
, iph2
);
161 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
164 quick_i1send(iph2
, msg
)
165 struct ph2handle
*iph2
;
166 vchar_t
*msg
; /* must be null pointer */
168 vchar_t
*body
= NULL
;
169 vchar_t
*hash
= NULL
;
171 vchar_t
*natoa_i
= NULL
;
172 vchar_t
*natoa_r
= NULL
;
173 #endif /* ENABLE_NATT */
175 struct isakmp_gen
*gen
;
178 int error
= ISAKMP_INTERNAL_ERROR
;
179 int pfsgroup
, idci
, idcr
;
181 struct ipsecdoi_id_b
*id
, *id_p
;
185 plog(LLV_ERROR
, LOCATION
, NULL
,
186 "msg has to be NULL in this function.\n");
189 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
190 plog(LLV_ERROR
, LOCATION
, NULL
,
191 "status mismatched %d.\n", iph2
->status
);
195 /* create SA payload for my proposal */
196 if (ipsecdoi_setph2proposal(iph2
) < 0) {
197 plog(LLV_ERROR
, LOCATION
, NULL
,
198 "failed to set proposal");
202 /* generate NONCE value */
203 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
204 if (iph2
->nonce
== NULL
) {
205 plog(LLV_ERROR
, LOCATION
, NULL
,
206 "failed to generate NONCE");
211 * DH value calculation is kicked out into cfparse.y.
212 * because pfs group can not be negotiated, it's only to be checked
215 /* generate KE value if need */
216 pfsgroup
= iph2
->proposal
->pfs_group
;
218 /* DH group settting if PFS is required. */
219 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
220 plog(LLV_ERROR
, LOCATION
, NULL
,
221 "failed to set DH value.\n");
225 if (oakley_dh_generate(iph2
->pfsgrp
,
226 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
228 if (oakley_dh_generate(iph2
->pfsgrp
,
229 &iph2
->dhpub
, &iph2
->publicKeySize
, &iph2
->dhC
) < 0) {
231 plog(LLV_ERROR
, LOCATION
, NULL
,
232 "failed to generate DH");
237 /* generate ID value */
238 if (ipsecdoi_setid2(iph2
) < 0) {
239 plog(LLV_ERROR
, LOCATION
, NULL
,
240 "failed to get ID.\n");
243 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDci:\n");
244 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
245 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDcr:\n");
246 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
249 * we do not attach IDci nor IDcr, under the following condition:
250 * - all proposals are transport mode
252 * - id payload suggests to encrypt all the traffic (no specific
255 id
= (struct ipsecdoi_id_b
*)iph2
->id
->v
;
256 id_p
= (struct ipsecdoi_id_b
*)iph2
->id_p
->v
;
257 if (id
->proto_id
== 0
258 && id_p
->proto_id
== 0
259 && iph2
->ph1
->rmconf
->support_proxy
== 0
260 && ipsecdoi_transportmode(iph2
->proposal
)) {
265 /* create SA;NONCE payload, and KE if need, and IDii, IDir. */
266 tlen
= + sizeof(*gen
) + iph2
->sa
->l
267 + sizeof(*gen
) + iph2
->nonce
->l
;
269 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
271 tlen
+= sizeof(*gen
) + iph2
->id
->l
;
273 tlen
+= sizeof(*gen
) + iph2
->id_p
->l
;
277 * RFC3947 5.2. if we propose UDP-Encapsulated-Transport
278 * we should send NAT-OA
280 if (ipsecdoi_any_transportmode(iph2
->proposal
)
281 && (iph2
->ph1
->natt_flags
& NAT_DETECTED
)) {
282 natoa_type
= create_natoa_payloads(iph2
, &natoa_i
, &natoa_r
);
283 if (natoa_type
== -1) {
284 plog(LLV_ERROR
, LOCATION
, NULL
,
285 "failed to generate NAT-OA payload.\n");
287 } else if (natoa_type
!= 0) {
288 tlen
+= sizeof(*gen
) + natoa_i
->l
;
289 tlen
+= sizeof(*gen
) + natoa_r
->l
;
291 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiator send NAT-OAi:\n");
292 plogdump(LLV_DEBUG
, natoa_i
->v
, natoa_i
->l
);
293 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiator send NAT-OAr:\n");
294 plogdump(LLV_DEBUG
, natoa_r
->v
, natoa_r
->l
);
299 body
= vmalloc(tlen
);
301 plog(LLV_ERROR
, LOCATION
, NULL
,
302 "failed to get buffer to send.\n");
309 p
= set_isakmp_payload(p
, iph2
->sa
, ISAKMP_NPTYPE_NONCE
);
311 /* add NONCE payload */
313 np
= ISAKMP_NPTYPE_KE
;
314 else if (idci
|| idcr
)
315 np
= ISAKMP_NPTYPE_ID
;
317 np
= (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
318 p
= set_isakmp_payload(p
, iph2
->nonce
, np
);
320 /* add KE payload if need. */
321 np
= (idci
|| idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
323 p
= set_isakmp_payload(p
, iph2
->dhpub
, np
);
326 np
= (idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
328 p
= set_isakmp_payload(p
, iph2
->id
, np
);
332 p
= set_isakmp_payload(p
, iph2
->id_p
, natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
336 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
337 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
340 /* generate HASH(1) */
341 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, body
);
343 plog(LLV_ERROR
, LOCATION
, NULL
,
344 "failed to compute HASH");
348 /* send isakmp payload */
349 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
350 if (iph2
->sendbuf
== NULL
) {
351 plog(LLV_ERROR
, LOCATION
, NULL
,
352 "failed to get send buffer");
356 /* send the packet, add to the schedule to resend */
357 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
358 if (isakmp_ph2resend(iph2
) == -1) {
359 plog(LLV_ERROR
, LOCATION
, NULL
,
360 "failed to send packet");
364 /* change status of isakmp status entry */
365 iph2
->status
= PHASE2ST_MSG1SENT
;
369 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
370 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
371 CONSTSTR("Initiator, Quick-Mode message 1"),
376 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
377 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
378 CONSTSTR("Initiator, Quick-Mode Message 1"),
379 CONSTSTR("Failed to transmit Quick-Mode Message 1"));
390 #endif /* ENABLE_NATT */
396 * receive from responder
397 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
400 quick_i2recv(iph2
, msg0
)
401 struct ph2handle
*iph2
;
405 vchar_t
*hbuf
= NULL
; /* for hash computing. */
406 vchar_t
*pbuf
= NULL
; /* for payload parsing */
407 struct isakmp_parse_t
*pa
;
408 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
409 struct isakmp_pl_hash
*hash
= NULL
;
413 int error
= ISAKMP_INTERNAL_ERROR
;
414 struct sockaddr
*natoa_i
= NULL
;
415 struct sockaddr
*natoa_r
= NULL
;
418 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
419 plog(LLV_ERROR
, LOCATION
, NULL
,
420 "status mismatched %d.\n", iph2
->status
);
425 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
426 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
427 "Packet wasn't encrypted.\n");
430 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
432 plog(LLV_ERROR
, LOCATION
, NULL
,
433 "failed to decrypt");
437 /* create buffer for validating HASH(2) */
440 * 1. the first one must be HASH
441 * 2. the second one must be SA (added in isakmp-oakley-05!)
442 * 3. two IDs must be considered as IDci, then IDcr
444 pbuf
= isakmp_parse(msg
);
446 plog(LLV_ERROR
, LOCATION
, NULL
,
447 "failed to parse msg");
450 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
452 /* HASH payload is fixed postion */
453 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
454 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
455 "received invalid next payload type %d, "
457 pa
->type
, ISAKMP_NPTYPE_HASH
);
460 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
464 * this restriction was introduced in isakmp-oakley-05.
465 * we do not check this for backward compatibility.
466 * TODO: command line/config file option to enable/disable this code
468 /* HASH payload is fixed postion */
469 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
470 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
471 "received invalid next payload type %d, "
473 pa
->type
, ISAKMP_NPTYPE_HASH
);
476 /* allocate buffer for computing HASH(2) */
477 tlen
= iph2
->nonce
->l
478 + ntohl(isakmp
->len
) - sizeof(*isakmp
);
480 plog(LLV_ERROR
, LOCATION
, NULL
,
481 "invalid length (%d,%d) while getting hash buffer.\n",
482 iph2
->nonce
->l
, ntohl(isakmp
->len
));
485 hbuf
= vmalloc(tlen
);
487 plog(LLV_ERROR
, LOCATION
, NULL
,
488 "failed to get hash buffer.\n");
491 p
= hbuf
->v
+ iph2
->nonce
->l
; /* retain the space for Ni_b */
494 * parse the payloads.
495 * copy non-HASH payloads into hbuf, so that we can validate HASH.
498 f_id
= 0; /* flag to use checking ID */
499 tlen
= 0; /* count payload length except of HASH payload. */
500 for (; pa
->type
; pa
++) {
502 /* copy to buffer for HASH */
503 /* Don't modify the payload */
504 memcpy(p
, pa
->ptr
, pa
->len
);
507 case ISAKMP_NPTYPE_SA
:
508 if (iph2
->sa_ret
!= NULL
) {
509 plog(LLV_ERROR
, LOCATION
, NULL
,
510 "Ignored, multiple SA "
511 "isn't supported.\n");
514 if (isakmp_p2ph(&iph2
->sa_ret
, pa
->ptr
) < 0) {
515 plog(LLV_ERROR
, LOCATION
, NULL
,
516 "failed to process SA payload");
521 case ISAKMP_NPTYPE_NONCE
:
522 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0) {
523 plog(LLV_ERROR
, LOCATION
, NULL
,
524 "failed to process NONCE payload");
529 case ISAKMP_NPTYPE_KE
:
530 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0) {
531 plog(LLV_ERROR
, LOCATION
, NULL
,
532 "failed to process KE payload");
537 case ISAKMP_NPTYPE_ID
:
550 /* These ids may not match when natt is used with some devices.
551 * RFC 2407 says that the protocol and port fields should be ignored
552 * if they are zero, therefore they need to be checked individually.
554 struct ipsecdoi_id_b
*id_ptr
= (struct ipsecdoi_id_b
*)vp
->v
;
555 struct ipsecdoi_pl_id
*idp_ptr
= (struct ipsecdoi_pl_id
*)pa
->ptr
;
557 if (id_ptr
->type
!= idp_ptr
->b
.type
558 || (idp_ptr
->b
.proto_id
!= 0 && idp_ptr
->b
.proto_id
!= id_ptr
->proto_id
)
559 || (idp_ptr
->b
.port
!= 0 && idp_ptr
->b
.port
!= id_ptr
->port
)
560 || memcmp(vp
->v
+ sizeof(struct ipsecdoi_id_b
), (caddr_t
)pa
->ptr
+ sizeof(struct ipsecdoi_pl_id
),
561 vp
->l
- sizeof(struct ipsecdoi_id_b
))) {
562 // to support servers that use our external nat address as our ID
563 if (iph2
->ph1
->natt_flags
& NAT_DETECTED
) {
564 plog(LLV_WARNING
, LOCATION
, NULL
,
565 "mismatched ID was returned - ignored because nat traversal is being used.\n");
566 /* If I'm behind a nat and the ID is type address - save the address
567 * and port for when the peer rekeys.
569 if (f_id
== 0 && (iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
)) {
570 if (lcconf
->ext_nat_id
)
571 vfree(lcconf
->ext_nat_id
);
572 if (idp_ptr
->h
.len
< sizeof(struct isakmp_gen
)) {
573 plog(LLV_ERROR
, LOCATION
, NULL
, "invalid length (%d) while allocating external nat id.\n", idp_ptr
->h
.len
);
576 lcconf
->ext_nat_id
= vmalloc(ntohs(idp_ptr
->h
.len
) - sizeof(struct isakmp_gen
));
577 if (lcconf
->ext_nat_id
== NULL
) {
578 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating external nat id.\n");
581 memcpy(lcconf
->ext_nat_id
->v
, &(idp_ptr
->b
), lcconf
->ext_nat_id
->l
);
582 if (iph2
->ext_nat_id
)
583 vfree(iph2
->ext_nat_id
);
584 iph2
->ext_nat_id
= vdup(lcconf
->ext_nat_id
);
585 if (iph2
->ext_nat_id
== NULL
) {
586 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating ph2's external nat id.\n");
589 plog(LLV_DEBUG
, LOCATION
, NULL
, "external nat address saved.\n");
590 plogdump(LLV_DEBUG
, iph2
->ext_nat_id
->v
, iph2
->ext_nat_id
->l
);
591 } else if (f_id
&& (iph2
->ph1
->natt_flags
& NAT_DETECTED_PEER
)) {
592 if (iph2
->ext_nat_id_p
)
593 vfree(iph2
->ext_nat_id_p
);
594 iph2
->ext_nat_id_p
= vmalloc(ntohs(idp_ptr
->h
.len
) - sizeof(struct isakmp_gen
));
595 if (iph2
->ext_nat_id_p
== NULL
) {
596 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating peers ph2's external nat id.\n");
599 memcpy(iph2
->ext_nat_id_p
->v
, &(idp_ptr
->b
), iph2
->ext_nat_id_p
->l
);
600 plog(LLV_DEBUG
, LOCATION
, NULL
, "peer's external nat address saved.\n");
601 plogdump(LLV_DEBUG
, iph2
->ext_nat_id_p
->v
, iph2
->ext_nat_id_p
->l
);
604 plog(LLV_ERROR
, LOCATION
, NULL
, "mismatched ID was returned.\n");
605 error
= ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED
;
614 case ISAKMP_NPTYPE_N
:
615 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
619 case ISAKMP_NPTYPE_NATOA_DRAFT
:
620 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
621 case ISAKMP_NPTYPE_NATOA_RFC
:
624 struct sockaddr
*daddr
;
626 isakmp_p2ph(&vp
, pa
->ptr
);
629 daddr
= process_natoa_payload(vp
);
631 if (natoa_i
== NULL
) {
633 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiaor rcvd NAT-OA i: %s\n",
635 } else if (natoa_r
== NULL
) {
637 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiator rcvd NAT-OA r: %s\n",
651 /* don't send information, see ident_r1recv() */
652 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
653 "ignore the packet, "
654 "received unexpecting payload type %d.\n",
661 /* compute true length of payload. */
665 /* payload existency check */
666 if (hash
== NULL
|| iph2
->sa_ret
== NULL
|| iph2
->nonce_p
== NULL
) {
667 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
668 "few isakmp message received.\n");
672 /* Fixed buffer for calculating HASH */
673 memcpy(hbuf
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
674 plog(LLV_DEBUG
, LOCATION
, NULL
,
675 "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n",
676 hbuf
->l
, tlen
+ iph2
->nonce
->l
);
677 /* adjust buffer length for HASH */
678 hbuf
->l
= iph2
->nonce
->l
+ tlen
;
680 /* validate HASH(2) */
683 vchar_t
*my_hash
= NULL
;
686 r_hash
= (char *)hash
+ sizeof(*hash
);
688 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(2) received:");
689 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
691 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
692 if (my_hash
== NULL
) {
693 plog(LLV_ERROR
, LOCATION
, NULL
,
694 "failed to compute HASH");
698 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
702 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
703 "HASH(2) mismatch.\n");
704 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
709 /* validity check SA payload sent from responder */
710 if (ipsecdoi_checkph2proposal(iph2
) < 0) {
711 plog(LLV_ERROR
, LOCATION
, NULL
,
712 "failed to validate SA proposal");
713 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
717 /* change status of isakmp status entry */
718 iph2
->status
= PHASE2ST_STATUS6
;
722 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
723 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
724 CONSTSTR("Initiator, Quick-Mode message 2"),
729 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
730 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
731 CONSTSTR("Initiator, Quick-Mode Message 2"),
732 CONSTSTR("Failed to process Quick-Mode Message 2 "));
743 racoon_free(natoa_i
);
746 racoon_free(natoa_r
);
751 VPTRINIT(iph2
->sa_ret
);
752 VPTRINIT(iph2
->nonce_p
);
753 VPTRINIT(iph2
->dhpub_p
);
755 VPTRINIT(iph2
->id_p
);
766 quick_i2send(iph2
, msg0
)
767 struct ph2handle
*iph2
;
772 vchar_t
*hash
= NULL
;
775 int error
= ISAKMP_INTERNAL_ERROR
;
776 int packet_error
= -1;
779 if (iph2
->status
!= PHASE2ST_STATUS6
) {
780 plog(LLV_ERROR
, LOCATION
, NULL
,
781 "status mismatched %d.\n", iph2
->status
);
785 /* generate HASH(3) */
789 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) generate\n");
791 tmp
= vmalloc(iph2
->nonce
->l
+ iph2
->nonce_p
->l
);
793 plog(LLV_ERROR
, LOCATION
, NULL
,
794 "failed to get hash buffer.\n");
797 memcpy(tmp
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
798 memcpy(tmp
->v
+ iph2
->nonce
->l
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
800 hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
804 plog(LLV_ERROR
, LOCATION
, NULL
,
805 "failed to compute HASH");
810 /* create buffer for isakmp payload */
811 tlen
= sizeof(struct isakmp
)
812 + sizeof(struct isakmp_gen
) + hash
->l
;
815 plog(LLV_ERROR
, LOCATION
, NULL
,
816 "failed to get buffer to send.\n");
820 /* create isakmp header */
821 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
823 plog(LLV_ERROR
, LOCATION
, NULL
,
824 "failed to create ISAKMP header");
828 /* add HASH(3) payload */
829 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_NONE
);
831 #ifdef HAVE_PRINT_ISAKMP_C
832 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
836 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
837 if (iph2
->sendbuf
== NULL
) {
838 plog(LLV_ERROR
, LOCATION
, NULL
,
839 "failed to encrypt packet");
843 /* if there is commit bit, need resending */
844 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
845 /* send the packet, add to the schedule to resend */
846 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
847 if (isakmp_ph2resend(iph2
) == -1) {
848 plog(LLV_ERROR
, LOCATION
, NULL
,
849 "failed to send packet, commit-bit");
853 /* send the packet */
854 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0) {
855 plog(LLV_ERROR
, LOCATION
, NULL
,
856 "failed to send packet");
861 /* the sending message is added to the received-list. */
862 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
,
864 PH2_NON_ESP_EXTRA_LEN(iph2
), PH2_FRAG_FLAGS(iph2
)) == -1) {
865 plog(LLV_ERROR
, LOCATION
, NULL
,
866 "failed to add a response packet to the tree.\n");
870 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
871 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
872 CONSTSTR("Initiator, Quick-Mode message 3"),
876 /* compute both of KEYMATs */
877 if (oakley_compute_keymat(iph2
, INITIATOR
) < 0) {
878 plog(LLV_ERROR
, LOCATION
, NULL
,
879 "failed to compute KEYMAT");
883 iph2
->status
= PHASE2ST_ADDSA
;
885 /* don't anything if local test mode. */
891 /* if there is commit bit don't set up SA now. */
892 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
893 iph2
->status
= PHASE2ST_COMMIT
;
898 /* Do UPDATE for initiator */
899 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
900 if (pk_sendupdate(iph2
) < 0) {
901 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
904 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
906 /* Do ADD for responder */
907 if (pk_sendadd(iph2
) < 0) {
908 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
911 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
917 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
918 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
919 CONSTSTR("Initiator, Quick-Mode Message 3"),
920 CONSTSTR("Failed to transmit Quick-Mode Message 3"));
933 * receive from responder
934 * HDR#*, HASH(4), notify
937 quick_i3recv(iph2
, msg0
)
938 struct ph2handle
*iph2
;
942 vchar_t
*pbuf
= NULL
; /* for payload parsing */
943 struct isakmp_parse_t
*pa
;
944 struct isakmp_pl_hash
*hash
= NULL
;
945 vchar_t
*notify
= NULL
;
946 int error
= ISAKMP_INTERNAL_ERROR
;
947 int packet_error
= -1;
950 if (iph2
->status
!= PHASE2ST_COMMIT
) {
951 plog(LLV_ERROR
, LOCATION
, NULL
,
952 "status mismatched %d.\n", iph2
->status
);
957 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
958 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
959 "Packet wasn't encrypted.\n");
962 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
964 plog(LLV_ERROR
, LOCATION
, NULL
,
965 "failed to decrypt packet\n");
969 /* validate the type of next payload */
970 pbuf
= isakmp_parse(msg
);
972 plog(LLV_ERROR
, LOCATION
, NULL
,
973 "failed to parse msg\n");
977 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
978 pa
->type
!= ISAKMP_NPTYPE_NONE
;
982 case ISAKMP_NPTYPE_HASH
:
983 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
985 case ISAKMP_NPTYPE_N
:
986 if (notify
!= NULL
) {
987 plog(LLV_WARNING
, LOCATION
, NULL
,
988 "Ignoring multiple notifications\n");
991 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
992 notify
= vmalloc(pa
->len
);
993 if (notify
== NULL
) {
994 plog(LLV_ERROR
, LOCATION
, NULL
,
995 "failed to get notify buffer.\n");
998 memcpy(notify
->v
, pa
->ptr
, notify
->l
);
1001 /* don't send information, see ident_r1recv() */
1002 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1003 "ignore the packet, "
1004 "received unexpecting payload type %d.\n",
1010 /* payload existency check */
1012 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1013 "few isakmp message received.\n");
1017 /* validate HASH(4) */
1020 vchar_t
*my_hash
= NULL
;
1021 vchar_t
*tmp
= NULL
;
1024 r_hash
= (char *)hash
+ sizeof(*hash
);
1026 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) validate:");
1027 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1029 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
1031 if (my_hash
== NULL
) {
1032 plog(LLV_ERROR
, LOCATION
, NULL
,
1033 "failed to compute HASH\n");
1037 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1041 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
1042 "HASH(4) mismatch.\n");
1043 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1048 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1049 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
1050 CONSTSTR("Initiator, Quick-Mode message 4"),
1054 iph2
->status
= PHASE2ST_ADDSA
;
1055 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
1057 /* don't anything if local test mode. */
1063 /* Do UPDATE for initiator */
1064 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
1065 if (pk_sendupdate(iph2
) < 0) {
1066 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
1069 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
1071 /* Do ADD for responder */
1072 if (pk_sendadd(iph2
) < 0) {
1073 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
1076 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
1082 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1083 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
1084 CONSTSTR("Initiator, Quick-Mode Message 4"),
1085 CONSTSTR("Failed to process Quick-Mode Message 4"));
1098 * receive from initiator
1099 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
1102 quick_r1recv(iph2
, msg0
)
1103 struct ph2handle
*iph2
;
1106 vchar_t
*msg
= NULL
;
1107 vchar_t
*hbuf
= NULL
; /* for hash computing. */
1108 vchar_t
*pbuf
= NULL
; /* for payload parsing */
1109 struct isakmp_parse_t
*pa
;
1110 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
1111 struct isakmp_pl_hash
*hash
= NULL
;
1114 int f_id_order
; /* for ID payload detection */
1115 int error
= ISAKMP_INTERNAL_ERROR
;
1116 struct sockaddr
*natoa_i
= NULL
;
1117 struct sockaddr
*natoa_r
= NULL
;
1119 /* validity check */
1120 if (iph2
->status
!= PHASE2ST_START
) {
1121 plog(LLV_ERROR
, LOCATION
, NULL
,
1122 "status mismatched %d.\n", iph2
->status
);
1127 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1128 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1129 "Packet wasn't encrypted.\n");
1130 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1133 /* decrypt packet */
1134 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
1136 plog(LLV_ERROR
, LOCATION
, NULL
,
1137 "failed to decrypt packet\n");
1141 /* create buffer for using to validate HASH(1) */
1144 * 1. the first one must be HASH
1145 * 2. the second one must be SA (added in isakmp-oakley-05!)
1146 * 3. two IDs must be considered as IDci, then IDcr
1148 pbuf
= isakmp_parse(msg
);
1150 plog(LLV_ERROR
, LOCATION
, NULL
,
1151 "failed to parse msg\n");
1154 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1156 /* HASH payload is fixed postion */
1157 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
1158 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1159 "received invalid next payload type %d, "
1161 pa
->type
, ISAKMP_NPTYPE_HASH
);
1162 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
1165 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1169 * this restriction was introduced in isakmp-oakley-05.
1170 * we do not check this for backward compatibility.
1171 * TODO: command line/config file option to enable/disable this code
1173 /* HASH payload is fixed postion */
1174 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
1175 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
1176 "received invalid next payload type %d, "
1178 pa
->type
, ISAKMP_NPTYPE_SA
);
1179 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
1182 /* allocate buffer for computing HASH(1) */
1183 tlen
= ntohl(isakmp
->len
) - sizeof(*isakmp
);
1185 plog(LLV_ERROR
, LOCATION
, NULL
, "invalid length (%d) while extracting hash.\n",
1186 ntohl(isakmp
->len
));
1189 hbuf
= vmalloc(tlen
);
1191 plog(LLV_ERROR
, LOCATION
, NULL
,
1192 "failed to get hash buffer.\n");
1198 * parse the payloads.
1199 * copy non-HASH payloads into hbuf, so that we can validate HASH.
1201 iph2
->sa
= NULL
; /* we don't support multi SAs. */
1202 iph2
->nonce_p
= NULL
;
1203 iph2
->dhpub_p
= NULL
;
1206 tlen
= 0; /* count payload length except of HASH payload. */
1209 * IDi2 MUST be immediatelly followed by IDr2. We allowed the
1210 * illegal case, but logged. First ID payload is to be IDi2.
1211 * And next ID payload is to be IDr2.
1215 for (; pa
->type
; pa
++) {
1217 /* copy to buffer for HASH */
1218 /* Don't modify the payload */
1219 memcpy(p
, pa
->ptr
, pa
->len
);
1221 if (pa
->type
!= ISAKMP_NPTYPE_ID
)
1225 case ISAKMP_NPTYPE_SA
:
1226 if (iph2
->sa
!= NULL
) {
1227 plog(LLV_ERROR
, LOCATION
, NULL
,
1228 "Multi SAs isn't supported.\n");
1231 if (isakmp_p2ph(&iph2
->sa
, pa
->ptr
) < 0) {
1232 plog(LLV_ERROR
, LOCATION
, NULL
,
1233 "failed to process SA payload\n");
1238 case ISAKMP_NPTYPE_NONCE
:
1239 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0) {
1240 plog(LLV_ERROR
, LOCATION
, NULL
,
1241 "failed to process NONCE payload\n");
1246 case ISAKMP_NPTYPE_KE
:
1247 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0) {
1248 plog(LLV_ERROR
, LOCATION
, NULL
,
1249 "failed to process KE payload\n");
1254 case ISAKMP_NPTYPE_ID
:
1255 if (iph2
->id_p
== NULL
) {
1259 if (isakmp_p2ph(&iph2
->id_p
, pa
->ptr
) < 0) {
1260 plog(LLV_ERROR
, LOCATION
, NULL
,
1261 "failed to process IDci2 payload\n");
1265 } else if (iph2
->id
== NULL
) {
1267 if (f_id_order
== 0) {
1268 plog(LLV_ERROR
, LOCATION
, NULL
,
1269 "IDr2 payload is not "
1270 "immediatelly followed "
1271 "by IDi2. We allowed.\n");
1272 /* XXX we allowed in this case. */
1275 if (isakmp_p2ph(&iph2
->id
, pa
->ptr
) < 0) {
1276 plog(LLV_ERROR
, LOCATION
, NULL
,
1277 "failed to process IDcr2 payload\n");
1281 plog(LLV_ERROR
, LOCATION
, NULL
,
1282 "received too many ID payloads.\n");
1283 plogdump(LLV_ERROR
, iph2
->id
->v
, iph2
->id
->l
);
1284 error
= ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1289 case ISAKMP_NPTYPE_N
:
1290 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
1294 case ISAKMP_NPTYPE_NATOA_DRAFT
:
1295 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
1296 case ISAKMP_NPTYPE_NATOA_RFC
:
1299 struct sockaddr
*daddr
;
1301 isakmp_p2ph(&vp
, pa
->ptr
);
1304 daddr
= process_natoa_payload(vp
);
1306 if (natoa_i
== NULL
) {
1308 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder rcvd NAT-OA i: %s\n",
1309 saddr2str(natoa_i
));
1310 } else if (natoa_r
== NULL
) {
1312 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder rcvd NAT-OA r: %s\n",
1313 saddr2str(natoa_r
));
1326 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1327 "ignore the packet, "
1328 "received unexpected payload type %d.\n",
1330 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1336 /* compute true length of payload. */
1340 /* payload existency check */
1341 if (hash
== NULL
|| iph2
->sa
== NULL
|| iph2
->nonce_p
== NULL
) {
1342 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1343 "expected isakmp payloads missing.\n");
1344 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1349 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDci2:");
1350 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
1353 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDcr2:");
1354 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
1357 /* adjust buffer length for HASH */
1360 /* validate HASH(1) */
1363 vchar_t
*my_hash
= NULL
;
1366 r_hash
= (caddr_t
)hash
+ sizeof(*hash
);
1368 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(1) validate:");
1369 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1371 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
1372 if (my_hash
== NULL
) {
1373 plog(LLV_ERROR
, LOCATION
, NULL
,
1374 "failed to compute HASH\n");
1378 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1382 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
1383 "HASH(1) mismatch.\n");
1384 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1390 error
= get_sainfo_r(iph2
);
1392 plog(LLV_ERROR
, LOCATION
, NULL
,
1393 "failed to get sainfo.\n");
1397 /* check the existence of ID payload and create responder's proposal */
1398 error
= get_proposal_r(iph2
);
1401 /* generate a policy template from peer's proposal */
1402 if (set_proposal_from_proposal(iph2
)) {
1403 plog(LLV_ERROR
, LOCATION
, NULL
,
1404 "failed to generate a proposal template "
1405 "from client's proposal.\n");
1406 return ISAKMP_INTERNAL_ERROR
;
1410 /* select single proposal or reject it. */
1411 if (ipsecdoi_selectph2proposal(iph2
) < 0) {
1412 plog(LLV_ERROR
, LOCATION
, NULL
,
1413 "failed to select proposal.\n");
1414 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1419 plog(LLV_ERROR
, LOCATION
, NULL
,
1420 "failed to get proposal for responder.\n");
1424 /* check KE and attribute of PFS */
1425 if (iph2
->dhpub_p
!= NULL
&& iph2
->approval
->pfs_group
== 0) {
1426 plog(LLV_ERROR
, LOCATION
, NULL
,
1427 "no PFS is specified, but peer sends KE.\n");
1428 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1431 if (iph2
->dhpub_p
== NULL
&& iph2
->approval
->pfs_group
!= 0) {
1432 plog(LLV_ERROR
, LOCATION
, NULL
,
1433 "PFS is specified, but peer doesn't sends KE.\n");
1434 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1438 ike_session_update_mode(iph2
); /* update the mode, now that we have a proposal */
1441 * save the packet from the initiator in order to resend the
1442 * responder's first packet against this packet.
1444 iph2
->msg1
= vdup(msg0
);
1446 /* change status of isakmp status entry */
1447 iph2
->status
= PHASE2ST_STATUS2
;
1451 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1452 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
1453 CONSTSTR("Responder, Quick-Mode message 1"),
1458 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1459 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
1460 CONSTSTR("Responder, Quick-Mode Message 1"),
1461 CONSTSTR("Failed to process Quick-Mode Message 1"));
1472 racoon_free(natoa_i
);
1475 racoon_free(natoa_r
);
1481 VPTRINIT(iph2
->nonce_p
);
1482 VPTRINIT(iph2
->dhpub_p
);
1484 VPTRINIT(iph2
->id_p
);
1491 * call pfkey_getspi.
1494 quick_r1prep(iph2
, msg
)
1495 struct ph2handle
*iph2
;
1498 int error
= ISAKMP_INTERNAL_ERROR
;
1500 /* validity check */
1501 if (iph2
->status
!= PHASE2ST_STATUS2
) {
1502 plog(LLV_ERROR
, LOCATION
, NULL
,
1503 "status mismatched %d.\n", iph2
->status
);
1507 iph2
->status
= PHASE2ST_GETSPISENT
;
1509 /* send getspi message */
1510 if (pk_sendgetspi(iph2
) < 0) {
1511 plog(LLV_ERROR
, LOCATION
, NULL
,
1512 "failed to send getspi");
1516 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
1518 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
1519 pfkey_timeover_stub
, iph2
);
1529 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
1532 quick_r2send(iph2
, msg
)
1533 struct ph2handle
*iph2
;
1536 vchar_t
*body
= NULL
;
1537 vchar_t
*hash
= NULL
;
1538 vchar_t
*natoa_i
= NULL
;
1539 vchar_t
*natoa_r
= NULL
;
1541 struct isakmp_gen
*gen
;
1544 int error
= ISAKMP_INTERNAL_ERROR
;
1546 u_int8_t
*np_p
= NULL
;
1548 /* validity check */
1550 plog(LLV_ERROR
, LOCATION
, NULL
,
1551 "msg has to be NULL in this function.\n");
1554 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
1555 plog(LLV_ERROR
, LOCATION
, NULL
,
1556 "status mismatched %d.\n", iph2
->status
);
1560 /* update responders SPI */
1561 if (ipsecdoi_updatespi(iph2
) < 0) {
1562 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to update spi.\n");
1566 /* generate NONCE value */
1567 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
1568 if (iph2
->nonce
== NULL
) {
1569 plog(LLV_ERROR
, LOCATION
, NULL
,
1570 "failed to generate NONCE");
1574 /* generate KE value if need */
1575 pfsgroup
= iph2
->approval
->pfs_group
;
1576 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0) {
1577 /* DH group settting if PFS is required. */
1578 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
1579 plog(LLV_ERROR
, LOCATION
, NULL
,
1580 "failed to set DH value.\n");
1583 /* generate DH public value */
1585 if (oakley_dh_generate(iph2
->pfsgrp
,
1586 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
1588 if (oakley_dh_generate(iph2
->pfsgrp
,
1589 &iph2
->dhpub
, &iph2
->publicKeySize
, &iph2
->dhC
) < 0) {
1591 plog(LLV_ERROR
, LOCATION
, NULL
,
1592 "failed to generate DH public");
1597 /* create SA;NONCE payload, and KE and ID if need */
1598 tlen
= sizeof(*gen
) + iph2
->sa_ret
->l
1599 + sizeof(*gen
) + iph2
->nonce
->l
;
1600 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0)
1601 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
1602 if (iph2
->id_p
!= NULL
)
1603 tlen
+= (sizeof(*gen
) + iph2
->id_p
->l
1604 + sizeof(*gen
) + iph2
->id
->l
);
1608 * RFC3947 5.2. if we chose UDP-Encapsulated-Transport
1609 * we should send NAT-OA
1611 if (ipsecdoi_any_transportmode(iph2
->approval
)
1612 && (iph2
->ph1
->natt_flags
& NAT_DETECTED
)) {
1613 natoa_type
= create_natoa_payloads(iph2
, &natoa_i
, &natoa_r
);
1614 if (natoa_type
== -1) {
1615 plog(LLV_ERROR
, LOCATION
, NULL
,
1616 "failed to create NATOA payloads");
1619 else if (natoa_type
!= 0) {
1620 tlen
+= sizeof(*gen
) + natoa_i
->l
;
1621 tlen
+= sizeof(*gen
) + natoa_r
->l
;
1623 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder send NAT-OAi:\n");
1624 plogdump(LLV_DEBUG
, natoa_i
->v
, natoa_i
->l
);
1625 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder send NAT-OAr:\n");
1626 plogdump(LLV_DEBUG
, natoa_r
->v
, natoa_r
->l
);
1631 plog(LLV_DEBUG
, LOCATION
, NULL
, "Approved SA\n");
1632 printsaprop0(LLV_DEBUG
, iph2
->approval
);
1634 body
= vmalloc(tlen
);
1636 plog(LLV_ERROR
, LOCATION
, NULL
,
1637 "failed to get buffer to send.\n");
1642 /* make SA payload */
1643 p
= set_isakmp_payload(body
->v
, iph2
->sa_ret
, ISAKMP_NPTYPE_NONCE
);
1645 /* add NONCE payload */
1646 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1647 p
= set_isakmp_payload(p
, iph2
->nonce
,
1648 (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0)
1650 : (iph2
->id_p
!= NULL
1652 : (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
)));
1654 /* add KE payload if need. */
1655 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0) {
1656 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1657 p
= set_isakmp_payload(p
, iph2
->dhpub
,
1658 (iph2
->id_p
== NULL
) ? (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
) : ISAKMP_NPTYPE_ID
);
1661 /* add ID payloads received. */
1662 if (iph2
->id_p
!= NULL
) {
1664 p
= set_isakmp_payload(p
, iph2
->id_p
, ISAKMP_NPTYPE_ID
);
1665 plog(LLV_DEBUG
, LOCATION
, NULL
, "sending IDci2:\n");
1666 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
1668 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1669 p
= set_isakmp_payload(p
, iph2
->id
, (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
));
1670 plog(LLV_DEBUG
, LOCATION
, NULL
, "sending IDcr2:\n");
1671 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
1674 /* add a RESPONDER-LIFETIME notify payload if needed */
1676 vchar_t
*data
= NULL
;
1677 struct saprop
*pp
= iph2
->approval
;
1680 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_SEC
) {
1681 u_int32_t v
= htonl((u_int32_t
)pp
->lifetime
);
1682 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1683 IPSECDOI_ATTR_SA_LD_TYPE_SEC
);
1685 plog(LLV_ERROR
, LOCATION
, NULL
,
1686 "failed to add RESPONDER-LIFETIME notify (type) payload");
1689 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1690 (caddr_t
)&v
, sizeof(v
));
1692 plog(LLV_ERROR
, LOCATION
, NULL
,
1693 "failed to add RESPONDER-LIFETIME notify (value) payload");
1697 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_KB
) {
1698 u_int32_t v
= htonl((u_int32_t
)pp
->lifebyte
);
1699 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1700 IPSECDOI_ATTR_SA_LD_TYPE_KB
);
1702 plog(LLV_ERROR
, LOCATION
, NULL
,
1703 "failed to add RESPONDER-LIFETIME notify (type) payload");
1706 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1707 (caddr_t
)&v
, sizeof(v
));
1709 plog(LLV_ERROR
, LOCATION
, NULL
,
1710 "failed to add RESPONDER-LIFETIME notify (value) payload");
1716 * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1717 * in the case of SA bundle ?
1720 for (pr
= pp
->head
; pr
; pr
= pr
->next
) {
1721 body
= isakmp_add_pl_n(body
, &np_p
,
1722 ISAKMP_NTYPE_RESPONDER_LIFETIME
, pr
, data
);
1724 plog(LLV_ERROR
, LOCATION
, NULL
,
1725 "invalid RESPONDER-LIFETIME payload");
1727 return error
; /* XXX */
1736 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
1737 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
1740 /* generate HASH(2) */
1744 tmp
= vmalloc(iph2
->nonce_p
->l
+ body
->l
);
1746 plog(LLV_ERROR
, LOCATION
, NULL
,
1747 "failed to get hash buffer.\n");
1750 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1751 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, body
->v
, body
->l
);
1753 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, tmp
);
1757 plog(LLV_ERROR
, LOCATION
, NULL
,
1758 "failed to compute HASH");
1763 /* send isakmp payload */
1764 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
1765 if (iph2
->sendbuf
== NULL
) {
1766 plog(LLV_ERROR
, LOCATION
, NULL
,
1767 "failed to get send buffer");
1771 /* send the packet, add to the schedule to resend */
1772 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
1773 if (isakmp_ph2resend(iph2
) == -1) {
1774 plog(LLV_ERROR
, LOCATION
, NULL
,
1775 "failed to send packet");
1779 /* the sending message is added to the received-list. */
1780 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, iph2
->msg1
,
1781 PH2_NON_ESP_EXTRA_LEN(iph2
), PH2_FRAG_FLAGS(iph2
)) == -1) {
1782 plog(LLV_ERROR
, LOCATION
, NULL
,
1783 "failed to add a response packet to the tree.\n");
1787 /* change status of isakmp status entry */
1788 iph2
->status
= PHASE2ST_MSG1SENT
;
1792 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1793 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
1794 CONSTSTR("Responder, Quick-Mode message 2"),
1799 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1800 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
1801 CONSTSTR("Responder, Quick-Mode Message 2"),
1802 CONSTSTR("Failed to transmit Quick-Mode Message 2"));
1817 * receive from initiator
1821 quick_r3recv(iph2
, msg0
)
1822 struct ph2handle
*iph2
;
1825 vchar_t
*msg
= NULL
;
1826 vchar_t
*pbuf
= NULL
; /* for payload parsing */
1827 struct isakmp_parse_t
*pa
;
1828 struct isakmp_pl_hash
*hash
= NULL
;
1829 int error
= ISAKMP_INTERNAL_ERROR
;
1831 /* validity check */
1832 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
1833 plog(LLV_ERROR
, LOCATION
, NULL
,
1834 "status mismatched %d.\n", iph2
->status
);
1838 /* decrypt packet */
1839 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1840 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1841 "Packet wasn't encrypted.\n");
1844 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
1846 plog(LLV_ERROR
, LOCATION
, NULL
,
1847 "failed to decrypt packet\n");
1851 /* validate the type of next payload */
1852 pbuf
= isakmp_parse(msg
);
1854 plog(LLV_ERROR
, LOCATION
, NULL
,
1855 "failed to parse msg\n");
1859 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1860 pa
->type
!= ISAKMP_NPTYPE_NONE
;
1864 case ISAKMP_NPTYPE_HASH
:
1865 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1867 case ISAKMP_NPTYPE_N
:
1868 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
1871 /* don't send information, see ident_r1recv() */
1872 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1873 "ignore the packet, "
1874 "received unexpecting payload type %d.\n",
1880 /* payload existency check */
1882 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1883 "few isakmp message received.\n");
1887 /* validate HASH(3) */
1888 /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1891 vchar_t
*my_hash
= NULL
;
1892 vchar_t
*tmp
= NULL
;
1895 r_hash
= (char *)hash
+ sizeof(*hash
);
1897 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) validate:");
1898 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1900 tmp
= vmalloc(iph2
->nonce_p
->l
+ iph2
->nonce
->l
);
1902 plog(LLV_ERROR
, LOCATION
, NULL
,
1903 "failed to get hash buffer.\n");
1906 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1907 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, iph2
->nonce
->v
, iph2
->nonce
->l
);
1909 my_hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
1911 if (my_hash
== NULL
) {
1912 plog(LLV_ERROR
, LOCATION
, NULL
,
1913 "failed to compute HASH\n");
1917 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1921 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1922 "HASH(3) mismatch.\n");
1923 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1928 /* if there is commit bit, don't set up SA now. */
1929 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
1930 iph2
->status
= PHASE2ST_COMMIT
;
1932 iph2
->status
= PHASE2ST_STATUS6
;
1936 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1937 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
1938 CONSTSTR("Responder, Quick-Mode message 3"),
1943 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1944 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
1945 CONSTSTR("Responder, Quick-Mode Message 3"),
1946 CONSTSTR("Failed to process Quick-Mode Message 3"));
1958 * HDR#*, HASH(4), notify
1961 quick_r3send(iph2
, msg0
)
1962 struct ph2handle
*iph2
;
1965 vchar_t
*buf
= NULL
;
1966 vchar_t
*myhash
= NULL
;
1967 struct isakmp_pl_n
*n
;
1968 vchar_t
*notify
= NULL
;
1971 int error
= ISAKMP_INTERNAL_ERROR
;
1973 /* validity check */
1974 if (iph2
->status
!= PHASE2ST_COMMIT
) {
1975 plog(LLV_ERROR
, LOCATION
, NULL
,
1976 "status mismatched %d.\n", iph2
->status
);
1980 /* generate HASH(4) */
1981 /* XXX What can I do in the case of multiple different SA */
1982 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) generate\n");
1984 /* XXX What should I do if there are multiple SAs ? */
1985 tlen
= sizeof(struct isakmp_pl_n
) + iph2
->approval
->head
->spisize
;
1986 notify
= vmalloc(tlen
);
1987 if (notify
== NULL
) {
1988 plog(LLV_ERROR
, LOCATION
, NULL
,
1989 "failed to get notify buffer.\n");
1992 n
= (struct isakmp_pl_n
*)notify
->v
;
1993 n
->h
.np
= ISAKMP_NPTYPE_NONE
;
1994 n
->h
.len
= htons(tlen
);
1995 n
->doi
= htonl(IPSEC_DOI
);
1996 n
->proto_id
= iph2
->approval
->head
->proto_id
;
1997 n
->spi_size
= sizeof(iph2
->approval
->head
->spisize
);
1998 n
->type
= htons(ISAKMP_NTYPE_CONNECTED
);
1999 memcpy(n
+ 1, &iph2
->approval
->head
->spi
, iph2
->approval
->head
->spisize
);
2001 myhash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
2002 if (myhash
== NULL
) {
2003 plog(LLV_ERROR
, LOCATION
, NULL
,
2004 "failed to compute HASH");
2008 /* create buffer for isakmp payload */
2009 tlen
= sizeof(struct isakmp
)
2010 + sizeof(struct isakmp_gen
) + myhash
->l
2012 buf
= vmalloc(tlen
);
2014 plog(LLV_ERROR
, LOCATION
, NULL
,
2015 "failed to get buffer to send.\n");
2019 /* create isakmp header */
2020 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
2022 plog(LLV_ERROR
, LOCATION
, NULL
,
2023 "failed to set ISAKMP header");
2027 /* add HASH(4) payload */
2028 p
= set_isakmp_payload(p
, myhash
, ISAKMP_NPTYPE_N
);
2030 /* add notify payload */
2031 memcpy(p
, notify
->v
, notify
->l
);
2033 #ifdef HAVE_PRINT_ISAKMP_C
2034 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
2038 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
2039 if (iph2
->sendbuf
== NULL
) {
2040 plog(LLV_ERROR
, LOCATION
, NULL
,
2041 "failed to encrypt packet");
2045 /* send the packet */
2046 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0) {
2047 plog(LLV_ERROR
, LOCATION
, NULL
,
2048 "failed to send packet");
2052 /* the sending message is added to the received-list. */
2053 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, msg0
,
2054 PH2_NON_ESP_EXTRA_LEN(iph2
), PH2_FRAG_FLAGS(iph2
)) == -1) {
2055 plog(LLV_ERROR
, LOCATION
, NULL
,
2056 "failed to add a response packet to the tree.\n");
2060 iph2
->status
= PHASE2ST_COMMIT
;
2064 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
2065 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
2066 CONSTSTR("Responder, Quick-Mode message 4"),
2071 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
2072 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
2073 CONSTSTR("Responder, Quick-Mode Message 4"),
2074 CONSTSTR("Failed to transmit Quick-Mode Message 4"));
2091 quick_r3prep(iph2
, msg0
)
2092 struct ph2handle
*iph2
;
2095 vchar_t
*msg
= NULL
;
2096 int error
= ISAKMP_INTERNAL_ERROR
;
2098 /* validity check */
2099 if (iph2
->status
!= PHASE2ST_STATUS6
) {
2100 plog(LLV_ERROR
, LOCATION
, NULL
,
2101 "status mismatched %d.\n", iph2
->status
);
2105 /* compute both of KEYMATs */
2106 if (oakley_compute_keymat(iph2
, RESPONDER
) < 0) {
2107 plog(LLV_ERROR
, LOCATION
, NULL
,
2108 "failed to compute KEYMAT");
2112 iph2
->status
= PHASE2ST_ADDSA
;
2113 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
2115 /* don't anything if local test mode. */
2121 /* Do UPDATE as responder */
2122 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
2123 if (pk_sendupdate(iph2
) < 0) {
2124 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
2127 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
2129 /* Do ADD for responder */
2130 if (pk_sendadd(iph2
) < 0) {
2131 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
2134 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
2137 * set policies into SPD if the policy is generated
2138 * from peer's policy.
2140 if (iph2
->spidx_gen
) {
2142 struct policyindex
*spidx
;
2143 struct sockaddr_storage addr
;
2145 struct sockaddr
*src
= iph2
->src
;
2146 struct sockaddr
*dst
= iph2
->dst
;
2148 /* make inbound policy */
2151 if (pk_sendspdupdate2(iph2
) < 0) {
2152 plog(LLV_ERROR
, LOCATION
, NULL
,
2153 "pfkey spdupdate2(inbound) failed.\n");
2156 plog(LLV_DEBUG
, LOCATION
, NULL
,
2157 "pfkey spdupdate2(inbound) sent.\n");
2159 spidx
= (struct policyindex
*)iph2
->spidx_gen
;
2160 #ifdef HAVE_POLICY_FWD
2161 /* make forward policy if required */
2162 if (tunnel_mode_prop(iph2
->approval
)) {
2163 spidx
->dir
= IPSEC_DIR_FWD
;
2164 if (pk_sendspdupdate2(iph2
) < 0) {
2165 plog(LLV_ERROR
, LOCATION
, NULL
,
2166 "pfkey spdupdate2(forward) failed.\n");
2169 plog(LLV_DEBUG
, LOCATION
, NULL
,
2170 "pfkey spdupdate2(forward) sent.\n");
2174 /* make outbound policy */
2177 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
2179 spidx
->src
= spidx
->dst
;
2181 pref
= spidx
->prefs
;
2182 spidx
->prefs
= spidx
->prefd
;
2183 spidx
->prefd
= pref
;
2185 if (pk_sendspdupdate2(iph2
) < 0) {
2186 plog(LLV_ERROR
, LOCATION
, NULL
,
2187 "pfkey spdupdate2(outbound) failed.\n");
2190 plog(LLV_DEBUG
, LOCATION
, NULL
,
2191 "pfkey spdupdate2(outbound) sent.\n");
2193 /* spidx_gen is unnecessary any more */
2194 delsp_bothdir((struct policyindex
*)iph2
->spidx_gen
);
2195 racoon_free(iph2
->spidx_gen
);
2196 iph2
->spidx_gen
= NULL
;
2197 iph2
->generated_spidx
=1;
2210 * create HASH, body (SA, NONCE) payload with isakmp header.
2213 quick_ir1mx(iph2
, body
, hash
)
2214 struct ph2handle
*iph2
;
2215 vchar_t
*body
, *hash
;
2217 struct isakmp
*isakmp
;
2218 vchar_t
*buf
= NULL
, *new = NULL
;
2221 struct isakmp_gen
*gen
;
2222 int error
= ISAKMP_INTERNAL_ERROR
;
2224 /* create buffer for isakmp payload */
2225 tlen
= sizeof(*isakmp
)
2226 + sizeof(*gen
) + hash
->l
2228 buf
= vmalloc(tlen
);
2230 plog(LLV_ERROR
, LOCATION
, NULL
,
2231 "failed to get buffer to send.\n");
2235 /* re-set encryption flag, for serurity. */
2236 iph2
->flags
|= ISAKMP_FLAG_E
;
2238 /* set isakmp header */
2239 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
2241 plog(LLV_ERROR
, LOCATION
, NULL
,
2242 "failed to set ISAKMP header");
2246 /* add HASH payload */
2247 /* XXX is next type always SA ? */
2248 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_SA
);
2250 /* add body payload */
2251 memcpy(p
, body
->v
, body
->l
);
2253 #ifdef HAVE_PRINT_ISAKMP_C
2254 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
2258 new = oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
2260 plog(LLV_ERROR
, LOCATION
, NULL
,
2261 "failed to encrypt packet");
2272 if (error
&& buf
!= NULL
) {
2281 * get remote's sainfo.
2282 * NOTE: this function is for responder.
2286 struct ph2handle
*iph2
;
2288 vchar_t
*idsrc
= NULL
, *iddst
= NULL
;
2290 int error
= ISAKMP_INTERNAL_ERROR
;
2291 struct sainfo
*anonymous
= NULL
;
2293 if (iph2
->id
== NULL
) {
2294 switch (iph2
->src
->sa_family
) {
2296 prefixlen
= sizeof(struct in_addr
) << 3;
2299 prefixlen
= sizeof(struct in6_addr
) << 3;
2302 plog(LLV_ERROR
, LOCATION
, NULL
,
2303 "invalid family: %d\n", iph2
->src
->sa_family
);
2306 idsrc
= ipsecdoi_sockaddr2id(iph2
->src
, prefixlen
,
2309 idsrc
= vdup(iph2
->id
);
2311 if (idsrc
== NULL
) {
2312 plog(LLV_ERROR
, LOCATION
, NULL
,
2313 "failed to set ID for source.\n");
2317 if (iph2
->id_p
== NULL
) {
2318 switch (iph2
->dst
->sa_family
) {
2320 prefixlen
= sizeof(struct in_addr
) << 3;
2323 prefixlen
= sizeof(struct in6_addr
) << 3;
2326 plog(LLV_ERROR
, LOCATION
, NULL
,
2327 "invalid family: %d\n", iph2
->dst
->sa_family
);
2330 iddst
= ipsecdoi_sockaddr2id(iph2
->dst
, prefixlen
,
2333 iddst
= vdup(iph2
->id_p
);
2335 if (iddst
== NULL
) {
2336 plog(LLV_ERROR
, LOCATION
, NULL
,
2337 "failed to set ID for destination.\n");
2341 iph2
->sainfo
= getsainfo(idsrc
, iddst
, iph2
->ph1
->id_p
, 0);
2342 // track anonymous sainfo, because we'll try to find a better sainfo if this is a client
2343 if (iph2
->sainfo
&& iph2
->sainfo
->idsrc
== NULL
)
2344 anonymous
= iph2
->sainfo
;
2346 if (iph2
->sainfo
== NULL
||
2347 (anonymous
&& iph2
->parent_session
&& iph2
->parent_session
->is_client
)) {
2348 if ((iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) && lcconf
->ext_nat_id
!= NULL
)
2349 iph2
->sainfo
= getsainfo(idsrc
, iddst
, iph2
->ph1
->id_p
, 1);
2351 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2352 "get_sainfo_r case 1.\n");
2354 // still no sainfo (or anonymous): for client, fallback to sainfo used by a previous established phase2
2355 if (iph2
->sainfo
== NULL
||
2356 (iph2
->sainfo
->idsrc
== NULL
&& iph2
->parent_session
&& iph2
->parent_session
->is_client
)) {
2357 ike_session_get_sainfo_r(iph2
);
2359 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2360 "get_sainfo_r case 2.\n");
2362 // still no sainfo (or anonymous): fallback to sainfo picked by dst id
2363 if ((iph2
->sainfo
== NULL
|| iph2
->sainfo
->idsrc
== NULL
) && iph2
->id_p
) {
2364 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2365 "get_sainfo_r about to try dst id only.\n");
2366 iph2
->sainfo
= getsainfo_by_dst_id(iph2
->id_p
, iph2
->ph1
->id_p
);
2368 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2369 "get_sainfo_r case 3.\n");
2370 if (iph2
->sainfo
->idsrc
== NULL
)
2371 anonymous
= iph2
->sainfo
;
2376 if (iph2
->sainfo
== NULL
) {
2377 if (anonymous
== NULL
) {
2378 plog(LLV_ERROR
, LOCATION
, NULL
,
2379 "failed to get sainfo.\n");
2382 iph2
->sainfo
= anonymous
;
2384 if (link_sainfo_to_ph2(iph2
->sainfo
) != 0) {
2385 plog(LLV_ERROR
, LOCATION
, NULL
,
2386 "failed to link sainfo\n");
2387 iph2
->sainfo
= NULL
;
2391 #ifdef ENABLE_HYBRID
2392 /* xauth group inclusion check */
2393 if (iph2
->sainfo
->group
!= NULL
)
2394 if(group_check(iph2
->ph1
,&iph2
->sainfo
->group
->v
,1)) {
2395 plog(LLV_ERROR
, LOCATION
, NULL
,
2396 "failed to group check");
2401 plog(LLV_DEBUG
, LOCATION
, NULL
,
2402 "selected sainfo: %s\n", sainfo2str(iph2
->sainfo
));
2415 get_proposal_r(iph2
)
2416 struct ph2handle
*iph2
;
2418 int error
= get_proposal_r_remote(iph2
, 0);
2419 if (error
!= -2 && error
!= 0 &&
2420 (((iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) && lcconf
->ext_nat_id
!= NULL
) ||
2421 (iph2
->parent_session
&& iph2
->parent_session
->is_client
))) {
2422 if (iph2
->parent_session
&& iph2
->parent_session
->is_client
)
2423 error
= ike_session_get_proposal_r(iph2
);
2424 if (error
!= -2 && error
!= 0)
2425 error
= get_proposal_r_remote(iph2
, 1);
2431 * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
2432 * are IP address and same address family.
2433 * Then get remote's policy from SPD copied from kernel.
2434 * If the type of ID payload is address or subnet type, then the index is
2435 * made from the payload. If there is no ID payload, or the type of ID
2436 * payload is NOT address type, then the index is made from the address
2438 * NOTE: This function is only for responder.
2441 get_proposal_r_remote(iph2
, ignore_id
)
2442 struct ph2handle
*iph2
;
2445 struct policyindex spidx
;
2446 struct secpolicy
*sp_in
, *sp_out
;
2447 int idi2type
= 0; /* switch whether copy IDs into id[src,dst]. */
2448 int error
= ISAKMP_INTERNAL_ERROR
;
2449 int generated_policy_exit_early
= 1;
2451 /* check the existence of ID payload */
2452 if ((iph2
->id_p
!= NULL
&& iph2
->id
== NULL
)
2453 || (iph2
->id_p
== NULL
&& iph2
->id
!= NULL
)) {
2454 plog(LLV_ERROR
, LOCATION
, NULL
,
2455 "Both IDs wasn't found in payload.\n");
2456 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2459 /* make sure if id[src,dst] is null (if use_remote_addr == 0). */
2460 if (!ignore_id
&& (iph2
->src_id
|| iph2
->dst_id
)) {
2461 plog(LLV_ERROR
, LOCATION
, NULL
,
2462 "Why do ID[src,dst] exist already.\n");
2463 return ISAKMP_INTERNAL_ERROR
;
2466 plog(LLV_DEBUG
, LOCATION
, NULL
,
2467 "%s: ignore_id %x.\n", __FUNCTION__
, ignore_id
);
2469 memset(&spidx
, 0, sizeof(spidx
));
2471 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
2473 /* make a spidx; a key to search SPD */
2474 spidx
.dir
= IPSEC_DIR_INBOUND
;
2478 * make destination address in spidx from either ID payload
2479 * or phase 1 address into a address in spidx.
2480 * If behind a nat - use phase1 address because server's
2481 * use the nat's address in the ID payload.
2483 if (iph2
->id
!= NULL
2485 && (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
2486 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
2487 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2488 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
2489 /* get a destination address of a policy */
2490 error
= ipsecdoi_id2sockaddr(iph2
->id
,
2491 (struct sockaddr
*)&spidx
.dst
,
2492 &spidx
.prefd
, &spidx
.ul_proto
);
2498 * get scopeid from the SA address.
2499 * note that the phase 1 source address is used as
2500 * a destination address to search for a inbound policy entry
2501 * because rcoon is responder.
2503 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
) {
2504 error
= setscopeid((struct sockaddr
*)&spidx
.dst
,
2511 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
2512 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
)
2513 idi2type
= _XIDT(iph2
->id
);
2517 plog(LLV_DEBUG
, LOCATION
, NULL
,
2518 "get a destination address of SP index "
2519 "from phase1 address "
2520 "due to no ID payloads found "
2521 "OR because ID type is not address.\n");
2524 * copy the SOURCE address of IKE into the DESTINATION address
2525 * of the key to search the SPD because the direction of policy
2528 memcpy(&spidx
.dst
, iph2
->src
, sysdep_sa_len(iph2
->src
));
2529 switch (spidx
.dst
.ss_family
) {
2532 struct sockaddr_in
*s
= (struct sockaddr_in
*)&spidx
.dst
;
2533 spidx
.prefd
= sizeof(struct in_addr
) << 3;
2534 s
->sin_port
= htons(0);
2539 spidx
.prefd
= sizeof(struct in6_addr
) << 3;
2548 /* make source address in spidx */
2549 if (iph2
->id_p
!= NULL
2551 && (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR
2552 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
2553 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2554 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
2555 /* get a source address of inbound SA */
2556 error
= ipsecdoi_id2sockaddr(iph2
->id_p
,
2557 (struct sockaddr
*)&spidx
.src
,
2558 &spidx
.prefs
, &spidx
.ul_proto
);
2564 * get scopeid from the SA address.
2565 * for more detail, see above of this function.
2567 if (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
) {
2568 error
= setscopeid((struct sockaddr
*)&spidx
.src
,
2575 /* make id[src,dst] if both ID types are IP address and same */
2576 if (_XIDT(iph2
->id_p
) == idi2type
2577 && spidx
.dst
.ss_family
== spidx
.src
.ss_family
) {
2578 iph2
->src_id
= dupsaddr((struct sockaddr
*)&spidx
.dst
);
2579 if (iph2
->src_id
== NULL
) {
2580 plog(LLV_ERROR
, LOCATION
, NULL
,
2581 "buffer allocation failed.\n");
2582 return ISAKMP_INTERNAL_ERROR
;
2584 iph2
->dst_id
= dupsaddr((struct sockaddr
*)&spidx
.src
);
2585 if (iph2
->dst_id
== NULL
) {
2586 plog(LLV_ERROR
, LOCATION
, NULL
,
2587 "buffer allocation failed.\n");
2588 return ISAKMP_INTERNAL_ERROR
;
2593 plog(LLV_DEBUG
, LOCATION
, NULL
,
2594 "get a source address of SP index "
2595 "from phase1 address "
2596 "due to no ID payloads found "
2597 "OR because ID type is not address.\n");
2599 /* see above comment. */
2600 memcpy(&spidx
.src
, iph2
->dst
, sysdep_sa_len(iph2
->dst
));
2601 switch (spidx
.src
.ss_family
) {
2604 struct sockaddr_in
*s
= (struct sockaddr_in
*)&spidx
.src
;
2605 spidx
.prefs
= sizeof(struct in_addr
) << 3;
2606 s
->sin_port
= htons(0);
2611 spidx
.prefs
= sizeof(struct in6_addr
) << 3;
2622 plog(LLV_DEBUG
, LOCATION
, NULL
,
2623 "get a src address from ID payload "
2624 "%s prefixlen=%u ul_proto=%u\n",
2625 saddr2str((struct sockaddr
*)&spidx
.src
),
2626 spidx
.prefs
, spidx
.ul_proto
);
2627 plog(LLV_DEBUG
, LOCATION
, NULL
,
2628 "get dst address from ID payload "
2629 "%s prefixlen=%u ul_proto=%u\n",
2630 saddr2str((struct sockaddr
*)&spidx
.dst
),
2631 spidx
.prefd
, spidx
.ul_proto
);
2634 * convert the ul_proto if it is 0
2635 * because 0 in ID payload means a wild card.
2637 if (spidx
.ul_proto
== 0)
2638 spidx
.ul_proto
= IPSEC_ULPROTO_ANY
;
2640 /* get inbound policy */
2641 sp_in
= getsp_r(&spidx
, iph2
);
2642 if (sp_in
== NULL
|| sp_in
->policy
== IPSEC_POLICY_GENERATE
) {
2643 if (iph2
->ph1
->rmconf
->gen_policy
) {
2645 plog(LLV_INFO
, LOCATION
, NULL
,
2646 "Update the generated policy : %s\n",
2649 plog(LLV_INFO
, LOCATION
, NULL
,
2651 "try to generate the policy : %s\n",
2653 iph2
->spidx_gen
= racoon_malloc(sizeof(spidx
));
2654 if (!iph2
->spidx_gen
) {
2655 plog(LLV_ERROR
, LOCATION
, NULL
,
2656 "buffer allocation failed.\n");
2657 return ISAKMP_INTERNAL_ERROR
;
2659 memcpy(iph2
->spidx_gen
, &spidx
, sizeof(spidx
));
2660 generated_policy_exit_early
= 1; /* special value */
2662 plog(LLV_ERROR
, LOCATION
, NULL
,
2663 "no policy found: %s\n", spidx2str(&spidx
));
2664 return ISAKMP_INTERNAL_ERROR
;
2668 /* get outbound policy */
2670 struct sockaddr_storage addr
;
2673 spidx
.dir
= IPSEC_DIR_OUTBOUND
;
2675 spidx
.src
= spidx
.dst
;
2678 spidx
.prefs
= spidx
.prefd
;
2681 sp_out
= getsp_r(&spidx
, iph2
);
2683 plog(LLV_WARNING
, LOCATION
, NULL
,
2684 "no outbound policy found: %s\n",
2689 iph2
->spid
= sp_out
->id
;
2694 plog(LLV_DEBUG
, LOCATION
, NULL
,
2695 "suitable SP found:%s\n", spidx2str(&spidx
));
2697 if (generated_policy_exit_early
) {
2702 * In the responder side, the inbound policy should be using IPsec.
2703 * outbound policy is not checked currently.
2705 if (sp_in
->policy
!= IPSEC_POLICY_IPSEC
) {
2706 plog(LLV_ERROR
, LOCATION
, NULL
,
2707 "policy found, but no IPsec required: %s\n",
2709 return ISAKMP_INTERNAL_ERROR
;
2712 /* set new proposal derived from a policy into the iph2->proposal. */
2713 if (set_proposal_from_policy(iph2
, sp_in
, sp_out
) < 0) {
2714 plog(LLV_ERROR
, LOCATION
, NULL
,
2715 "failed to create saprop.\n");
2716 return ISAKMP_INTERNAL_ERROR
;