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