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