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