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