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