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