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