]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/isakmp_quick.c
ipsec-286.1.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_quick.c
CommitLineData
d1e348cf
A
1/* $NetBSD: isakmp_quick.c,v 1.11.4.1 2007/08/01 11:52:21 vanhu Exp $ */
2
3/* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd Exp */
52b7d2ce
A
4
5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
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.
20 *
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
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <sys/types.h>
37#include <sys/param.h>
38#include <sys/socket.h>
39
40#include <netinet/in.h>
41
42#include <stdlib.h>
43#include <stdio.h>
44#include <string.h>
45#include <errno.h>
46#if TIME_WITH_SYS_TIME
47# include <sys/time.h>
48# include <time.h>
49#else
50# if HAVE_SYS_TIME_H
51# include <sys/time.h>
52# else
53# include <time.h>
54# endif
55#endif
d1e348cf
A
56#ifdef ENABLE_HYBRID
57#include <resolv.h>
58#endif
52b7d2ce
A
59
60#ifndef HAVE_NETINET6_IPSEC
61#include <netinet/ipsec.h>
62#else
63#include <netinet6/ipsec.h>
64#endif
65
66#include "var.h"
67#include "vmbuf.h"
68#include "schedule.h"
69#include "misc.h"
70#include "plog.h"
71#include "debug.h"
72
65c25746 73#include "fsm.h"
52b7d2ce
A
74#include "localconf.h"
75#include "remoteconf.h"
d1e348cf
A
76#include "handler.h"
77#include "policy.h"
78#include "proposal.h"
52b7d2ce
A
79#include "isakmp_var.h"
80#include "isakmp.h"
81#include "isakmp_inf.h"
82#include "isakmp_quick.h"
83#include "oakley.h"
52b7d2ce
A
84#include "ipsec_doi.h"
85#include "crypto_openssl.h"
86#include "pfkey.h"
87#include "policy.h"
88#include "algorithm.h"
89#include "sockmisc.h"
90#include "proposal.h"
91#include "sainfo.h"
52b7d2ce
A
92#include "strnames.h"
93#include "nattraversal.h"
d1e348cf
A
94#include "ipsecSessionTracer.h"
95#include "ipsecMessageTracer.h"
e8d9021d
A
96#ifndef HAVE_OPENSSL
97#include <Security/SecDH.h>
98#endif
52b7d2ce
A
99
100/* quick mode */
65c25746
A
101static vchar_t *quick_ir1mx (phase2_handle_t *, vchar_t *, vchar_t *);
102static int get_proposal_r_remote (phase2_handle_t *, int);
52b7d2ce
A
103
104/* \f%%%
105 * Quick Mode
106 */
107/*
108 * begin Quick Mode as initiator. send pfkey getspi message to kernel.
109 */
110int
65c25746
A
111quick_iprep(iph2, msg)
112 phase2_handle_t *iph2;
52b7d2ce
A
113 vchar_t *msg; /* must be null pointer */
114{
115 int error = ISAKMP_INTERNAL_ERROR;
116
117 /* validity check */
65c25746
A
118 if (iph2->status != IKEV1_STATE_QUICK_I_START) {
119 plog(ASL_LEVEL_ERR,
52b7d2ce
A
120 "status mismatched %d.\n", iph2->status);
121 goto end;
122 }
123
124 iph2->msgid = isakmp_newmsgid2(iph2->ph1);
d1e348cf
A
125 if (iph2->ivm != NULL)
126 oakley_delivm(iph2->ivm);
52b7d2ce
A
127 iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid);
128 if (iph2->ivm == NULL)
129 return 0;
130
65c25746 131 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_GETSPISENT);
52b7d2ce
A
132
133 /* don't anything if local test mode. */
134 if (f_local) {
135 error = 0;
136 goto end;
137 }
138
139 /* send getspi message */
d1e348cf 140 if (pk_sendgetspi(iph2) < 0) {
65c25746 141 plog(ASL_LEVEL_ERR,
d1e348cf 142 "failed to send getspi message");
52b7d2ce 143 goto end;
d1e348cf 144 }
52b7d2ce 145
65c25746 146 plog(ASL_LEVEL_DEBUG, "pfkey getspi sent.\n");
52b7d2ce
A
147
148 iph2->sce = sched_new(lcconf->wait_ph2complete,
149 pfkey_timeover_stub, iph2);
150
151 error = 0;
152
153end:
154 return error;
155}
156
157/*
158 * send to responder
d1e348cf 159 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
52b7d2ce
A
160 */
161int
162quick_i1send(iph2, msg)
65c25746 163 phase2_handle_t *iph2;
52b7d2ce
A
164 vchar_t *msg; /* must be null pointer */
165{
166 vchar_t *body = NULL;
167 vchar_t *hash = NULL;
d1e348cf 168#ifdef ENABLE_NATT
52b7d2ce
A
169 vchar_t *natoa_i = NULL;
170 vchar_t *natoa_r = NULL;
d1e348cf 171#endif /* ENABLE_NATT */
52b7d2ce
A
172 int natoa_type = 0;
173 struct isakmp_gen *gen;
174 char *p;
175 int tlen;
176 int error = ISAKMP_INTERNAL_ERROR;
177 int pfsgroup, idci, idcr;
178 int np;
179 struct ipsecdoi_id_b *id, *id_p;
180
181 /* validity check */
182 if (msg != NULL) {
65c25746 183 plog(ASL_LEVEL_ERR,
52b7d2ce
A
184 "msg has to be NULL in this function.\n");
185 goto end;
186 }
65c25746
A
187 if (iph2->status != IKEV1_STATE_QUICK_I_GETSPIDONE) {
188 plog(ASL_LEVEL_ERR,
52b7d2ce
A
189 "status mismatched %d.\n", iph2->status);
190 goto end;
191 }
192
193 /* create SA payload for my proposal */
65c25746
A
194 if (ipsecdoi_setph2proposal(iph2, FALSE) < 0) {
195 plog(ASL_LEVEL_ERR,
d1e348cf 196 "failed to set proposal");
52b7d2ce 197 goto end;
d1e348cf 198 }
52b7d2ce
A
199
200 /* generate NONCE value */
201 iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
d1e348cf 202 if (iph2->nonce == NULL) {
65c25746 203 plog(ASL_LEVEL_ERR,
d1e348cf 204 "failed to generate NONCE");
52b7d2ce 205 goto end;
d1e348cf 206 }
52b7d2ce
A
207
208 /*
209 * DH value calculation is kicked out into cfparse.y.
210 * because pfs group can not be negotiated, it's only to be checked
211 * acceptable.
212 */
213 /* generate KE value if need */
214 pfsgroup = iph2->proposal->pfs_group;
215 if (pfsgroup) {
216 /* DH group settting if PFS is required. */
217 if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
65c25746 218 plog(ASL_LEVEL_ERR,
52b7d2ce
A
219 "failed to set DH value.\n");
220 goto end;
221 }
e8d9021d 222#ifdef HAVE_OPENSSL
52b7d2ce 223 if (oakley_dh_generate(iph2->pfsgrp,
e8d9021d
A
224 &iph2->dhpub, &iph2->dhpriv) < 0) {
225#else
226 if (oakley_dh_generate(iph2->pfsgrp,
227 &iph2->dhpub, &iph2->publicKeySize, &iph2->dhC) < 0) {
228#endif
65c25746 229 plog(ASL_LEVEL_ERR,
d1e348cf 230 "failed to generate DH");
52b7d2ce
A
231 goto end;
232 }
233 }
234
235 /* generate ID value */
236 if (ipsecdoi_setid2(iph2) < 0) {
65c25746 237 plog(ASL_LEVEL_ERR,
52b7d2ce
A
238 "failed to get ID.\n");
239 goto end;
240 }
65c25746
A
241 plogdump(ASL_LEVEL_DEBUG, iph2->id->v, iph2->id->l, "IDci:\n");
242 plogdump(ASL_LEVEL_DEBUG, iph2->id_p->v, iph2->id_p->l, "IDcr:\n");
52b7d2ce
A
243
244 /*
245 * we do not attach IDci nor IDcr, under the following condition:
246 * - all proposals are transport mode
247 * - no MIP6 or proxy
248 * - id payload suggests to encrypt all the traffic (no specific
249 * protocol type)
250 */
85f41bec
A
251 id = ALIGNED_CAST(struct ipsecdoi_id_b *)iph2->id->v;
252 id_p = ALIGNED_CAST(struct ipsecdoi_id_b *)iph2->id_p->v;
52b7d2ce
A
253 if (id->proto_id == 0
254 && id_p->proto_id == 0
255 && iph2->ph1->rmconf->support_proxy == 0
256 && ipsecdoi_transportmode(iph2->proposal)) {
257 idci = idcr = 0;
258 } else
259 idci = idcr = 1;
260
261 /* create SA;NONCE payload, and KE if need, and IDii, IDir. */
262 tlen = + sizeof(*gen) + iph2->sa->l
263 + sizeof(*gen) + iph2->nonce->l;
264 if (pfsgroup)
265 tlen += (sizeof(*gen) + iph2->dhpub->l);
266 if (idci)
267 tlen += sizeof(*gen) + iph2->id->l;
268 if (idcr)
269 tlen += sizeof(*gen) + iph2->id_p->l;
270
52b7d2ce 271#ifdef ENABLE_NATT
d1e348cf
A
272 /*
273 * RFC3947 5.2. if we propose UDP-Encapsulated-Transport
274 * we should send NAT-OA
52b7d2ce 275 */
d1e348cf
A
276 if (ipsecdoi_any_transportmode(iph2->proposal)
277 && (iph2->ph1->natt_flags & NAT_DETECTED)) {
52b7d2ce 278 natoa_type = create_natoa_payloads(iph2, &natoa_i, &natoa_r);
d1e348cf 279 if (natoa_type == -1) {
65c25746 280 plog(ASL_LEVEL_ERR,
d1e348cf 281 "failed to generate NAT-OA payload.\n");
52b7d2ce 282 goto end;
d1e348cf 283 } else if (natoa_type != 0) {
52b7d2ce
A
284 tlen += sizeof(*gen) + natoa_i->l;
285 tlen += sizeof(*gen) + natoa_r->l;
d1e348cf 286
65c25746
A
287 //plogdump(ASL_LEVEL_DEBUG, natoa_i->v, natoa_i->l, "initiator send NAT-OAi:\n");
288 //plogdump(ASL_LEVEL_DEBUG, natoa_r->v, natoa_r->l, "initiator send NAT-OAr:\n");
52b7d2ce
A
289 }
290 }
52b7d2ce
A
291#endif
292
293 body = vmalloc(tlen);
294 if (body == NULL) {
65c25746 295 plog(ASL_LEVEL_ERR,
52b7d2ce
A
296 "failed to get buffer to send.\n");
297 goto end;
298 }
299
300 p = body->v;
301
302 /* add SA payload */
303 p = set_isakmp_payload(p, iph2->sa, ISAKMP_NPTYPE_NONCE);
304
305 /* add NONCE payload */
306 if (pfsgroup)
307 np = ISAKMP_NPTYPE_KE;
308 else if (idci || idcr)
309 np = ISAKMP_NPTYPE_ID;
310 else
52b7d2ce 311 np = (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE);
52b7d2ce
A
312 p = set_isakmp_payload(p, iph2->nonce, np);
313
314 /* add KE payload if need. */
52b7d2ce 315 np = (idci || idcr) ? ISAKMP_NPTYPE_ID : (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE);
52b7d2ce
A
316 if (pfsgroup)
317 p = set_isakmp_payload(p, iph2->dhpub, np);
318
319 /* IDci */
52b7d2ce 320 np = (idcr) ? ISAKMP_NPTYPE_ID : (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE);
52b7d2ce
A
321 if (idci)
322 p = set_isakmp_payload(p, iph2->id, np);
323
324 /* IDcr */
325 if (idcr)
52b7d2ce
A
326 p = set_isakmp_payload(p, iph2->id_p, natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE);
327
328 /* natoa */
329 if (natoa_type) {
330 p = set_isakmp_payload(p, natoa_i, natoa_type);
331 p = set_isakmp_payload(p, natoa_r, ISAKMP_NPTYPE_NONE);
332 }
52b7d2ce
A
333
334 /* generate HASH(1) */
335 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body);
d1e348cf 336 if (hash == NULL) {
65c25746 337 plog(ASL_LEVEL_ERR,
d1e348cf 338 "failed to compute HASH");
52b7d2ce 339 goto end;
d1e348cf 340 }
52b7d2ce
A
341
342 /* send isakmp payload */
343 iph2->sendbuf = quick_ir1mx(iph2, body, hash);
d1e348cf 344 if (iph2->sendbuf == NULL) {
65c25746 345 plog(ASL_LEVEL_ERR,
d1e348cf 346 "failed to get send buffer");
52b7d2ce 347 goto end;
d1e348cf 348 }
52b7d2ce
A
349
350 /* send the packet, add to the schedule to resend */
351 iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
d1e348cf 352 if (isakmp_ph2resend(iph2) == -1) {
65c25746 353 plog(ASL_LEVEL_ERR,
d1e348cf 354 "failed to send packet");
52b7d2ce 355 goto end;
d1e348cf 356 }
52b7d2ce
A
357
358 /* change status of isakmp status entry */
65c25746 359 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_MSG1SENT);
52b7d2ce
A
360
361 error = 0;
362
d1e348cf
A
363 IPSECSESSIONTRACEREVENT(iph2->parent_session,
364 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
365 CONSTSTR("Initiator, Quick-Mode message 1"),
366 CONSTSTR(NULL));
367
52b7d2ce 368end:
d1e348cf
A
369 if (error) {
370 IPSECSESSIONTRACEREVENT(iph2->parent_session,
371 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
372 CONSTSTR("Initiator, Quick-Mode Message 1"),
373 CONSTSTR("Failed to transmit Quick-Mode Message 1"));
374 }
52b7d2ce
A
375 if (body != NULL)
376 vfree(body);
377 if (hash != NULL)
378 vfree(hash);
d1e348cf 379#ifdef ENABLE_NATT
52b7d2ce
A
380 if (natoa_i)
381 vfree(natoa_i);
382 if (natoa_r)
383 vfree(natoa_r);
d1e348cf 384#endif /* ENABLE_NATT */
52b7d2ce
A
385
386 return error;
387}
388
389/*
390 * receive from responder
d1e348cf 391 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
52b7d2ce
A
392 */
393int
394quick_i2recv(iph2, msg0)
65c25746 395 phase2_handle_t *iph2;
52b7d2ce
A
396 vchar_t *msg0;
397{
398 vchar_t *msg = NULL;
399 vchar_t *hbuf = NULL; /* for hash computing. */
400 vchar_t *pbuf = NULL; /* for payload parsing */
401 struct isakmp_parse_t *pa;
402 struct isakmp *isakmp = (struct isakmp *)msg0->v;
403 struct isakmp_pl_hash *hash = NULL;
404 int f_id;
405 char *p;
406 int tlen;
407 int error = ISAKMP_INTERNAL_ERROR;
85f41bec
A
408 struct sockaddr_storage *natoa_i = NULL;
409 struct sockaddr_storage *natoa_r = NULL;
52b7d2ce
A
410
411 /* validity check */
65c25746
A
412 if (iph2->status != IKEV1_STATE_QUICK_I_MSG1SENT) {
413 plog(ASL_LEVEL_ERR,
52b7d2ce
A
414 "status mismatched %d.\n", iph2->status);
415 goto end;
416 }
417
418 /* decrypt packet */
419 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
65c25746 420 plog(ASL_LEVEL_ERR,
52b7d2ce
A
421 "Packet wasn't encrypted.\n");
422 goto end;
423 }
424 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
d1e348cf 425 if (msg == NULL) {
65c25746 426 plog(ASL_LEVEL_ERR,
d1e348cf 427 "failed to decrypt");
52b7d2ce 428 goto end;
d1e348cf 429 }
52b7d2ce
A
430
431 /* create buffer for validating HASH(2) */
432 /*
433 * ordering rule:
434 * 1. the first one must be HASH
435 * 2. the second one must be SA (added in isakmp-oakley-05!)
436 * 3. two IDs must be considered as IDci, then IDcr
437 */
438 pbuf = isakmp_parse(msg);
d1e348cf 439 if (pbuf == NULL) {
65c25746 440 plog(ASL_LEVEL_ERR,
d1e348cf 441 "failed to parse msg");
52b7d2ce 442 goto end;
d1e348cf 443 }
85f41bec 444 pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v;
52b7d2ce
A
445
446 /* HASH payload is fixed postion */
447 if (pa->type != ISAKMP_NPTYPE_HASH) {
65c25746 448 plog(ASL_LEVEL_ERR,
52b7d2ce
A
449 "received invalid next payload type %d, "
450 "expecting %d.\n",
451 pa->type, ISAKMP_NPTYPE_HASH);
452 goto end;
453 }
454 hash = (struct isakmp_pl_hash *)pa->ptr;
455 pa++;
456
457 /*
458 * this restriction was introduced in isakmp-oakley-05.
459 * we do not check this for backward compatibility.
460 * TODO: command line/config file option to enable/disable this code
461 */
462 /* HASH payload is fixed postion */
463 if (pa->type != ISAKMP_NPTYPE_SA) {
65c25746 464 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
465 "received invalid next payload type %d, "
466 "expecting %d.\n",
467 pa->type, ISAKMP_NPTYPE_HASH);
468 }
469
470 /* allocate buffer for computing HASH(2) */
471 tlen = iph2->nonce->l
472 + ntohl(isakmp->len) - sizeof(*isakmp);
e8d9021d 473 if (tlen < 0) {
65c25746
A
474 plog(ASL_LEVEL_ERR,
475 "invalid length (%lu,%d) while getting hash buffer.\n",
e8d9021d
A
476 iph2->nonce->l, ntohl(isakmp->len));
477 goto end;
478 }
52b7d2ce
A
479 hbuf = vmalloc(tlen);
480 if (hbuf == NULL) {
65c25746 481 plog(ASL_LEVEL_ERR,
52b7d2ce
A
482 "failed to get hash buffer.\n");
483 goto end;
484 }
485 p = hbuf->v + iph2->nonce->l; /* retain the space for Ni_b */
486
487 /*
488 * parse the payloads.
489 * copy non-HASH payloads into hbuf, so that we can validate HASH.
490 */
491 iph2->sa_ret = NULL;
492 f_id = 0; /* flag to use checking ID */
493 tlen = 0; /* count payload length except of HASH payload. */
494 for (; pa->type; pa++) {
495
496 /* copy to buffer for HASH */
497 /* Don't modify the payload */
498 memcpy(p, pa->ptr, pa->len);
499
500 switch (pa->type) {
501 case ISAKMP_NPTYPE_SA:
502 if (iph2->sa_ret != NULL) {
65c25746 503 plog(ASL_LEVEL_ERR,
52b7d2ce
A
504 "Ignored, multiple SA "
505 "isn't supported.\n");
506 break;
507 }
d1e348cf 508 if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) {
65c25746 509 plog(ASL_LEVEL_ERR,
d1e348cf 510 "failed to process SA payload");
52b7d2ce 511 goto end;
d1e348cf 512 }
52b7d2ce
A
513 break;
514
515 case ISAKMP_NPTYPE_NONCE:
d1e348cf 516 if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
65c25746 517 plog(ASL_LEVEL_ERR,
d1e348cf 518 "failed to process NONCE payload");
52b7d2ce 519 goto end;
d1e348cf 520 }
52b7d2ce
A
521 break;
522
523 case ISAKMP_NPTYPE_KE:
d1e348cf 524 if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
65c25746 525 plog(ASL_LEVEL_ERR,
d1e348cf 526 "failed to process KE payload");
52b7d2ce 527 goto end;
d1e348cf 528 }
52b7d2ce
A
529 break;
530
531 case ISAKMP_NPTYPE_ID:
532 {
05434fec
A
533 vchar_t *vp;
534
65c25746
A
535 if (iph2->id == NULL || iph2->id_p == NULL) {
536 error = ISAKMP_INTERNAL_ERROR; // shouldn't happen
537 goto end;
538 }
539
05434fec
A
540 /* check ID value */
541 if (f_id == 0) {
542 /* for IDci */
543 vp = iph2->id;
544 } else {
545 /* for IDcr */
546 vp = iph2->id_p;
52b7d2ce 547 }
05434fec
A
548
549 /* These ids may not match when natt is used with some devices.
550 * RFC 2407 says that the protocol and port fields should be ignored
551 * if they are zero, therefore they need to be checked individually.
552 */
85f41bec 553 struct ipsecdoi_id_b *id_ptr = ALIGNED_CAST(struct ipsecdoi_id_b *)vp->v;
05434fec
A
554 struct ipsecdoi_pl_id *idp_ptr = (struct ipsecdoi_pl_id *)pa->ptr;
555
556 if (id_ptr->type != idp_ptr->b.type
557 || (idp_ptr->b.proto_id != 0 && idp_ptr->b.proto_id != id_ptr->proto_id)
558 || (idp_ptr->b.port != 0 && idp_ptr->b.port != id_ptr->port)
559 || memcmp(vp->v + sizeof(struct ipsecdoi_id_b), (caddr_t)pa->ptr + sizeof(struct ipsecdoi_pl_id),
560 vp->l - sizeof(struct ipsecdoi_id_b))) {
561 // to support servers that use our external nat address as our ID
562 if (iph2->ph1->natt_flags & NAT_DETECTED) {
65c25746 563 plog(ASL_LEVEL_WARNING,
05434fec
A
564 "mismatched ID was returned - ignored because nat traversal is being used.\n");
565 /* If I'm behind a nat and the ID is type address - save the address
566 * and port for when the peer rekeys.
567 */
568 if (f_id == 0 && (iph2->ph1->natt_flags & NAT_DETECTED_ME)) {
569 if (lcconf->ext_nat_id)
570 vfree(lcconf->ext_nat_id);
e8d9021d 571 if (idp_ptr->h.len < sizeof(struct isakmp_gen)) {
65c25746 572 plog(ASL_LEVEL_ERR, "invalid length (%d) while allocating external nat id.\n", idp_ptr->h.len);
e8d9021d
A
573 goto end;
574 }
47612122 575 lcconf->ext_nat_id = vmalloc(ntohs(idp_ptr->h.len) - sizeof(struct isakmp_gen));
05434fec 576 if (lcconf->ext_nat_id == NULL) {
65c25746 577 plog(ASL_LEVEL_ERR, "memory error while allocating external nat id.\n");
05434fec
A
578 goto end;
579 }
580 memcpy(lcconf->ext_nat_id->v, &(idp_ptr->b), lcconf->ext_nat_id->l);
47612122
A
581 if (iph2->ext_nat_id)
582 vfree(iph2->ext_nat_id);
583 iph2->ext_nat_id = vdup(lcconf->ext_nat_id);
584 if (iph2->ext_nat_id == NULL) {
65c25746 585 plog(ASL_LEVEL_ERR, "memory error while allocating ph2's external nat id.\n");
47612122
A
586 goto end;
587 }
65c25746 588 plogdump(ASL_LEVEL_DEBUG, iph2->ext_nat_id->v, iph2->ext_nat_id->l, "external nat address saved.\n");
47612122
A
589 } else if (f_id && (iph2->ph1->natt_flags & NAT_DETECTED_PEER)) {
590 if (iph2->ext_nat_id_p)
591 vfree(iph2->ext_nat_id_p);
592 iph2->ext_nat_id_p = vmalloc(ntohs(idp_ptr->h.len) - sizeof(struct isakmp_gen));
593 if (iph2->ext_nat_id_p == NULL) {
65c25746 594 plog(ASL_LEVEL_ERR, "memory error while allocating peers ph2's external nat id.\n");
47612122
A
595 goto end;
596 }
597 memcpy(iph2->ext_nat_id_p->v, &(idp_ptr->b), iph2->ext_nat_id_p->l);
65c25746 598 plogdump(ASL_LEVEL_DEBUG, iph2->ext_nat_id_p->v, iph2->ext_nat_id_p->l, "peer's external nat address saved.\n");
05434fec
A
599 }
600 } else {
65c25746 601 plog(ASL_LEVEL_ERR, "mismatched ID was returned.\n");
05434fec
A
602 error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
603 goto end;
604 }
52b7d2ce 605 }
05434fec
A
606 if (f_id == 0)
607 f_id = 1;
52b7d2ce 608 }
52b7d2ce
A
609 break;
610
611 case ISAKMP_NPTYPE_N:
d1e348cf 612 isakmp_check_ph2_notify(pa->ptr, iph2);
52b7d2ce
A
613 break;
614
615#ifdef ENABLE_NATT
616 case ISAKMP_NPTYPE_NATOA_DRAFT:
617 case ISAKMP_NPTYPE_NATOA_BADDRAFT:
618 case ISAKMP_NPTYPE_NATOA_RFC:
d1e348cf
A
619 {
620 vchar_t *vp = NULL;
85f41bec 621 struct sockaddr_storage *daddr;
d1e348cf
A
622
623 isakmp_p2ph(&vp, pa->ptr);
624
625 if (vp) {
626 daddr = process_natoa_payload(vp);
627 if (daddr) {
628 if (natoa_i == NULL) {
629 natoa_i = daddr;
65c25746 630 plog(ASL_LEVEL_DEBUG, "initiaor rcvd NAT-OA i: %s\n",
85f41bec 631 saddr2str((struct sockaddr *)natoa_i));
d1e348cf
A
632 } else if (natoa_r == NULL) {
633 natoa_r = daddr;
65c25746 634 plog(ASL_LEVEL_DEBUG, "initiator rcvd NAT-OA r: %s\n",
85f41bec 635 saddr2str((struct sockaddr *)natoa_r));
d1e348cf
A
636 } else {
637 racoon_free(daddr);
638 }
639 }
640 vfree(vp);
641 }
642
643 }
52b7d2ce
A
644 break;
645#endif
646
647 default:
648 /* don't send information, see ident_r1recv() */
65c25746 649 plog(ASL_LEVEL_ERR,
52b7d2ce
A
650 "ignore the packet, "
651 "received unexpecting payload type %d.\n",
652 pa->type);
653 goto end;
654 }
655
656 p += pa->len;
657
658 /* compute true length of payload. */
659 tlen += pa->len;
660 }
661
662 /* payload existency check */
663 if (hash == NULL || iph2->sa_ret == NULL || iph2->nonce_p == NULL) {
65c25746 664 plog(ASL_LEVEL_ERR,
52b7d2ce
A
665 "few isakmp message received.\n");
666 goto end;
667 }
668
669 /* Fixed buffer for calculating HASH */
670 memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l);
65c25746 671 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
672 "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n",
673 hbuf->l, tlen + iph2->nonce->l);
674 /* adjust buffer length for HASH */
675 hbuf->l = iph2->nonce->l + tlen;
676
677 /* validate HASH(2) */
678 {
679 char *r_hash;
680 vchar_t *my_hash = NULL;
681 int result;
682
683 r_hash = (char *)hash + sizeof(*hash);
684
65c25746 685 //plogdump(ASL_LEVEL_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash), "HASH(2) received:");
52b7d2ce
A
686
687 my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
d1e348cf 688 if (my_hash == NULL) {
65c25746 689 plog(ASL_LEVEL_ERR,
d1e348cf 690 "failed to compute HASH");
52b7d2ce 691 goto end;
d1e348cf 692 }
52b7d2ce
A
693
694 result = memcmp(my_hash->v, r_hash, my_hash->l);
695 vfree(my_hash);
696
697 if (result) {
65c25746 698 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
699 "HASH(2) mismatch.\n");
700 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
701 goto end;
702 }
703 }
704
705 /* validity check SA payload sent from responder */
706 if (ipsecdoi_checkph2proposal(iph2) < 0) {
65c25746 707 plog(ASL_LEVEL_ERR,
d1e348cf 708 "failed to validate SA proposal");
52b7d2ce
A
709 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
710 goto end;
711 }
712
713 /* change status of isakmp status entry */
65c25746 714 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_MSG2RCVD);
52b7d2ce
A
715
716 error = 0;
717
d1e348cf
A
718 IPSECSESSIONTRACEREVENT(iph2->parent_session,
719 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
720 CONSTSTR("Initiator, Quick-Mode message 2"),
721 CONSTSTR(NULL));
722
52b7d2ce 723end:
d1e348cf
A
724 if (error) {
725 IPSECSESSIONTRACEREVENT(iph2->parent_session,
726 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
727 CONSTSTR("Initiator, Quick-Mode Message 2"),
728 CONSTSTR("Failed to process Quick-Mode Message 2 "));
729 }
52b7d2ce
A
730 if (hbuf)
731 vfree(hbuf);
732 if (pbuf)
733 vfree(pbuf);
734 if (msg)
735 vfree(msg);
736
d1e348cf
A
737#ifdef ENABLE_NATT
738 if (natoa_i) {
739 racoon_free(natoa_i);
740 }
741 if (natoa_r) {
742 racoon_free(natoa_r);
743 }
744#endif
52b7d2ce
A
745 if (error) {
746 VPTRINIT(iph2->sa_ret);
747 VPTRINIT(iph2->nonce_p);
748 VPTRINIT(iph2->dhpub_p);
52b7d2ce
A
749 }
750
751 return error;
752}
753
754/*
755 * send to responder
756 * HDR*, HASH(3)
757 */
758int
65c25746
A
759quick_i3send(iph2, msg0)
760 phase2_handle_t *iph2;
52b7d2ce
A
761 vchar_t *msg0;
762{
763 vchar_t *msg = NULL;
764 vchar_t *buf = NULL;
765 vchar_t *hash = NULL;
766 char *p = NULL;
767 int tlen;
768 int error = ISAKMP_INTERNAL_ERROR;
d1e348cf 769 int packet_error = -1;
52b7d2ce
A
770
771 /* validity check */
65c25746
A
772 if (iph2->status != IKEV1_STATE_QUICK_I_MSG2RCVD) {
773 plog(ASL_LEVEL_ERR,
52b7d2ce
A
774 "status mismatched %d.\n", iph2->status);
775 goto end;
776 }
777
778 /* generate HASH(3) */
779 {
780 vchar_t *tmp = NULL;
781
65c25746 782 plog(ASL_LEVEL_DEBUG, "HASH(3) generate\n");
52b7d2ce
A
783
784 tmp = vmalloc(iph2->nonce->l + iph2->nonce_p->l);
785 if (tmp == NULL) {
65c25746 786 plog(ASL_LEVEL_ERR,
52b7d2ce
A
787 "failed to get hash buffer.\n");
788 goto end;
789 }
790 memcpy(tmp->v, iph2->nonce->v, iph2->nonce->l);
791 memcpy(tmp->v + iph2->nonce->l, iph2->nonce_p->v, iph2->nonce_p->l);
792
793 hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
794 vfree(tmp);
795
d1e348cf 796 if (hash == NULL) {
65c25746 797 plog(ASL_LEVEL_ERR,
d1e348cf 798 "failed to compute HASH");
52b7d2ce 799 goto end;
d1e348cf 800 }
52b7d2ce
A
801 }
802
803 /* create buffer for isakmp payload */
804 tlen = sizeof(struct isakmp)
805 + sizeof(struct isakmp_gen) + hash->l;
806 buf = vmalloc(tlen);
807 if (buf == NULL) {
65c25746 808 plog(ASL_LEVEL_ERR,
52b7d2ce
A
809 "failed to get buffer to send.\n");
810 goto end;
811 }
812
813 /* create isakmp header */
814 p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
d1e348cf 815 if (p == NULL) {
65c25746 816 plog(ASL_LEVEL_ERR,
d1e348cf 817 "failed to create ISAKMP header");
52b7d2ce 818 goto end;
d1e348cf 819 }
52b7d2ce
A
820
821 /* add HASH(3) payload */
822 p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE);
823
824#ifdef HAVE_PRINT_ISAKMP_C
825 isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
826#endif
827
828 /* encoding */
829 iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
d1e348cf 830 if (iph2->sendbuf == NULL) {
65c25746 831 plog(ASL_LEVEL_ERR,
d1e348cf 832 "failed to encrypt packet");
52b7d2ce 833 goto end;
d1e348cf 834 }
52b7d2ce
A
835
836 /* if there is commit bit, need resending */
837 if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
838 /* send the packet, add to the schedule to resend */
839 iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
d1e348cf 840 if (isakmp_ph2resend(iph2) == -1) {
65c25746 841 plog(ASL_LEVEL_ERR,
d1e348cf 842 "failed to send packet, commit-bit");
52b7d2ce 843 goto end;
d1e348cf 844 }
52b7d2ce
A
845 } else {
846 /* send the packet */
d1e348cf 847 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
65c25746 848 plog(ASL_LEVEL_ERR,
d1e348cf 849 "failed to send packet");
52b7d2ce 850 goto end;
d1e348cf 851 }
52b7d2ce
A
852 }
853
854 /* the sending message is added to the received-list. */
65c25746 855 if (ike_session_add_recvdpkt(iph2->ph1->remote, iph2->ph1->local,
d1e348cf 856 iph2->sendbuf, msg0,
65c25746
A
857 PH2_NON_ESP_EXTRA_LEN(iph2, iph2->sendbuf), PH2_FRAG_FLAGS(iph2)) == -1) {
858 plog(ASL_LEVEL_ERR ,
52b7d2ce
A
859 "failed to add a response packet to the tree.\n");
860 goto end;
861 }
862
d1e348cf
A
863 IPSECSESSIONTRACEREVENT(iph2->parent_session,
864 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
865 CONSTSTR("Initiator, Quick-Mode message 3"),
866 CONSTSTR(NULL));
867 packet_error = 0;
868
52b7d2ce 869 /* compute both of KEYMATs */
d1e348cf 870 if (oakley_compute_keymat(iph2, INITIATOR) < 0) {
65c25746 871 plog(ASL_LEVEL_ERR,
d1e348cf 872 "failed to compute KEYMAT");
52b7d2ce 873 goto end;
d1e348cf 874 }
52b7d2ce 875
52b7d2ce
A
876 /* if there is commit bit don't set up SA now. */
877 if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
65c25746 878 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_MSG3SENT);
52b7d2ce
A
879 error = 0;
880 goto end;
881 }
65c25746
A
882
883 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_ADDSA);
52b7d2ce
A
884
885 /* Do UPDATE for initiator */
65c25746 886 plog(ASL_LEVEL_DEBUG, "call pk_sendupdate\n");
52b7d2ce 887 if (pk_sendupdate(iph2) < 0) {
65c25746 888 plog(ASL_LEVEL_ERR, "pfkey update failed.\n");
52b7d2ce
A
889 goto end;
890 }
65c25746 891 plog(ASL_LEVEL_DEBUG, "pfkey update sent.\n");
52b7d2ce
A
892
893 /* Do ADD for responder */
894 if (pk_sendadd(iph2) < 0) {
65c25746 895 plog(ASL_LEVEL_ERR, "pfkey add failed.\n");
52b7d2ce
A
896 goto end;
897 }
65c25746 898 plog(ASL_LEVEL_DEBUG, "pfkey add sent.\n");
52b7d2ce
A
899
900 error = 0;
901
902end:
d1e348cf
A
903 if (packet_error) {
904 IPSECSESSIONTRACEREVENT(iph2->parent_session,
905 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
906 CONSTSTR("Initiator, Quick-Mode Message 3"),
907 CONSTSTR("Failed to transmit Quick-Mode Message 3"));
908 }
52b7d2ce
A
909 if (buf != NULL)
910 vfree(buf);
911 if (msg != NULL)
912 vfree(msg);
913 if (hash != NULL)
914 vfree(hash);
915
916 return error;
917}
918
919/*
920 * receive from responder
921 * HDR#*, HASH(4), notify
922 */
923int
65c25746
A
924quick_i4recv(iph2, msg0)
925 phase2_handle_t *iph2;
52b7d2ce
A
926 vchar_t *msg0;
927{
928 vchar_t *msg = NULL;
929 vchar_t *pbuf = NULL; /* for payload parsing */
930 struct isakmp_parse_t *pa;
931 struct isakmp_pl_hash *hash = NULL;
932 vchar_t *notify = NULL;
933 int error = ISAKMP_INTERNAL_ERROR;
d1e348cf 934 int packet_error = -1;
52b7d2ce
A
935
936 /* validity check */
65c25746
A
937 if (iph2->status != IKEV1_STATE_QUICK_I_MSG3SENT) {
938 plog(ASL_LEVEL_ERR,
52b7d2ce
A
939 "status mismatched %d.\n", iph2->status);
940 goto end;
941 }
942
943 /* decrypt packet */
944 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
65c25746 945 plog(ASL_LEVEL_ERR,
52b7d2ce
A
946 "Packet wasn't encrypted.\n");
947 goto end;
948 }
949 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
d1e348cf 950 if (msg == NULL) {
65c25746 951 plog(ASL_LEVEL_ERR,
e8d9021d 952 "failed to decrypt packet\n");
52b7d2ce 953 goto end;
d1e348cf 954 }
52b7d2ce
A
955
956 /* validate the type of next payload */
957 pbuf = isakmp_parse(msg);
d1e348cf 958 if (pbuf == NULL) {
65c25746 959 plog(ASL_LEVEL_ERR,
e8d9021d 960 "failed to parse msg\n");
52b7d2ce 961 goto end;
d1e348cf 962 }
52b7d2ce 963
85f41bec 964 for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v;
52b7d2ce
A
965 pa->type != ISAKMP_NPTYPE_NONE;
966 pa++) {
967
968 switch (pa->type) {
969 case ISAKMP_NPTYPE_HASH:
970 hash = (struct isakmp_pl_hash *)pa->ptr;
971 break;
972 case ISAKMP_NPTYPE_N:
d1e348cf 973 if (notify != NULL) {
65c25746 974 plog(ASL_LEVEL_WARNING,
d1e348cf
A
975 "Ignoring multiple notifications\n");
976 break;
977 }
978 isakmp_check_ph2_notify(pa->ptr, iph2);
52b7d2ce
A
979 notify = vmalloc(pa->len);
980 if (notify == NULL) {
65c25746 981 plog(ASL_LEVEL_ERR,
52b7d2ce
A
982 "failed to get notify buffer.\n");
983 goto end;
984 }
985 memcpy(notify->v, pa->ptr, notify->l);
986 break;
987 default:
988 /* don't send information, see ident_r1recv() */
65c25746 989 plog(ASL_LEVEL_ERR,
52b7d2ce
A
990 "ignore the packet, "
991 "received unexpecting payload type %d.\n",
992 pa->type);
993 goto end;
994 }
995 }
996
997 /* payload existency check */
998 if (hash == NULL) {
65c25746 999 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1000 "few isakmp message received.\n");
1001 goto end;
1002 }
1003
1004 /* validate HASH(4) */
1005 {
1006 char *r_hash;
1007 vchar_t *my_hash = NULL;
1008 vchar_t *tmp = NULL;
1009 int result;
1010
1011 r_hash = (char *)hash + sizeof(*hash);
1012
65c25746 1013 //plogdump(ASL_LEVEL_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash), "HASH(4) validate:");
52b7d2ce
A
1014
1015 my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
1016 vfree(tmp);
d1e348cf 1017 if (my_hash == NULL) {
65c25746 1018 plog(ASL_LEVEL_ERR,
e8d9021d 1019 "failed to compute HASH\n");
52b7d2ce 1020 goto end;
d1e348cf 1021 }
52b7d2ce
A
1022
1023 result = memcmp(my_hash->v, r_hash, my_hash->l);
1024 vfree(my_hash);
1025
1026 if (result) {
65c25746 1027 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
1028 "HASH(4) mismatch.\n");
1029 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1030 goto end;
1031 }
1032 }
1033
d1e348cf
A
1034 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1035 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
1036 CONSTSTR("Initiator, Quick-Mode message 4"),
1037 CONSTSTR(NULL));
1038 packet_error = 0;
1039
65c25746
A
1040 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_ADDSA);
1041
52b7d2ce
A
1042 iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */
1043
1044 /* don't anything if local test mode. */
1045 if (f_local) {
1046 error = 0;
1047 goto end;
1048 }
1049
1050 /* Do UPDATE for initiator */
65c25746 1051 plog(ASL_LEVEL_DEBUG, "call pk_sendupdate\n");
52b7d2ce 1052 if (pk_sendupdate(iph2) < 0) {
65c25746 1053 plog(ASL_LEVEL_ERR, "pfkey update failed.\n");
52b7d2ce
A
1054 goto end;
1055 }
65c25746 1056 plog(ASL_LEVEL_DEBUG, "pfkey update sent.\n");
52b7d2ce
A
1057
1058 /* Do ADD for responder */
1059 if (pk_sendadd(iph2) < 0) {
65c25746 1060 plog(ASL_LEVEL_ERR, "pfkey add failed.\n");
52b7d2ce
A
1061 goto end;
1062 }
65c25746 1063 plog(ASL_LEVEL_DEBUG, "pfkey add sent.\n");
52b7d2ce
A
1064
1065 error = 0;
1066
1067end:
d1e348cf
A
1068 if (packet_error) {
1069 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1070 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
1071 CONSTSTR("Initiator, Quick-Mode Message 4"),
1072 CONSTSTR("Failed to process Quick-Mode Message 4"));
1073 }
52b7d2ce
A
1074 if (msg != NULL)
1075 vfree(msg);
1076 if (pbuf != NULL)
1077 vfree(pbuf);
1078 if (notify != NULL)
1079 vfree(notify);
1080
1081 return error;
1082}
1083
1084/*
1085 * receive from initiator
d1e348cf 1086 * HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
52b7d2ce
A
1087 */
1088int
1089quick_r1recv(iph2, msg0)
65c25746 1090 phase2_handle_t *iph2;
52b7d2ce
A
1091 vchar_t *msg0;
1092{
1093 vchar_t *msg = NULL;
1094 vchar_t *hbuf = NULL; /* for hash computing. */
1095 vchar_t *pbuf = NULL; /* for payload parsing */
1096 struct isakmp_parse_t *pa;
1097 struct isakmp *isakmp = (struct isakmp *)msg0->v;
1098 struct isakmp_pl_hash *hash = NULL;
1099 char *p;
1100 int tlen;
1101 int f_id_order; /* for ID payload detection */
1102 int error = ISAKMP_INTERNAL_ERROR;
85f41bec
A
1103 struct sockaddr_storage *natoa_i = NULL;
1104 struct sockaddr_storage *natoa_r = NULL;
52b7d2ce
A
1105
1106 /* validity check */
65c25746
A
1107 if (iph2->status != IKEV1_STATE_QUICK_R_START) {
1108 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1109 "status mismatched %d.\n", iph2->status);
1110 goto end;
1111 }
1112
1113 /* decrypting */
1114 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
65c25746 1115 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1116 "Packet wasn't encrypted.\n");
1117 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1118 goto end;
1119 }
1120 /* decrypt packet */
1121 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
d1e348cf 1122 if (msg == NULL) {
65c25746 1123 plog(ASL_LEVEL_ERR,
e8d9021d 1124 "failed to decrypt packet\n");
52b7d2ce 1125 goto end;
d1e348cf 1126 }
52b7d2ce
A
1127
1128 /* create buffer for using to validate HASH(1) */
1129 /*
1130 * ordering rule:
1131 * 1. the first one must be HASH
1132 * 2. the second one must be SA (added in isakmp-oakley-05!)
1133 * 3. two IDs must be considered as IDci, then IDcr
1134 */
1135 pbuf = isakmp_parse(msg);
d1e348cf 1136 if (pbuf == NULL) {
65c25746 1137 plog(ASL_LEVEL_ERR,
e8d9021d 1138 "failed to parse msg\n");
52b7d2ce 1139 goto end;
d1e348cf 1140 }
85f41bec 1141 pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v;
52b7d2ce
A
1142
1143 /* HASH payload is fixed postion */
1144 if (pa->type != ISAKMP_NPTYPE_HASH) {
65c25746 1145 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1146 "received invalid next payload type %d, "
1147 "expecting %d.\n",
1148 pa->type, ISAKMP_NPTYPE_HASH);
1149 error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
1150 goto end;
1151 }
1152 hash = (struct isakmp_pl_hash *)pa->ptr;
1153 pa++;
1154
1155 /*
1156 * this restriction was introduced in isakmp-oakley-05.
1157 * we do not check this for backward compatibility.
1158 * TODO: command line/config file option to enable/disable this code
1159 */
1160 /* HASH payload is fixed postion */
1161 if (pa->type != ISAKMP_NPTYPE_SA) {
65c25746 1162 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
1163 "received invalid next payload type %d, "
1164 "expecting %d.\n",
1165 pa->type, ISAKMP_NPTYPE_SA);
1166 error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
1167 }
1168
1169 /* allocate buffer for computing HASH(1) */
1170 tlen = ntohl(isakmp->len) - sizeof(*isakmp);
e8d9021d 1171 if (tlen < 0) {
65c25746 1172 plog(ASL_LEVEL_ERR, "invalid length (%d) while extracting hash.\n",
e8d9021d
A
1173 ntohl(isakmp->len));
1174 goto end;
1175 }
52b7d2ce
A
1176 hbuf = vmalloc(tlen);
1177 if (hbuf == NULL) {
65c25746 1178 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1179 "failed to get hash buffer.\n");
1180 goto end;
1181 }
1182 p = hbuf->v;
1183
1184 /*
1185 * parse the payloads.
1186 * copy non-HASH payloads into hbuf, so that we can validate HASH.
1187 */
1188 iph2->sa = NULL; /* we don't support multi SAs. */
1189 iph2->nonce_p = NULL;
1190 iph2->dhpub_p = NULL;
1191 iph2->id_p = NULL;
1192 iph2->id = NULL;
1193 tlen = 0; /* count payload length except of HASH payload. */
1194
1195 /*
1196 * IDi2 MUST be immediatelly followed by IDr2. We allowed the
1197 * illegal case, but logged. First ID payload is to be IDi2.
1198 * And next ID payload is to be IDr2.
1199 */
1200 f_id_order = 0;
1201
1202 for (; pa->type; pa++) {
1203
1204 /* copy to buffer for HASH */
1205 /* Don't modify the payload */
1206 memcpy(p, pa->ptr, pa->len);
1207
1208 if (pa->type != ISAKMP_NPTYPE_ID)
1209 f_id_order = 0;
1210
1211 switch (pa->type) {
1212 case ISAKMP_NPTYPE_SA:
1213 if (iph2->sa != NULL) {
65c25746 1214 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1215 "Multi SAs isn't supported.\n");
1216 goto end;
1217 }
d1e348cf 1218 if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) {
65c25746 1219 plog(ASL_LEVEL_ERR,
e8d9021d 1220 "failed to process SA payload\n");
52b7d2ce 1221 goto end;
d1e348cf 1222 }
52b7d2ce
A
1223 break;
1224
1225 case ISAKMP_NPTYPE_NONCE:
d1e348cf 1226 if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
65c25746 1227 plog(ASL_LEVEL_ERR,
e8d9021d 1228 "failed to process NONCE payload\n");
52b7d2ce 1229 goto end;
d1e348cf 1230 }
52b7d2ce
A
1231 break;
1232
1233 case ISAKMP_NPTYPE_KE:
d1e348cf 1234 if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
65c25746 1235 plog(ASL_LEVEL_ERR,
e8d9021d 1236 "failed to process KE payload\n");
52b7d2ce 1237 goto end;
d1e348cf 1238 }
52b7d2ce
A
1239 break;
1240
1241 case ISAKMP_NPTYPE_ID:
1242 if (iph2->id_p == NULL) {
1243 /* for IDci */
1244 f_id_order++;
1245
d1e348cf 1246 if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0) {
65c25746 1247 plog(ASL_LEVEL_ERR,
e8d9021d 1248 "failed to process IDci2 payload\n");
52b7d2ce 1249 goto end;
d1e348cf 1250 }
52b7d2ce
A
1251
1252 } else if (iph2->id == NULL) {
1253 /* for IDcr */
1254 if (f_id_order == 0) {
65c25746 1255 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1256 "IDr2 payload is not "
1257 "immediatelly followed "
1258 "by IDi2. We allowed.\n");
1259 /* XXX we allowed in this case. */
1260 }
1261
d1e348cf 1262 if (isakmp_p2ph(&iph2->id, pa->ptr) < 0) {
65c25746 1263 plog(ASL_LEVEL_ERR,
e8d9021d 1264 "failed to process IDcr2 payload\n");
52b7d2ce 1265 goto end;
d1e348cf 1266 }
52b7d2ce 1267 } else {
65c25746 1268 plogdump(ASL_LEVEL_ERR, iph2->id->v, iph2->id->l, "received too many ID payloads");
52b7d2ce
A
1269 error = ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1270 goto end;
1271 }
1272 break;
1273
1274 case ISAKMP_NPTYPE_N:
d1e348cf 1275 isakmp_check_ph2_notify(pa->ptr, iph2);
52b7d2ce
A
1276 break;
1277
1278#ifdef ENABLE_NATT
1279 case ISAKMP_NPTYPE_NATOA_DRAFT:
1280 case ISAKMP_NPTYPE_NATOA_BADDRAFT:
1281 case ISAKMP_NPTYPE_NATOA_RFC:
d1e348cf
A
1282 {
1283 vchar_t *vp = NULL;
85f41bec 1284 struct sockaddr_storage *daddr;
d1e348cf
A
1285
1286 isakmp_p2ph(&vp, pa->ptr);
1287
1288 if (vp) {
1289 daddr = process_natoa_payload(vp);
1290 if (daddr) {
1291 if (natoa_i == NULL) {
1292 natoa_i = daddr;
65c25746 1293 plog(ASL_LEVEL_DEBUG, "responder rcvd NAT-OA i: %s\n",
85f41bec 1294 saddr2str((struct sockaddr *)natoa_i));
d1e348cf
A
1295 } else if (natoa_r == NULL) {
1296 natoa_r = daddr;
65c25746 1297 plog(ASL_LEVEL_DEBUG, "responder rcvd NAT-OA r: %s\n",
85f41bec 1298 saddr2str((struct sockaddr *)natoa_r));
d1e348cf
A
1299 } else {
1300 racoon_free(daddr);
1301 }
1302 }
1303 vfree(vp);
1304 }
1305
1306 }
52b7d2ce
A
1307 break;
1308#endif
1309
1310 default:
65c25746 1311 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1312 "ignore the packet, "
1313 "received unexpected payload type %d.\n",
1314 pa->type);
1315 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1316 goto end;
1317 }
1318
1319 p += pa->len;
1320
1321 /* compute true length of payload. */
1322 tlen += pa->len;
1323 }
1324
1325 /* payload existency check */
1326 if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) {
65c25746 1327 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1328 "expected isakmp payloads missing.\n");
1329 error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1330 goto end;
1331 }
1332
1333 if (iph2->id_p) {
65c25746 1334 plogdump(ASL_LEVEL_DEBUG, iph2->id_p->v, iph2->id_p->l, "received IDci2:");
52b7d2ce
A
1335 }
1336 if (iph2->id) {
65c25746 1337 plogdump(ASL_LEVEL_DEBUG, iph2->id->v, iph2->id->l, "received IDcr2:");
52b7d2ce
A
1338 }
1339
1340 /* adjust buffer length for HASH */
1341 hbuf->l = tlen;
1342
1343 /* validate HASH(1) */
1344 {
1345 char *r_hash;
1346 vchar_t *my_hash = NULL;
1347 int result;
1348
1349 r_hash = (caddr_t)hash + sizeof(*hash);
1350
65c25746 1351 //plogdump(ASL_LEVEL_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash), "HASH(1) validate:");
52b7d2ce
A
1352
1353 my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
d1e348cf 1354 if (my_hash == NULL) {
65c25746 1355 plog(ASL_LEVEL_ERR,
e8d9021d 1356 "failed to compute HASH\n");
52b7d2ce 1357 goto end;
d1e348cf 1358 }
52b7d2ce
A
1359
1360 result = memcmp(my_hash->v, r_hash, my_hash->l);
1361 vfree(my_hash);
1362
1363 if (result) {
65c25746 1364 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1365 "HASH(1) mismatch.\n");
1366 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1367 goto end;
1368 }
1369 }
1370
1371 /* get sainfo */
1372 error = get_sainfo_r(iph2);
1373 if (error) {
65c25746 1374 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1375 "failed to get sainfo.\n");
1376 goto end;
1377 }
1378
d1e348cf 1379 /* check the existence of ID payload and create responder's proposal */
80318cb7 1380 error = get_proposal_r(iph2);
52b7d2ce
A
1381 switch (error) {
1382 case -2:
1383 /* generate a policy template from peer's proposal */
1384 if (set_proposal_from_proposal(iph2)) {
65c25746 1385 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1386 "failed to generate a proposal template "
1387 "from client's proposal.\n");
1388 return ISAKMP_INTERNAL_ERROR;
1389 }
1390 /*FALLTHROUGH*/
1391 case 0:
1392 /* select single proposal or reject it. */
1393 if (ipsecdoi_selectph2proposal(iph2) < 0) {
65c25746 1394 plog(ASL_LEVEL_ERR,
d1e348cf 1395 "failed to select proposal.\n");
52b7d2ce
A
1396 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1397 goto end;
1398 }
1399 break;
1400 default:
65c25746 1401 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1402 "failed to get proposal for responder.\n");
1403 goto end;
1404 }
1405
1406 /* check KE and attribute of PFS */
1407 if (iph2->dhpub_p != NULL && iph2->approval->pfs_group == 0) {
65c25746 1408 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1409 "no PFS is specified, but peer sends KE.\n");
1410 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1411 goto end;
1412 }
1413 if (iph2->dhpub_p == NULL && iph2->approval->pfs_group != 0) {
65c25746 1414 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1415 "PFS is specified, but peer doesn't sends KE.\n");
1416 error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1417 goto end;
1418 }
1419
d1e348cf
A
1420 ike_session_update_mode(iph2); /* update the mode, now that we have a proposal */
1421
52b7d2ce
A
1422 /*
1423 * save the packet from the initiator in order to resend the
1424 * responder's first packet against this packet.
1425 */
1426 iph2->msg1 = vdup(msg0);
1427
1428 /* change status of isakmp status entry */
65c25746 1429 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_MSG1RCVD);
52b7d2ce
A
1430
1431 error = 0;
1432
d1e348cf
A
1433 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1434 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
1435 CONSTSTR("Responder, Quick-Mode message 1"),
1436 CONSTSTR(NULL));
1437
52b7d2ce 1438end:
d1e348cf
A
1439 if (error) {
1440 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1441 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
1442 CONSTSTR("Responder, Quick-Mode Message 1"),
1443 CONSTSTR("Failed to process Quick-Mode Message 1"));
1444 }
52b7d2ce
A
1445 if (hbuf)
1446 vfree(hbuf);
1447 if (msg)
1448 vfree(msg);
1449 if (pbuf)
1450 vfree(pbuf);
1451
d1e348cf
A
1452#ifdef ENABLE_NATT
1453 if (natoa_i) {
1454 racoon_free(natoa_i);
1455 }
1456 if (natoa_r) {
1457 racoon_free(natoa_r);
1458 }
1459#endif
1460
52b7d2ce
A
1461 if (error) {
1462 VPTRINIT(iph2->sa);
1463 VPTRINIT(iph2->nonce_p);
1464 VPTRINIT(iph2->dhpub_p);
1465 VPTRINIT(iph2->id);
1466 VPTRINIT(iph2->id_p);
1467 }
1468
1469 return error;
1470}
1471
1472/*
1473 * call pfkey_getspi.
1474 */
1475int
65c25746
A
1476quick_rprep(iph2, msg)
1477 phase2_handle_t *iph2;
52b7d2ce
A
1478 vchar_t *msg;
1479{
1480 int error = ISAKMP_INTERNAL_ERROR;
1481
1482 /* validity check */
65c25746
A
1483 if (iph2->status != IKEV1_STATE_QUICK_R_MSG1RCVD) {
1484 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1485 "status mismatched %d.\n", iph2->status);
1486 goto end;
1487 }
1488
65c25746 1489 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_GETSPISENT);
52b7d2ce
A
1490
1491 /* send getspi message */
d1e348cf 1492 if (pk_sendgetspi(iph2) < 0) {
65c25746 1493 plog(ASL_LEVEL_ERR,
d1e348cf 1494 "failed to send getspi");
52b7d2ce 1495 goto end;
d1e348cf 1496 }
52b7d2ce 1497
65c25746 1498 plog(ASL_LEVEL_DEBUG, "pfkey getspi sent.\n");
52b7d2ce
A
1499
1500 iph2->sce = sched_new(lcconf->wait_ph2complete,
1501 pfkey_timeover_stub, iph2);
1502
1503 error = 0;
1504
1505end:
1506 return error;
1507}
1508
1509/*
1510 * send to initiator
d1e348cf 1511 * HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
52b7d2ce
A
1512 */
1513int
1514quick_r2send(iph2, msg)
65c25746 1515 phase2_handle_t *iph2;
52b7d2ce
A
1516 vchar_t *msg;
1517{
1518 vchar_t *body = NULL;
1519 vchar_t *hash = NULL;
1520 vchar_t *natoa_i = NULL;
1521 vchar_t *natoa_r = NULL;
1522 int natoa_type = 0;
52b7d2ce
A
1523 struct isakmp_gen *gen;
1524 char *p;
1525 int tlen;
1526 int error = ISAKMP_INTERNAL_ERROR;
1527 int pfsgroup;
1528 u_int8_t *np_p = NULL;
1529
1530 /* validity check */
1531 if (msg != NULL) {
65c25746 1532 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1533 "msg has to be NULL in this function.\n");
1534 goto end;
1535 }
65c25746
A
1536 if (iph2->status != IKEV1_STATE_QUICK_R_GETSPIDONE) {
1537 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1538 "status mismatched %d.\n", iph2->status);
1539 goto end;
1540 }
1541
1542 /* update responders SPI */
1543 if (ipsecdoi_updatespi(iph2) < 0) {
65c25746 1544 plog(ASL_LEVEL_ERR, "failed to update spi.\n");
52b7d2ce
A
1545 goto end;
1546 }
1547
1548 /* generate NONCE value */
1549 iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
d1e348cf 1550 if (iph2->nonce == NULL) {
65c25746 1551 plog(ASL_LEVEL_ERR,
d1e348cf 1552 "failed to generate NONCE");
52b7d2ce 1553 goto end;
d1e348cf 1554 }
52b7d2ce
A
1555
1556 /* generate KE value if need */
1557 pfsgroup = iph2->approval->pfs_group;
1558 if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1559 /* DH group settting if PFS is required. */
1560 if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
65c25746 1561 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1562 "failed to set DH value.\n");
1563 goto end;
1564 }
1565 /* generate DH public value */
e8d9021d 1566#ifdef HAVE_OPENSSL
52b7d2ce
A
1567 if (oakley_dh_generate(iph2->pfsgrp,
1568 &iph2->dhpub, &iph2->dhpriv) < 0) {
e8d9021d
A
1569#else
1570 if (oakley_dh_generate(iph2->pfsgrp,
1571 &iph2->dhpub, &iph2->publicKeySize, &iph2->dhC) < 0) {
1572#endif
65c25746 1573 plog(ASL_LEVEL_ERR,
d1e348cf 1574 "failed to generate DH public");
52b7d2ce
A
1575 goto end;
1576 }
1577 }
1578
1579 /* create SA;NONCE payload, and KE and ID if need */
1580 tlen = sizeof(*gen) + iph2->sa_ret->l
1581 + sizeof(*gen) + iph2->nonce->l;
1582 if (iph2->dhpub_p != NULL && pfsgroup != 0)
1583 tlen += (sizeof(*gen) + iph2->dhpub->l);
1584 if (iph2->id_p != NULL)
1585 tlen += (sizeof(*gen) + iph2->id_p->l
1586 + sizeof(*gen) + iph2->id->l);
1587
52b7d2ce 1588#ifdef ENABLE_NATT
d1e348cf
A
1589 /*
1590 * RFC3947 5.2. if we chose UDP-Encapsulated-Transport
1591 * we should send NAT-OA
1592 */
1593 if (ipsecdoi_any_transportmode(iph2->approval)
1594 && (iph2->ph1->natt_flags & NAT_DETECTED)) {
52b7d2ce 1595 natoa_type = create_natoa_payloads(iph2, &natoa_i, &natoa_r);
d1e348cf 1596 if (natoa_type == -1) {
65c25746 1597 plog(ASL_LEVEL_ERR,
d1e348cf 1598 "failed to create NATOA payloads");
52b7d2ce 1599 goto end;
d1e348cf 1600 }
52b7d2ce
A
1601 else if (natoa_type != 0) {
1602 tlen += sizeof(*gen) + natoa_i->l;
1603 tlen += sizeof(*gen) + natoa_r->l;
d1e348cf 1604
65c25746
A
1605 //plogdump(ASL_LEVEL_DEBUG, natoa_i->v, natoa_i->l, "responder send NAT-OAi:");
1606 //plogdump(ASL_LEVEL_DEBUG, natoa_r->v, natoa_r->l, "responder send NAT-OAr:");
52b7d2ce
A
1607 }
1608 }
1609#endif
52b7d2ce 1610
65c25746
A
1611 plog(ASL_LEVEL_DEBUG, "Approved SA\n");
1612 printsaprop0(ASL_LEVEL_DEBUG, iph2->approval);
52b7d2ce
A
1613
1614 body = vmalloc(tlen);
1615 if (body == NULL) {
65c25746 1616 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1617 "failed to get buffer to send.\n");
1618 goto end;
1619 }
1620 p = body->v;
1621
1622 /* make SA payload */
1623 p = set_isakmp_payload(body->v, iph2->sa_ret, ISAKMP_NPTYPE_NONCE);
1624
1625 /* add NONCE payload */
1626 np_p = &((struct isakmp_gen *)p)->np; /* XXX */
1627 p = set_isakmp_payload(p, iph2->nonce,
1628 (iph2->dhpub_p != NULL && pfsgroup != 0)
1629 ? ISAKMP_NPTYPE_KE
1630 : (iph2->id_p != NULL
1631 ? ISAKMP_NPTYPE_ID
52b7d2ce 1632 : (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE)));
52b7d2ce
A
1633
1634 /* add KE payload if need. */
1635 if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1636 np_p = &((struct isakmp_gen *)p)->np; /* XXX */
1637 p = set_isakmp_payload(p, iph2->dhpub,
d1e348cf 1638 (iph2->id_p == NULL) ? (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE) : ISAKMP_NPTYPE_ID);
52b7d2ce
A
1639 }
1640
1641 /* add ID payloads received. */
1642 if (iph2->id_p != NULL) {
1643 /* IDci */
1644 p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID);
65c25746 1645 plogdump(ASL_LEVEL_DEBUG, iph2->id_p->v, iph2->id_p->l, "sending IDci2:");
52b7d2ce
A
1646 /* IDcr */
1647 np_p = &((struct isakmp_gen *)p)->np; /* XXX */
52b7d2ce 1648 p = set_isakmp_payload(p, iph2->id, (natoa_type ? natoa_type : ISAKMP_NPTYPE_NONE));
65c25746 1649 plogdump(ASL_LEVEL_DEBUG, iph2->id->v, iph2->id->l, "sending IDcr2:");
52b7d2ce
A
1650 }
1651
1652 /* add a RESPONDER-LIFETIME notify payload if needed */
1653 {
1654 vchar_t *data = NULL;
1655 struct saprop *pp = iph2->approval;
1656 struct saproto *pr;
1657
1658 if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_SEC) {
1659 u_int32_t v = htonl((u_int32_t)pp->lifetime);
1660 data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1661 IPSECDOI_ATTR_SA_LD_TYPE_SEC);
d1e348cf 1662 if (!data) {
65c25746 1663 plog(ASL_LEVEL_ERR,
d1e348cf 1664 "failed to add RESPONDER-LIFETIME notify (type) payload");
52b7d2ce 1665 goto end;
d1e348cf 1666 }
52b7d2ce
A
1667 data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1668 (caddr_t)&v, sizeof(v));
d1e348cf 1669 if (!data) {
65c25746 1670 plog(ASL_LEVEL_ERR,
d1e348cf 1671 "failed to add RESPONDER-LIFETIME notify (value) payload");
52b7d2ce 1672 goto end;
d1e348cf 1673 }
52b7d2ce
A
1674 }
1675 if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) {
1676 u_int32_t v = htonl((u_int32_t)pp->lifebyte);
1677 data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1678 IPSECDOI_ATTR_SA_LD_TYPE_KB);
d1e348cf 1679 if (!data) {
65c25746 1680 plog(ASL_LEVEL_ERR,
d1e348cf 1681 "failed to add RESPONDER-LIFETIME notify (type) payload");
52b7d2ce 1682 goto end;
d1e348cf 1683 }
52b7d2ce
A
1684 data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1685 (caddr_t)&v, sizeof(v));
d1e348cf 1686 if (!data) {
65c25746 1687 plog(ASL_LEVEL_ERR,
d1e348cf 1688 "failed to add RESPONDER-LIFETIME notify (value) payload");
52b7d2ce 1689 goto end;
d1e348cf 1690 }
52b7d2ce
A
1691 }
1692
1693 /*
1694 * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1695 * in the case of SA bundle ?
1696 */
1697 if (data) {
1698 for (pr = pp->head; pr; pr = pr->next) {
1699 body = isakmp_add_pl_n(body, &np_p,
1700 ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data);
1701 if (!body) {
65c25746 1702 plog(ASL_LEVEL_ERR,
d1e348cf 1703 "invalid RESPONDER-LIFETIME payload");
52b7d2ce
A
1704 vfree(data);
1705 return error; /* XXX */
1706 }
1707 }
1708 vfree(data);
1709 }
1710 }
1711
52b7d2ce
A
1712 /* natoa */
1713 if (natoa_type) {
1714 p = set_isakmp_payload(p, natoa_i, natoa_type);
1715 p = set_isakmp_payload(p, natoa_r, ISAKMP_NPTYPE_NONE);
1716 }
52b7d2ce
A
1717
1718 /* generate HASH(2) */
1719 {
1720 vchar_t *tmp;
1721
1722 tmp = vmalloc(iph2->nonce_p->l + body->l);
1723 if (tmp == NULL) {
65c25746 1724 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1725 "failed to get hash buffer.\n");
1726 goto end;
1727 }
1728 memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1729 memcpy(tmp->v + iph2->nonce_p->l, body->v, body->l);
1730
1731 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp);
1732 vfree(tmp);
1733
d1e348cf 1734 if (hash == NULL) {
65c25746 1735 plog(ASL_LEVEL_ERR,
d1e348cf 1736 "failed to compute HASH");
52b7d2ce
A
1737 goto end;
1738 }
d1e348cf 1739 }
52b7d2ce
A
1740
1741 /* send isakmp payload */
1742 iph2->sendbuf = quick_ir1mx(iph2, body, hash);
d1e348cf 1743 if (iph2->sendbuf == NULL) {
65c25746 1744 plog(ASL_LEVEL_ERR,
d1e348cf 1745 "failed to get send buffer");
52b7d2ce 1746 goto end;
d1e348cf 1747 }
52b7d2ce
A
1748
1749 /* send the packet, add to the schedule to resend */
1750 iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
d1e348cf 1751 if (isakmp_ph2resend(iph2) == -1) {
65c25746 1752 plog(ASL_LEVEL_ERR,
d1e348cf 1753 "failed to send packet");
52b7d2ce 1754 goto end;
d1e348cf 1755 }
52b7d2ce
A
1756
1757 /* the sending message is added to the received-list. */
65c25746
A
1758 if (ike_session_add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1,
1759 PH2_NON_ESP_EXTRA_LEN(iph2, iph2->sendbuf), PH2_FRAG_FLAGS(iph2)) == -1) {
1760 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1761 "failed to add a response packet to the tree.\n");
1762 goto end;
1763 }
1764
1765 /* change status of isakmp status entry */
65c25746 1766 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_MSG2SENT);
52b7d2ce
A
1767
1768 error = 0;
1769
d1e348cf
A
1770 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1771 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
1772 CONSTSTR("Responder, Quick-Mode message 2"),
1773 CONSTSTR(NULL));
1774
52b7d2ce 1775end:
d1e348cf
A
1776 if (error) {
1777 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1778 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
1779 CONSTSTR("Responder, Quick-Mode Message 2"),
1780 CONSTSTR("Failed to transmit Quick-Mode Message 2"));
1781 }
52b7d2ce
A
1782 if (body != NULL)
1783 vfree(body);
1784 if (hash != NULL)
1785 vfree(hash);
52b7d2ce
A
1786 if (natoa_i)
1787 vfree(natoa_i);
1788 if (natoa_r)
1789 vfree(natoa_r);
52b7d2ce
A
1790
1791 return error;
1792}
1793
1794/*
1795 * receive from initiator
1796 * HDR*, HASH(3)
1797 */
1798int
1799quick_r3recv(iph2, msg0)
65c25746 1800 phase2_handle_t *iph2;
52b7d2ce
A
1801 vchar_t *msg0;
1802{
1803 vchar_t *msg = NULL;
1804 vchar_t *pbuf = NULL; /* for payload parsing */
1805 struct isakmp_parse_t *pa;
1806 struct isakmp_pl_hash *hash = NULL;
1807 int error = ISAKMP_INTERNAL_ERROR;
1808
1809 /* validity check */
65c25746
A
1810 if (iph2->status != IKEV1_STATE_QUICK_R_MSG2SENT) {
1811 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1812 "status mismatched %d.\n", iph2->status);
1813 goto end;
1814 }
1815
1816 /* decrypt packet */
1817 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
65c25746 1818 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1819 "Packet wasn't encrypted.\n");
1820 goto end;
1821 }
1822 msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
d1e348cf 1823 if (msg == NULL) {
65c25746 1824 plog(ASL_LEVEL_ERR,
e8d9021d 1825 "failed to decrypt packet\n");
52b7d2ce 1826 goto end;
d1e348cf 1827 }
52b7d2ce
A
1828
1829 /* validate the type of next payload */
1830 pbuf = isakmp_parse(msg);
d1e348cf 1831 if (pbuf == NULL) {
65c25746 1832 plog(ASL_LEVEL_ERR,
e8d9021d 1833 "failed to parse msg\n");
52b7d2ce 1834 goto end;
d1e348cf 1835 }
52b7d2ce 1836
85f41bec 1837 for (pa = ALIGNED_CAST(struct isakmp_parse_t *)pbuf->v;
52b7d2ce
A
1838 pa->type != ISAKMP_NPTYPE_NONE;
1839 pa++) {
1840
1841 switch (pa->type) {
1842 case ISAKMP_NPTYPE_HASH:
1843 hash = (struct isakmp_pl_hash *)pa->ptr;
1844 break;
1845 case ISAKMP_NPTYPE_N:
d1e348cf 1846 isakmp_check_ph2_notify(pa->ptr, iph2);
52b7d2ce
A
1847 break;
1848 default:
1849 /* don't send information, see ident_r1recv() */
65c25746 1850 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1851 "ignore the packet, "
1852 "received unexpecting payload type %d.\n",
1853 pa->type);
1854 goto end;
1855 }
1856 }
1857
1858 /* payload existency check */
1859 if (hash == NULL) {
65c25746 1860 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1861 "few isakmp message received.\n");
1862 goto end;
1863 }
1864
1865 /* validate HASH(3) */
1866 /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1867 {
1868 char *r_hash;
1869 vchar_t *my_hash = NULL;
1870 vchar_t *tmp = NULL;
1871 int result;
1872
1873 r_hash = (char *)hash + sizeof(*hash);
1874
65c25746 1875 //plogdump(ASL_LEVEL_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash), "HASH(3) validate:");
52b7d2ce
A
1876
1877 tmp = vmalloc(iph2->nonce_p->l + iph2->nonce->l);
1878 if (tmp == NULL) {
65c25746 1879 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1880 "failed to get hash buffer.\n");
1881 goto end;
1882 }
1883 memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1884 memcpy(tmp->v + iph2->nonce_p->l, iph2->nonce->v, iph2->nonce->l);
1885
1886 my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
1887 vfree(tmp);
d1e348cf 1888 if (my_hash == NULL) {
65c25746 1889 plog(ASL_LEVEL_ERR,
e8d9021d 1890 "failed to compute HASH\n");
52b7d2ce 1891 goto end;
d1e348cf 1892 }
52b7d2ce
A
1893
1894 result = memcmp(my_hash->v, r_hash, my_hash->l);
1895 vfree(my_hash);
1896
1897 if (result) {
65c25746 1898 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1899 "HASH(3) mismatch.\n");
1900 error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1901 goto end;
1902 }
1903 }
1904
1905 /* if there is commit bit, don't set up SA now. */
1906 if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
65c25746 1907 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_MSG3RCVD);
52b7d2ce 1908 } else
65c25746 1909 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_COMMIT);
52b7d2ce
A
1910
1911 error = 0;
1912
d1e348cf
A
1913 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1914 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
1915 CONSTSTR("Responder, Quick-Mode message 3"),
1916 CONSTSTR(NULL));
1917
52b7d2ce 1918end:
d1e348cf
A
1919 if (error) {
1920 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1921 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
1922 CONSTSTR("Responder, Quick-Mode Message 3"),
1923 CONSTSTR("Failed to process Quick-Mode Message 3"));
1924 }
52b7d2ce
A
1925 if (pbuf != NULL)
1926 vfree(pbuf);
1927 if (msg != NULL)
1928 vfree(msg);
1929
1930 return error;
1931}
1932
1933/*
1934 * send to initiator
1935 * HDR#*, HASH(4), notify
1936 */
1937int
65c25746
A
1938quick_r4send(iph2, msg0)
1939 phase2_handle_t *iph2;
52b7d2ce
A
1940 vchar_t *msg0;
1941{
1942 vchar_t *buf = NULL;
1943 vchar_t *myhash = NULL;
1944 struct isakmp_pl_n *n;
1945 vchar_t *notify = NULL;
1946 char *p;
1947 int tlen;
1948 int error = ISAKMP_INTERNAL_ERROR;
1949
1950 /* validity check */
65c25746
A
1951 if (iph2->status != IKEV1_STATE_QUICK_R_MSG3RCVD) {
1952 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1953 "status mismatched %d.\n", iph2->status);
1954 goto end;
1955 }
1956
1957 /* generate HASH(4) */
1958 /* XXX What can I do in the case of multiple different SA */
65c25746 1959 plog(ASL_LEVEL_DEBUG, "HASH(4) generate\n");
52b7d2ce
A
1960
1961 /* XXX What should I do if there are multiple SAs ? */
1962 tlen = sizeof(struct isakmp_pl_n) + iph2->approval->head->spisize;
1963 notify = vmalloc(tlen);
1964 if (notify == NULL) {
65c25746 1965 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1966 "failed to get notify buffer.\n");
1967 goto end;
1968 }
1969 n = (struct isakmp_pl_n *)notify->v;
1970 n->h.np = ISAKMP_NPTYPE_NONE;
1971 n->h.len = htons(tlen);
1972 n->doi = htonl(IPSEC_DOI);
1973 n->proto_id = iph2->approval->head->proto_id;
1974 n->spi_size = sizeof(iph2->approval->head->spisize);
1975 n->type = htons(ISAKMP_NTYPE_CONNECTED);
1976 memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize);
1977
1978 myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
d1e348cf 1979 if (myhash == NULL) {
65c25746 1980 plog(ASL_LEVEL_ERR,
d1e348cf 1981 "failed to compute HASH");
52b7d2ce 1982 goto end;
d1e348cf 1983 }
52b7d2ce
A
1984
1985 /* create buffer for isakmp payload */
1986 tlen = sizeof(struct isakmp)
1987 + sizeof(struct isakmp_gen) + myhash->l
1988 + notify->l;
1989 buf = vmalloc(tlen);
1990 if (buf == NULL) {
65c25746 1991 plog(ASL_LEVEL_ERR,
52b7d2ce
A
1992 "failed to get buffer to send.\n");
1993 goto end;
1994 }
1995
1996 /* create isakmp header */
1997 p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
d1e348cf 1998 if (p == NULL) {
65c25746 1999 plog(ASL_LEVEL_ERR,
d1e348cf 2000 "failed to set ISAKMP header");
52b7d2ce 2001 goto end;
d1e348cf 2002 }
52b7d2ce
A
2003
2004 /* add HASH(4) payload */
2005 p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N);
2006
2007 /* add notify payload */
2008 memcpy(p, notify->v, notify->l);
2009
2010#ifdef HAVE_PRINT_ISAKMP_C
2011 isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
2012#endif
2013
2014 /* encoding */
2015 iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
d1e348cf 2016 if (iph2->sendbuf == NULL) {
65c25746 2017 plog(ASL_LEVEL_ERR,
d1e348cf 2018 "failed to encrypt packet");
52b7d2ce 2019 goto end;
d1e348cf 2020 }
52b7d2ce
A
2021
2022 /* send the packet */
d1e348cf 2023 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
65c25746 2024 plog(ASL_LEVEL_ERR,
d1e348cf 2025 "failed to send packet");
52b7d2ce 2026 goto end;
d1e348cf 2027 }
52b7d2ce
A
2028
2029 /* the sending message is added to the received-list. */
65c25746
A
2030 if (ike_session_add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0,
2031 PH2_NON_ESP_EXTRA_LEN(iph2, iph2->sendbuf), PH2_FRAG_FLAGS(iph2)) == -1) {
2032 plog(ASL_LEVEL_ERR ,
52b7d2ce
A
2033 "failed to add a response packet to the tree.\n");
2034 goto end;
2035 }
2036
65c25746 2037 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_COMMIT);
52b7d2ce
A
2038
2039 error = 0;
2040
d1e348cf
A
2041 IPSECSESSIONTRACEREVENT(iph2->parent_session,
2042 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
2043 CONSTSTR("Responder, Quick-Mode message 4"),
2044 CONSTSTR(NULL));
2045
52b7d2ce 2046end:
d1e348cf
A
2047 if (error) {
2048 IPSECSESSIONTRACEREVENT(iph2->parent_session,
2049 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
2050 CONSTSTR("Responder, Quick-Mode Message 4"),
2051 CONSTSTR("Failed to transmit Quick-Mode Message 4"));
2052 }
52b7d2ce
A
2053 if (buf != NULL)
2054 vfree(buf);
2055 if (myhash != NULL)
2056 vfree(myhash);
2057 if (notify != NULL)
2058 vfree(notify);
2059
2060 return error;
2061}
2062
d1e348cf 2063
52b7d2ce
A
2064/*
2065 * set SA to kernel.
2066 */
2067int
65c25746
A
2068quick_rfinalize(iph2, msg0)
2069 phase2_handle_t *iph2;
52b7d2ce
A
2070 vchar_t *msg0;
2071{
2072 vchar_t *msg = NULL;
2073 int error = ISAKMP_INTERNAL_ERROR;
2074
2075 /* validity check */
65c25746
A
2076 if (iph2->status != IKEV1_STATE_QUICK_R_COMMIT) {
2077 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2078 "status mismatched %d.\n", iph2->status);
2079 goto end;
2080 }
2081
2082 /* compute both of KEYMATs */
d1e348cf 2083 if (oakley_compute_keymat(iph2, RESPONDER) < 0) {
65c25746 2084 plog(ASL_LEVEL_ERR,
d1e348cf 2085 "failed to compute KEYMAT");
52b7d2ce 2086 goto end;
d1e348cf 2087 }
52b7d2ce 2088
65c25746
A
2089 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_R_ADDSA);
2090
52b7d2ce
A
2091 iph2->flags ^= ISAKMP_FLAG_C; /* reset bit */
2092
2093 /* don't anything if local test mode. */
2094 if (f_local) {
2095 error = 0;
2096 goto end;
2097 }
2098
2099 /* Do UPDATE as responder */
65c25746 2100 plog(ASL_LEVEL_DEBUG, "call pk_sendupdate\n");
52b7d2ce 2101 if (pk_sendupdate(iph2) < 0) {
65c25746 2102 plog(ASL_LEVEL_ERR, "pfkey update failed.\n");
52b7d2ce
A
2103 goto end;
2104 }
65c25746 2105 plog(ASL_LEVEL_DEBUG, "pfkey update sent.\n");
52b7d2ce
A
2106
2107 /* Do ADD for responder */
2108 if (pk_sendadd(iph2) < 0) {
65c25746 2109 plog(ASL_LEVEL_ERR, "pfkey add failed.\n");
52b7d2ce
A
2110 goto end;
2111 }
65c25746 2112 plog(ASL_LEVEL_DEBUG, "pfkey add sent.\n");
52b7d2ce
A
2113
2114 /*
2115 * set policies into SPD if the policy is generated
2116 * from peer's policy.
2117 */
2118 if (iph2->spidx_gen) {
2119
2120 struct policyindex *spidx;
2121 struct sockaddr_storage addr;
2122 u_int8_t pref;
85f41bec
A
2123 struct sockaddr_storage *src = iph2->src;
2124 struct sockaddr_storage *dst = iph2->dst;
52b7d2ce
A
2125
2126 /* make inbound policy */
2127 iph2->src = dst;
2128 iph2->dst = src;
2129 if (pk_sendspdupdate2(iph2) < 0) {
65c25746 2130 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2131 "pfkey spdupdate2(inbound) failed.\n");
2132 goto end;
2133 }
65c25746 2134 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
2135 "pfkey spdupdate2(inbound) sent.\n");
2136
85f41bec 2137 spidx = iph2->spidx_gen;
52b7d2ce
A
2138#ifdef HAVE_POLICY_FWD
2139 /* make forward policy if required */
2140 if (tunnel_mode_prop(iph2->approval)) {
2141 spidx->dir = IPSEC_DIR_FWD;
2142 if (pk_sendspdupdate2(iph2) < 0) {
65c25746 2143 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2144 "pfkey spdupdate2(forward) failed.\n");
2145 goto end;
2146 }
65c25746 2147 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
2148 "pfkey spdupdate2(forward) sent.\n");
2149 }
2150#endif
2151
2152 /* make outbound policy */
2153 iph2->src = src;
2154 iph2->dst = dst;
2155 spidx->dir = IPSEC_DIR_OUTBOUND;
2156 addr = spidx->src;
2157 spidx->src = spidx->dst;
2158 spidx->dst = addr;
2159 pref = spidx->prefs;
2160 spidx->prefs = spidx->prefd;
2161 spidx->prefd = pref;
2162
2163 if (pk_sendspdupdate2(iph2) < 0) {
65c25746 2164 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2165 "pfkey spdupdate2(outbound) failed.\n");
2166 goto end;
2167 }
65c25746 2168 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
2169 "pfkey spdupdate2(outbound) sent.\n");
2170
2171 /* spidx_gen is unnecessary any more */
85f41bec 2172 delsp_bothdir(iph2->spidx_gen);
52b7d2ce
A
2173 racoon_free(iph2->spidx_gen);
2174 iph2->spidx_gen = NULL;
2175 iph2->generated_spidx=1;
2176 }
2177
2178 error = 0;
2179
2180end:
2181 if (msg != NULL)
2182 vfree(msg);
2183
2184 return error;
2185}
2186
2187/*
2188 * create HASH, body (SA, NONCE) payload with isakmp header.
2189 */
2190static vchar_t *
2191quick_ir1mx(iph2, body, hash)
65c25746 2192 phase2_handle_t *iph2;
52b7d2ce
A
2193 vchar_t *body, *hash;
2194{
2195 struct isakmp *isakmp;
2196 vchar_t *buf = NULL, *new = NULL;
2197 char *p;
2198 int tlen;
2199 struct isakmp_gen *gen;
2200 int error = ISAKMP_INTERNAL_ERROR;
2201
2202 /* create buffer for isakmp payload */
2203 tlen = sizeof(*isakmp)
2204 + sizeof(*gen) + hash->l
2205 + body->l;
2206 buf = vmalloc(tlen);
2207 if (buf == NULL) {
65c25746 2208 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2209 "failed to get buffer to send.\n");
2210 goto end;
2211 }
2212
2213 /* re-set encryption flag, for serurity. */
2214 iph2->flags |= ISAKMP_FLAG_E;
2215
2216 /* set isakmp header */
2217 p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
d1e348cf 2218 if (p == NULL) {
65c25746 2219 plog(ASL_LEVEL_ERR,
d1e348cf 2220 "failed to set ISAKMP header");
52b7d2ce 2221 goto end;
d1e348cf 2222 }
52b7d2ce
A
2223
2224 /* add HASH payload */
2225 /* XXX is next type always SA ? */
2226 p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_SA);
2227
2228 /* add body payload */
2229 memcpy(p, body->v, body->l);
2230
2231#ifdef HAVE_PRINT_ISAKMP_C
2232 isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
2233#endif
2234
2235 /* encoding */
2236 new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
d1e348cf 2237 if (new == NULL) {
65c25746 2238 plog(ASL_LEVEL_ERR,
d1e348cf 2239 "failed to encrypt packet");
52b7d2ce 2240 goto end;
d1e348cf 2241 }
52b7d2ce
A
2242
2243 vfree(buf);
2244
2245 buf = new;
2246
2247 error = 0;
2248
2249end:
2250 if (error && buf != NULL) {
2251 vfree(buf);
2252 buf = NULL;
2253 }
2254
2255 return buf;
2256}
2257
2258/*
2259 * get remote's sainfo.
2260 * NOTE: this function is for responder.
2261 */
65c25746 2262int
52b7d2ce 2263get_sainfo_r(iph2)
65c25746 2264 phase2_handle_t *iph2;
52b7d2ce
A
2265{
2266 vchar_t *idsrc = NULL, *iddst = NULL;
2267 int prefixlen;
2268 int error = ISAKMP_INTERNAL_ERROR;
47612122 2269 struct sainfo *anonymous = NULL;
52b7d2ce 2270
47612122 2271 if (iph2->id == NULL) {
85f41bec 2272 switch (iph2->src->ss_family) {
52b7d2ce
A
2273 case AF_INET:
2274 prefixlen = sizeof(struct in_addr) << 3;
2275 break;
2276 case AF_INET6:
2277 prefixlen = sizeof(struct in6_addr) << 3;
2278 break;
2279 default:
65c25746 2280 plog(ASL_LEVEL_ERR,
85f41bec 2281 "invalid family: %d\n", iph2->src->ss_family);
52b7d2ce
A
2282 goto end;
2283 }
2284 idsrc = ipsecdoi_sockaddr2id(iph2->src, prefixlen,
2285 IPSEC_ULPROTO_ANY);
2286 } else {
2287 idsrc = vdup(iph2->id);
2288 }
2289 if (idsrc == NULL) {
65c25746 2290 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2291 "failed to set ID for source.\n");
2292 goto end;
2293 }
2294
47612122 2295 if (iph2->id_p == NULL) {
85f41bec 2296 switch (iph2->dst->ss_family) {
52b7d2ce
A
2297 case AF_INET:
2298 prefixlen = sizeof(struct in_addr) << 3;
2299 break;
2300 case AF_INET6:
2301 prefixlen = sizeof(struct in6_addr) << 3;
2302 break;
2303 default:
65c25746 2304 plog(ASL_LEVEL_ERR,
85f41bec 2305 "invalid family: %d\n", iph2->dst->ss_family);
52b7d2ce
A
2306 goto end;
2307 }
2308 iddst = ipsecdoi_sockaddr2id(iph2->dst, prefixlen,
2309 IPSEC_ULPROTO_ANY);
2310 } else {
2311 iddst = vdup(iph2->id_p);
2312 }
2313 if (iddst == NULL) {
65c25746 2314 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2315 "failed to set ID for destination.\n");
2316 goto end;
2317 }
2318
05434fec 2319 iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p, 0);
47612122
A
2320 // track anonymous sainfo, because we'll try to find a better sainfo if this is a client
2321 if (iph2->sainfo && iph2->sainfo->idsrc == NULL)
2322 anonymous = iph2->sainfo;
2323
2324 if (iph2->sainfo == NULL ||
2325 (anonymous && iph2->parent_session && iph2->parent_session->is_client)) {
05434fec
A
2326 if ((iph2->ph1->natt_flags & NAT_DETECTED_ME) && lcconf->ext_nat_id != NULL)
2327 iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p, 1);
47612122 2328 if (iph2->sainfo) {
65c25746 2329 plog(ASL_LEVEL_DEBUG,
47612122
A
2330 "get_sainfo_r case 1.\n");
2331 }
2332 // still no sainfo (or anonymous): for client, fallback to sainfo used by a previous established phase2
2333 if (iph2->sainfo == NULL ||
2334 (iph2->sainfo->idsrc == NULL && iph2->parent_session && iph2->parent_session->is_client)) {
2335 ike_session_get_sainfo_r(iph2);
2336 if (iph2->sainfo) {
65c25746 2337 plog(ASL_LEVEL_DEBUG,
47612122
A
2338 "get_sainfo_r case 2.\n");
2339 }
b8c37798
A
2340 // still no sainfo (or anonymous): fallback to sainfo picked by dst id
2341 if ((iph2->sainfo == NULL || iph2->sainfo->idsrc == NULL) && iph2->id_p) {
65c25746 2342 plog(ASL_LEVEL_DEBUG,
b8c37798
A
2343 "get_sainfo_r about to try dst id only.\n");
2344 iph2->sainfo = getsainfo_by_dst_id(iph2->id_p, iph2->ph1->id_p);
2345 if (iph2->sainfo) {
65c25746 2346 plog(ASL_LEVEL_DEBUG,
b8c37798
A
2347 "get_sainfo_r case 3.\n");
2348 if (iph2->sainfo->idsrc == NULL)
2349 anonymous = iph2->sainfo;
2350 }
2351 }
47612122
A
2352 }
2353 }
52b7d2ce 2354 if (iph2->sainfo == NULL) {
47612122 2355 if (anonymous == NULL) {
65c25746 2356 plog(ASL_LEVEL_ERR,
47612122
A
2357 "failed to get sainfo.\n");
2358 goto end;
2359 }
2360 iph2->sainfo = anonymous;
52b7d2ce 2361 }
65c25746
A
2362 retain_sainfo(iph2->sainfo);
2363
d1e348cf
A
2364#ifdef ENABLE_HYBRID
2365 /* xauth group inclusion check */
2366 if (iph2->sainfo->group != NULL)
2367 if(group_check(iph2->ph1,&iph2->sainfo->group->v,1)) {
65c25746 2368 plog(ASL_LEVEL_ERR,
d1e348cf
A
2369 "failed to group check");
2370 goto end;
2371 }
2372#endif
52b7d2ce 2373
65c25746 2374 plog(ASL_LEVEL_DEBUG,
d1e348cf 2375 "selected sainfo: %s\n", sainfo2str(iph2->sainfo));
52b7d2ce
A
2376
2377 error = 0;
2378end:
2379 if (idsrc)
2380 vfree(idsrc);
2381 if (iddst)
2382 vfree(iddst);
2383
2384 return error;
2385}
2386
65c25746 2387int
80318cb7 2388get_proposal_r(iph2)
65c25746 2389 phase2_handle_t *iph2;
80318cb7
A
2390{
2391 int error = get_proposal_r_remote(iph2, 0);
2392 if (error != -2 && error != 0 &&
2393 (((iph2->ph1->natt_flags & NAT_DETECTED_ME) && lcconf->ext_nat_id != NULL) ||
2394 (iph2->parent_session && iph2->parent_session->is_client))) {
2395 if (iph2->parent_session && iph2->parent_session->is_client)
2396 error = ike_session_get_proposal_r(iph2);
2397 if (error != -2 && error != 0)
2398 error = get_proposal_r_remote(iph2, 1);
2399 }
2400 return error;
2401}
2402
52b7d2ce
A
2403/*
2404 * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
2405 * are IP address and same address family.
2406 * Then get remote's policy from SPD copied from kernel.
2407 * If the type of ID payload is address or subnet type, then the index is
2408 * made from the payload. If there is no ID payload, or the type of ID
2409 * payload is NOT address type, then the index is made from the address
2410 * pair of phase 1.
2411 * NOTE: This function is only for responder.
2412 */
2413static int
b8c37798 2414get_proposal_r_remote(iph2, ignore_id)
65c25746 2415 phase2_handle_t *iph2;
b8c37798 2416 int ignore_id;
52b7d2ce
A
2417{
2418 struct policyindex spidx;
2419 struct secpolicy *sp_in, *sp_out;
2420 int idi2type = 0; /* switch whether copy IDs into id[src,dst]. */
2421 int error = ISAKMP_INTERNAL_ERROR;
65c25746 2422 int generated_policy_exit_early = 0;
52b7d2ce
A
2423
2424 /* check the existence of ID payload */
2425 if ((iph2->id_p != NULL && iph2->id == NULL)
2426 || (iph2->id_p == NULL && iph2->id != NULL)) {
65c25746 2427 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2428 "Both IDs wasn't found in payload.\n");
2429 return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2430 }
2431
b8c37798
A
2432 /* make sure if id[src,dst] is null (if use_remote_addr == 0). */
2433 if (!ignore_id && (iph2->src_id || iph2->dst_id)) {
65c25746 2434 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2435 "Why do ID[src,dst] exist already.\n");
2436 return ISAKMP_INTERNAL_ERROR;
2437 }
2438
65c25746 2439 plog(ASL_LEVEL_DEBUG,
b8c37798
A
2440 "%s: ignore_id %x.\n", __FUNCTION__, ignore_id);
2441
52b7d2ce
A
2442 memset(&spidx, 0, sizeof(spidx));
2443
85f41bec 2444#define _XIDT(d) (ALIGNED_CAST(struct ipsecdoi_id_b *)((d)->v))->type
52b7d2ce
A
2445 /* make a spidx; a key to search SPD */
2446 spidx.dir = IPSEC_DIR_INBOUND;
2447 spidx.ul_proto = 0;
2448
2449 /*
2450 * make destination address in spidx from either ID payload
2451 * or phase 1 address into a address in spidx.
05434fec
A
2452 * If behind a nat - use phase1 address because server's
2453 * use the nat's address in the ID payload.
52b7d2ce
A
2454 */
2455 if (iph2->id != NULL
b8c37798 2456 && ignore_id == 0
52b7d2ce
A
2457 && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
2458 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
2459 || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2460 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
2461 /* get a destination address of a policy */
85f41bec 2462 error = ipsecdoi_id2sockaddr(iph2->id, &spidx.dst,
65c25746 2463 &spidx.prefd, &spidx.ul_proto, iph2->version);
52b7d2ce
A
2464 if (error)
2465 return error;
2466
2467#ifdef INET6
2468 /*
2469 * get scopeid from the SA address.
2470 * note that the phase 1 source address is used as
2471 * a destination address to search for a inbound policy entry
2472 * because rcoon is responder.
2473 */
2474 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
85f41bec 2475 error = setscopeid(&spidx.dst, iph2->src);
52b7d2ce
A
2476 if (error)
2477 return error;
2478 }
2479#endif
2480
2481 if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
2482 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
2483 idi2type = _XIDT(iph2->id);
2484
2485 } else {
2486
65c25746
A
2487 plog(ASL_LEVEL_DEBUG,
2488 "Get a destination address of SP index "
2489 "from Phase 1 address "
52b7d2ce
A
2490 "due to no ID payloads found "
2491 "OR because ID type is not address.\n");
2492
2493 /*
2494 * copy the SOURCE address of IKE into the DESTINATION address
2495 * of the key to search the SPD because the direction of policy
2496 * is inbound.
2497 */
85f41bec 2498 memcpy(&spidx.dst, iph2->src, sysdep_sa_len((struct sockaddr *)iph2->src));
52b7d2ce
A
2499 switch (spidx.dst.ss_family) {
2500 case AF_INET:
05434fec
A
2501 {
2502 struct sockaddr_in *s = (struct sockaddr_in *)&spidx.dst;
2503 spidx.prefd = sizeof(struct in_addr) << 3;
2504 s->sin_port = htons(0);
2505 }
52b7d2ce
A
2506 break;
2507#ifdef INET6
2508 case AF_INET6:
2509 spidx.prefd = sizeof(struct in6_addr) << 3;
2510 break;
2511#endif
2512 default:
2513 spidx.prefd = 0;
2514 break;
2515 }
2516 }
2517
2518 /* make source address in spidx */
2519 if (iph2->id_p != NULL
b8c37798 2520 && ignore_id == 0
52b7d2ce
A
2521 && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
2522 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
2523 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2524 || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
2525 /* get a source address of inbound SA */
85f41bec 2526 error = ipsecdoi_id2sockaddr(iph2->id_p, &spidx.src,
65c25746 2527 &spidx.prefs, &spidx.ul_proto, iph2->version);
52b7d2ce
A
2528 if (error)
2529 return error;
2530
2531#ifdef INET6
2532 /*
2533 * get scopeid from the SA address.
2534 * for more detail, see above of this function.
2535 */
2536 if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
85f41bec 2537 error = setscopeid(&spidx.src, iph2->dst);
52b7d2ce
A
2538 if (error)
2539 return error;
2540 }
2541#endif
2542
2543 /* make id[src,dst] if both ID types are IP address and same */
2544 if (_XIDT(iph2->id_p) == idi2type
2545 && spidx.dst.ss_family == spidx.src.ss_family) {
65c25746 2546 iph2->src_id = dupsaddr(&spidx.dst);
d1e348cf 2547 if (iph2->src_id == NULL) {
65c25746 2548 plog(ASL_LEVEL_ERR,
d1e348cf
A
2549 "buffer allocation failed.\n");
2550 return ISAKMP_INTERNAL_ERROR;
2551 }
65c25746 2552 iph2->dst_id = dupsaddr(&spidx.src);
d1e348cf 2553 if (iph2->dst_id == NULL) {
65c25746 2554 plog(ASL_LEVEL_ERR,
d1e348cf
A
2555 "buffer allocation failed.\n");
2556 return ISAKMP_INTERNAL_ERROR;
2557 }
52b7d2ce
A
2558 }
2559
2560 } else {
65c25746
A
2561 plog(ASL_LEVEL_DEBUG,
2562 "Get a source address of SP index "
2563 "from Phase 1 address "
52b7d2ce
A
2564 "due to no ID payloads found "
2565 "OR because ID type is not address.\n");
2566
2567 /* see above comment. */
85f41bec 2568 memcpy(&spidx.src, iph2->dst, sysdep_sa_len((struct sockaddr *)iph2->dst));
52b7d2ce
A
2569 switch (spidx.src.ss_family) {
2570 case AF_INET:
05434fec
A
2571 {
2572 struct sockaddr_in *s = (struct sockaddr_in *)&spidx.src;
2573 spidx.prefs = sizeof(struct in_addr) << 3;
2574 s->sin_port = htons(0);
2575 }
52b7d2ce
A
2576 break;
2577#ifdef INET6
2578 case AF_INET6:
2579 spidx.prefs = sizeof(struct in6_addr) << 3;
2580 break;
2581#endif
2582 default:
2583 spidx.prefs = 0;
2584 break;
2585 }
2586 }
2587
2588#undef _XIDT
2589
65c25746 2590 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
2591 "get a src address from ID payload "
2592 "%s prefixlen=%u ul_proto=%u\n",
2593 saddr2str((struct sockaddr *)&spidx.src),
2594 spidx.prefs, spidx.ul_proto);
65c25746 2595 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
2596 "get dst address from ID payload "
2597 "%s prefixlen=%u ul_proto=%u\n",
2598 saddr2str((struct sockaddr *)&spidx.dst),
2599 spidx.prefd, spidx.ul_proto);
2600
2601 /*
2602 * convert the ul_proto if it is 0
2603 * because 0 in ID payload means a wild card.
2604 */
2605 if (spidx.ul_proto == 0)
2606 spidx.ul_proto = IPSEC_ULPROTO_ANY;
2607
2608 /* get inbound policy */
e97d2cf9 2609 sp_in = getsp_r(&spidx, iph2);
52b7d2ce
A
2610 if (sp_in == NULL || sp_in->policy == IPSEC_POLICY_GENERATE) {
2611 if (iph2->ph1->rmconf->gen_policy) {
d1e348cf 2612 if (sp_in)
65c25746 2613 plog(ASL_LEVEL_INFO,
d1e348cf
A
2614 "Update the generated policy : %s\n",
2615 spidx2str(&spidx));
2616 else
65c25746 2617 plog(ASL_LEVEL_INFO,
d1e348cf
A
2618 "no policy found, "
2619 "try to generate the policy : %s\n",
2620 spidx2str(&spidx));
85f41bec 2621 iph2->spidx_gen = (struct policyindex *)racoon_malloc(sizeof(spidx));
52b7d2ce 2622 if (!iph2->spidx_gen) {
65c25746 2623 plog(ASL_LEVEL_ERR,
d1e348cf 2624 "buffer allocation failed.\n");
52b7d2ce
A
2625 return ISAKMP_INTERNAL_ERROR;
2626 }
2627 memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
d1e348cf
A
2628 generated_policy_exit_early = 1; /* special value */
2629 } else {
65c25746 2630 plog(ASL_LEVEL_ERR,
d1e348cf 2631 "no policy found: %s\n", spidx2str(&spidx));
52b7d2ce
A
2632 return ISAKMP_INTERNAL_ERROR;
2633 }
52b7d2ce 2634 }
d1e348cf 2635
52b7d2ce
A
2636 /* get outbound policy */
2637 {
2638 struct sockaddr_storage addr;
2639 u_int8_t pref;
2640
2641 spidx.dir = IPSEC_DIR_OUTBOUND;
2642 addr = spidx.src;
2643 spidx.src = spidx.dst;
2644 spidx.dst = addr;
2645 pref = spidx.prefs;
2646 spidx.prefs = spidx.prefd;
2647 spidx.prefd = pref;
2648
e97d2cf9 2649 sp_out = getsp_r(&spidx, iph2);
52b7d2ce 2650 if (!sp_out) {
65c25746 2651 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
2652 "no outbound policy found: %s\n",
2653 spidx2str(&spidx));
d1e348cf
A
2654 } else {
2655
2656 if (!iph2->spid) {
2657 iph2->spid = sp_out->id;
2658 }
52b7d2ce
A
2659 }
2660 }
2661
65c25746 2662 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
2663 "suitable SP found:%s\n", spidx2str(&spidx));
2664
d1e348cf
A
2665 if (generated_policy_exit_early) {
2666 return -2;
2667 }
2668
52b7d2ce
A
2669 /*
2670 * In the responder side, the inbound policy should be using IPsec.
2671 * outbound policy is not checked currently.
2672 */
2673 if (sp_in->policy != IPSEC_POLICY_IPSEC) {
65c25746 2674 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2675 "policy found, but no IPsec required: %s\n",
2676 spidx2str(&spidx));
2677 return ISAKMP_INTERNAL_ERROR;
2678 }
2679
2680 /* set new proposal derived from a policy into the iph2->proposal. */
2681 if (set_proposal_from_policy(iph2, sp_in, sp_out) < 0) {
65c25746 2682 plog(ASL_LEVEL_ERR,
52b7d2ce
A
2683 "failed to create saprop.\n");
2684 return ISAKMP_INTERNAL_ERROR;
2685 }
2686
2687 return 0;
2688}