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