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
*, int));
106 * begin Quick Mode as initiator. send pfkey getspi message to kernel.
109 quick_i1prep(iph2
, msg
)
110 struct ph2handle
*iph2
;
111 vchar_t
*msg
; /* must be null pointer */
113 int error
= ISAKMP_INTERNAL_ERROR
;
116 if (iph2
->status
!= PHASE2ST_STATUS2
) {
117 plog(LLV_ERROR
, LOCATION
, NULL
,
118 "status mismatched %d.\n", iph2
->status
);
122 iph2
->msgid
= isakmp_newmsgid2(iph2
->ph1
);
123 if (iph2
->ivm
!= NULL
)
124 oakley_delivm(iph2
->ivm
);
125 iph2
->ivm
= oakley_newiv2(iph2
->ph1
, iph2
->msgid
);
126 if (iph2
->ivm
== NULL
)
129 iph2
->status
= PHASE2ST_GETSPISENT
;
131 /* don't anything if local test mode. */
137 /* send getspi message */
138 if (pk_sendgetspi(iph2
) < 0) {
139 plog(LLV_ERROR
, LOCATION
, NULL
,
140 "failed to send getspi message");
144 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
146 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
147 pfkey_timeover_stub
, iph2
);
157 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
160 quick_i1send(iph2
, msg
)
161 struct ph2handle
*iph2
;
162 vchar_t
*msg
; /* must be null pointer */
164 vchar_t
*body
= NULL
;
165 vchar_t
*hash
= NULL
;
167 vchar_t
*natoa_i
= NULL
;
168 vchar_t
*natoa_r
= NULL
;
169 #endif /* ENABLE_NATT */
171 struct isakmp_gen
*gen
;
174 int error
= ISAKMP_INTERNAL_ERROR
;
175 int pfsgroup
, idci
, idcr
;
177 struct ipsecdoi_id_b
*id
, *id_p
;
181 plog(LLV_ERROR
, LOCATION
, NULL
,
182 "msg has to be NULL in this function.\n");
185 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
186 plog(LLV_ERROR
, LOCATION
, NULL
,
187 "status mismatched %d.\n", iph2
->status
);
191 /* create SA payload for my proposal */
192 if (ipsecdoi_setph2proposal(iph2
) < 0) {
193 plog(LLV_ERROR
, LOCATION
, NULL
,
194 "failed to set proposal");
198 /* generate NONCE value */
199 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
200 if (iph2
->nonce
== NULL
) {
201 plog(LLV_ERROR
, LOCATION
, NULL
,
202 "failed to generate NONCE");
207 * DH value calculation is kicked out into cfparse.y.
208 * because pfs group can not be negotiated, it's only to be checked
211 /* generate KE value if need */
212 pfsgroup
= iph2
->proposal
->pfs_group
;
214 /* DH group settting if PFS is required. */
215 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
216 plog(LLV_ERROR
, LOCATION
, NULL
,
217 "failed to set DH value.\n");
220 if (oakley_dh_generate(iph2
->pfsgrp
,
221 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
222 plog(LLV_ERROR
, LOCATION
, NULL
,
223 "failed to generate DH");
228 /* generate ID value */
229 if (ipsecdoi_setid2(iph2
) < 0) {
230 plog(LLV_ERROR
, LOCATION
, NULL
,
231 "failed to get ID.\n");
234 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDci:\n");
235 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
236 plog(LLV_DEBUG
, LOCATION
, NULL
, "IDcr:\n");
237 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
240 * we do not attach IDci nor IDcr, under the following condition:
241 * - all proposals are transport mode
243 * - id payload suggests to encrypt all the traffic (no specific
246 id
= (struct ipsecdoi_id_b
*)iph2
->id
->v
;
247 id_p
= (struct ipsecdoi_id_b
*)iph2
->id_p
->v
;
248 if (id
->proto_id
== 0
249 && id_p
->proto_id
== 0
250 && iph2
->ph1
->rmconf
->support_proxy
== 0
251 && ipsecdoi_transportmode(iph2
->proposal
)) {
256 /* create SA;NONCE payload, and KE if need, and IDii, IDir. */
257 tlen
= + sizeof(*gen
) + iph2
->sa
->l
258 + sizeof(*gen
) + iph2
->nonce
->l
;
260 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
262 tlen
+= sizeof(*gen
) + iph2
->id
->l
;
264 tlen
+= sizeof(*gen
) + iph2
->id_p
->l
;
268 * RFC3947 5.2. if we propose UDP-Encapsulated-Transport
269 * we should send NAT-OA
271 if (ipsecdoi_any_transportmode(iph2
->proposal
)
272 && (iph2
->ph1
->natt_flags
& NAT_DETECTED
)) {
273 natoa_type
= create_natoa_payloads(iph2
, &natoa_i
, &natoa_r
);
274 if (natoa_type
== -1) {
275 plog(LLV_ERROR
, LOCATION
, NULL
,
276 "failed to generate NAT-OA payload.\n");
278 } else if (natoa_type
!= 0) {
279 tlen
+= sizeof(*gen
) + natoa_i
->l
;
280 tlen
+= sizeof(*gen
) + natoa_r
->l
;
282 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiator send NAT-OAi:\n");
283 plogdump(LLV_DEBUG
, natoa_i
->v
, natoa_i
->l
);
284 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiator send NAT-OAr:\n");
285 plogdump(LLV_DEBUG
, natoa_r
->v
, natoa_r
->l
);
290 body
= vmalloc(tlen
);
292 plog(LLV_ERROR
, LOCATION
, NULL
,
293 "failed to get buffer to send.\n");
300 p
= set_isakmp_payload(p
, iph2
->sa
, ISAKMP_NPTYPE_NONCE
);
302 /* add NONCE payload */
304 np
= ISAKMP_NPTYPE_KE
;
305 else if (idci
|| idcr
)
306 np
= ISAKMP_NPTYPE_ID
;
308 np
= (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
309 p
= set_isakmp_payload(p
, iph2
->nonce
, np
);
311 /* add KE payload if need. */
312 np
= (idci
|| idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
314 p
= set_isakmp_payload(p
, iph2
->dhpub
, np
);
317 np
= (idcr
) ? ISAKMP_NPTYPE_ID
: (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
319 p
= set_isakmp_payload(p
, iph2
->id
, np
);
323 p
= set_isakmp_payload(p
, iph2
->id_p
, natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
);
327 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
328 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
331 /* generate HASH(1) */
332 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, body
);
334 plog(LLV_ERROR
, LOCATION
, NULL
,
335 "failed to compute HASH");
339 /* send isakmp payload */
340 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
341 if (iph2
->sendbuf
== NULL
) {
342 plog(LLV_ERROR
, LOCATION
, NULL
,
343 "failed to get send buffer");
347 /* send the packet, add to the schedule to resend */
348 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
349 if (isakmp_ph2resend(iph2
) == -1) {
350 plog(LLV_ERROR
, LOCATION
, NULL
,
351 "failed to send packet");
355 /* change status of isakmp status entry */
356 iph2
->status
= PHASE2ST_MSG1SENT
;
360 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
361 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
362 CONSTSTR("Initiator, Quick-Mode message 1"),
367 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
368 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
369 CONSTSTR("Initiator, Quick-Mode Message 1"),
370 CONSTSTR("Failed to transmit Quick-Mode Message 1"));
381 #endif /* ENABLE_NATT */
387 * receive from responder
388 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
391 quick_i2recv(iph2
, msg0
)
392 struct ph2handle
*iph2
;
396 vchar_t
*hbuf
= NULL
; /* for hash computing. */
397 vchar_t
*pbuf
= NULL
; /* for payload parsing */
398 struct isakmp_parse_t
*pa
;
399 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
400 struct isakmp_pl_hash
*hash
= NULL
;
404 int error
= ISAKMP_INTERNAL_ERROR
;
405 struct sockaddr
*natoa_i
= NULL
;
406 struct sockaddr
*natoa_r
= NULL
;
409 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
410 plog(LLV_ERROR
, LOCATION
, NULL
,
411 "status mismatched %d.\n", iph2
->status
);
416 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
417 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
418 "Packet wasn't encrypted.\n");
421 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
423 plog(LLV_ERROR
, LOCATION
, NULL
,
424 "failed to decrypt");
428 /* create buffer for validating HASH(2) */
431 * 1. the first one must be HASH
432 * 2. the second one must be SA (added in isakmp-oakley-05!)
433 * 3. two IDs must be considered as IDci, then IDcr
435 pbuf
= isakmp_parse(msg
);
437 plog(LLV_ERROR
, LOCATION
, NULL
,
438 "failed to parse msg");
441 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
443 /* HASH payload is fixed postion */
444 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
445 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
446 "received invalid next payload type %d, "
448 pa
->type
, ISAKMP_NPTYPE_HASH
);
451 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
455 * this restriction was introduced in isakmp-oakley-05.
456 * we do not check this for backward compatibility.
457 * TODO: command line/config file option to enable/disable this code
459 /* HASH payload is fixed postion */
460 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
461 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
462 "received invalid next payload type %d, "
464 pa
->type
, ISAKMP_NPTYPE_HASH
);
467 /* allocate buffer for computing HASH(2) */
468 tlen
= iph2
->nonce
->l
469 + ntohl(isakmp
->len
) - sizeof(*isakmp
);
470 hbuf
= vmalloc(tlen
);
472 plog(LLV_ERROR
, LOCATION
, NULL
,
473 "failed to get hash buffer.\n");
476 p
= hbuf
->v
+ iph2
->nonce
->l
; /* retain the space for Ni_b */
479 * parse the payloads.
480 * copy non-HASH payloads into hbuf, so that we can validate HASH.
483 f_id
= 0; /* flag to use checking ID */
484 tlen
= 0; /* count payload length except of HASH payload. */
485 for (; pa
->type
; pa
++) {
487 /* copy to buffer for HASH */
488 /* Don't modify the payload */
489 memcpy(p
, pa
->ptr
, pa
->len
);
492 case ISAKMP_NPTYPE_SA
:
493 if (iph2
->sa_ret
!= NULL
) {
494 plog(LLV_ERROR
, LOCATION
, NULL
,
495 "Ignored, multiple SA "
496 "isn't supported.\n");
499 if (isakmp_p2ph(&iph2
->sa_ret
, pa
->ptr
) < 0) {
500 plog(LLV_ERROR
, LOCATION
, NULL
,
501 "failed to process SA payload");
506 case ISAKMP_NPTYPE_NONCE
:
507 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0) {
508 plog(LLV_ERROR
, LOCATION
, NULL
,
509 "failed to process NONCE payload");
514 case ISAKMP_NPTYPE_KE
:
515 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0) {
516 plog(LLV_ERROR
, LOCATION
, NULL
,
517 "failed to process KE payload");
522 case ISAKMP_NPTYPE_ID
:
535 /* These ids may not match when natt is used with some devices.
536 * RFC 2407 says that the protocol and port fields should be ignored
537 * if they are zero, therefore they need to be checked individually.
539 struct ipsecdoi_id_b
*id_ptr
= (struct ipsecdoi_id_b
*)vp
->v
;
540 struct ipsecdoi_pl_id
*idp_ptr
= (struct ipsecdoi_pl_id
*)pa
->ptr
;
542 if (id_ptr
->type
!= idp_ptr
->b
.type
543 || (idp_ptr
->b
.proto_id
!= 0 && idp_ptr
->b
.proto_id
!= id_ptr
->proto_id
)
544 || (idp_ptr
->b
.port
!= 0 && idp_ptr
->b
.port
!= id_ptr
->port
)
545 || memcmp(vp
->v
+ sizeof(struct ipsecdoi_id_b
), (caddr_t
)pa
->ptr
+ sizeof(struct ipsecdoi_pl_id
),
546 vp
->l
- sizeof(struct ipsecdoi_id_b
))) {
547 // to support servers that use our external nat address as our ID
548 if (iph2
->ph1
->natt_flags
& NAT_DETECTED
) {
549 plog(LLV_WARNING
, LOCATION
, NULL
,
550 "mismatched ID was returned - ignored because nat traversal is being used.\n");
551 /* If I'm behind a nat and the ID is type address - save the address
552 * and port for when the peer rekeys.
554 if (f_id
== 0 && (iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
)) {
555 if (lcconf
->ext_nat_id
)
556 vfree(lcconf
->ext_nat_id
);
557 lcconf
->ext_nat_id
= vmalloc(ntohs(idp_ptr
->h
.len
) - sizeof(struct isakmp_gen
));
558 if (lcconf
->ext_nat_id
== NULL
) {
559 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating external nat id.\n");
562 memcpy(lcconf
->ext_nat_id
->v
, &(idp_ptr
->b
), lcconf
->ext_nat_id
->l
);
563 if (iph2
->ext_nat_id
)
564 vfree(iph2
->ext_nat_id
);
565 iph2
->ext_nat_id
= vdup(lcconf
->ext_nat_id
);
566 if (iph2
->ext_nat_id
== NULL
) {
567 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating ph2's external nat id.\n");
570 plog(LLV_DEBUG
, LOCATION
, NULL
, "external nat address saved.\n");
571 } else if (f_id
&& (iph2
->ph1
->natt_flags
& NAT_DETECTED_PEER
)) {
572 if (iph2
->ext_nat_id_p
)
573 vfree(iph2
->ext_nat_id_p
);
574 iph2
->ext_nat_id_p
= vmalloc(ntohs(idp_ptr
->h
.len
) - sizeof(struct isakmp_gen
));
575 if (iph2
->ext_nat_id_p
== NULL
) {
576 plog(LLV_ERROR
, LOCATION
, NULL
, "memory error while allocating peers ph2's external nat id.\n");
579 memcpy(iph2
->ext_nat_id_p
->v
, &(idp_ptr
->b
), iph2
->ext_nat_id_p
->l
);
580 plog(LLV_DEBUG
, LOCATION
, NULL
, "peer's external nat address saved.\n");
583 plog(LLV_ERROR
, LOCATION
, NULL
, "mismatched ID was returned.\n");
584 error
= ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED
;
593 case ISAKMP_NPTYPE_N
:
594 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
598 case ISAKMP_NPTYPE_NATOA_DRAFT
:
599 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
600 case ISAKMP_NPTYPE_NATOA_RFC
:
603 struct sockaddr
*daddr
;
605 isakmp_p2ph(&vp
, pa
->ptr
);
608 daddr
= process_natoa_payload(vp
);
610 if (natoa_i
== NULL
) {
612 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiaor rcvd NAT-OA i: %s\n",
614 } else if (natoa_r
== NULL
) {
616 plog(LLV_DEBUG
, LOCATION
, NULL
, "initiator rcvd NAT-OA r: %s\n",
630 /* don't send information, see ident_r1recv() */
631 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
632 "ignore the packet, "
633 "received unexpecting payload type %d.\n",
640 /* compute true length of payload. */
644 /* payload existency check */
645 if (hash
== NULL
|| iph2
->sa_ret
== NULL
|| iph2
->nonce_p
== NULL
) {
646 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
647 "few isakmp message received.\n");
651 /* Fixed buffer for calculating HASH */
652 memcpy(hbuf
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
653 plog(LLV_DEBUG
, LOCATION
, NULL
,
654 "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n",
655 hbuf
->l
, tlen
+ iph2
->nonce
->l
);
656 /* adjust buffer length for HASH */
657 hbuf
->l
= iph2
->nonce
->l
+ tlen
;
659 /* validate HASH(2) */
662 vchar_t
*my_hash
= NULL
;
665 r_hash
= (char *)hash
+ sizeof(*hash
);
667 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(2) received:");
668 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
670 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
671 if (my_hash
== NULL
) {
672 plog(LLV_ERROR
, LOCATION
, NULL
,
673 "failed to compute HASH");
677 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
681 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
682 "HASH(2) mismatch.\n");
683 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
688 /* validity check SA payload sent from responder */
689 if (ipsecdoi_checkph2proposal(iph2
) < 0) {
690 plog(LLV_ERROR
, LOCATION
, NULL
,
691 "failed to validate SA proposal");
692 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
696 /* change status of isakmp status entry */
697 iph2
->status
= PHASE2ST_STATUS6
;
701 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
702 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
703 CONSTSTR("Initiator, Quick-Mode message 2"),
708 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
709 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
710 CONSTSTR("Initiator, Quick-Mode Message 2"),
711 CONSTSTR("Failed to process Quick-Mode Message 2 "));
722 racoon_free(natoa_i
);
725 racoon_free(natoa_r
);
730 VPTRINIT(iph2
->sa_ret
);
731 VPTRINIT(iph2
->nonce_p
);
732 VPTRINIT(iph2
->dhpub_p
);
734 VPTRINIT(iph2
->id_p
);
745 quick_i2send(iph2
, msg0
)
746 struct ph2handle
*iph2
;
751 vchar_t
*hash
= NULL
;
754 int error
= ISAKMP_INTERNAL_ERROR
;
755 int packet_error
= -1;
758 if (iph2
->status
!= PHASE2ST_STATUS6
) {
759 plog(LLV_ERROR
, LOCATION
, NULL
,
760 "status mismatched %d.\n", iph2
->status
);
764 /* generate HASH(3) */
768 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) generate\n");
770 tmp
= vmalloc(iph2
->nonce
->l
+ iph2
->nonce_p
->l
);
772 plog(LLV_ERROR
, LOCATION
, NULL
,
773 "failed to get hash buffer.\n");
776 memcpy(tmp
->v
, iph2
->nonce
->v
, iph2
->nonce
->l
);
777 memcpy(tmp
->v
+ iph2
->nonce
->l
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
779 hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
783 plog(LLV_ERROR
, LOCATION
, NULL
,
784 "failed to compute HASH");
789 /* create buffer for isakmp payload */
790 tlen
= sizeof(struct isakmp
)
791 + sizeof(struct isakmp_gen
) + hash
->l
;
794 plog(LLV_ERROR
, LOCATION
, NULL
,
795 "failed to get buffer to send.\n");
799 /* create isakmp header */
800 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
802 plog(LLV_ERROR
, LOCATION
, NULL
,
803 "failed to create ISAKMP header");
807 /* add HASH(3) payload */
808 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_NONE
);
810 #ifdef HAVE_PRINT_ISAKMP_C
811 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
815 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
816 if (iph2
->sendbuf
== NULL
) {
817 plog(LLV_ERROR
, LOCATION
, NULL
,
818 "failed to encrypt packet");
822 /* if there is commit bit, need resending */
823 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
824 /* send the packet, add to the schedule to resend */
825 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
826 if (isakmp_ph2resend(iph2
) == -1) {
827 plog(LLV_ERROR
, LOCATION
, NULL
,
828 "failed to send packet, commit-bit");
832 /* send the packet */
833 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0) {
834 plog(LLV_ERROR
, LOCATION
, NULL
,
835 "failed to send packet");
840 /* the sending message is added to the received-list. */
841 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
,
843 PH2_NON_ESP_EXTRA_LEN(iph2
)) == -1) {
844 plog(LLV_ERROR
, LOCATION
, NULL
,
845 "failed to add a response packet to the tree.\n");
849 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
850 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
851 CONSTSTR("Initiator, Quick-Mode message 3"),
855 /* compute both of KEYMATs */
856 if (oakley_compute_keymat(iph2
, INITIATOR
) < 0) {
857 plog(LLV_ERROR
, LOCATION
, NULL
,
858 "failed to compute KEYMAT");
862 iph2
->status
= PHASE2ST_ADDSA
;
864 /* don't anything if local test mode. */
870 /* if there is commit bit don't set up SA now. */
871 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
872 iph2
->status
= PHASE2ST_COMMIT
;
877 /* Do UPDATE for initiator */
878 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
879 if (pk_sendupdate(iph2
) < 0) {
880 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
883 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
885 /* Do ADD for responder */
886 if (pk_sendadd(iph2
) < 0) {
887 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
890 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
896 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
897 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
898 CONSTSTR("Initiator, Quick-Mode Message 3"),
899 CONSTSTR("Failed to transmit Quick-Mode Message 3"));
912 * receive from responder
913 * HDR#*, HASH(4), notify
916 quick_i3recv(iph2
, msg0
)
917 struct ph2handle
*iph2
;
921 vchar_t
*pbuf
= NULL
; /* for payload parsing */
922 struct isakmp_parse_t
*pa
;
923 struct isakmp_pl_hash
*hash
= NULL
;
924 vchar_t
*notify
= NULL
;
925 int error
= ISAKMP_INTERNAL_ERROR
;
926 int packet_error
= -1;
929 if (iph2
->status
!= PHASE2ST_COMMIT
) {
930 plog(LLV_ERROR
, LOCATION
, NULL
,
931 "status mismatched %d.\n", iph2
->status
);
936 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
937 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
938 "Packet wasn't encrypted.\n");
941 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
943 plog(LLV_ERROR
, LOCATION
, NULL
,
944 "failed to decrypt packet");
948 /* validate the type of next payload */
949 pbuf
= isakmp_parse(msg
);
951 plog(LLV_ERROR
, LOCATION
, NULL
,
952 "failed to parse msg");
956 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
957 pa
->type
!= ISAKMP_NPTYPE_NONE
;
961 case ISAKMP_NPTYPE_HASH
:
962 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
964 case ISAKMP_NPTYPE_N
:
965 if (notify
!= NULL
) {
966 plog(LLV_WARNING
, LOCATION
, NULL
,
967 "Ignoring multiple notifications\n");
970 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
971 notify
= vmalloc(pa
->len
);
972 if (notify
== NULL
) {
973 plog(LLV_ERROR
, LOCATION
, NULL
,
974 "failed to get notify buffer.\n");
977 memcpy(notify
->v
, pa
->ptr
, notify
->l
);
980 /* don't send information, see ident_r1recv() */
981 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
982 "ignore the packet, "
983 "received unexpecting payload type %d.\n",
989 /* payload existency check */
991 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
992 "few isakmp message received.\n");
996 /* validate HASH(4) */
999 vchar_t
*my_hash
= NULL
;
1000 vchar_t
*tmp
= NULL
;
1003 r_hash
= (char *)hash
+ sizeof(*hash
);
1005 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) validate:");
1006 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1008 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
1010 if (my_hash
== NULL
) {
1011 plog(LLV_ERROR
, LOCATION
, NULL
,
1012 "failed to compute HASH");
1016 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1020 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
1021 "HASH(4) mismatch.\n");
1022 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1027 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1028 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
1029 CONSTSTR("Initiator, Quick-Mode message 4"),
1033 iph2
->status
= PHASE2ST_ADDSA
;
1034 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
1036 /* don't anything if local test mode. */
1042 /* Do UPDATE for initiator */
1043 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
1044 if (pk_sendupdate(iph2
) < 0) {
1045 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
1048 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
1050 /* Do ADD for responder */
1051 if (pk_sendadd(iph2
) < 0) {
1052 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
1055 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
1061 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1062 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
1063 CONSTSTR("Initiator, Quick-Mode Message 4"),
1064 CONSTSTR("Failed to process Quick-Mode Message 4"));
1077 * receive from initiator
1078 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
1081 quick_r1recv(iph2
, msg0
)
1082 struct ph2handle
*iph2
;
1085 vchar_t
*msg
= NULL
;
1086 vchar_t
*hbuf
= NULL
; /* for hash computing. */
1087 vchar_t
*pbuf
= NULL
; /* for payload parsing */
1088 struct isakmp_parse_t
*pa
;
1089 struct isakmp
*isakmp
= (struct isakmp
*)msg0
->v
;
1090 struct isakmp_pl_hash
*hash
= NULL
;
1093 int f_id_order
; /* for ID payload detection */
1094 int error
= ISAKMP_INTERNAL_ERROR
;
1095 struct sockaddr
*natoa_i
= NULL
;
1096 struct sockaddr
*natoa_r
= NULL
;
1098 /* validity check */
1099 if (iph2
->status
!= PHASE2ST_START
) {
1100 plog(LLV_ERROR
, LOCATION
, NULL
,
1101 "status mismatched %d.\n", iph2
->status
);
1106 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1107 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1108 "Packet wasn't encrypted.\n");
1109 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1112 /* decrypt packet */
1113 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
1115 plog(LLV_ERROR
, LOCATION
, NULL
,
1116 "failed to decrypt packet");
1120 /* create buffer for using to validate HASH(1) */
1123 * 1. the first one must be HASH
1124 * 2. the second one must be SA (added in isakmp-oakley-05!)
1125 * 3. two IDs must be considered as IDci, then IDcr
1127 pbuf
= isakmp_parse(msg
);
1129 plog(LLV_ERROR
, LOCATION
, NULL
,
1130 "failed to parse msg");
1133 pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1135 /* HASH payload is fixed postion */
1136 if (pa
->type
!= ISAKMP_NPTYPE_HASH
) {
1137 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1138 "received invalid next payload type %d, "
1140 pa
->type
, ISAKMP_NPTYPE_HASH
);
1141 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
1144 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1148 * this restriction was introduced in isakmp-oakley-05.
1149 * we do not check this for backward compatibility.
1150 * TODO: command line/config file option to enable/disable this code
1152 /* HASH payload is fixed postion */
1153 if (pa
->type
!= ISAKMP_NPTYPE_SA
) {
1154 plog(LLV_WARNING
, LOCATION
, iph2
->ph1
->remote
,
1155 "received invalid next payload type %d, "
1157 pa
->type
, ISAKMP_NPTYPE_SA
);
1158 error
= ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX
;
1161 /* allocate buffer for computing HASH(1) */
1162 tlen
= ntohl(isakmp
->len
) - sizeof(*isakmp
);
1163 hbuf
= vmalloc(tlen
);
1165 plog(LLV_ERROR
, LOCATION
, NULL
,
1166 "failed to get hash buffer.\n");
1172 * parse the payloads.
1173 * copy non-HASH payloads into hbuf, so that we can validate HASH.
1175 iph2
->sa
= NULL
; /* we don't support multi SAs. */
1176 iph2
->nonce_p
= NULL
;
1177 iph2
->dhpub_p
= NULL
;
1180 tlen
= 0; /* count payload length except of HASH payload. */
1183 * IDi2 MUST be immediatelly followed by IDr2. We allowed the
1184 * illegal case, but logged. First ID payload is to be IDi2.
1185 * And next ID payload is to be IDr2.
1189 for (; pa
->type
; pa
++) {
1191 /* copy to buffer for HASH */
1192 /* Don't modify the payload */
1193 memcpy(p
, pa
->ptr
, pa
->len
);
1195 if (pa
->type
!= ISAKMP_NPTYPE_ID
)
1199 case ISAKMP_NPTYPE_SA
:
1200 if (iph2
->sa
!= NULL
) {
1201 plog(LLV_ERROR
, LOCATION
, NULL
,
1202 "Multi SAs isn't supported.\n");
1205 if (isakmp_p2ph(&iph2
->sa
, pa
->ptr
) < 0) {
1206 plog(LLV_ERROR
, LOCATION
, NULL
,
1207 "failed to process SA payload");
1212 case ISAKMP_NPTYPE_NONCE
:
1213 if (isakmp_p2ph(&iph2
->nonce_p
, pa
->ptr
) < 0) {
1214 plog(LLV_ERROR
, LOCATION
, NULL
,
1215 "failed to process NONCE payload");
1220 case ISAKMP_NPTYPE_KE
:
1221 if (isakmp_p2ph(&iph2
->dhpub_p
, pa
->ptr
) < 0) {
1222 plog(LLV_ERROR
, LOCATION
, NULL
,
1223 "failed to process KE payload");
1228 case ISAKMP_NPTYPE_ID
:
1229 if (iph2
->id_p
== NULL
) {
1233 if (isakmp_p2ph(&iph2
->id_p
, pa
->ptr
) < 0) {
1234 plog(LLV_ERROR
, LOCATION
, NULL
,
1235 "failed to process IDci2 payload");
1239 } else if (iph2
->id
== NULL
) {
1241 if (f_id_order
== 0) {
1242 plog(LLV_ERROR
, LOCATION
, NULL
,
1243 "IDr2 payload is not "
1244 "immediatelly followed "
1245 "by IDi2. We allowed.\n");
1246 /* XXX we allowed in this case. */
1249 if (isakmp_p2ph(&iph2
->id
, pa
->ptr
) < 0) {
1250 plog(LLV_ERROR
, LOCATION
, NULL
,
1251 "failed to process IDcr2 payload");
1255 plog(LLV_ERROR
, LOCATION
, NULL
,
1256 "received too many ID payloads.\n");
1257 plogdump(LLV_ERROR
, iph2
->id
->v
, iph2
->id
->l
);
1258 error
= ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
1263 case ISAKMP_NPTYPE_N
:
1264 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
1268 case ISAKMP_NPTYPE_NATOA_DRAFT
:
1269 case ISAKMP_NPTYPE_NATOA_BADDRAFT
:
1270 case ISAKMP_NPTYPE_NATOA_RFC
:
1273 struct sockaddr
*daddr
;
1275 isakmp_p2ph(&vp
, pa
->ptr
);
1278 daddr
= process_natoa_payload(vp
);
1280 if (natoa_i
== NULL
) {
1282 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder rcvd NAT-OA i: %s\n",
1283 saddr2str(natoa_i
));
1284 } else if (natoa_r
== NULL
) {
1286 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder rcvd NAT-OA r: %s\n",
1287 saddr2str(natoa_r
));
1300 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1301 "ignore the packet, "
1302 "received unexpected payload type %d.\n",
1304 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1310 /* compute true length of payload. */
1314 /* payload existency check */
1315 if (hash
== NULL
|| iph2
->sa
== NULL
|| iph2
->nonce_p
== NULL
) {
1316 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1317 "expected isakmp payloads missing.\n");
1318 error
= ISAKMP_NTYPE_PAYLOAD_MALFORMED
;
1323 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDci2:");
1324 plogdump(LLV_DEBUG
, iph2
->id_p
->v
, iph2
->id_p
->l
);
1327 plog(LLV_DEBUG
, LOCATION
, NULL
, "received IDcr2:");
1328 plogdump(LLV_DEBUG
, iph2
->id
->v
, iph2
->id
->l
);
1331 /* adjust buffer length for HASH */
1334 /* validate HASH(1) */
1337 vchar_t
*my_hash
= NULL
;
1340 r_hash
= (caddr_t
)hash
+ sizeof(*hash
);
1342 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(1) validate:");
1343 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1345 my_hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, hbuf
);
1346 if (my_hash
== NULL
) {
1347 plog(LLV_ERROR
, LOCATION
, NULL
,
1348 "failed to compute HASH");
1352 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1356 plog(LLV_DEBUG
, LOCATION
, iph2
->ph1
->remote
,
1357 "HASH(1) mismatch.\n");
1358 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1364 error
= get_sainfo_r(iph2
);
1366 plog(LLV_ERROR
, LOCATION
, NULL
,
1367 "failed to get sainfo.\n");
1371 /* check the existence of ID payload and create responder's proposal */
1372 error
= get_proposal_r(iph2
, 0);
1373 if (error
!= -2 && error
!= 0 &&
1374 (((iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) && lcconf
->ext_nat_id
!= NULL
) ||
1375 (iph2
->parent_session
&& iph2
->parent_session
->is_client
)))
1376 error
= get_proposal_r(iph2
, 1);
1380 /* generate a policy template from peer's proposal */
1381 if (set_proposal_from_proposal(iph2
)) {
1382 plog(LLV_ERROR
, LOCATION
, NULL
,
1383 "failed to generate a proposal template "
1384 "from client's proposal.\n");
1385 return ISAKMP_INTERNAL_ERROR
;
1389 /* select single proposal or reject it. */
1390 if (ipsecdoi_selectph2proposal(iph2
) < 0) {
1391 plog(LLV_ERROR
, LOCATION
, NULL
,
1392 "failed to select proposal.\n");
1393 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1398 plog(LLV_ERROR
, LOCATION
, NULL
,
1399 "failed to get proposal for responder.\n");
1403 /* check KE and attribute of PFS */
1404 if (iph2
->dhpub_p
!= NULL
&& iph2
->approval
->pfs_group
== 0) {
1405 plog(LLV_ERROR
, LOCATION
, NULL
,
1406 "no PFS is specified, but peer sends KE.\n");
1407 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1410 if (iph2
->dhpub_p
== NULL
&& iph2
->approval
->pfs_group
!= 0) {
1411 plog(LLV_ERROR
, LOCATION
, NULL
,
1412 "PFS is specified, but peer doesn't sends KE.\n");
1413 error
= ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
;
1417 ike_session_update_mode(iph2
); /* update the mode, now that we have a proposal */
1420 * save the packet from the initiator in order to resend the
1421 * responder's first packet against this packet.
1423 iph2
->msg1
= vdup(msg0
);
1425 /* change status of isakmp status entry */
1426 iph2
->status
= PHASE2ST_STATUS2
;
1430 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1431 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
1432 CONSTSTR("Responder, Quick-Mode message 1"),
1437 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1438 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
1439 CONSTSTR("Responder, Quick-Mode Message 1"),
1440 CONSTSTR("Failed to process Quick-Mode Message 1"));
1451 racoon_free(natoa_i
);
1454 racoon_free(natoa_r
);
1460 VPTRINIT(iph2
->nonce_p
);
1461 VPTRINIT(iph2
->dhpub_p
);
1463 VPTRINIT(iph2
->id_p
);
1470 * call pfkey_getspi.
1473 quick_r1prep(iph2
, msg
)
1474 struct ph2handle
*iph2
;
1477 int error
= ISAKMP_INTERNAL_ERROR
;
1479 /* validity check */
1480 if (iph2
->status
!= PHASE2ST_STATUS2
) {
1481 plog(LLV_ERROR
, LOCATION
, NULL
,
1482 "status mismatched %d.\n", iph2
->status
);
1486 iph2
->status
= PHASE2ST_GETSPISENT
;
1488 /* send getspi message */
1489 if (pk_sendgetspi(iph2
) < 0) {
1490 plog(LLV_ERROR
, LOCATION
, NULL
,
1491 "failed to send getspi");
1495 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey getspi sent.\n");
1497 iph2
->sce
= sched_new(lcconf
->wait_ph2complete
,
1498 pfkey_timeover_stub
, iph2
);
1508 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
1511 quick_r2send(iph2
, msg
)
1512 struct ph2handle
*iph2
;
1515 vchar_t
*body
= NULL
;
1516 vchar_t
*hash
= NULL
;
1517 vchar_t
*natoa_i
= NULL
;
1518 vchar_t
*natoa_r
= NULL
;
1520 struct isakmp_gen
*gen
;
1523 int error
= ISAKMP_INTERNAL_ERROR
;
1525 u_int8_t
*np_p
= NULL
;
1527 /* validity check */
1529 plog(LLV_ERROR
, LOCATION
, NULL
,
1530 "msg has to be NULL in this function.\n");
1533 if (iph2
->status
!= PHASE2ST_GETSPIDONE
) {
1534 plog(LLV_ERROR
, LOCATION
, NULL
,
1535 "status mismatched %d.\n", iph2
->status
);
1539 /* update responders SPI */
1540 if (ipsecdoi_updatespi(iph2
) < 0) {
1541 plog(LLV_ERROR
, LOCATION
, NULL
, "failed to update spi.\n");
1545 /* generate NONCE value */
1546 iph2
->nonce
= eay_set_random(iph2
->ph1
->rmconf
->nonce_size
);
1547 if (iph2
->nonce
== NULL
) {
1548 plog(LLV_ERROR
, LOCATION
, NULL
,
1549 "failed to generate NONCE");
1553 /* generate KE value if need */
1554 pfsgroup
= iph2
->approval
->pfs_group
;
1555 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0) {
1556 /* DH group settting if PFS is required. */
1557 if (oakley_setdhgroup(pfsgroup
, &iph2
->pfsgrp
) < 0) {
1558 plog(LLV_ERROR
, LOCATION
, NULL
,
1559 "failed to set DH value.\n");
1562 /* generate DH public value */
1563 if (oakley_dh_generate(iph2
->pfsgrp
,
1564 &iph2
->dhpub
, &iph2
->dhpriv
) < 0) {
1565 plog(LLV_ERROR
, LOCATION
, NULL
,
1566 "failed to generate DH public");
1571 /* create SA;NONCE payload, and KE and ID if need */
1572 tlen
= sizeof(*gen
) + iph2
->sa_ret
->l
1573 + sizeof(*gen
) + iph2
->nonce
->l
;
1574 if (iph2
->dhpub_p
!= NULL
&& pfsgroup
!= 0)
1575 tlen
+= (sizeof(*gen
) + iph2
->dhpub
->l
);
1576 if (iph2
->id_p
!= NULL
)
1577 tlen
+= (sizeof(*gen
) + iph2
->id_p
->l
1578 + sizeof(*gen
) + iph2
->id
->l
);
1582 * RFC3947 5.2. if we chose UDP-Encapsulated-Transport
1583 * we should send NAT-OA
1585 if (ipsecdoi_any_transportmode(iph2
->approval
)
1586 && (iph2
->ph1
->natt_flags
& NAT_DETECTED
)) {
1587 natoa_type
= create_natoa_payloads(iph2
, &natoa_i
, &natoa_r
);
1588 if (natoa_type
== -1) {
1589 plog(LLV_ERROR
, LOCATION
, NULL
,
1590 "failed to create NATOA payloads");
1593 else if (natoa_type
!= 0) {
1594 tlen
+= sizeof(*gen
) + natoa_i
->l
;
1595 tlen
+= sizeof(*gen
) + natoa_r
->l
;
1597 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder send NAT-OAi:\n");
1598 plogdump(LLV_DEBUG
, natoa_i
->v
, natoa_i
->l
);
1599 plog(LLV_DEBUG
, LOCATION
, NULL
, "responder send NAT-OAr:\n");
1600 plogdump(LLV_DEBUG
, natoa_r
->v
, natoa_r
->l
);
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
);
1638 np_p
= &((struct isakmp_gen
*)p
)->np
; /* XXX */
1639 p
= set_isakmp_payload(p
, iph2
->id
, (natoa_type
? natoa_type
: ISAKMP_NPTYPE_NONE
));
1642 /* add a RESPONDER-LIFETIME notify payload if needed */
1644 vchar_t
*data
= NULL
;
1645 struct saprop
*pp
= iph2
->approval
;
1648 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_SEC
) {
1649 u_int32_t v
= htonl((u_int32_t
)pp
->lifetime
);
1650 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1651 IPSECDOI_ATTR_SA_LD_TYPE_SEC
);
1653 plog(LLV_ERROR
, LOCATION
, NULL
,
1654 "failed to add RESPONDER-LIFETIME notify (type) payload");
1657 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1658 (caddr_t
)&v
, sizeof(v
));
1660 plog(LLV_ERROR
, LOCATION
, NULL
,
1661 "failed to add RESPONDER-LIFETIME notify (value) payload");
1665 if (pp
->claim
& IPSECDOI_ATTR_SA_LD_TYPE_KB
) {
1666 u_int32_t v
= htonl((u_int32_t
)pp
->lifebyte
);
1667 data
= isakmp_add_attr_l(data
, IPSECDOI_ATTR_SA_LD_TYPE
,
1668 IPSECDOI_ATTR_SA_LD_TYPE_KB
);
1670 plog(LLV_ERROR
, LOCATION
, NULL
,
1671 "failed to add RESPONDER-LIFETIME notify (type) payload");
1674 data
= isakmp_add_attr_v(data
, IPSECDOI_ATTR_SA_LD
,
1675 (caddr_t
)&v
, sizeof(v
));
1677 plog(LLV_ERROR
, LOCATION
, NULL
,
1678 "failed to add RESPONDER-LIFETIME notify (value) payload");
1684 * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1685 * in the case of SA bundle ?
1688 for (pr
= pp
->head
; pr
; pr
= pr
->next
) {
1689 body
= isakmp_add_pl_n(body
, &np_p
,
1690 ISAKMP_NTYPE_RESPONDER_LIFETIME
, pr
, data
);
1692 plog(LLV_ERROR
, LOCATION
, NULL
,
1693 "invalid RESPONDER-LIFETIME payload");
1695 return error
; /* XXX */
1704 p
= set_isakmp_payload(p
, natoa_i
, natoa_type
);
1705 p
= set_isakmp_payload(p
, natoa_r
, ISAKMP_NPTYPE_NONE
);
1708 /* generate HASH(2) */
1712 tmp
= vmalloc(iph2
->nonce_p
->l
+ body
->l
);
1714 plog(LLV_ERROR
, LOCATION
, NULL
,
1715 "failed to get hash buffer.\n");
1718 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1719 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, body
->v
, body
->l
);
1721 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, tmp
);
1725 plog(LLV_ERROR
, LOCATION
, NULL
,
1726 "failed to compute HASH");
1731 /* send isakmp payload */
1732 iph2
->sendbuf
= quick_ir1mx(iph2
, body
, hash
);
1733 if (iph2
->sendbuf
== NULL
) {
1734 plog(LLV_ERROR
, LOCATION
, NULL
,
1735 "failed to get send buffer");
1739 /* send the packet, add to the schedule to resend */
1740 iph2
->retry_counter
= iph2
->ph1
->rmconf
->retry_counter
;
1741 if (isakmp_ph2resend(iph2
) == -1) {
1742 plog(LLV_ERROR
, LOCATION
, NULL
,
1743 "failed to send packet");
1747 /* the sending message is added to the received-list. */
1748 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, iph2
->msg1
,
1749 PH2_NON_ESP_EXTRA_LEN(iph2
)) == -1) {
1750 plog(LLV_ERROR
, LOCATION
, NULL
,
1751 "failed to add a response packet to the tree.\n");
1755 /* change status of isakmp status entry */
1756 iph2
->status
= PHASE2ST_MSG1SENT
;
1760 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1761 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
1762 CONSTSTR("Responder, Quick-Mode message 2"),
1767 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1768 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
1769 CONSTSTR("Responder, Quick-Mode Message 2"),
1770 CONSTSTR("Failed to transmit Quick-Mode Message 2"));
1785 * receive from initiator
1789 quick_r3recv(iph2
, msg0
)
1790 struct ph2handle
*iph2
;
1793 vchar_t
*msg
= NULL
;
1794 vchar_t
*pbuf
= NULL
; /* for payload parsing */
1795 struct isakmp_parse_t
*pa
;
1796 struct isakmp_pl_hash
*hash
= NULL
;
1797 int error
= ISAKMP_INTERNAL_ERROR
;
1799 /* validity check */
1800 if (iph2
->status
!= PHASE2ST_MSG1SENT
) {
1801 plog(LLV_ERROR
, LOCATION
, NULL
,
1802 "status mismatched %d.\n", iph2
->status
);
1806 /* decrypt packet */
1807 if (!ISSET(((struct isakmp
*)msg0
->v
)->flags
, ISAKMP_FLAG_E
)) {
1808 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1809 "Packet wasn't encrypted.\n");
1812 msg
= oakley_do_decrypt(iph2
->ph1
, msg0
, iph2
->ivm
->iv
, iph2
->ivm
->ive
);
1814 plog(LLV_ERROR
, LOCATION
, NULL
,
1815 "failed to decrypt packet");
1819 /* validate the type of next payload */
1820 pbuf
= isakmp_parse(msg
);
1822 plog(LLV_ERROR
, LOCATION
, NULL
,
1823 "failed to parse msg");
1827 for (pa
= (struct isakmp_parse_t
*)pbuf
->v
;
1828 pa
->type
!= ISAKMP_NPTYPE_NONE
;
1832 case ISAKMP_NPTYPE_HASH
:
1833 hash
= (struct isakmp_pl_hash
*)pa
->ptr
;
1835 case ISAKMP_NPTYPE_N
:
1836 isakmp_check_ph2_notify(pa
->ptr
, iph2
);
1839 /* don't send information, see ident_r1recv() */
1840 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1841 "ignore the packet, "
1842 "received unexpecting payload type %d.\n",
1848 /* payload existency check */
1850 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1851 "few isakmp message received.\n");
1855 /* validate HASH(3) */
1856 /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1859 vchar_t
*my_hash
= NULL
;
1860 vchar_t
*tmp
= NULL
;
1863 r_hash
= (char *)hash
+ sizeof(*hash
);
1865 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(3) validate:");
1866 plogdump(LLV_DEBUG
, r_hash
, ntohs(hash
->h
.len
) - sizeof(*hash
));
1868 tmp
= vmalloc(iph2
->nonce_p
->l
+ iph2
->nonce
->l
);
1870 plog(LLV_ERROR
, LOCATION
, NULL
,
1871 "failed to get hash buffer.\n");
1874 memcpy(tmp
->v
, iph2
->nonce_p
->v
, iph2
->nonce_p
->l
);
1875 memcpy(tmp
->v
+ iph2
->nonce_p
->l
, iph2
->nonce
->v
, iph2
->nonce
->l
);
1877 my_hash
= oakley_compute_hash3(iph2
->ph1
, iph2
->msgid
, tmp
);
1879 if (my_hash
== NULL
) {
1880 plog(LLV_ERROR
, LOCATION
, NULL
,
1881 "failed to compute HASH");
1885 result
= memcmp(my_hash
->v
, r_hash
, my_hash
->l
);
1889 plog(LLV_ERROR
, LOCATION
, iph2
->ph1
->remote
,
1890 "HASH(3) mismatch.\n");
1891 error
= ISAKMP_NTYPE_INVALID_HASH_INFORMATION
;
1896 /* if there is commit bit, don't set up SA now. */
1897 if (ISSET(iph2
->flags
, ISAKMP_FLAG_C
)) {
1898 iph2
->status
= PHASE2ST_COMMIT
;
1900 iph2
->status
= PHASE2ST_STATUS6
;
1904 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1905 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC
,
1906 CONSTSTR("Responder, Quick-Mode message 3"),
1911 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1912 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL
,
1913 CONSTSTR("Responder, Quick-Mode Message 3"),
1914 CONSTSTR("Failed to process Quick-Mode Message 3"));
1926 * HDR#*, HASH(4), notify
1929 quick_r3send(iph2
, msg0
)
1930 struct ph2handle
*iph2
;
1933 vchar_t
*buf
= NULL
;
1934 vchar_t
*myhash
= NULL
;
1935 struct isakmp_pl_n
*n
;
1936 vchar_t
*notify
= NULL
;
1939 int error
= ISAKMP_INTERNAL_ERROR
;
1941 /* validity check */
1942 if (iph2
->status
!= PHASE2ST_COMMIT
) {
1943 plog(LLV_ERROR
, LOCATION
, NULL
,
1944 "status mismatched %d.\n", iph2
->status
);
1948 /* generate HASH(4) */
1949 /* XXX What can I do in the case of multiple different SA */
1950 plog(LLV_DEBUG
, LOCATION
, NULL
, "HASH(4) generate\n");
1952 /* XXX What should I do if there are multiple SAs ? */
1953 tlen
= sizeof(struct isakmp_pl_n
) + iph2
->approval
->head
->spisize
;
1954 notify
= vmalloc(tlen
);
1955 if (notify
== NULL
) {
1956 plog(LLV_ERROR
, LOCATION
, NULL
,
1957 "failed to get notify buffer.\n");
1960 n
= (struct isakmp_pl_n
*)notify
->v
;
1961 n
->h
.np
= ISAKMP_NPTYPE_NONE
;
1962 n
->h
.len
= htons(tlen
);
1963 n
->doi
= htonl(IPSEC_DOI
);
1964 n
->proto_id
= iph2
->approval
->head
->proto_id
;
1965 n
->spi_size
= sizeof(iph2
->approval
->head
->spisize
);
1966 n
->type
= htons(ISAKMP_NTYPE_CONNECTED
);
1967 memcpy(n
+ 1, &iph2
->approval
->head
->spi
, iph2
->approval
->head
->spisize
);
1969 myhash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, notify
);
1970 if (myhash
== NULL
) {
1971 plog(LLV_ERROR
, LOCATION
, NULL
,
1972 "failed to compute HASH");
1976 /* create buffer for isakmp payload */
1977 tlen
= sizeof(struct isakmp
)
1978 + sizeof(struct isakmp_gen
) + myhash
->l
1980 buf
= vmalloc(tlen
);
1982 plog(LLV_ERROR
, LOCATION
, NULL
,
1983 "failed to get buffer to send.\n");
1987 /* create isakmp header */
1988 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
1990 plog(LLV_ERROR
, LOCATION
, NULL
,
1991 "failed to set ISAKMP header");
1995 /* add HASH(4) payload */
1996 p
= set_isakmp_payload(p
, myhash
, ISAKMP_NPTYPE_N
);
1998 /* add notify payload */
1999 memcpy(p
, notify
->v
, notify
->l
);
2001 #ifdef HAVE_PRINT_ISAKMP_C
2002 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
2006 iph2
->sendbuf
= oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
2007 if (iph2
->sendbuf
== NULL
) {
2008 plog(LLV_ERROR
, LOCATION
, NULL
,
2009 "failed to encrypt packet");
2013 /* send the packet */
2014 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0) {
2015 plog(LLV_ERROR
, LOCATION
, NULL
,
2016 "failed to send packet");
2020 /* the sending message is added to the received-list. */
2021 if (add_recvdpkt(iph2
->ph1
->remote
, iph2
->ph1
->local
, iph2
->sendbuf
, msg0
,
2022 PH2_NON_ESP_EXTRA_LEN(iph2
)) == -1) {
2023 plog(LLV_ERROR
, LOCATION
, NULL
,
2024 "failed to add a response packet to the tree.\n");
2028 iph2
->status
= PHASE2ST_COMMIT
;
2032 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
2033 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC
,
2034 CONSTSTR("Responder, Quick-Mode message 4"),
2039 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
2040 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL
,
2041 CONSTSTR("Responder, Quick-Mode Message 4"),
2042 CONSTSTR("Failed to transmit Quick-Mode Message 4"));
2059 quick_r3prep(iph2
, msg0
)
2060 struct ph2handle
*iph2
;
2063 vchar_t
*msg
= NULL
;
2064 int error
= ISAKMP_INTERNAL_ERROR
;
2066 /* validity check */
2067 if (iph2
->status
!= PHASE2ST_STATUS6
) {
2068 plog(LLV_ERROR
, LOCATION
, NULL
,
2069 "status mismatched %d.\n", iph2
->status
);
2073 /* compute both of KEYMATs */
2074 if (oakley_compute_keymat(iph2
, RESPONDER
) < 0) {
2075 plog(LLV_ERROR
, LOCATION
, NULL
,
2076 "failed to compute KEYMAT");
2080 iph2
->status
= PHASE2ST_ADDSA
;
2081 iph2
->flags
^= ISAKMP_FLAG_C
; /* reset bit */
2083 /* don't anything if local test mode. */
2089 /* Do UPDATE as responder */
2090 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pk_sendupdate\n");
2091 if (pk_sendupdate(iph2
) < 0) {
2092 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey update failed.\n");
2095 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey update sent.\n");
2097 /* Do ADD for responder */
2098 if (pk_sendadd(iph2
) < 0) {
2099 plog(LLV_ERROR
, LOCATION
, NULL
, "pfkey add failed.\n");
2102 plog(LLV_DEBUG
, LOCATION
, NULL
, "pfkey add sent.\n");
2105 * set policies into SPD if the policy is generated
2106 * from peer's policy.
2108 if (iph2
->spidx_gen
) {
2110 struct policyindex
*spidx
;
2111 struct sockaddr_storage addr
;
2113 struct sockaddr
*src
= iph2
->src
;
2114 struct sockaddr
*dst
= iph2
->dst
;
2116 /* make inbound policy */
2119 if (pk_sendspdupdate2(iph2
) < 0) {
2120 plog(LLV_ERROR
, LOCATION
, NULL
,
2121 "pfkey spdupdate2(inbound) failed.\n");
2124 plog(LLV_DEBUG
, LOCATION
, NULL
,
2125 "pfkey spdupdate2(inbound) sent.\n");
2127 spidx
= (struct policyindex
*)iph2
->spidx_gen
;
2128 #ifdef HAVE_POLICY_FWD
2129 /* make forward policy if required */
2130 if (tunnel_mode_prop(iph2
->approval
)) {
2131 spidx
->dir
= IPSEC_DIR_FWD
;
2132 if (pk_sendspdupdate2(iph2
) < 0) {
2133 plog(LLV_ERROR
, LOCATION
, NULL
,
2134 "pfkey spdupdate2(forward) failed.\n");
2137 plog(LLV_DEBUG
, LOCATION
, NULL
,
2138 "pfkey spdupdate2(forward) sent.\n");
2142 /* make outbound policy */
2145 spidx
->dir
= IPSEC_DIR_OUTBOUND
;
2147 spidx
->src
= spidx
->dst
;
2149 pref
= spidx
->prefs
;
2150 spidx
->prefs
= spidx
->prefd
;
2151 spidx
->prefd
= pref
;
2153 if (pk_sendspdupdate2(iph2
) < 0) {
2154 plog(LLV_ERROR
, LOCATION
, NULL
,
2155 "pfkey spdupdate2(outbound) failed.\n");
2158 plog(LLV_DEBUG
, LOCATION
, NULL
,
2159 "pfkey spdupdate2(outbound) sent.\n");
2161 /* spidx_gen is unnecessary any more */
2162 delsp_bothdir((struct policyindex
*)iph2
->spidx_gen
);
2163 racoon_free(iph2
->spidx_gen
);
2164 iph2
->spidx_gen
= NULL
;
2165 iph2
->generated_spidx
=1;
2178 * create HASH, body (SA, NONCE) payload with isakmp header.
2181 quick_ir1mx(iph2
, body
, hash
)
2182 struct ph2handle
*iph2
;
2183 vchar_t
*body
, *hash
;
2185 struct isakmp
*isakmp
;
2186 vchar_t
*buf
= NULL
, *new = NULL
;
2189 struct isakmp_gen
*gen
;
2190 int error
= ISAKMP_INTERNAL_ERROR
;
2192 /* create buffer for isakmp payload */
2193 tlen
= sizeof(*isakmp
)
2194 + sizeof(*gen
) + hash
->l
2196 buf
= vmalloc(tlen
);
2198 plog(LLV_ERROR
, LOCATION
, NULL
,
2199 "failed to get buffer to send.\n");
2203 /* re-set encryption flag, for serurity. */
2204 iph2
->flags
|= ISAKMP_FLAG_E
;
2206 /* set isakmp header */
2207 p
= set_isakmp_header2(buf
, iph2
, ISAKMP_NPTYPE_HASH
);
2209 plog(LLV_ERROR
, LOCATION
, NULL
,
2210 "failed to set ISAKMP header");
2214 /* add HASH payload */
2215 /* XXX is next type always SA ? */
2216 p
= set_isakmp_payload(p
, hash
, ISAKMP_NPTYPE_SA
);
2218 /* add body payload */
2219 memcpy(p
, body
->v
, body
->l
);
2221 #ifdef HAVE_PRINT_ISAKMP_C
2222 isakmp_printpacket(buf
, iph2
->ph1
->local
, iph2
->ph1
->remote
, 1);
2226 new = oakley_do_encrypt(iph2
->ph1
, buf
, iph2
->ivm
->ive
, iph2
->ivm
->iv
);
2228 plog(LLV_ERROR
, LOCATION
, NULL
,
2229 "failed to encrypt packet");
2240 if (error
&& buf
!= NULL
) {
2249 * get remote's sainfo.
2250 * NOTE: this function is for responder.
2254 struct ph2handle
*iph2
;
2256 vchar_t
*idsrc
= NULL
, *iddst
= NULL
;
2258 int error
= ISAKMP_INTERNAL_ERROR
;
2259 struct sainfo
*anonymous
= NULL
;
2261 if (iph2
->id
== NULL
) {
2262 switch (iph2
->src
->sa_family
) {
2264 prefixlen
= sizeof(struct in_addr
) << 3;
2267 prefixlen
= sizeof(struct in6_addr
) << 3;
2270 plog(LLV_ERROR
, LOCATION
, NULL
,
2271 "invalid family: %d\n", iph2
->src
->sa_family
);
2274 idsrc
= ipsecdoi_sockaddr2id(iph2
->src
, prefixlen
,
2277 idsrc
= vdup(iph2
->id
);
2279 if (idsrc
== NULL
) {
2280 plog(LLV_ERROR
, LOCATION
, NULL
,
2281 "failed to set ID for source.\n");
2285 if (iph2
->id_p
== NULL
) {
2286 switch (iph2
->dst
->sa_family
) {
2288 prefixlen
= sizeof(struct in_addr
) << 3;
2291 prefixlen
= sizeof(struct in6_addr
) << 3;
2294 plog(LLV_ERROR
, LOCATION
, NULL
,
2295 "invalid family: %d\n", iph2
->dst
->sa_family
);
2298 iddst
= ipsecdoi_sockaddr2id(iph2
->dst
, prefixlen
,
2301 iddst
= vdup(iph2
->id_p
);
2303 if (iddst
== NULL
) {
2304 plog(LLV_ERROR
, LOCATION
, NULL
,
2305 "failed to set ID for destination.\n");
2309 iph2
->sainfo
= getsainfo(idsrc
, iddst
, iph2
->ph1
->id_p
, 0);
2310 // track anonymous sainfo, because we'll try to find a better sainfo if this is a client
2311 if (iph2
->sainfo
&& iph2
->sainfo
->idsrc
== NULL
)
2312 anonymous
= iph2
->sainfo
;
2314 if (iph2
->sainfo
== NULL
||
2315 (anonymous
&& iph2
->parent_session
&& iph2
->parent_session
->is_client
)) {
2316 if ((iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) && lcconf
->ext_nat_id
!= NULL
)
2317 iph2
->sainfo
= getsainfo(idsrc
, iddst
, iph2
->ph1
->id_p
, 1);
2319 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2320 "get_sainfo_r case 1.\n");
2322 // still no sainfo (or anonymous): for client, fallback to sainfo used by a previous established phase2
2323 if (iph2
->sainfo
== NULL
||
2324 (iph2
->sainfo
->idsrc
== NULL
&& iph2
->parent_session
&& iph2
->parent_session
->is_client
)) {
2325 ike_session_get_sainfo_r(iph2
);
2327 plog(LLV_DEBUG2
, LOCATION
, NULL
,
2328 "get_sainfo_r case 2.\n");
2332 if (iph2
->sainfo
== NULL
) {
2333 if (anonymous
== NULL
) {
2334 plog(LLV_ERROR
, LOCATION
, NULL
,
2335 "failed to get sainfo.\n");
2338 iph2
->sainfo
= anonymous
;
2341 if (link_sainfo_to_ph2(iph2
->sainfo
) != 0) {
2342 plog(LLV_ERROR
, LOCATION
, NULL
,
2343 "failed to link sainfo\n");
2344 iph2
->sainfo
= NULL
;
2349 #ifdef ENABLE_HYBRID
2350 /* xauth group inclusion check */
2351 if (iph2
->sainfo
->group
!= NULL
)
2352 if(group_check(iph2
->ph1
,&iph2
->sainfo
->group
->v
,1)) {
2353 plog(LLV_ERROR
, LOCATION
, NULL
,
2354 "failed to group check");
2359 plog(LLV_DEBUG
, LOCATION
, NULL
,
2360 "selected sainfo: %s\n", sainfo2str(iph2
->sainfo
));
2373 * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
2374 * are IP address and same address family.
2375 * Then get remote's policy from SPD copied from kernel.
2376 * If the type of ID payload is address or subnet type, then the index is
2377 * made from the payload. If there is no ID payload, or the type of ID
2378 * payload is NOT address type, then the index is made from the address
2380 * NOTE: This function is only for responder.
2383 get_proposal_r(iph2
, use_remote_addr
)
2384 struct ph2handle
*iph2
;
2385 int use_remote_addr
;
2387 struct policyindex spidx
;
2388 struct secpolicy
*sp_in
, *sp_out
;
2389 int idi2type
= 0; /* switch whether copy IDs into id[src,dst]. */
2390 int error
= ISAKMP_INTERNAL_ERROR
;
2391 int generated_policy_exit_early
= 1;
2393 /* check the existence of ID payload */
2394 if ((iph2
->id_p
!= NULL
&& iph2
->id
== NULL
)
2395 || (iph2
->id_p
== NULL
&& iph2
->id
!= NULL
)) {
2396 plog(LLV_ERROR
, LOCATION
, NULL
,
2397 "Both IDs wasn't found in payload.\n");
2398 return ISAKMP_NTYPE_INVALID_ID_INFORMATION
;
2401 /* make sure if id[src,dst] is null. */
2402 if (iph2
->src_id
|| iph2
->dst_id
) {
2403 plog(LLV_ERROR
, LOCATION
, NULL
,
2404 "Why do ID[src,dst] exist already.\n");
2405 return ISAKMP_INTERNAL_ERROR
;
2408 memset(&spidx
, 0, sizeof(spidx
));
2410 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
2412 /* make a spidx; a key to search SPD */
2413 spidx
.dir
= IPSEC_DIR_INBOUND
;
2417 * make destination address in spidx from either ID payload
2418 * or phase 1 address into a address in spidx.
2419 * If behind a nat - use phase1 address because server's
2420 * use the nat's address in the ID payload.
2422 if (iph2
->id
!= NULL
2423 && use_remote_addr
== 0
2424 && (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
2425 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
2426 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2427 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
2428 /* get a destination address of a policy */
2429 error
= ipsecdoi_id2sockaddr(iph2
->id
,
2430 (struct sockaddr
*)&spidx
.dst
,
2431 &spidx
.prefd
, &spidx
.ul_proto
);
2437 * get scopeid from the SA address.
2438 * note that the phase 1 source address is used as
2439 * a destination address to search for a inbound policy entry
2440 * because rcoon is responder.
2442 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
) {
2443 error
= setscopeid((struct sockaddr
*)&spidx
.dst
,
2450 if (_XIDT(iph2
->id
) == IPSECDOI_ID_IPV4_ADDR
2451 || _XIDT(iph2
->id
) == IPSECDOI_ID_IPV6_ADDR
)
2452 idi2type
= _XIDT(iph2
->id
);
2456 plog(LLV_DEBUG
, LOCATION
, NULL
,
2457 "get a destination address of SP index "
2458 "from phase1 address "
2459 "due to no ID payloads found "
2460 "OR because ID type is not address.\n");
2463 * copy the SOURCE address of IKE into the DESTINATION address
2464 * of the key to search the SPD because the direction of policy
2467 memcpy(&spidx
.dst
, iph2
->src
, sysdep_sa_len(iph2
->src
));
2468 switch (spidx
.dst
.ss_family
) {
2471 struct sockaddr_in
*s
= (struct sockaddr_in
*)&spidx
.dst
;
2472 spidx
.prefd
= sizeof(struct in_addr
) << 3;
2473 s
->sin_port
= htons(0);
2478 spidx
.prefd
= sizeof(struct in6_addr
) << 3;
2487 /* make source address in spidx */
2488 if (iph2
->id_p
!= NULL
2489 && use_remote_addr
== 0
2490 && (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR
2491 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
2492 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2493 || _XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR_SUBNET
)) {
2494 /* get a source address of inbound SA */
2495 error
= ipsecdoi_id2sockaddr(iph2
->id_p
,
2496 (struct sockaddr
*)&spidx
.src
,
2497 &spidx
.prefs
, &spidx
.ul_proto
);
2503 * get scopeid from the SA address.
2504 * for more detail, see above of this function.
2506 if (_XIDT(iph2
->id_p
) == IPSECDOI_ID_IPV6_ADDR
) {
2507 error
= setscopeid((struct sockaddr
*)&spidx
.src
,
2514 /* make id[src,dst] if both ID types are IP address and same */
2515 if (_XIDT(iph2
->id_p
) == idi2type
2516 && spidx
.dst
.ss_family
== spidx
.src
.ss_family
) {
2517 iph2
->src_id
= dupsaddr((struct sockaddr
*)&spidx
.dst
);
2518 if (iph2
->src_id
== NULL
) {
2519 plog(LLV_ERROR
, LOCATION
, NULL
,
2520 "buffer allocation failed.\n");
2521 return ISAKMP_INTERNAL_ERROR
;
2523 iph2
->dst_id
= dupsaddr((struct sockaddr
*)&spidx
.src
);
2524 if (iph2
->dst_id
== NULL
) {
2525 plog(LLV_ERROR
, LOCATION
, NULL
,
2526 "buffer allocation failed.\n");
2527 return ISAKMP_INTERNAL_ERROR
;
2532 plog(LLV_DEBUG
, LOCATION
, NULL
,
2533 "get a source address of SP index "
2534 "from phase1 address "
2535 "due to no ID payloads found "
2536 "OR because ID type is not address.\n");
2538 /* see above comment. */
2539 memcpy(&spidx
.src
, iph2
->dst
, sysdep_sa_len(iph2
->dst
));
2540 switch (spidx
.src
.ss_family
) {
2543 struct sockaddr_in
*s
= (struct sockaddr_in
*)&spidx
.src
;
2544 spidx
.prefs
= sizeof(struct in_addr
) << 3;
2545 s
->sin_port
= htons(0);
2550 spidx
.prefs
= sizeof(struct in6_addr
) << 3;
2561 plog(LLV_DEBUG
, LOCATION
, NULL
,
2562 "get a src address from ID payload "
2563 "%s prefixlen=%u ul_proto=%u\n",
2564 saddr2str((struct sockaddr
*)&spidx
.src
),
2565 spidx
.prefs
, spidx
.ul_proto
);
2566 plog(LLV_DEBUG
, LOCATION
, NULL
,
2567 "get dst address from ID payload "
2568 "%s prefixlen=%u ul_proto=%u\n",
2569 saddr2str((struct sockaddr
*)&spidx
.dst
),
2570 spidx
.prefd
, spidx
.ul_proto
);
2573 * convert the ul_proto if it is 0
2574 * because 0 in ID payload means a wild card.
2576 if (spidx
.ul_proto
== 0)
2577 spidx
.ul_proto
= IPSEC_ULPROTO_ANY
;
2579 /* get inbound policy */
2580 sp_in
= getsp_r(&spidx
);
2581 if (sp_in
== NULL
|| sp_in
->policy
== IPSEC_POLICY_GENERATE
) {
2582 if (iph2
->ph1
->rmconf
->gen_policy
) {
2584 plog(LLV_INFO
, LOCATION
, NULL
,
2585 "Update the generated policy : %s\n",
2588 plog(LLV_INFO
, LOCATION
, NULL
,
2590 "try to generate the policy : %s\n",
2592 iph2
->spidx_gen
= racoon_malloc(sizeof(spidx
));
2593 if (!iph2
->spidx_gen
) {
2594 plog(LLV_ERROR
, LOCATION
, NULL
,
2595 "buffer allocation failed.\n");
2596 return ISAKMP_INTERNAL_ERROR
;
2598 memcpy(iph2
->spidx_gen
, &spidx
, sizeof(spidx
));
2599 generated_policy_exit_early
= 1; /* special value */
2601 plog(LLV_ERROR
, LOCATION
, NULL
,
2602 "no policy found: %s\n", spidx2str(&spidx
));
2603 return ISAKMP_INTERNAL_ERROR
;
2606 /* Refresh existing generated policies
2608 if (iph2
->ph1
->rmconf
->gen_policy
) {
2609 plog(LLV_INFO
, LOCATION
, NULL
,
2610 "Update the generated policy : %s\n",
2612 iph2
->spidx_gen
= racoon_malloc(sizeof(spidx
));
2613 if (!iph2
->spidx_gen
) {
2614 plog(LLV_ERROR
, LOCATION
, NULL
,
2615 "buffer allocation failed.\n");
2616 return ISAKMP_INTERNAL_ERROR
;
2618 memcpy(iph2
->spidx_gen
, &spidx
, sizeof(spidx
));
2622 /* get outbound policy */
2624 struct sockaddr_storage addr
;
2627 spidx
.dir
= IPSEC_DIR_OUTBOUND
;
2629 spidx
.src
= spidx
.dst
;
2632 spidx
.prefs
= spidx
.prefd
;
2635 sp_out
= getsp_r(&spidx
);
2637 plog(LLV_WARNING
, LOCATION
, NULL
,
2638 "no outbound policy found: %s\n",
2643 iph2
->spid
= sp_out
->id
;
2648 plog(LLV_DEBUG
, LOCATION
, NULL
,
2649 "suitable SP found:%s\n", spidx2str(&spidx
));
2651 if (generated_policy_exit_early
) {
2656 * In the responder side, the inbound policy should be using IPsec.
2657 * outbound policy is not checked currently.
2659 if (sp_in
->policy
!= IPSEC_POLICY_IPSEC
) {
2660 plog(LLV_ERROR
, LOCATION
, NULL
,
2661 "policy found, but no IPsec required: %s\n",
2663 return ISAKMP_INTERNAL_ERROR
;
2666 /* set new proposal derived from a policy into the iph2->proposal. */
2667 if (set_proposal_from_policy(iph2
, sp_in
, sp_out
) < 0) {
2668 plog(LLV_ERROR
, LOCATION
, NULL
,
2669 "failed to create saprop.\n");
2670 return ISAKMP_INTERNAL_ERROR
;