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