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