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