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