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