Annotation of embedaddon/ipsec-tools/src/racoon/isakmp.c, revision 1.1.1.1
1.1 misho 1: /* $NetBSD: isakmp.c,v 1.71 2011/03/15 13:20:14 vanhu Exp $ */
2:
3: /* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 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: #include <sys/queue.h>
40:
41: #include <netinet/in.h>
42: #include <arpa/inet.h>
43:
44: #include PATH_IPSEC_H
45:
46: #include <stdlib.h>
47: #include <stdio.h>
48: #include <string.h>
49: #include <errno.h>
50: #if TIME_WITH_SYS_TIME
51: # include <sys/time.h>
52: # include <time.h>
53: #else
54: # if HAVE_SYS_TIME_H
55: # include <sys/time.h>
56: # else
57: # include <time.h>
58: # endif
59: #endif
60: #include <netdb.h>
61: #ifdef HAVE_UNISTD_H
62: #include <unistd.h>
63: #endif
64: #include <ctype.h>
65: #ifdef ENABLE_HYBRID
66: #include <resolv.h>
67: #endif
68:
69: #include "var.h"
70: #include "misc.h"
71: #include "vmbuf.h"
72: #include "plog.h"
73: #include "sockmisc.h"
74: #include "schedule.h"
75: #include "session.h"
76: #include "debug.h"
77:
78: #include "remoteconf.h"
79: #include "localconf.h"
80: #include "grabmyaddr.h"
81: #include "admin.h"
82: #include "privsep.h"
83: #include "isakmp_var.h"
84: #include "isakmp.h"
85: #include "oakley.h"
86: #include "evt.h"
87: #include "handler.h"
88: #include "ipsec_doi.h"
89: #include "pfkey.h"
90: #include "crypto_openssl.h"
91: #include "policy.h"
92: #include "algorithm.h"
93: #include "proposal.h"
94: #include "sainfo.h"
95: #include "isakmp_ident.h"
96: #include "isakmp_agg.h"
97: #include "isakmp_base.h"
98: #include "isakmp_quick.h"
99: #include "isakmp_inf.h"
100: #include "isakmp_newg.h"
101: #ifdef ENABLE_HYBRID
102: #include "vendorid.h"
103: #include "isakmp_xauth.h"
104: #include "isakmp_unity.h"
105: #include "isakmp_cfg.h"
106: #endif
107: #ifdef ENABLE_FRAG
108: #include "isakmp_frag.h"
109: #endif
110: #include "strnames.h"
111:
112: #include <fcntl.h>
113:
114: #ifdef ENABLE_NATT
115: # include "nattraversal.h"
116: #endif
117: # ifdef __linux__
118: # include <linux/udp.h>
119: # include <linux/ip.h>
120: # ifndef SOL_UDP
121: # define SOL_UDP 17
122: # endif
123: # endif /* __linux__ */
124: # if defined(__NetBSD__) || defined(__FreeBSD__) || \
125: (defined(__APPLE__) && defined(__MACH__))
126: # include <netinet/in.h>
127: # include <netinet/udp.h>
128: # include <netinet/in_systm.h>
129: # include <netinet/ip.h>
130: # define SOL_UDP IPPROTO_UDP
131: # endif /* __NetBSD__ / __FreeBSD__ */
132:
133: static int nostate1 __P((struct ph1handle *, vchar_t *));
134: static int nostate2 __P((struct ph2handle *, vchar_t *));
135:
136: extern caddr_t val2str(const char *, size_t);
137:
138: static int (*ph1exchange[][2][PHASE1ST_MAX])
139: __P((struct ph1handle *, vchar_t *)) = {
140: /* error */
141: { { 0 }, { 0 }, },
142: /* Identity Protection exchange */
143: {
144: { nostate1, ident_i1send, nostate1, ident_i2recv, ident_i2send,
145: ident_i3recv, ident_i3send, ident_i4recv, ident_i4send, nostate1, nostate1,},
146: { nostate1, ident_r1recv, ident_r1send, ident_r2recv, ident_r2send,
147: ident_r3recv, ident_r3send, nostate1, nostate1, nostate1, nostate1, },
148: },
149: /* Aggressive exchange */
150: {
151: { nostate1, agg_i1send, nostate1, agg_i2recv, agg_i2send,
152: nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, },
153: { nostate1, agg_r1recv, agg_r1send, agg_r2recv, agg_r2send,
154: nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, },
155: },
156: /* Base exchange */
157: {
158: { nostate1, base_i1send, nostate1, base_i2recv, base_i2send,
159: base_i3recv, base_i3send, nostate1, nostate1, nostate1, nostate1, },
160: { nostate1, base_r1recv, base_r1send, base_r2recv, base_r2send,
161: nostate1, nostate1, nostate1, nostate1, nostate1, nostate1, },
162: },
163: };
164:
165: static int (*ph2exchange[][2][PHASE2ST_MAX])
166: __P((struct ph2handle *, vchar_t *)) = {
167: /* error */
168: { { 0 }, { 0 }, },
169: /* Quick mode for IKE */
170: {
171: { nostate2, nostate2, quick_i1prep, nostate2, quick_i1send,
172: quick_i2recv, quick_i2send, quick_i3recv, nostate2, nostate2, },
173: { nostate2, quick_r1recv, quick_r1prep, nostate2, quick_r2send,
174: quick_r3recv, quick_r3prep, quick_r3send, nostate2, nostate2, }
175: },
176: };
177:
178: static u_char r_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the r_ck. */
179:
180: static int isakmp_main __P((vchar_t *, struct sockaddr *, struct sockaddr *));
181: static int ph1_main __P((struct ph1handle *, vchar_t *));
182: static int quick_main __P((struct ph2handle *, vchar_t *));
183: static int isakmp_ph1begin_r __P((vchar_t *,
184: struct sockaddr *, struct sockaddr *, u_int8_t));
185: static int isakmp_ph2begin_i __P((struct ph1handle *, struct ph2handle *));
186: static int isakmp_ph2begin_r __P((struct ph1handle *, vchar_t *));
187: static int etypesw1 __P((int));
188: static int etypesw2 __P((int));
189: static int isakmp_ph1resend __P((struct ph1handle *));
190: static int isakmp_ph2resend __P((struct ph2handle *));
191:
192: #ifdef ENABLE_FRAG
193: static int frag_handler(struct ph1handle *,
194: vchar_t *, struct sockaddr *, struct sockaddr *);
195: #endif
196:
197: /*
198: * isakmp packet handler
199: */
200: static int
201: isakmp_handler(ctx, so_isakmp)
202: void *ctx;
203: int so_isakmp;
204: {
205: struct isakmp isakmp;
206: union {
207: char buf[sizeof (isakmp) + 4];
208: u_int32_t non_esp[2];
209: struct {
210: struct udphdr udp;
211: #ifdef __linux
212: struct iphdr ip;
213: #else
214: struct ip ip;
215: #endif
216: char buf[sizeof(isakmp) + 4];
217: } lbuf;
218: } x;
219: struct sockaddr_storage remote;
220: struct sockaddr_storage local;
221: unsigned int remote_len = sizeof(remote);
222: unsigned int local_len = sizeof(local);
223: int len = 0, extralen = 0;
224: vchar_t *buf = NULL, *tmpbuf = NULL;
225: int error = -1, res;
226:
227: /* read message by MSG_PEEK */
228: while ((len = recvfromto(so_isakmp, x.buf, sizeof(x),
229: MSG_PEEK, (struct sockaddr *)&remote, &remote_len,
230: (struct sockaddr *)&local, &local_len)) < 0) {
231: if (errno == EINTR)
232: continue;
233: plog(LLV_ERROR, LOCATION, NULL,
234: "failed to receive isakmp packet: %s\n",
235: strerror (errno));
236: goto end;
237: }
238:
239: /* keep-alive packet - ignore */
240: if (len == 1 && (x.buf[0]&0xff) == 0xff) {
241: /* Pull the keep-alive packet */
242: if ((len = recvfrom(so_isakmp, (char *)x.buf, 1,
243: 0, (struct sockaddr *)&remote, &remote_len)) != 1) {
244: plog(LLV_ERROR, LOCATION, NULL,
245: "failed to receive keep alive packet: %s\n",
246: strerror (errno));
247: }
248: goto end;
249: }
250:
251: /* Lucent IKE in UDP encapsulation */
252: {
253: #ifdef __linux__
254: if (ntohs(x.lbuf.udp.dest) == 501) {
255: extralen += sizeof(x.lbuf.udp) + x.lbuf.ip.ihl;
256: }
257: #else
258: if (ntohs(x.lbuf.udp.uh_dport) == 501) {
259: extralen += sizeof(x.lbuf.udp) + x.lbuf.ip.ip_hl;
260: }
261: #endif
262: }
263:
264: #ifdef ENABLE_NATT
265: /* we don't know about portchange yet,
266: look for non-esp marker instead */
267: if (x.non_esp[0] == 0 && x.non_esp[1] != 0)
268: extralen = NON_ESP_MARKER_LEN;
269: #endif
270:
271: /* now we know if there is an extra non-esp
272: marker at the beginning or not */
273: memcpy ((char *)&isakmp, x.buf + extralen, sizeof (isakmp));
274:
275: /* check isakmp header length, as well as sanity of header length */
276: if (len < sizeof(isakmp) || ntohl(isakmp.len) < sizeof(isakmp)) {
277: plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
278: "packet shorter than isakmp header size (%u, %u, %zu)\n",
279: len, ntohl(isakmp.len), sizeof(isakmp));
280: /* dummy receive */
281: if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
282: 0, (struct sockaddr *)&remote, &remote_len)) < 0) {
283: plog(LLV_ERROR, LOCATION, NULL,
284: "failed to receive isakmp packet: %s\n",
285: strerror (errno));
286: }
287: goto end;
288: }
289:
290: /* reject it if the size is tooooo big. */
291: if (ntohl(isakmp.len) > 0xffff) {
292: plog(LLV_ERROR, LOCATION, NULL,
293: "the length in the isakmp header is too big.\n");
294: if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
295: 0, (struct sockaddr *)&remote, &remote_len)) < 0) {
296: plog(LLV_ERROR, LOCATION, NULL,
297: "failed to receive isakmp packet: %s\n",
298: strerror (errno));
299: }
300: goto end;
301: }
302:
303: /* read real message */
304: if ((tmpbuf = vmalloc(ntohl(isakmp.len) + extralen)) == NULL) {
305: plog(LLV_ERROR, LOCATION, NULL,
306: "failed to allocate reading buffer (%u Bytes)\n",
307: ntohl(isakmp.len) + extralen);
308: /* dummy receive */
309: if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
310: 0, (struct sockaddr *)&remote, &remote_len)) < 0) {
311: plog(LLV_ERROR, LOCATION, NULL,
312: "failed to receive isakmp packet: %s\n",
313: strerror (errno));
314: }
315: goto end;
316: }
317:
318: while ((len = recvfromto(so_isakmp, (char *)tmpbuf->v, tmpbuf->l,
319: 0, (struct sockaddr *)&remote, &remote_len,
320: (struct sockaddr *)&local, &local_len)) < 0) {
321: if (errno == EINTR)
322: continue;
323: plog(LLV_ERROR, LOCATION, NULL,
324: "failed to receive isakmp packet: %s\n",
325: strerror (errno));
326: goto end;
327: }
328:
329: if ((buf = vmalloc(len - extralen)) == NULL) {
330: plog(LLV_ERROR, LOCATION, NULL,
331: "failed to allocate reading buffer (%u Bytes)\n",
332: (len - extralen));
333: goto end;
334: }
335:
336: memcpy (buf->v, tmpbuf->v + extralen, buf->l);
337:
338: len -= extralen;
339:
340: if (len != buf->l) {
341: plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
342: "received invalid length (%d != %zu), why ?\n",
343: len, buf->l);
344: goto end;
345: }
346:
347: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
348: plog(LLV_DEBUG, LOCATION, NULL,
349: "%d bytes message received %s\n",
350: len, saddr2str_fromto("from %s to %s",
351: (struct sockaddr *)&remote,
352: (struct sockaddr *)&local));
353: plogdump(LLV_DEBUG, buf->v, buf->l);
354:
355: /* avoid packets with malicious port/address */
356: if (extract_port((struct sockaddr *)&remote) == 0) {
357: plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
358: "src port == 0 (valid as UDP but not with IKE)\n");
359: goto end;
360: }
361:
362: /* XXX: check sender whether to be allowed or not to accept */
363:
364: /* XXX: I don't know how to check isakmp half connection attack. */
365:
366: /* simply reply if the packet was processed. */
367: res=check_recvdpkt((struct sockaddr *)&remote,(struct sockaddr *)&local, buf);
368: if (res) {
369: plog(LLV_NOTIFY, LOCATION, NULL,
370: "the packet is retransmitted by %s (%d).\n",
371: saddr2str((struct sockaddr *)&remote), res);
372: error = 0;
373: goto end;
374: }
375:
376: /* isakmp main routine */
377: if (isakmp_main(buf, (struct sockaddr *)&remote,
378: (struct sockaddr *)&local) != 0) goto end;
379:
380: error = 0;
381:
382: end:
383: if (tmpbuf != NULL)
384: vfree(tmpbuf);
385: if (buf != NULL)
386: vfree(buf);
387: return error;
388: }
389:
390: /*
391: * main processing to handle isakmp payload
392: */
393: static int
394: isakmp_main(msg, remote, local)
395: vchar_t *msg;
396: struct sockaddr *remote, *local;
397: {
398: struct isakmp *isakmp = (struct isakmp *)msg->v;
399: isakmp_index *index = (isakmp_index *)isakmp;
400: u_int32_t msgid = isakmp->msgid;
401: struct ph1handle *iph1;
402:
403: #ifdef HAVE_PRINT_ISAKMP_C
404: isakmp_printpacket(msg, remote, local, 0);
405: #endif
406:
407: /* the initiator's cookie must not be zero */
408: if (memcmp(&isakmp->i_ck, r_ck0, sizeof(cookie_t)) == 0) {
409: plog(LLV_ERROR, LOCATION, remote,
410: "malformed cookie received.\n");
411: return -1;
412: }
413:
414: /* Check the Major and Minor Version fields. */
415: /*
416: * XXX Is is right to check version here ?
417: * I think it may no be here because the version depends
418: * on exchange status.
419: */
420: if (isakmp->v < ISAKMP_VERSION_NUMBER) {
421: if (ISAKMP_GETMAJORV(isakmp->v) < ISAKMP_MAJOR_VERSION) {
422: plog(LLV_ERROR, LOCATION, remote,
423: "invalid major version %d.\n",
424: ISAKMP_GETMAJORV(isakmp->v));
425: return -1;
426: }
427: #if ISAKMP_MINOR_VERSION > 0
428: if (ISAKMP_GETMINORV(isakmp->v) < ISAKMP_MINOR_VERSION) {
429: plog(LLV_ERROR, LOCATION, remote,
430: "invalid minor version %d.\n",
431: ISAKMP_GETMINORV(isakmp->v));
432: return -1;
433: }
434: #endif
435: }
436:
437: /* check the Flags field. */
438: /* XXX How is the exclusive check, E and A ? */
439: if (isakmp->flags & ~(ISAKMP_FLAG_E | ISAKMP_FLAG_C | ISAKMP_FLAG_A)) {
440: plog(LLV_ERROR, LOCATION, remote,
441: "invalid flag 0x%02x.\n", isakmp->flags);
442: return -1;
443: }
444:
445: /* ignore commit bit. */
446: if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) {
447: if (isakmp->msgid == 0) {
448: isakmp_info_send_nx(isakmp, remote, local,
449: ISAKMP_NTYPE_INVALID_FLAGS, NULL);
450: plog(LLV_ERROR, LOCATION, remote,
451: "Commit bit on phase1 forbidden.\n");
452: return -1;
453: }
454: }
455:
456: iph1 = getph1byindex(index);
457: if (iph1 != NULL) {
458: /* validity check */
459: if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 &&
460: iph1->side == INITIATOR) {
461: plog(LLV_DEBUG, LOCATION, remote,
462: "malformed cookie received or "
463: "the initiator's cookies collide.\n");
464: return -1;
465: }
466:
467: #ifdef ENABLE_NATT
468: /* Floating ports for NAT-T */
469: if (NATT_AVAILABLE(iph1) &&
470: ! (iph1->natt_flags & NAT_PORTS_CHANGED) &&
471: ((cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) ||
472: (cmpsaddr(iph1->local, local) != CMPSADDR_MATCH)))
473: {
474: /* prevent memory leak */
475: racoon_free(iph1->remote);
476: racoon_free(iph1->local);
477: iph1->remote = NULL;
478: iph1->local = NULL;
479:
480: /* copy-in new addresses */
481: iph1->remote = dupsaddr(remote);
482: if (iph1->remote == NULL) {
483: plog(LLV_ERROR, LOCATION, iph1->remote,
484: "phase1 failed: dupsaddr failed.\n");
485: remph1(iph1);
486: delph1(iph1);
487: return -1;
488: }
489: iph1->local = dupsaddr(local);
490: if (iph1->local == NULL) {
491: plog(LLV_ERROR, LOCATION, iph1->remote,
492: "phase1 failed: dupsaddr failed.\n");
493: remph1(iph1);
494: delph1(iph1);
495: return -1;
496: }
497:
498: /* set the flag to prevent further port floating
499: (FIXME: should we allow it? E.g. when the NAT gw
500: is rebooted?) */
501: iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
502:
503: /* print some neat info */
504: plog (LLV_INFO, LOCATION, NULL,
505: "NAT-T: ports changed to: %s\n",
506: saddr2str_fromto ("%s<->%s", iph1->remote, iph1->local));
507:
508: natt_keepalive_add_ph1 (iph1);
509: }
510: #endif
511:
512: /* must be same addresses in one stream of a phase at least. */
513: if (cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) {
514: char *saddr_db, *saddr_act;
515:
516: saddr_db = racoon_strdup(saddr2str(iph1->remote));
517: saddr_act = racoon_strdup(saddr2str(remote));
518: STRDUP_FATAL(saddr_db);
519: STRDUP_FATAL(saddr_act);
520:
521: plog(LLV_WARNING, LOCATION, remote,
522: "remote address mismatched. db=%s, act=%s\n",
523: saddr_db, saddr_act);
524:
525: racoon_free(saddr_db);
526: racoon_free(saddr_act);
527: }
528:
529: /*
530: * don't check of exchange type here because other type will be
531: * with same index, for example, informational exchange.
532: */
533:
534: /* XXX more acceptable check */
535: }
536:
537: switch (isakmp->etype) {
538: case ISAKMP_ETYPE_IDENT:
539: case ISAKMP_ETYPE_AGG:
540: case ISAKMP_ETYPE_BASE:
541: /* phase 1 validity check */
542: if (isakmp->msgid != 0) {
543: plog(LLV_ERROR, LOCATION, remote,
544: "message id should be zero in phase1.\n");
545: return -1;
546: }
547:
548: /* search for isakmp status record of phase 1 */
549: if (iph1 == NULL) {
550: /*
551: * the packet must be the 1st message from a initiator
552: * or the 2nd message from the responder.
553: */
554:
555: /* search for phase1 handle by index without r_ck */
556: iph1 = getph1byindex0(index);
557: if (iph1 == NULL) {
558: /*it must be the 1st message from a initiator.*/
559: if (memcmp(&isakmp->r_ck, r_ck0,
560: sizeof(cookie_t)) != 0) {
561:
562: plog(LLV_DEBUG, LOCATION, remote,
563: "malformed cookie received "
564: "or the spi expired.\n");
565: return -1;
566: }
567:
568: /* it must be responder's 1st exchange. */
569: if (isakmp_ph1begin_r(msg, remote, local,
570: isakmp->etype) < 0)
571: return -1;
572: break;
573:
574: /*NOTREACHED*/
575: }
576:
577: /* it must be the 2nd message from the responder. */
578: if (iph1->side != INITIATOR) {
579: plog(LLV_DEBUG, LOCATION, remote,
580: "malformed cookie received. "
581: "it has to be as the initiator. %s\n",
582: isakmp_pindex(&iph1->index, 0));
583: return -1;
584: }
585: }
586:
587: /*
588: * Don't delete phase 1 handler when the exchange type
589: * in handler is not equal to packet's one because of no
590: * authencication completed.
591: */
592: if (iph1->etype != isakmp->etype) {
593: plog(LLV_ERROR, LOCATION, iph1->remote,
594: "exchange type is mismatched: "
595: "db=%s packet=%s, ignore it.\n",
596: s_isakmp_etype(iph1->etype),
597: s_isakmp_etype(isakmp->etype));
598: return -1;
599: }
600:
601: #ifdef ENABLE_FRAG
602: if (isakmp->np == ISAKMP_NPTYPE_FRAG)
603: return frag_handler(iph1, msg, remote, local);
604: #endif
605:
606: /* call main process of phase 1 */
607: if (ph1_main(iph1, msg) < 0) {
608: plog(LLV_ERROR, LOCATION, iph1->remote,
609: "phase1 negotiation failed.\n");
610: remph1(iph1);
611: delph1(iph1);
612: return -1;
613: }
614: break;
615:
616: case ISAKMP_ETYPE_AUTH:
617: plog(LLV_INFO, LOCATION, remote,
618: "unsupported exchange %d received.\n",
619: isakmp->etype);
620: break;
621:
622: case ISAKMP_ETYPE_INFO:
623: case ISAKMP_ETYPE_ACKINFO:
624: /*
625: * iph1 must be present for Information message.
626: * if iph1 is null then trying to get the phase1 status
627: * as the packet from responder againt initiator's 1st
628: * exchange in phase 1.
629: * NOTE: We think such informational exchange should be ignored.
630: */
631: if (iph1 == NULL) {
632: iph1 = getph1byindex0(index);
633: if (iph1 == NULL) {
634: plog(LLV_ERROR, LOCATION, remote,
635: "unknown Informational "
636: "exchange received.\n");
637: return -1;
638: }
639: if (cmpsaddr(iph1->remote, remote) != CMPSADDR_MATCH) {
640: plog(LLV_WARNING, LOCATION, remote,
641: "remote address mismatched. "
642: "db=%s\n",
643: saddr2str(iph1->remote));
644: }
645: }
646:
647: #ifdef ENABLE_FRAG
648: if (isakmp->np == ISAKMP_NPTYPE_FRAG)
649: return frag_handler(iph1, msg, remote, local);
650: #endif
651:
652: if (isakmp_info_recv(iph1, msg) < 0)
653: return -1;
654: break;
655:
656: case ISAKMP_ETYPE_QUICK:
657: {
658: struct ph2handle *iph2;
659:
660: if (iph1 == NULL) {
661: isakmp_info_send_nx(isakmp, remote, local,
662: ISAKMP_NTYPE_INVALID_COOKIE, NULL);
663: plog(LLV_ERROR, LOCATION, remote,
664: "can't start the quick mode, "
665: "there is no ISAKMP-SA, %s\n",
666: isakmp_pindex((isakmp_index *)&isakmp->i_ck,
667: isakmp->msgid));
668: return -1;
669: }
670: #ifdef ENABLE_HYBRID
671: /* Reinit the IVM if it's still there */
672: if (iph1->mode_cfg && iph1->mode_cfg->ivm) {
673: oakley_delivm(iph1->mode_cfg->ivm);
674: iph1->mode_cfg->ivm = NULL;
675: }
676: #endif
677: #ifdef ENABLE_FRAG
678: if (isakmp->np == ISAKMP_NPTYPE_FRAG)
679: return frag_handler(iph1, msg, remote, local);
680: #endif
681:
682: /* check status of phase 1 whether negotiated or not. */
683: if (iph1->status != PHASE1ST_ESTABLISHED &&
684: iph1->status != PHASE1ST_DYING) {
685: plog(LLV_ERROR, LOCATION, remote,
686: "can't start the quick mode, "
687: "there is no valid ISAKMP-SA, %s\n",
688: isakmp_pindex(&iph1->index, iph1->msgid));
689: return -1;
690: }
691:
692: /* search isakmp phase 2 stauts record. */
693: iph2 = getph2bymsgid(iph1, msgid);
694: if (iph2 == NULL) {
695: /* it must be new negotiation as responder */
696: if (isakmp_ph2begin_r(iph1, msg) < 0)
697: return -1;
698: return 0;
699: /*NOTREACHED*/
700: }
701:
702: /* commit bit. */
703: /* XXX
704: * we keep to set commit bit during negotiation.
705: * When SA is configured, bit will be reset.
706: * XXX
707: * don't initiate commit bit. should be fixed in the future.
708: */
709: if (ISSET(isakmp->flags, ISAKMP_FLAG_C))
710: iph2->flags |= ISAKMP_FLAG_C;
711:
712: /* call main process of quick mode */
713: if (quick_main(iph2, msg) < 0) {
714: plog(LLV_ERROR, LOCATION, iph1->remote,
715: "phase2 negotiation failed.\n");
716: remph2(iph2);
717: delph2(iph2);
718: return -1;
719: }
720: }
721: break;
722:
723: case ISAKMP_ETYPE_NEWGRP:
724: if (iph1 == NULL) {
725: plog(LLV_ERROR, LOCATION, remote,
726: "Unknown new group mode exchange, "
727: "there is no ISAKMP-SA.\n");
728: return -1;
729: }
730:
731: #ifdef ENABLE_FRAG
732: if (isakmp->np == ISAKMP_NPTYPE_FRAG)
733: return frag_handler(iph1, msg, remote, local);
734: #endif
735:
736: isakmp_newgroup_r(iph1, msg);
737: break;
738:
739: #ifdef ENABLE_HYBRID
740: case ISAKMP_ETYPE_CFG:
741: if (iph1 == NULL) {
742: plog(LLV_ERROR, LOCATION, NULL,
743: "mode config %d from %s, "
744: "but we have no ISAKMP-SA.\n",
745: isakmp->etype, saddr2str(remote));
746: return -1;
747: }
748:
749: #ifdef ENABLE_FRAG
750: if (isakmp->np == ISAKMP_NPTYPE_FRAG)
751: return frag_handler(iph1, msg, remote, local);
752: #endif
753:
754: isakmp_cfg_r(iph1, msg);
755: break;
756: #endif
757:
758: case ISAKMP_ETYPE_NONE:
759: default:
760: plog(LLV_ERROR, LOCATION, NULL,
761: "Invalid exchange type %d from %s.\n",
762: isakmp->etype, saddr2str(remote));
763: return -1;
764: }
765:
766: return 0;
767: }
768:
769: /*
770: * main function of phase 1.
771: */
772: static int
773: ph1_main(iph1, msg)
774: struct ph1handle *iph1;
775: vchar_t *msg;
776: {
777: int error;
778: #ifdef ENABLE_STATS
779: struct timeval start, end;
780: #endif
781:
782: /* ignore a packet */
783: if (iph1->status >= PHASE1ST_ESTABLISHED)
784: return 0;
785:
786: #ifdef ENABLE_STATS
787: gettimeofday(&start, NULL);
788: #endif
789: /* receive */
790: if (ph1exchange[etypesw1(iph1->etype)]
791: [iph1->side]
792: [iph1->status] == NULL) {
793: plog(LLV_ERROR, LOCATION, iph1->remote,
794: "why isn't the function defined.\n");
795: return -1;
796: }
797: error = (ph1exchange[etypesw1(iph1->etype)]
798: [iph1->side]
799: [iph1->status])(iph1, msg);
800: if (error != 0) {
801:
802: /* XXX
803: * When an invalid packet is received on phase1, it should
804: * be selected to process this packet. That is to respond
805: * with a notify and delete phase 1 handler, OR not to respond
806: * and keep phase 1 handler. However, in PHASE1ST_START when
807: * acting as RESPONDER we must not keep phase 1 handler or else
808: * it will stay forever.
809: */
810:
811: if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) {
812: plog(LLV_ERROR, LOCATION, iph1->remote,
813: "failed to pre-process ph1 packet (side: %d, status %d).\n",
814: iph1->side, iph1->status);
815: return -1;
816: } else {
817: /* ignore the error and keep phase 1 handler */
818: return 0;
819: }
820: }
821:
822: #ifndef ENABLE_FRAG
823: /* free resend buffer */
824: if (iph1->sendbuf == NULL) {
825: plog(LLV_ERROR, LOCATION, NULL,
826: "no buffer found as sendbuf\n");
827: return -1;
828: }
829: #endif
830:
831: VPTRINIT(iph1->sendbuf);
832:
833: /* turn off schedule */
834: sched_cancel(&iph1->scr);
835:
836: /* send */
837: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
838: if ((ph1exchange[etypesw1(iph1->etype)]
839: [iph1->side]
840: [iph1->status])(iph1, msg) != 0) {
841: plog(LLV_ERROR, LOCATION, iph1->remote,
842: "failed to process ph1 packet (side: %d, status: %d).\n",
843: iph1->side, iph1->status);
844: return -1;
845: }
846:
847: #ifdef ENABLE_STATS
848: gettimeofday(&end, NULL);
849: syslog(LOG_NOTICE, "%s(%s): %8.6f",
850: "phase1", s_isakmp_state(iph1->etype, iph1->side, iph1->status),
851: timedelta(&start, &end));
852: #endif
853: if (iph1->status == PHASE1ST_ESTABLISHED) {
854:
855: #ifdef ENABLE_STATS
856: gettimeofday(&iph1->end, NULL);
857: syslog(LOG_NOTICE, "%s(%s): %8.6f",
858: "phase1", s_isakmp_etype(iph1->etype),
859: timedelta(&iph1->start, &iph1->end));
860: #endif
861:
862: /* save created date. */
863: (void)time(&iph1->created);
864:
865: /* migrate ph2s from dying ph1s */
866: migrate_dying_ph12(iph1);
867:
868: /* add to the schedule to expire, and seve back pointer. */
869: if (ph1_rekey_enabled(iph1)) {
870: sched_schedule(&iph1->sce,
871: iph1->approval->lifetime *
872: PFKEY_SOFT_LIFETIME_RATE / 100,
873: isakmp_ph1dying_stub);
874: } else {
875: sched_schedule(&iph1->sce, iph1->approval->lifetime,
876: isakmp_ph1expire_stub);
877: }
878:
879: #ifdef ENABLE_HYBRID
880: if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
881: switch (iph1->approval->authmethod) {
882: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
883: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
884: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
885: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
886: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
887: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
888: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
889: xauth_sendreq(iph1);
890: /* XXX Don't process INITIAL_CONTACT */
891: iph1->rmconf->ini_contact = 0;
892: break;
893: default:
894: break;
895: }
896: }
897: #endif
898: #ifdef ENABLE_DPD
899: /* Schedule the r_u_there.... */
900: if(iph1->dpd_support && iph1->rmconf->dpd_interval)
901: isakmp_sched_r_u(iph1, 0);
902: #endif
903:
904: /* INITIAL-CONTACT processing */
905: /* don't anything if local test mode. */
906: if (!f_local
907: && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) {
908: /* send INITIAL-CONTACT */
909: isakmp_info_send_n1(iph1,
910: ISAKMP_NTYPE_INITIAL_CONTACT, NULL);
911: /* insert a node into contacted list. */
912: if (inscontacted(iph1->remote) == -1) {
913: plog(LLV_ERROR, LOCATION, iph1->remote,
914: "failed to add contacted list.\n");
915: /* ignore */
916: }
917: }
918: if (iph1->initial_contact_received)
919: isakmp_info_recv_initialcontact(iph1, NULL);
920:
921: log_ph1established(iph1);
922: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
923:
924: /*
925: * SA up shell script hook: do it now,except if
926: * ISAKMP mode config was requested. In the later
927: * case it is done when we receive the configuration.
928: */
929: if ((iph1->status == PHASE1ST_ESTABLISHED) &&
930: !iph1->rmconf->mode_cfg) {
931: switch (iph1->approval->authmethod) {
932: #ifdef ENABLE_HYBRID
933: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
934: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
935: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
936: /* Unimplemeted... */
937: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
938: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
939: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
940: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
941: break;
942: #endif
943: default:
944: script_hook(iph1, SCRIPT_PHASE1_UP);
945: break;
946: }
947: }
948: }
949:
950: return 0;
951: }
952:
953: /*
954: * main function of quick mode.
955: */
956: static int
957: quick_main(iph2, msg)
958: struct ph2handle *iph2;
959: vchar_t *msg;
960: {
961: struct isakmp *isakmp = (struct isakmp *)msg->v;
962: int error;
963: #ifdef ENABLE_STATS
964: struct timeval start, end;
965: #endif
966:
967: /* ignore a packet */
968: if (iph2->status == PHASE2ST_ESTABLISHED
969: || iph2->status == PHASE2ST_GETSPISENT)
970: return 0;
971:
972: #ifdef ENABLE_STATS
973: gettimeofday(&start, NULL);
974: #endif
975:
976: /* receive */
977: if (ph2exchange[etypesw2(isakmp->etype)]
978: [iph2->side]
979: [iph2->status] == NULL) {
980: plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
981: "why isn't the function defined.\n");
982: return -1;
983: }
984: error = (ph2exchange[etypesw2(isakmp->etype)]
985: [iph2->side]
986: [iph2->status])(iph2, msg);
987: if (error != 0) {
988: plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
989: "failed to pre-process ph2 packet (side: %d, status %d).\n",
990: iph2->side, iph2->status);
991: if (error == ISAKMP_INTERNAL_ERROR)
992: return 0;
993: isakmp_info_send_n1(iph2->ph1, error, NULL);
994: return -1;
995: }
996:
997: /* when using commit bit, status will be reached here. */
998: if (iph2->status == PHASE2ST_ADDSA)
999: return 0;
1000:
1001: /* free resend buffer */
1002: if (iph2->sendbuf == NULL) {
1003: plog(LLV_ERROR, LOCATION, NULL,
1004: "no buffer found as sendbuf\n");
1005: return -1;
1006: }
1007: VPTRINIT(iph2->sendbuf);
1008:
1009: /* turn off schedule */
1010: sched_cancel(&iph2->scr);
1011:
1012: /* send */
1013: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1014: if ((ph2exchange[etypesw2(isakmp->etype)]
1015: [iph2->side]
1016: [iph2->status])(iph2, msg) != 0) {
1017: plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1018: "failed to process ph2 packet (side: %d, status: %d).\n",
1019: iph2->side, iph2->status);
1020: return -1;
1021: }
1022:
1023: #ifdef ENABLE_STATS
1024: gettimeofday(&end, NULL);
1025: syslog(LOG_NOTICE, "%s(%s): %8.6f",
1026: "phase2",
1027: s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
1028: timedelta(&start, &end));
1029: #endif
1030:
1031: return 0;
1032: }
1033:
1034: /* new negotiation of phase 1 for initiator */
1035: struct ph1handle *
1036: isakmp_ph1begin_i(rmconf, remote, local)
1037: struct remoteconf *rmconf;
1038: struct sockaddr *remote, *local;
1039: {
1040: struct ph1handle *iph1;
1041: #ifdef ENABLE_STATS
1042: struct timeval start, end;
1043: #endif
1044:
1045: /* get new entry to isakmp status table. */
1046: iph1 = newph1();
1047: if (iph1 == NULL)
1048: return NULL;
1049:
1050: iph1->status = PHASE1ST_START;
1051: iph1->rmconf = rmconf;
1052: iph1->side = INITIATOR;
1053: iph1->version = ISAKMP_VERSION_NUMBER;
1054: iph1->msgid = 0;
1055: iph1->flags = 0;
1056: iph1->ph2cnt = 0;
1057: #ifdef HAVE_GSSAPI
1058: iph1->gssapi_state = NULL;
1059: #endif
1060: #ifdef ENABLE_HYBRID
1061: if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
1062: delph1(iph1);
1063: return NULL;
1064: }
1065: #endif
1066: #ifdef ENABLE_FRAG
1067:
1068: if(rmconf->ike_frag == ISAKMP_FRAG_FORCE)
1069: iph1->frag = 1;
1070: else
1071: iph1->frag = 0;
1072: iph1->frag_chain = NULL;
1073: #endif
1074: iph1->approval = NULL;
1075:
1076: /* XXX copy remote address */
1077: if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
1078: delph1(iph1);
1079: return NULL;
1080: }
1081:
1082: (void)insph1(iph1);
1083:
1084: /* start phase 1 exchange */
1085: iph1->etype = rmconf->etypes->type;
1086:
1087: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1088: {
1089: char *a;
1090:
1091: a = racoon_strdup(saddr2str(iph1->local));
1092: STRDUP_FATAL(a);
1093:
1094: plog(LLV_INFO, LOCATION, NULL,
1095: "initiate new phase 1 negotiation: %s<=>%s\n",
1096: a, saddr2str(iph1->remote));
1097: racoon_free(a);
1098: }
1099: plog(LLV_INFO, LOCATION, NULL,
1100: "begin %s mode.\n",
1101: s_isakmp_etype(iph1->etype));
1102:
1103: #ifdef ENABLE_STATS
1104: gettimeofday(&iph1->start, NULL);
1105: gettimeofday(&start, NULL);
1106: #endif
1107: /* start exchange */
1108: if ((ph1exchange[etypesw1(iph1->etype)]
1109: [iph1->side]
1110: [iph1->status])(iph1, NULL) != 0) {
1111: /* failed to start phase 1 negotiation */
1112: remph1(iph1);
1113: delph1(iph1);
1114:
1115: return NULL;
1116: }
1117:
1118: #ifdef ENABLE_STATS
1119: gettimeofday(&end, NULL);
1120: syslog(LOG_NOTICE, "%s(%s): %8.6f",
1121: "phase1",
1122: s_isakmp_state(iph1->etype, iph1->side, iph1->status),
1123: timedelta(&start, &end));
1124: #endif
1125:
1126: return iph1;
1127: }
1128:
1129: /* new negotiation of phase 1 for responder */
1130: static int
1131: isakmp_ph1begin_r(msg, remote, local, etype)
1132: vchar_t *msg;
1133: struct sockaddr *remote, *local;
1134: u_int8_t etype;
1135: {
1136: struct isakmp *isakmp = (struct isakmp *)msg->v;
1137: struct ph1handle *iph1;
1138: struct rmconfselector rmsel;
1139: #ifdef ENABLE_STATS
1140: struct timeval start, end;
1141: #endif
1142:
1143: /* check if this etype is allowed */
1144: memset(&rmsel, 0, sizeof(rmsel));
1145: rmsel.remote = remote;
1146: if (enumrmconf(&rmsel, check_etypeok, (void *) (intptr_t) etype) == 0) {
1147: plog(LLV_ERROR, LOCATION, remote,
1148: "exchange %s not allowed in any applicable rmconf.\n",
1149: s_isakmp_etype(etype));
1150: return -1;
1151: }
1152:
1153: /* get new entry to isakmp status table. */
1154: iph1 = newph1();
1155: if (iph1 == NULL)
1156: return -1;
1157:
1158: memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck));
1159: iph1->status = PHASE1ST_START;
1160: iph1->flags = 0;
1161: iph1->side = RESPONDER;
1162: iph1->etype = etype;
1163: iph1->version = isakmp->v;
1164: iph1->msgid = 0;
1165: #ifdef HAVE_GSSAPI
1166: iph1->gssapi_state = NULL;
1167: #endif
1168: #ifdef ENABLE_HYBRID
1169: if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
1170: delph1(iph1);
1171: return -1;
1172: }
1173: #endif
1174: #ifdef ENABLE_FRAG
1175: iph1->frag = 0;
1176: iph1->frag_chain = NULL;
1177: #endif
1178: iph1->approval = NULL;
1179:
1180: #ifdef ENABLE_NATT
1181: /* RFC3947 says that we MUST accept new phases1 on NAT-T floated port.
1182: * We have to setup this flag now to correctly generate the first reply.
1183: * Don't know if a better check could be done for that ?
1184: */
1185: if(extract_port(local) == lcconf->port_isakmp_natt)
1186: iph1->natt_flags |= (NAT_PORTS_CHANGED);
1187: #endif
1188:
1189: /* copy remote address; remote and local always contain
1190: * port numbers so rmconf is not needed */
1191: if (copy_ph1addresses(iph1, NULL, remote, local) < 0) {
1192: delph1(iph1);
1193: return -1;
1194: }
1195: (void)insph1(iph1);
1196:
1197: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1198: {
1199: char *a;
1200:
1201: a = racoon_strdup(saddr2str(iph1->local));
1202: STRDUP_FATAL(a);
1203:
1204: plog(LLV_INFO, LOCATION, NULL,
1205: "respond new phase 1 negotiation: %s<=>%s\n",
1206: a, saddr2str(iph1->remote));
1207: racoon_free(a);
1208: }
1209: plog(LLV_INFO, LOCATION, NULL,
1210: "begin %s mode.\n", s_isakmp_etype(etype));
1211:
1212: #ifdef ENABLE_STATS
1213: gettimeofday(&iph1->start, NULL);
1214: gettimeofday(&start, NULL);
1215: #endif
1216:
1217: #ifndef ENABLE_FRAG
1218:
1219: /* start exchange */
1220: if ((ph1exchange[etypesw1(iph1->etype)]
1221: [iph1->side]
1222: [iph1->status])(iph1, msg) < 0
1223: || (ph1exchange[etypesw1(iph1->etype)]
1224: [iph1->side]
1225: [iph1->status])(iph1, msg) < 0) {
1226: plog(LLV_ERROR, LOCATION, remote,
1227: "failed to process ph1 packet (side: %d, status: %d).\n",
1228: iph1->side, iph1->status);
1229: remph1(iph1);
1230: delph1(iph1);
1231: return -1;
1232: }
1233:
1234: #ifdef ENABLE_STATS
1235: gettimeofday(&end, NULL);
1236: syslog(LOG_NOTICE, "%s(%s): %8.6f",
1237: "phase1",
1238: s_isakmp_state(iph1->etype, iph1->side, iph1->status),
1239: timedelta(&start, &end));
1240: #endif
1241:
1242: return 0;
1243:
1244: #else /* ENABLE_FRAG */
1245:
1246: /* now that we have a phase1 handle, feed back into our
1247: * main receive function to catch fragmented packets
1248: */
1249:
1250: return isakmp_main(msg, remote, local);
1251:
1252: #endif /* ENABLE_FRAG */
1253:
1254: }
1255:
1256: /* new negotiation of phase 2 for initiator */
1257: static int
1258: isakmp_ph2begin_i(iph1, iph2)
1259: struct ph1handle *iph1;
1260: struct ph2handle *iph2;
1261: {
1262: #ifdef ENABLE_HYBRID
1263: if (xauth_check(iph1) != 0) {
1264: plog(LLV_ERROR, LOCATION, NULL,
1265: "Attempt to start phase 2 whereas Xauth failed\n");
1266: return -1;
1267: }
1268: #endif
1269:
1270: /* fixup ph2 ports for this ph1 */
1271: if (extract_port(iph2->src) == 0)
1272: set_port(iph2->src, extract_port(iph1->local));
1273: if (extract_port(iph2->dst) == 0)
1274: set_port(iph2->dst, extract_port(iph1->remote));
1275:
1276: /* found ISAKMP-SA. */
1277: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1278: plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
1279: {
1280: char *a;
1281: a = racoon_strdup(saddr2str(iph2->src));
1282: STRDUP_FATAL(a);
1283:
1284: plog(LLV_INFO, LOCATION, NULL,
1285: "initiate new phase 2 negotiation: %s<=>%s\n",
1286: a, saddr2str(iph2->dst));
1287: racoon_free(a);
1288: }
1289:
1290: #ifdef ENABLE_STATS
1291: gettimeofday(&iph2->start, NULL);
1292: #endif
1293: if (iph2->status != PHASE2ST_EXPIRED) /* Phase 1 is already bound (ongoing rekeying) */
1294: bindph12(iph1, iph2);
1295: iph2->status = PHASE2ST_STATUS2;
1296:
1297: if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
1298: [iph2->side]
1299: [iph2->status])(iph2, NULL) < 0) {
1300: /* release ipsecsa handler due to internal error. */
1301: remph2(iph2);
1302: return -1;
1303: }
1304: return 0;
1305: }
1306:
1307: /* new negotiation of phase 2 for responder */
1308: static int
1309: isakmp_ph2begin_r(iph1, msg)
1310: struct ph1handle *iph1;
1311: vchar_t *msg;
1312: {
1313: struct isakmp *isakmp = (struct isakmp *)msg->v;
1314: struct ph2handle *iph2 = 0;
1315: int error;
1316: #ifdef ENABLE_STATS
1317: struct timeval start, end;
1318: #endif
1319: #ifdef ENABLE_HYBRID
1320: if (xauth_check(iph1) != 0) {
1321: plog(LLV_ERROR, LOCATION, NULL,
1322: "Attempt to start phase 2 whereas Xauth failed\n");
1323: return -1;
1324: }
1325: #endif
1326:
1327: iph2 = newph2();
1328: if (iph2 == NULL) {
1329: plog(LLV_ERROR, LOCATION, NULL,
1330: "failed to allocate phase2 entry.\n");
1331: return -1;
1332: }
1333:
1334: iph2->side = RESPONDER;
1335: iph2->status = PHASE2ST_START;
1336: iph2->flags = isakmp->flags;
1337: iph2->msgid = isakmp->msgid;
1338: iph2->seq = pk_getseq();
1339: iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
1340: if (iph2->ivm == NULL) {
1341: delph2(iph2);
1342: return -1;
1343: }
1344: iph2->dst = dupsaddr(iph1->remote); /* XXX should be considered */
1345: if (iph2->dst == NULL) {
1346: delph2(iph2);
1347: return -1;
1348: }
1349: iph2->src = dupsaddr(iph1->local); /* XXX should be considered */
1350: if (iph2->src == NULL) {
1351: delph2(iph2);
1352: return -1;
1353: }
1354:
1355: /* add new entry to isakmp status table */
1356: insph2(iph2);
1357: bindph12(iph1, iph2);
1358:
1359: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1360: {
1361: char *a;
1362:
1363: a = racoon_strdup(saddr2str(iph2->src));
1364: STRDUP_FATAL(a);
1365:
1366: plog(LLV_INFO, LOCATION, NULL,
1367: "respond new phase 2 negotiation: %s<=>%s\n",
1368: a, saddr2str(iph2->dst));
1369: racoon_free(a);
1370: }
1371:
1372: #ifdef ENABLE_STATS
1373: gettimeofday(&start, NULL);
1374: #endif
1375:
1376: error = (ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
1377: [iph2->side]
1378: [iph2->status])(iph2, msg);
1379: if (error != 0) {
1380: plog(LLV_ERROR, LOCATION, iph1->remote,
1381: "failed to pre-process ph2 packet (side: %d, status: %d).\n",
1382: iph2->side, iph2->status);
1383: if (error != ISAKMP_INTERNAL_ERROR)
1384: isakmp_info_send_n1(iph2->ph1, error, NULL);
1385: /*
1386: * release handler because it's wrong that ph2handle is kept
1387: * after failed to check message for responder's.
1388: */
1389: remph2(iph2);
1390: delph2(iph2);
1391: return -1;
1392: }
1393:
1394: /* send */
1395: plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1396: if ((ph2exchange[etypesw2(isakmp->etype)]
1397: [iph2->side]
1398: [iph2->status])(iph2, msg) < 0) {
1399: plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1400: "failed to process ph2 packet (side: %d, status: %d).\n",
1401: iph2->side, iph2->status);
1402: /* don't release handler */
1403: return -1;
1404: }
1405: #ifdef ENABLE_STATS
1406: gettimeofday(&end, NULL);
1407: syslog(LOG_NOTICE, "%s(%s): %8.6f",
1408: "phase2",
1409: s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
1410: timedelta(&start, &end));
1411: #endif
1412:
1413: return 0;
1414: }
1415:
1416: /*
1417: * parse ISAKMP payloads, without ISAKMP base header.
1418: */
1419: vchar_t *
1420: isakmp_parsewoh(np0, gen, len)
1421: int np0;
1422: struct isakmp_gen *gen;
1423: int len;
1424: {
1425: u_char np = np0 & 0xff;
1426: int tlen, plen;
1427: vchar_t *result;
1428: struct isakmp_parse_t *p, *ep;
1429:
1430: plog(LLV_DEBUG, LOCATION, NULL, "begin.\n");
1431:
1432: /*
1433: * 5 is a magic number, but any value larger than 2 should be fine
1434: * as we do vrealloc() in the following loop.
1435: */
1436: result = vmalloc(sizeof(struct isakmp_parse_t) * 5);
1437: if (result == NULL) {
1438: plog(LLV_ERROR, LOCATION, NULL,
1439: "failed to get buffer.\n");
1440: return NULL;
1441: }
1442: p = (struct isakmp_parse_t *)result->v;
1443: ep = (struct isakmp_parse_t *)(result->v + result->l - sizeof(*ep));
1444:
1445: tlen = len;
1446:
1447: /* parse through general headers */
1448: while (0 < tlen && np != ISAKMP_NPTYPE_NONE) {
1449: if (tlen <= sizeof(struct isakmp_gen)) {
1450: /* don't send information, see isakmp_ident_r1() */
1451: plog(LLV_ERROR, LOCATION, NULL,
1452: "invalid length of payload\n");
1453: vfree(result);
1454: return NULL;
1455: }
1456:
1457: plog(LLV_DEBUG, LOCATION, NULL,
1458: "seen nptype=%u(%s)\n", np, s_isakmp_nptype(np));
1459:
1460: p->type = np;
1461: p->len = ntohs(gen->len);
1462: if (p->len < sizeof(struct isakmp_gen) || p->len > tlen) {
1463: plog(LLV_DEBUG, LOCATION, NULL,
1464: "invalid length of payload\n");
1465: vfree(result);
1466: return NULL;
1467: }
1468: p->ptr = gen;
1469: p++;
1470: if (ep <= p) {
1471: int off;
1472:
1473: off = p - (struct isakmp_parse_t *)result->v;
1474: result = vrealloc(result, result->l * 2);
1475: if (result == NULL) {
1476: plog(LLV_DEBUG, LOCATION, NULL,
1477: "failed to realloc buffer.\n");
1478: vfree(result);
1479: return NULL;
1480: }
1481: ep = (struct isakmp_parse_t *)
1482: (result->v + result->l - sizeof(*ep));
1483: p = (struct isakmp_parse_t *)result->v;
1484: p += off;
1485: }
1486:
1487: np = gen->np;
1488: plen = ntohs(gen->len);
1489: gen = (struct isakmp_gen *)((caddr_t)gen + plen);
1490: tlen -= plen;
1491: }
1492: p->type = ISAKMP_NPTYPE_NONE;
1493: p->len = 0;
1494: p->ptr = NULL;
1495:
1496: plog(LLV_DEBUG, LOCATION, NULL, "succeed.\n");
1497:
1498: return result;
1499: }
1500:
1501: /*
1502: * parse ISAKMP payloads, including ISAKMP base header.
1503: */
1504: vchar_t *
1505: isakmp_parse(buf)
1506: vchar_t *buf;
1507: {
1508: struct isakmp *isakmp = (struct isakmp *)buf->v;
1509: struct isakmp_gen *gen;
1510: int tlen;
1511: vchar_t *result;
1512: u_char np;
1513:
1514: np = isakmp->np;
1515: gen = (struct isakmp_gen *)(buf->v + sizeof(*isakmp));
1516: tlen = buf->l - sizeof(struct isakmp);
1517: result = isakmp_parsewoh(np, gen, tlen);
1518:
1519: return result;
1520: }
1521:
1522: /* %%% */
1523: int
1524: isakmp_init()
1525: {
1526: /* initialize a isakmp status table */
1527: initph1tree();
1528: initph2tree();
1529: initctdtree();
1530: init_recvdpkt();
1531:
1532: return 0;
1533: }
1534:
1535: /*
1536: * make strings containing i_cookie + r_cookie + msgid
1537: */
1538: const char *
1539: isakmp_pindex(index, msgid)
1540: const isakmp_index *index;
1541: const u_int32_t msgid;
1542: {
1543: static char buf[64];
1544: const u_char *p;
1545: int i, j;
1546:
1547: memset(buf, 0, sizeof(buf));
1548:
1549: /* copy index */
1550: p = (const u_char *)index;
1551: for (j = 0, i = 0; i < sizeof(isakmp_index); i++) {
1552: snprintf((char *)&buf[j], sizeof(buf) - j, "%02x", p[i]);
1553: j += 2;
1554: switch (i) {
1555: case 7:
1556: buf[j++] = ':';
1557: }
1558: }
1559:
1560: if (msgid == 0)
1561: return buf;
1562:
1563: /* copy msgid */
1564: snprintf((char *)&buf[j], sizeof(buf) - j, ":%08x", ntohs(msgid));
1565:
1566: return buf;
1567: }
1568:
1569: /* open ISAKMP sockets. */
1570: int
1571: isakmp_open(struct sockaddr *addr, int udp_encap)
1572: {
1573: const int yes = 1;
1574: int ifnum = 0, encap_ifnum = 0, fd;
1575: struct sockaddr_in *sin = (struct sockaddr_in *) addr;
1576: #ifdef INET6
1577: struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr;
1578: int pktinfo;
1579: #endif
1580: #ifdef ENABLE_NATT
1581: int option = -1;
1582: #endif
1583:
1584: /* warn if wildcard address - should we forbid this? */
1585: switch (addr->sa_family) {
1586: case AF_INET:
1587: if (sin->sin_addr.s_addr == 0)
1588: plog(LLV_WARNING, LOCATION, NULL,
1589: "listening to wildcard address,"
1590: "broadcast IKE packet may kill you\n");
1591: break;
1592: #ifdef INET6
1593: case AF_INET6:
1594: if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
1595: plog(LLV_DEBUG, LOCATION, NULL,
1596: "ignoring multicast address %s\n",
1597: saddr2str(addr));
1598: return -1;
1599: }
1600:
1601: if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
1602: plog(LLV_WARNING, LOCATION, NULL,
1603: "listening to wildcard address, "
1604: "broadcast IKE packet may kill you\n");
1605: break;
1606: #endif
1607: default:
1608: plog(LLV_ERROR, LOCATION, NULL,
1609: "unsupported address family %d\n",
1610: addr->sa_family);
1611: return -1;
1612: }
1613:
1614: if ((fd = privsep_socket(addr->sa_family, SOCK_DGRAM, 0)) < 0) {
1615: plog(LLV_ERROR, LOCATION, NULL,
1616: "socket(%s)\n", strerror(errno));
1617: return -1;
1618: }
1619: close_on_exec(fd);
1620: if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
1621: plog(LLV_WARNING, LOCATION, NULL,
1622: "failed to put socket in non-blocking mode\n");
1623:
1624: /* receive my interface address on inbound packets. */
1625: switch (addr->sa_family) {
1626: case AF_INET:
1627: if (setsockopt(fd, IPPROTO_IP,
1628: #ifdef __linux__
1629: IP_PKTINFO,
1630: #else
1631: IP_RECVDSTADDR,
1632: #endif
1633: (const void *) &yes, sizeof(yes)) < 0) {
1634: plog(LLV_ERROR, LOCATION, NULL,
1635: "setsockopt IP_RECVDSTADDR (%s)\n",
1636: strerror(errno));
1637: goto err;
1638: }
1639:
1640: #ifdef ENABLE_NATT
1641: if (udp_encap)
1642: option = UDP_ENCAP_ESPINUDP;
1643: #if defined(ENABLE_NATT_00) || defined(ENABLE_NATT_01)
1644: else
1645: option = UDP_ENCAP_ESPINUDP_NON_IKE;
1646: #endif
1647: if (option == -1)
1648: break;
1649:
1650: if (setsockopt(fd, SOL_UDP,
1651: UDP_ENCAP, &option,
1652: sizeof(option)) < 0) {
1653: plog(LLV_WARNING, LOCATION, NULL,
1654: "setsockopt(%s): UDP_ENCAP %s\n",
1655: option == UDP_ENCAP_ESPINUDP ? "UDP_ENCAP_ESPINUDP" : "UDP_ENCAP_ESPINUDP_NON_IKE",
1656: strerror(errno));
1657: } else {
1658: plog(LLV_INFO, LOCATION, NULL,
1659: "%s used for NAT-T\n",
1660: saddr2str(addr));
1661: }
1662: #endif
1663: break;
1664:
1665: #ifdef INET6
1666: case AF_INET6:
1667: #if defined(INET6_ADVAPI)
1668: #ifdef IPV6_RECVPKTINFO
1669: pktinfo = IPV6_RECVPKTINFO;
1670: #else /* old adv. API */
1671: pktinfo = IPV6_PKTINFO;
1672: #endif /* IPV6_RECVPKTINFO */
1673: #else
1674: pktinfo = IPV6_RECVDSTADDR;
1675: #endif
1676: if (setsockopt(fd, IPPROTO_IPV6, pktinfo,
1677: (const void *) &yes, sizeof(yes)) < 0) {
1678: plog(LLV_ERROR, LOCATION, NULL,
1679: "setsockopt IPV6_RECVDSTADDR (%d):%s\n",
1680: pktinfo, strerror(errno));
1681: goto err;
1682: }
1683:
1684: #ifdef IPV6_USE_MIN_MTU
1685: if (setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
1686: (void *) &yes, sizeof(yes)) < 0) {
1687: plog(LLV_ERROR, LOCATION, NULL,
1688: "setsockopt IPV6_USE_MIN_MTU (%s)\n",
1689: strerror(errno));
1690: goto err;
1691: }
1692: #endif
1693: break;
1694: #endif
1695: }
1696:
1697: if (setsockopt(fd, SOL_SOCKET,
1698: #ifdef __linux__
1699: SO_REUSEADDR,
1700: #else
1701: SO_REUSEPORT,
1702: #endif
1703: (void *) &yes, sizeof(yes)) < 0) {
1704: plog(LLV_ERROR, LOCATION, NULL,
1705: "failed to set REUSE flag on %s (%s).\n",
1706: saddr2str(addr), strerror(errno));
1707: goto err;
1708: }
1709:
1710: if (setsockopt_bypass(fd, addr->sa_family) < 0)
1711: goto err;
1712:
1713: if (privsep_bind(fd, addr, sysdep_sa_len(addr)) < 0) {
1714: plog(LLV_ERROR, LOCATION, addr,
1715: "failed to bind to address %s (%s).\n",
1716: saddr2str(addr), strerror(errno));
1717: goto err;
1718: }
1719:
1720: plog(LLV_INFO, LOCATION, NULL,
1721: "%s used as isakmp port (fd=%d)\n",
1722: saddr2str(addr), fd);
1723:
1724: monitor_fd(fd, isakmp_handler, NULL, 1);
1725: return fd;
1726:
1727: err:
1728: close(fd);
1729: return -1;
1730: }
1731:
1732: void
1733: isakmp_close(int fd)
1734: {
1735: unmonitor_fd(fd);
1736: close(fd);
1737: }
1738:
1739: int
1740: isakmp_send(iph1, sbuf)
1741: struct ph1handle *iph1;
1742: vchar_t *sbuf;
1743: {
1744: int len = 0;
1745: int s;
1746: vchar_t *vbuf = NULL, swap;
1747:
1748: #ifdef ENABLE_NATT
1749: size_t extralen = NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0;
1750:
1751: /* Check if NON_ESP_MARKER_LEN is already there (happens when resending packets)
1752: */
1753: if(extralen == NON_ESP_MARKER_LEN &&
1754: *(u_int32_t *)sbuf->v == 0)
1755: extralen = 0;
1756:
1757: #ifdef ENABLE_FRAG
1758: /*
1759: * Do not add the non ESP marker for a packet that will
1760: * be fragmented. The non ESP marker should appear in
1761: * all fragment's packets, but not in the fragmented packet
1762: */
1763: if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN)
1764: extralen = 0;
1765: #endif
1766: if (extralen)
1767: plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n");
1768:
1769: /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker)
1770: must added just before the packet itself. For this we must
1771: allocate a new buffer and release it at the end. */
1772: if (extralen) {
1773: if ((vbuf = vmalloc (sbuf->l + extralen)) == NULL) {
1774: plog(LLV_ERROR, LOCATION, NULL,
1775: "vbuf allocation failed\n");
1776: return -1;
1777: }
1778: *(u_int32_t *)vbuf->v = 0;
1779: memcpy (vbuf->v + extralen, sbuf->v, sbuf->l);
1780: /* ensures that the modified buffer will be sent back to the caller, so
1781: * add_recvdpkt() will add the correct buffer
1782: */
1783: swap = *sbuf;
1784: *sbuf = *vbuf;
1785: *vbuf = swap;
1786: vfree(vbuf);
1787: }
1788: #endif
1789:
1790: /* select the socket to be sent */
1791: s = myaddr_getfd(iph1->local);
1792: if (s == -1)
1793: return -1;
1794:
1795: plog (LLV_DEBUG, LOCATION, NULL, "%zu bytes %s\n", sbuf->l,
1796: saddr2str_fromto("from %s to %s", iph1->local, iph1->remote));
1797:
1798: #ifdef ENABLE_FRAG
1799: if (iph1->frag && sbuf->l > ISAKMP_FRAG_MAXLEN) {
1800: if (isakmp_sendfrags(iph1, sbuf) == -1) {
1801: plog(LLV_ERROR, LOCATION, NULL,
1802: "isakmp_sendfrags failed\n");
1803: return -1;
1804: }
1805: } else
1806: #endif
1807: {
1808: len = sendfromto(s, sbuf->v, sbuf->l,
1809: iph1->local, iph1->remote, lcconf->count_persend);
1810:
1811: if (len == -1) {
1812: plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n");
1813: return -1;
1814: }
1815: }
1816:
1817: return 0;
1818: }
1819:
1820: /* called from scheduler */
1821: static void
1822: isakmp_ph1resend_stub(p)
1823: struct sched *p;
1824: {
1825: struct ph1handle *iph1 = container_of(p, struct ph1handle, scr);
1826:
1827: if (isakmp_ph1resend(iph1) < 0) {
1828: remph1(iph1);
1829: delph1(iph1);
1830: }
1831: }
1832:
1833: static int
1834: isakmp_ph1resend(iph1)
1835: struct ph1handle *iph1;
1836: {
1837: /* Note: NEVER do the rem/del here, it will be done by the caller or by the _stub function
1838: */
1839: if (iph1->retry_counter <= 0) {
1840: plog(LLV_ERROR, LOCATION, NULL,
1841: "phase1 negotiation failed due to time up. %s\n",
1842: isakmp_pindex(&iph1->index, iph1->msgid));
1843: /* XXX is the peer really "dead" here ??? */
1844: script_hook(iph1, SCRIPT_PHASE1_DEAD);
1845: evt_phase1(iph1, EVT_PHASE1_NO_RESPONSE, NULL);
1846:
1847: return -1;
1848: }
1849:
1850: if (isakmp_send(iph1, iph1->sendbuf) < 0){
1851: plog(LLV_ERROR, LOCATION, NULL,
1852: "phase1 negotiation failed due to send error. %s\n",
1853: isakmp_pindex(&iph1->index, iph1->msgid));
1854: evt_phase1(iph1, EVT_PHASE1_NO_RESPONSE, NULL);
1855: return -1;
1856: }
1857:
1858: plog(LLV_DEBUG, LOCATION, NULL,
1859: "resend phase1 packet %s\n",
1860: isakmp_pindex(&iph1->index, iph1->msgid));
1861:
1862: iph1->retry_counter--;
1863:
1864: sched_schedule(&iph1->scr, lcconf->retry_interval,
1865: isakmp_ph1resend_stub);
1866:
1867: return 0;
1868: }
1869:
1870: int
1871: isakmp_ph1send(iph1)
1872: struct ph1handle *iph1;
1873: {
1874: iph1->retry_counter = lcconf->retry_counter;
1875: return isakmp_ph1resend(iph1);
1876: }
1877:
1878: /* called from scheduler */
1879: static void
1880: isakmp_ph2resend_stub(p)
1881: struct sched *p;
1882: {
1883: struct ph2handle *iph2 = container_of(p, struct ph2handle, scr);
1884:
1885: if (isakmp_ph2resend(iph2) < 0) {
1886: remph2(iph2);
1887: delph2(iph2);
1888: }
1889: }
1890:
1891: static int
1892: isakmp_ph2resend(iph2)
1893: struct ph2handle *iph2;
1894: {
1895: /* Note: NEVER do the unbind/rem/del here, it will be done by the caller or by the _stub function
1896: */
1897: if (iph2->ph1->status >= PHASE1ST_EXPIRED) {
1898: plog(LLV_ERROR, LOCATION, NULL,
1899: "phase2 negotiation failed due to phase1 expired. %s\n",
1900: isakmp_pindex(&iph2->ph1->index, iph2->msgid));
1901: return -1;
1902: }
1903:
1904: if (iph2->retry_counter <= 0) {
1905: plog(LLV_ERROR, LOCATION, NULL,
1906: "phase2 negotiation failed due to time up. %s\n",
1907: isakmp_pindex(&iph2->ph1->index, iph2->msgid));
1908: evt_phase2(iph2, EVT_PHASE2_NO_RESPONSE, NULL);
1909: unbindph12(iph2);
1910: return -1;
1911: }
1912:
1913: if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0){
1914: plog(LLV_ERROR, LOCATION, NULL,
1915: "phase2 negotiation failed due to send error. %s\n",
1916: isakmp_pindex(&iph2->ph1->index, iph2->msgid));
1917: evt_phase2(iph2, EVT_PHASE2_NO_RESPONSE, NULL);
1918: return -1;
1919: }
1920:
1921: plog(LLV_DEBUG, LOCATION, NULL,
1922: "resend phase2 packet %s\n",
1923: isakmp_pindex(&iph2->ph1->index, iph2->msgid));
1924:
1925: iph2->retry_counter--;
1926:
1927: sched_schedule(&iph2->scr, lcconf->retry_interval,
1928: isakmp_ph2resend_stub);
1929:
1930: return 0;
1931: }
1932:
1933: int
1934: isakmp_ph2send(iph2)
1935: struct ph2handle *iph2;
1936: {
1937: iph2->retry_counter = lcconf->retry_counter;
1938: return isakmp_ph2resend(iph2);
1939: }
1940:
1941: /* called from scheduler */
1942: void
1943: isakmp_ph1dying_stub(p)
1944: struct sched *p;
1945: {
1946:
1947: isakmp_ph1dying(container_of(p, struct ph1handle, sce));
1948: }
1949:
1950: void
1951: isakmp_ph1dying(iph1)
1952: struct ph1handle *iph1;
1953: {
1954: struct ph1handle *new_iph1;
1955: struct ph2handle *p;
1956: struct remoteconf *rmconf;
1957:
1958: if (iph1->status >= PHASE1ST_DYING)
1959: return;
1960:
1961: /* Going away in after a while... */
1962: iph1->status = PHASE1ST_DYING;
1963:
1964: /* Any fresh phase1s? */
1965: new_iph1 = getph1(iph1, iph1->local, iph1->remote, 1);
1966: if (new_iph1 == NULL) {
1967: LIST_FOREACH(p, &iph1->ph2tree, ph1bind) {
1968: if (p->status != PHASE2ST_ESTABLISHED)
1969: continue;
1970:
1971: plog(LLV_INFO, LOCATION, NULL,
1972: "renegotiating phase1 to %s due to "
1973: "active phase2\n",
1974: saddrwop2str(iph1->remote));
1975:
1976: if (iph1->side == INITIATOR)
1977: isakmp_ph1begin_i(iph1->rmconf, iph1->remote,
1978: iph1->local);
1979:
1980: break;
1981: }
1982: } else {
1983: migrate_ph12(iph1, new_iph1);
1984: }
1985:
1986: /* Schedule for expiration */
1987: sched_schedule(&iph1->sce, iph1->approval->lifetime *
1988: (100 - PFKEY_SOFT_LIFETIME_RATE) / 100,
1989: isakmp_ph1expire_stub);
1990: }
1991:
1992: /* called from scheduler */
1993: void
1994: isakmp_ph1expire_stub(p)
1995: struct sched *p;
1996: {
1997: isakmp_ph1expire(container_of(p, struct ph1handle, sce));
1998: }
1999:
2000: void
2001: isakmp_ph1expire(iph1)
2002: struct ph1handle *iph1;
2003: {
2004: char *src, *dst;
2005:
2006: if (iph1->status < PHASE1ST_EXPIRED) {
2007: src = racoon_strdup(saddr2str(iph1->local));
2008: dst = racoon_strdup(saddr2str(iph1->remote));
2009: STRDUP_FATAL(src);
2010: STRDUP_FATAL(dst);
2011:
2012: plog(LLV_INFO, LOCATION, NULL,
2013: "ISAKMP-SA expired %s-%s spi:%s\n",
2014: src, dst,
2015: isakmp_pindex(&iph1->index, 0));
2016: racoon_free(src);
2017: racoon_free(dst);
2018: iph1->status = PHASE1ST_EXPIRED;
2019: }
2020:
2021: isakmp_ph1delete(iph1);
2022: }
2023:
2024: /* called from scheduler */
2025: void
2026: isakmp_ph1delete_stub(p)
2027: struct sched *p;
2028: {
2029:
2030: isakmp_ph1delete(container_of(p, struct ph1handle, sce));
2031: }
2032:
2033: void
2034: isakmp_ph1delete(iph1)
2035: struct ph1handle *iph1;
2036: {
2037: struct ph2handle *p, *next;
2038: struct ph1handle *new_iph1;
2039: char *src, *dst;
2040:
2041: /* Migrate established phase2s. Any fresh phase1s? */
2042: new_iph1 = getph1(iph1, iph1->local, iph1->remote, 1);
2043: if (new_iph1 != NULL)
2044: migrate_ph12(iph1, new_iph1);
2045:
2046: /* Discard any left phase2s */
2047: for (p = LIST_FIRST(&iph1->ph2tree); p; p = next) {
2048: next = LIST_NEXT(p, ph1bind);
2049: if (p->status == PHASE2ST_ESTABLISHED)
2050: isakmp_info_send_d2(p);
2051: /* remove all ph2 handles,
2052: * as ph1handle will be expired soon
2053: */
2054: delete_spd(p, 1);
2055: remph2(p);
2056: delph2(p);
2057: }
2058:
2059: src = racoon_strdup(saddr2str(iph1->local));
2060: dst = racoon_strdup(saddr2str(iph1->remote));
2061: STRDUP_FATAL(src);
2062: STRDUP_FATAL(dst);
2063:
2064: plog(LLV_INFO, LOCATION, NULL,
2065: "ISAKMP-SA deleted %s-%s spi:%s\n",
2066: src, dst, isakmp_pindex(&iph1->index, 0));
2067:
2068: evt_phase1(iph1, EVT_PHASE1_DOWN, NULL);
2069: if (new_iph1 == NULL && ph1_rekey_enabled(iph1))
2070: script_hook(iph1, SCRIPT_PHASE1_DEAD);
2071:
2072: racoon_free(src);
2073: racoon_free(dst);
2074:
2075: remph1(iph1);
2076: delph1(iph1);
2077: }
2078:
2079: /* called from scheduler.
2080: * this function will call only isakmp_ph2delete().
2081: * phase 2 handler remain forever if kernel doesn't cry a expire of phase 2 SA
2082: * by something cause. That's why this function is called after phase 2 SA
2083: * expires in the userland.
2084: */
2085: void
2086: isakmp_ph2expire_stub(p)
2087: struct sched *p;
2088: {
2089:
2090: isakmp_ph2expire(container_of(p, struct ph2handle, sce));
2091: }
2092:
2093: void
2094: isakmp_ph2expire(iph2)
2095: struct ph2handle *iph2;
2096: {
2097: char *src, *dst;
2098:
2099: src = racoon_strdup(saddrwop2str(iph2->src));
2100: dst = racoon_strdup(saddrwop2str(iph2->dst));
2101: STRDUP_FATAL(src);
2102: STRDUP_FATAL(dst);
2103:
2104: plog(LLV_INFO, LOCATION, NULL,
2105: "phase2 sa expired %s-%s\n", src, dst);
2106: racoon_free(src);
2107: racoon_free(dst);
2108:
2109: iph2->status = PHASE2ST_EXPIRED;
2110: sched_schedule(&iph2->sce, 1, isakmp_ph2delete_stub);
2111: }
2112:
2113: /* called from scheduler */
2114: void
2115: isakmp_ph2delete_stub(p)
2116: struct sched *p;
2117: {
2118:
2119: isakmp_ph2delete(container_of(p, struct ph2handle, sce));
2120: }
2121:
2122: void
2123: isakmp_ph2delete(iph2)
2124: struct ph2handle *iph2;
2125: {
2126: char *src, *dst;
2127:
2128: src = racoon_strdup(saddrwop2str(iph2->src));
2129: dst = racoon_strdup(saddrwop2str(iph2->dst));
2130: STRDUP_FATAL(src);
2131: STRDUP_FATAL(dst);
2132:
2133: plog(LLV_INFO, LOCATION, NULL,
2134: "phase2 sa deleted %s-%s\n", src, dst);
2135: racoon_free(src);
2136: racoon_free(dst);
2137:
2138: remph2(iph2);
2139: delph2(iph2);
2140:
2141: return;
2142: }
2143:
2144: /* %%%
2145: * Interface between PF_KEYv2 and ISAKMP
2146: */
2147: /*
2148: * receive ACQUIRE from kernel, and begin either phase1 or phase2.
2149: * if phase1 has been finished, begin phase2.
2150: */
2151: int
2152: isakmp_post_acquire(iph2, iph1hint, nopassive)
2153: struct ph2handle *iph2;
2154: struct ph1handle *iph1hint;
2155: int nopassive;
2156: {
2157: struct remoteconf *rmconf;
2158: struct ph1handle *iph1 = NULL;
2159:
2160: plog(LLV_DEBUG, LOCATION, NULL, "in post_acquire\n");
2161:
2162: /* Search appropriate configuration with masking port. Note that
2163: * we always use iph2->dst, and not iph2->sa_dst.
2164: *
2165: * XXX One possible need for using iph2->sa_dst if not NULL would
2166: * be for selecting a remote configuration based on a stable
2167: * address of a mobile node (not a CoA provided by MIGRATE/KMADDRESS
2168: * as iph2->dst hint). This scenario would require additional changes,
2169: * so no need to bother yet. --arno */
2170:
2171: if (iph1hint == NULL || iph1hint->rmconf == NULL) {
2172: rmconf = getrmconf(iph2->dst, nopassive ? GETRMCONF_F_NO_PASSIVE : 0);
2173: if (rmconf == NULL) {
2174: plog(LLV_ERROR, LOCATION, NULL,
2175: "no configuration found for %s.\n",
2176: saddrwop2str(iph2->dst));
2177: return -1;
2178: }
2179: } else {
2180: rmconf = iph1hint->rmconf;
2181: }
2182:
2183: /* if passive mode, ignore the acquire message */
2184: if (nopassive && rmconf->passive) {
2185: plog(LLV_DEBUG, LOCATION, NULL,
2186: "because of passive mode, "
2187: "ignore the acquire message for %s.\n",
2188: saddrwop2str(iph2->dst));
2189: return 0;
2190: }
2191:
2192: /*
2193: * XXX Searching by IP addresses + ports might fail on
2194: * some cases, we should use the ISAKMP identity to search
2195: * matching ISAKMP.
2196: */
2197: iph1 = getph1(iph1hint, iph2->src, iph2->dst, 0);
2198:
2199: /* no ISAKMP-SA found. */
2200: if (iph1 == NULL) {
2201: iph2->retry_checkph1 = lcconf->retry_checkph1;
2202: sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub);
2203: plog(LLV_INFO, LOCATION, NULL,
2204: "IPsec-SA request for %s queued "
2205: "due to no phase1 found.\n",
2206: saddrwop2str(iph2->dst));
2207:
2208: /* start phase 1 negotiation as a initiator. */
2209: if (isakmp_ph1begin_i(rmconf, iph2->dst, iph2->src) == NULL) {
2210: sched_cancel(&iph2->sce);
2211: return -1;
2212: }
2213:
2214: return 0;
2215: /*NOTREACHED*/
2216: }
2217:
2218: /* found ISAKMP-SA, but on negotiation. */
2219: if (iph1->status < PHASE1ST_ESTABLISHED) {
2220: iph2->retry_checkph1 = lcconf->retry_checkph1;
2221: sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub);
2222: plog(LLV_INFO, LOCATION, iph2->dst,
2223: "request for establishing IPsec-SA was queued "
2224: "due to no phase1 found.\n");
2225: return 0;
2226: /*NOTREACHED*/
2227: }
2228:
2229: /* found established ISAKMP-SA */
2230: /* i.e. iph1->status == PHASE1ST_ESTABLISHED */
2231:
2232: /* found ISAKMP-SA. */
2233: plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
2234:
2235: /* begin quick mode */
2236: if (isakmp_ph2begin_i(iph1, iph2))
2237: return -1;
2238:
2239: return 0;
2240: }
2241:
2242: int
2243: isakmp_get_sainfo(iph2, sp_out, sp_in)
2244: struct ph2handle *iph2;
2245: struct secpolicy *sp_out, *sp_in;
2246: {
2247: struct remoteconf *conf;
2248: uint32_t remoteid = 0;
2249:
2250: plog(LLV_DEBUG, LOCATION, NULL,
2251: "new acquire %s\n", spidx2str(&sp_out->spidx));
2252:
2253: /* get sainfo */
2254: {
2255: vchar_t *idsrc, *iddst;
2256:
2257: idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src,
2258: sp_out->spidx.prefs, sp_out->spidx.ul_proto);
2259: if (idsrc == NULL) {
2260: plog(LLV_ERROR, LOCATION, NULL,
2261: "failed to get ID for %s\n",
2262: spidx2str(&sp_out->spidx));
2263: return -1;
2264: }
2265: iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst,
2266: sp_out->spidx.prefd, sp_out->spidx.ul_proto);
2267: if (iddst == NULL) {
2268: plog(LLV_ERROR, LOCATION, NULL,
2269: "failed to get ID for %s\n",
2270: spidx2str(&sp_out->spidx));
2271: vfree(idsrc);
2272: return -1;
2273: }
2274:
2275: conf = getrmconf(iph2->dst, 0);
2276: if (conf != NULL)
2277: remoteid = conf->ph1id;
2278: else
2279: plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n");
2280:
2281: iph2->sainfo = getsainfo(idsrc, iddst, NULL, NULL, remoteid);
2282: vfree(idsrc);
2283: vfree(iddst);
2284: if (iph2->sainfo == NULL) {
2285: plog(LLV_ERROR, LOCATION, NULL,
2286: "failed to get sainfo.\n");
2287: return -1;
2288: /* XXX should use the algorithm list from register message */
2289: }
2290:
2291: plog(LLV_DEBUG, LOCATION, NULL,
2292: "selected sainfo: %s\n", sainfo2str(iph2->sainfo));
2293: }
2294:
2295: if (set_proposal_from_policy(iph2, sp_out, sp_in) < 0) {
2296: plog(LLV_ERROR, LOCATION, NULL,
2297: "failed to create saprop.\n");
2298: return -1;
2299: }
2300:
2301: return 0;
2302: }
2303:
2304:
2305: /*
2306: * receive GETSPI from kernel.
2307: */
2308: int
2309: isakmp_post_getspi(iph2)
2310: struct ph2handle *iph2;
2311: {
2312: #ifdef ENABLE_STATS
2313: struct timeval start, end;
2314: #endif
2315:
2316: /* don't process it because there is no suitable phase1-sa. */
2317: if (iph2->ph1->status >= PHASE1ST_EXPIRED) {
2318: plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
2319: "the negotiation is stopped, "
2320: "because there is no suitable ISAKMP-SA.\n");
2321: return -1;
2322: }
2323:
2324: #ifdef ENABLE_STATS
2325: gettimeofday(&start, NULL);
2326: #endif
2327: if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
2328: [iph2->side]
2329: [iph2->status])(iph2, NULL) != 0)
2330: return -1;
2331: #ifdef ENABLE_STATS
2332: gettimeofday(&end, NULL);
2333: syslog(LOG_NOTICE, "%s(%s): %8.6f",
2334: "phase2",
2335: s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
2336: timedelta(&start, &end));
2337: #endif
2338:
2339: return 0;
2340: }
2341:
2342: /* called by scheduler */
2343: void
2344: isakmp_chkph1there_stub(p)
2345: struct sched *p;
2346: {
2347: isakmp_chkph1there(container_of(p, struct ph2handle, sce));
2348: }
2349:
2350: void
2351: isakmp_chkph1there(iph2)
2352: struct ph2handle *iph2;
2353: {
2354: struct ph1handle *iph1;
2355:
2356: iph2->retry_checkph1--;
2357: if (iph2->retry_checkph1 < 0) {
2358: plog(LLV_ERROR, LOCATION, iph2->dst,
2359: "phase2 negotiation failed "
2360: "due to time up waiting for phase1. %s\n",
2361: sadbsecas2str(iph2->dst, iph2->src,
2362: iph2->satype, 0, 0));
2363: plog(LLV_INFO, LOCATION, NULL,
2364: "delete phase 2 handler.\n");
2365:
2366: /* send acquire to kernel as error */
2367: pk_sendeacquire(iph2);
2368:
2369: remph2(iph2);
2370: delph2(iph2);
2371:
2372: return;
2373: }
2374:
2375: /* Search isakmp status table by address and port */
2376: iph1 = getph1byaddr(iph2->src, iph2->dst, 0);
2377:
2378: /* XXX Even if ph1 as responder is there, should we not start
2379: * phase 2 negotiation ? */
2380: if (iph1 != NULL
2381: && iph1->status == PHASE1ST_ESTABLISHED) {
2382: /* found isakmp-sa */
2383:
2384: plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: got a ph1 handler, setting ports.\n");
2385: plog(LLV_DEBUG2, LOCATION, NULL, "iph1->local: %s\n", saddr2str(iph1->local));
2386: plog(LLV_DEBUG2, LOCATION, NULL, "iph1->remote: %s\n", saddr2str(iph1->remote));
2387: plog(LLV_DEBUG2, LOCATION, NULL, "before:\n");
2388: plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src));
2389: plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst));
2390: set_port(iph2->src, extract_port(iph1->local));
2391: set_port(iph2->dst, extract_port(iph1->remote));
2392: plog(LLV_DEBUG2, LOCATION, NULL, "After:\n");
2393: plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str(iph2->src));
2394: plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str(iph2->dst));
2395:
2396: /* begin quick mode */
2397: (void)isakmp_ph2begin_i(iph1, iph2);
2398: return;
2399: }
2400:
2401: plog(LLV_DEBUG2, LOCATION, NULL, "CHKPH1THERE: no established ph1 handler found\n");
2402:
2403: /* no isakmp-sa found */
2404: sched_schedule(&iph2->sce, 1, isakmp_chkph1there_stub);
2405:
2406: return;
2407: }
2408:
2409: /* copy variable data into ALLOCATED buffer. */
2410: caddr_t
2411: isakmp_set_attr_v(buf, type, val, len)
2412: caddr_t buf;
2413: int type;
2414: caddr_t val;
2415: int len;
2416: {
2417: struct isakmp_data *data;
2418:
2419: data = (struct isakmp_data *)buf;
2420: data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV);
2421: data->lorv = htons((u_int16_t)len);
2422: memcpy(data + 1, val, len);
2423:
2424: return buf + sizeof(*data) + len;
2425: }
2426:
2427: /* copy fixed length data into ALLOCATED buffer. */
2428: caddr_t
2429: isakmp_set_attr_l(buf, type, val)
2430: caddr_t buf;
2431: int type;
2432: u_int32_t val;
2433: {
2434: struct isakmp_data *data;
2435:
2436: data = (struct isakmp_data *)buf;
2437: data->type = htons((u_int16_t)type | ISAKMP_GEN_TV);
2438: data->lorv = htons((u_int16_t)val);
2439:
2440: return buf + sizeof(*data);
2441: }
2442:
2443: /* add a variable data attribute to the buffer by reallocating it. */
2444: vchar_t *
2445: isakmp_add_attr_v(buf0, type, val, len)
2446: vchar_t *buf0;
2447: int type;
2448: caddr_t val;
2449: int len;
2450: {
2451: vchar_t *buf = NULL;
2452: struct isakmp_data *data;
2453: int tlen;
2454: int oldlen = 0;
2455:
2456: tlen = sizeof(*data) + len;
2457:
2458: if (buf0) {
2459: oldlen = buf0->l;
2460: buf = vrealloc(buf0, oldlen + tlen);
2461: } else
2462: buf = vmalloc(tlen);
2463: if (!buf) {
2464: plog(LLV_ERROR, LOCATION, NULL,
2465: "failed to get a attribute buffer.\n");
2466: return NULL;
2467: }
2468:
2469: data = (struct isakmp_data *)(buf->v + oldlen);
2470: data->type = htons((u_int16_t)type | ISAKMP_GEN_TLV);
2471: data->lorv = htons((u_int16_t)len);
2472: memcpy(data + 1, val, len);
2473:
2474: return buf;
2475: }
2476:
2477: /* add a fixed data attribute to the buffer by reallocating it. */
2478: vchar_t *
2479: isakmp_add_attr_l(buf0, type, val)
2480: vchar_t *buf0;
2481: int type;
2482: u_int32_t val;
2483: {
2484: vchar_t *buf = NULL;
2485: struct isakmp_data *data;
2486: int tlen;
2487: int oldlen = 0;
2488:
2489: tlen = sizeof(*data);
2490:
2491: if (buf0) {
2492: oldlen = buf0->l;
2493: buf = vrealloc(buf0, oldlen + tlen);
2494: } else
2495: buf = vmalloc(tlen);
2496: if (!buf) {
2497: plog(LLV_ERROR, LOCATION, NULL,
2498: "failed to get a attribute buffer.\n");
2499: return NULL;
2500: }
2501:
2502: data = (struct isakmp_data *)(buf->v + oldlen);
2503: data->type = htons((u_int16_t)type | ISAKMP_GEN_TV);
2504: data->lorv = htons((u_int16_t)val);
2505:
2506: return buf;
2507: }
2508:
2509: /*
2510: * calculate cookie and set.
2511: */
2512: int
2513: isakmp_newcookie(place, remote, local)
2514: caddr_t place;
2515: struct sockaddr *remote;
2516: struct sockaddr *local;
2517: {
2518: vchar_t *buf = NULL, *buf2 = NULL;
2519: char *p;
2520: int blen;
2521: int alen;
2522: caddr_t sa1, sa2;
2523: time_t t;
2524: int error = -1;
2525: u_short port;
2526:
2527:
2528: if (remote->sa_family != local->sa_family) {
2529: plog(LLV_ERROR, LOCATION, NULL,
2530: "address family mismatch, remote:%d local:%d\n",
2531: remote->sa_family, local->sa_family);
2532: goto end;
2533: }
2534: switch (remote->sa_family) {
2535: case AF_INET:
2536: alen = sizeof(struct in_addr);
2537: sa1 = (caddr_t)&((struct sockaddr_in *)remote)->sin_addr;
2538: sa2 = (caddr_t)&((struct sockaddr_in *)local)->sin_addr;
2539: break;
2540: #ifdef INET6
2541: case AF_INET6:
2542: alen = sizeof(struct in6_addr);
2543: sa1 = (caddr_t)&((struct sockaddr_in6 *)remote)->sin6_addr;
2544: sa2 = (caddr_t)&((struct sockaddr_in6 *)local)->sin6_addr;
2545: break;
2546: #endif
2547: default:
2548: plog(LLV_ERROR, LOCATION, NULL,
2549: "invalid family: %d\n", remote->sa_family);
2550: goto end;
2551: }
2552: blen = (alen + sizeof(u_short)) * 2
2553: + sizeof(time_t) + lcconf->secret_size;
2554: buf = vmalloc(blen);
2555: if (buf == NULL) {
2556: plog(LLV_ERROR, LOCATION, NULL,
2557: "failed to get a cookie.\n");
2558: goto end;
2559: }
2560: p = buf->v;
2561:
2562: /* copy my address */
2563: memcpy(p, sa1, alen);
2564: p += alen;
2565: port = ((struct sockaddr_in *)remote)->sin_port;
2566: memcpy(p, &port, sizeof(u_short));
2567: p += sizeof(u_short);
2568:
2569: /* copy target address */
2570: memcpy(p, sa2, alen);
2571: p += alen;
2572: port = ((struct sockaddr_in *)local)->sin_port;
2573: memcpy(p, &port, sizeof(u_short));
2574: p += sizeof(u_short);
2575:
2576: /* copy time */
2577: t = time(0);
2578: memcpy(p, (caddr_t)&t, sizeof(t));
2579: p += sizeof(t);
2580:
2581: /* copy random value */
2582: buf2 = eay_set_random(lcconf->secret_size);
2583: if (buf2 == NULL)
2584: goto end;
2585: memcpy(p, buf2->v, lcconf->secret_size);
2586: p += lcconf->secret_size;
2587: vfree(buf2);
2588:
2589: buf2 = eay_sha1_one(buf);
2590: memcpy(place, buf2->v, sizeof(cookie_t));
2591:
2592: sa1 = val2str(place, sizeof (cookie_t));
2593: plog(LLV_DEBUG, LOCATION, NULL, "new cookie:\n%s\n", sa1);
2594: racoon_free(sa1);
2595:
2596: error = 0;
2597: end:
2598: if (buf != NULL)
2599: vfree(buf);
2600: if (buf2 != NULL)
2601: vfree(buf2);
2602: return error;
2603: }
2604:
2605: /*
2606: * save partner's(payload) data into phhandle.
2607: */
2608: int
2609: isakmp_p2ph(buf, gen)
2610: vchar_t **buf;
2611: struct isakmp_gen *gen;
2612: {
2613: /* XXX to be checked in each functions for logging. */
2614: if (*buf) {
2615: plog(LLV_WARNING, LOCATION, NULL,
2616: "ignore this payload, same payload type exist.\n");
2617: return -1;
2618: }
2619:
2620: *buf = vmalloc(ntohs(gen->len) - sizeof(*gen));
2621: if (*buf == NULL) {
2622: plog(LLV_ERROR, LOCATION, NULL,
2623: "failed to get buffer.\n");
2624: return -1;
2625: }
2626: memcpy((*buf)->v, gen + 1, (*buf)->l);
2627:
2628: return 0;
2629: }
2630:
2631: u_int32_t
2632: isakmp_newmsgid2(iph1)
2633: struct ph1handle *iph1;
2634: {
2635: u_int32_t msgid2;
2636:
2637: do {
2638: msgid2 = eay_random();
2639: } while (getph2bymsgid(iph1, msgid2));
2640:
2641: return msgid2;
2642: }
2643:
2644: /*
2645: * set values into allocated buffer of isakmp header for phase 1
2646: */
2647: static caddr_t
2648: set_isakmp_header(vbuf, iph1, nptype, etype, flags, msgid)
2649: vchar_t *vbuf;
2650: struct ph1handle *iph1;
2651: int nptype;
2652: u_int8_t etype;
2653: u_int8_t flags;
2654: u_int32_t msgid;
2655: {
2656: struct isakmp *isakmp;
2657:
2658: if (vbuf->l < sizeof(*isakmp))
2659: return NULL;
2660:
2661: isakmp = (struct isakmp *)vbuf->v;
2662:
2663: memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
2664: memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
2665: isakmp->np = nptype;
2666: isakmp->v = iph1->version;
2667: isakmp->etype = etype;
2668: isakmp->flags = flags;
2669: isakmp->msgid = msgid;
2670: isakmp->len = htonl(vbuf->l);
2671:
2672: return vbuf->v + sizeof(*isakmp);
2673: }
2674:
2675: /*
2676: * set values into allocated buffer of isakmp header for phase 1
2677: */
2678: caddr_t
2679: set_isakmp_header1(vbuf, iph1, nptype)
2680: vchar_t *vbuf;
2681: struct ph1handle *iph1;
2682: int nptype;
2683: {
2684: return set_isakmp_header (vbuf, iph1, nptype, iph1->etype, iph1->flags, iph1->msgid);
2685: }
2686:
2687: /*
2688: * set values into allocated buffer of isakmp header for phase 2
2689: */
2690: caddr_t
2691: set_isakmp_header2(vbuf, iph2, nptype)
2692: vchar_t *vbuf;
2693: struct ph2handle *iph2;
2694: int nptype;
2695: {
2696: return set_isakmp_header (vbuf, iph2->ph1, nptype, ISAKMP_ETYPE_QUICK, iph2->flags, iph2->msgid);
2697: }
2698:
2699: /*
2700: * set values into allocated buffer of isakmp payload.
2701: */
2702: caddr_t
2703: set_isakmp_payload(buf, src, nptype)
2704: caddr_t buf;
2705: vchar_t *src;
2706: int nptype;
2707: {
2708: struct isakmp_gen *gen;
2709: caddr_t p = buf;
2710:
2711: plog(LLV_DEBUG, LOCATION, NULL, "add payload of len %zu, next type %d\n",
2712: src->l, nptype);
2713:
2714: gen = (struct isakmp_gen *)p;
2715: gen->np = nptype;
2716: gen->len = htons(sizeof(*gen) + src->l);
2717: p += sizeof(*gen);
2718: memcpy(p, src->v, src->l);
2719: p += src->l;
2720:
2721: return p;
2722: }
2723:
2724: static int
2725: etypesw1(etype)
2726: int etype;
2727: {
2728: switch (etype) {
2729: case ISAKMP_ETYPE_IDENT:
2730: return 1;
2731: case ISAKMP_ETYPE_AGG:
2732: return 2;
2733: case ISAKMP_ETYPE_BASE:
2734: return 3;
2735: default:
2736: return 0;
2737: }
2738: /*NOTREACHED*/
2739: }
2740:
2741: static int
2742: etypesw2(etype)
2743: int etype;
2744: {
2745: switch (etype) {
2746: case ISAKMP_ETYPE_QUICK:
2747: return 1;
2748: default:
2749: return 0;
2750: }
2751: /*NOTREACHED*/
2752: }
2753:
2754: #ifdef HAVE_PRINT_ISAKMP_C
2755: /* for print-isakmp.c */
2756: char *snapend;
2757: extern void isakmp_print __P((const u_char *, u_int, const u_char *));
2758:
2759: char *getname __P((const u_char *));
2760: #ifdef INET6
2761: char *getname6 __P((const u_char *));
2762: #endif
2763: int safeputchar __P((int));
2764:
2765: /*
2766: * Return a name for the IP address pointed to by ap. This address
2767: * is assumed to be in network byte order.
2768: */
2769: char *
2770: getname(ap)
2771: const u_char *ap;
2772: {
2773: struct sockaddr_in addr;
2774: static char ntop_buf[NI_MAXHOST];
2775:
2776: memset(&addr, 0, sizeof(addr));
2777: #ifndef __linux__
2778: addr.sin_len = sizeof(struct sockaddr_in);
2779: #endif
2780: addr.sin_family = AF_INET;
2781: memcpy(&addr.sin_addr, ap, sizeof(addr.sin_addr));
2782: if (getnameinfo((struct sockaddr *)&addr, sizeof(addr),
2783: ntop_buf, sizeof(ntop_buf), NULL, 0,
2784: NI_NUMERICHOST | niflags))
2785: strlcpy(ntop_buf, "?", sizeof(ntop_buf));
2786:
2787: return ntop_buf;
2788: }
2789:
2790: #ifdef INET6
2791: /*
2792: * Return a name for the IP6 address pointed to by ap. This address
2793: * is assumed to be in network byte order.
2794: */
2795: char *
2796: getname6(ap)
2797: const u_char *ap;
2798: {
2799: struct sockaddr_in6 addr;
2800: static char ntop_buf[NI_MAXHOST];
2801:
2802: memset(&addr, 0, sizeof(addr));
2803: addr.sin6_len = sizeof(struct sockaddr_in6);
2804: addr.sin6_family = AF_INET6;
2805: memcpy(&addr.sin6_addr, ap, sizeof(addr.sin6_addr));
2806: if (getnameinfo((struct sockaddr *)&addr, addr.sin6_len,
2807: ntop_buf, sizeof(ntop_buf), NULL, 0,
2808: NI_NUMERICHOST | niflags))
2809: strlcpy(ntop_buf, "?", sizeof(ntop_buf));
2810:
2811: return ntop_buf;
2812: }
2813: #endif /* INET6 */
2814:
2815: int
2816: safeputchar(c)
2817: int c;
2818: {
2819: unsigned char ch;
2820:
2821: ch = (unsigned char)(c & 0xff);
2822: if (c < 0x80 && isprint(c))
2823: return printf("%c", c & 0xff);
2824: else
2825: return printf("\\%03o", c & 0xff);
2826: }
2827:
2828: void
2829: isakmp_printpacket(msg, from, my, decoded)
2830: vchar_t *msg;
2831: struct sockaddr *from;
2832: struct sockaddr *my;
2833: int decoded;
2834: {
2835: #ifdef YIPS_DEBUG
2836: struct timeval tv;
2837: int s;
2838: char hostbuf[NI_MAXHOST];
2839: char portbuf[NI_MAXSERV];
2840: struct isakmp *isakmp;
2841: vchar_t *buf;
2842: #endif
2843:
2844: if (loglevel < LLV_DEBUG)
2845: return;
2846:
2847: #ifdef YIPS_DEBUG
2848: plog(LLV_DEBUG, LOCATION, NULL, "begin.\n");
2849:
2850: gettimeofday(&tv, NULL);
2851: s = tv.tv_sec % 3600;
2852: printf("%02d:%02d.%06u ", s / 60, s % 60, (u_int32_t)tv.tv_usec);
2853:
2854: if (from) {
2855: if (getnameinfo(from, sysdep_sa_len(from), hostbuf, sizeof(hostbuf),
2856: portbuf, sizeof(portbuf),
2857: NI_NUMERICHOST | NI_NUMERICSERV | niflags)) {
2858: strlcpy(hostbuf, "?", sizeof(hostbuf));
2859: strlcpy(portbuf, "?", sizeof(portbuf));
2860: }
2861: printf("%s:%s", hostbuf, portbuf);
2862: } else
2863: printf("?");
2864: printf(" -> ");
2865: if (my) {
2866: if (getnameinfo(my, sysdep_sa_len(my), hostbuf, sizeof(hostbuf),
2867: portbuf, sizeof(portbuf),
2868: NI_NUMERICHOST | NI_NUMERICSERV | niflags)) {
2869: strlcpy(hostbuf, "?", sizeof(hostbuf));
2870: strlcpy(portbuf, "?", sizeof(portbuf));
2871: }
2872: printf("%s:%s", hostbuf, portbuf);
2873: } else
2874: printf("?");
2875: printf(": ");
2876:
2877: buf = vdup(msg);
2878: if (!buf) {
2879: printf("(malloc fail)\n");
2880: return;
2881: }
2882: if (decoded) {
2883: isakmp = (struct isakmp *)buf->v;
2884: if (isakmp->flags & ISAKMP_FLAG_E) {
2885: #if 0
2886: int pad;
2887: pad = *(u_char *)(buf->v + buf->l - 1);
2888: if (buf->l < pad && 2 < vflag)
2889: printf("(wrong padding)");
2890: #endif
2891: isakmp->flags &= ~ISAKMP_FLAG_E;
2892: }
2893: }
2894:
2895: snapend = buf->v + buf->l;
2896: isakmp_print(buf->v, buf->l, NULL);
2897: vfree(buf);
2898: printf("\n");
2899: fflush(stdout);
2900:
2901: return;
2902: #endif
2903: }
2904: #endif /*HAVE_PRINT_ISAKMP_C*/
2905:
2906: int
2907: copy_ph1addresses(iph1, rmconf, remote, local)
2908: struct ph1handle *iph1;
2909: struct remoteconf *rmconf;
2910: struct sockaddr *remote, *local;
2911: {
2912: u_int16_t port;
2913:
2914: /* address portion must be grabbed from real remote address "remote" */
2915: iph1->remote = dupsaddr(remote);
2916: if (iph1->remote == NULL)
2917: return -1;
2918:
2919: /*
2920: * if remote has no port # (in case of initiator - from ACQUIRE msg)
2921: * - if remote.conf specifies port #, use that
2922: * - if remote.conf does not, use 500
2923: * if remote has port # (in case of responder - from recvfrom(2))
2924: * respect content of "remote".
2925: */
2926: if (extract_port(iph1->remote) == 0) {
2927: port = 0;
2928: if (rmconf != NULL)
2929: port = extract_port(rmconf->remote);
2930: if (port == 0)
2931: port = PORT_ISAKMP;
2932: set_port(iph1->remote, port);
2933: }
2934:
2935: if (local == NULL)
2936: iph1->local = getlocaladdr(iph1->remote);
2937: else
2938: iph1->local = dupsaddr(local);
2939: if (iph1->local == NULL)
2940: return -1;
2941:
2942: if (extract_port(iph1->local) == 0) {
2943: port = myaddr_getsport(iph1->local);
2944: if (port == 0)
2945: port = PORT_ISAKMP;
2946: set_port(iph1->local, PORT_ISAKMP);
2947: }
2948:
2949: #ifdef ENABLE_NATT
2950: if (extract_port(iph1->local) == lcconf->port_isakmp_natt) {
2951: plog(LLV_DEBUG, LOCATION, NULL, "Marking ports as changed\n");
2952: iph1->natt_flags |= NAT_ADD_NON_ESP_MARKER;
2953: }
2954: #endif
2955:
2956: return 0;
2957: }
2958:
2959: static int
2960: nostate1(iph1, msg)
2961: struct ph1handle *iph1;
2962: vchar_t *msg;
2963: {
2964: plog(LLV_ERROR, LOCATION, iph1->remote, "wrong state %u.\n",
2965: iph1->status);
2966: return -1;
2967: }
2968:
2969: static int
2970: nostate2(iph2, msg)
2971: struct ph2handle *iph2;
2972: vchar_t *msg;
2973: {
2974: plog(LLV_ERROR, LOCATION, iph2->ph1->remote, "wrong state %u.\n",
2975: iph2->status);
2976: return -1;
2977: }
2978:
2979: void
2980: log_ph1established(iph1)
2981: const struct ph1handle *iph1;
2982: {
2983: char *src, *dst;
2984:
2985: src = racoon_strdup(saddr2str(iph1->local));
2986: dst = racoon_strdup(saddr2str(iph1->remote));
2987: STRDUP_FATAL(src);
2988: STRDUP_FATAL(dst);
2989:
2990: plog(LLV_INFO, LOCATION, NULL,
2991: "ISAKMP-SA established %s-%s spi:%s\n",
2992: src, dst,
2993: isakmp_pindex(&iph1->index, 0));
2994:
2995: evt_phase1(iph1, EVT_PHASE1_UP, NULL);
2996: if(!iph1->rmconf->mode_cfg)
2997: evt_phase1(iph1, EVT_PHASE1_MODE_CFG, NULL);
2998:
2999: racoon_free(src);
3000: racoon_free(dst);
3001:
3002: return;
3003: }
3004:
3005: struct payload_list *
3006: isakmp_plist_append_full (struct payload_list *plist, vchar_t *payload,
3007: u_int8_t payload_type, u_int8_t free_payload)
3008: {
3009: if (! plist) {
3010: plist = racoon_malloc (sizeof (struct payload_list));
3011: plist->prev = NULL;
3012: }
3013: else {
3014: plist->next = racoon_malloc (sizeof (struct payload_list));
3015: plist->next->prev = plist;
3016: plist = plist->next;
3017: }
3018:
3019: plist->next = NULL;
3020: plist->payload = payload;
3021: plist->payload_type = payload_type;
3022: plist->free_payload = free_payload;
3023:
3024: return plist;
3025: }
3026:
3027: vchar_t *
3028: isakmp_plist_set_all (struct payload_list **plist, struct ph1handle *iph1)
3029: {
3030: struct payload_list *ptr = *plist, *first;
3031: size_t tlen = sizeof (struct isakmp), n = 0;
3032: vchar_t *buf = NULL;
3033: char *p;
3034:
3035: /* Seek to the first item. */
3036: while (ptr->prev) ptr = ptr->prev;
3037: first = ptr;
3038:
3039: /* Compute the whole length. */
3040: while (ptr) {
3041: tlen += ptr->payload->l + sizeof (struct isakmp_gen);
3042: ptr = ptr->next;
3043: }
3044:
3045: buf = vmalloc(tlen);
3046: if (buf == NULL) {
3047: plog(LLV_ERROR, LOCATION, NULL,
3048: "failed to get buffer to send.\n");
3049: goto end;
3050: }
3051:
3052: ptr = first;
3053:
3054: p = set_isakmp_header1(buf, iph1, ptr->payload_type);
3055: if (p == NULL)
3056: goto end;
3057:
3058: while (ptr)
3059: {
3060: p = set_isakmp_payload (p, ptr->payload, ptr->next ? ptr->next->payload_type : ISAKMP_NPTYPE_NONE);
3061: first = ptr;
3062: ptr = ptr->next;
3063: if (first->free_payload)
3064: vfree(first->payload);
3065: racoon_free (first);
3066: /* ptr->prev = NULL; first = NULL; ... omitted. */
3067: n++;
3068: }
3069:
3070: *plist = NULL;
3071:
3072: return buf;
3073: end:
3074: if (buf != NULL)
3075: vfree(buf);
3076: return NULL;
3077: }
3078:
3079: #ifdef ENABLE_FRAG
3080: int
3081: frag_handler(iph1, msg, remote, local)
3082: struct ph1handle *iph1;
3083: vchar_t *msg;
3084: struct sockaddr *remote;
3085: struct sockaddr *local;
3086: {
3087: vchar_t *newmsg;
3088:
3089: if (isakmp_frag_extract(iph1, msg) == 1) {
3090: if ((newmsg = isakmp_frag_reassembly(iph1)) == NULL) {
3091: plog(LLV_ERROR, LOCATION, remote,
3092: "Packet reassembly failed\n");
3093: return -1;
3094: }
3095: return isakmp_main(newmsg, remote, local);
3096: }
3097:
3098: return 0;
3099: }
3100: #endif
3101:
3102: void
3103: script_hook(iph1, script)
3104: struct ph1handle *iph1;
3105: int script;
3106: {
3107: #define IP_MAX 40
3108: #define PORT_MAX 6
3109: char addrstr[IP_MAX];
3110: char portstr[PORT_MAX];
3111: char **envp = NULL;
3112: int envc = 1;
3113: char **c;
3114:
3115: if (iph1 == NULL ||
3116: iph1->rmconf == NULL ||
3117: iph1->rmconf->script[script] == NULL)
3118: return;
3119:
3120: #ifdef ENABLE_HYBRID
3121: (void)isakmp_cfg_setenv(iph1, &envp, &envc);
3122: #endif
3123:
3124: /* local address */
3125: GETNAMEINFO(iph1->local, addrstr, portstr);
3126:
3127: if (script_env_append(&envp, &envc, "LOCAL_ADDR", addrstr) != 0) {
3128: plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_ADDR\n");
3129: goto out;
3130: }
3131:
3132: if (script_env_append(&envp, &envc, "LOCAL_PORT", portstr) != 0) {
3133: plog(LLV_ERROR, LOCATION, NULL, "Cannot set LOCAL_PORT\n");
3134: goto out;
3135: }
3136:
3137: /* Peer address */
3138: if (iph1->remote != NULL) {
3139: GETNAMEINFO(iph1->remote, addrstr, portstr);
3140:
3141: if (script_env_append(&envp, &envc,
3142: "REMOTE_ADDR", addrstr) != 0) {
3143: plog(LLV_ERROR, LOCATION, NULL,
3144: "Cannot set REMOTE_ADDR\n");
3145: goto out;
3146: }
3147:
3148: if (script_env_append(&envp, &envc,
3149: "REMOTE_PORT", portstr) != 0) {
3150: plog(LLV_ERROR, LOCATION, NULL,
3151: "Cannot set REMOTEL_PORT\n");
3152: goto out;
3153: }
3154: }
3155:
3156: /* Peer identity. */
3157: if (iph1->id_p != NULL) {
3158: if (script_env_append(&envp, &envc, "REMOTE_ID",
3159: ipsecdoi_id2str(iph1->id_p)) != 0) {
3160: plog(LLV_ERROR, LOCATION, NULL,
3161: "Cannot set REMOTE_ID\n");
3162: goto out;
3163: }
3164: }
3165:
3166: if (privsep_script_exec(iph1->rmconf->script[script]->v,
3167: script, envp) != 0)
3168: plog(LLV_ERROR, LOCATION, NULL,
3169: "Script %s execution failed\n", script_names[script]);
3170:
3171: out:
3172: for (c = envp; *c; c++)
3173: racoon_free(*c);
3174:
3175: racoon_free(envp);
3176:
3177: return;
3178: }
3179:
3180: int
3181: script_env_append(envp, envc, name, value)
3182: char ***envp;
3183: int *envc;
3184: char *name;
3185: char *value;
3186: {
3187: char *envitem;
3188: char **newenvp;
3189: int newenvc;
3190:
3191: envitem = racoon_malloc(strlen(name) + 1 + strlen(value) + 1);
3192: if (envitem == NULL) {
3193: plog(LLV_ERROR, LOCATION, NULL,
3194: "Cannot allocate memory: %s\n", strerror(errno));
3195: return -1;
3196: }
3197: sprintf(envitem, "%s=%s", name, value);
3198:
3199: newenvc = (*envc) + 1;
3200: newenvp = racoon_realloc(*envp, newenvc * sizeof(char *));
3201: if (newenvp == NULL) {
3202: plog(LLV_ERROR, LOCATION, NULL,
3203: "Cannot allocate memory: %s\n", strerror(errno));
3204: racoon_free(envitem);
3205: return -1;
3206: }
3207:
3208: newenvp[newenvc - 2] = envitem;
3209: newenvp[newenvc - 1] = NULL;
3210:
3211: *envp = newenvp;
3212: *envc = newenvc;
3213: return 0;
3214: }
3215:
3216: int
3217: script_exec(script, name, envp)
3218: char *script;
3219: int name;
3220: char *const envp[];
3221: {
3222: char *argv[] = { NULL, NULL, NULL };
3223:
3224: argv[0] = script;
3225: argv[1] = script_names[name];
3226: argv[2] = NULL;
3227:
3228: switch (fork()) {
3229: case 0:
3230: execve(argv[0], argv, envp);
3231: plog(LLV_ERROR, LOCATION, NULL,
3232: "execve(\"%s\") failed: %s\n",
3233: argv[0], strerror(errno));
3234: _exit(1);
3235: break;
3236: case -1:
3237: plog(LLV_ERROR, LOCATION, NULL,
3238: "Cannot fork: %s\n", strerror(errno));
3239: return -1;
3240: break;
3241: default:
3242: break;
3243: }
3244: return 0;
3245:
3246: }
3247:
3248: void
3249: purge_remote(iph1)
3250: struct ph1handle *iph1;
3251: {
3252: vchar_t *buf = NULL;
3253: struct sadb_msg *msg, *next, *end;
3254: struct sadb_sa *sa;
3255: struct sockaddr *src, *dst;
3256: caddr_t mhp[SADB_EXT_MAX + 1];
3257: u_int proto_id;
3258: struct ph2handle *iph2;
3259: struct ph1handle *new_iph1;
3260:
3261: plog(LLV_INFO, LOCATION, NULL,
3262: "purging ISAKMP-SA spi=%s.\n",
3263: isakmp_pindex(&(iph1->index), iph1->msgid));
3264:
3265: /* Mark as expired. */
3266: iph1->status = PHASE1ST_EXPIRED;
3267:
3268: /* Check if we have another, still valid, phase1 SA. */
3269: new_iph1 = getph1(iph1, iph1->local, iph1->remote, GETPH1_F_ESTABLISHED);
3270:
3271: /*
3272: * Delete all orphaned or binded to the deleting ph1handle phase2 SAs.
3273: * Keep all others phase2 SAs.
3274: */
3275: buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
3276: if (buf == NULL) {
3277: plog(LLV_DEBUG, LOCATION, NULL,
3278: "pfkey_dump_sadb returned nothing.\n");
3279: return;
3280: }
3281:
3282: msg = (struct sadb_msg *)buf->v;
3283: end = (struct sadb_msg *)(buf->v + buf->l);
3284:
3285: while (msg < end) {
3286: if ((msg->sadb_msg_len << 3) < sizeof(*msg))
3287: break;
3288: next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
3289: if (msg->sadb_msg_type != SADB_DUMP) {
3290: msg = next;
3291: continue;
3292: }
3293:
3294: if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
3295: plog(LLV_ERROR, LOCATION, NULL,
3296: "pfkey_check (%s)\n", ipsec_strerror());
3297: msg = next;
3298: continue;
3299: }
3300:
3301: sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]);
3302: if (!sa ||
3303: !mhp[SADB_EXT_ADDRESS_SRC] ||
3304: !mhp[SADB_EXT_ADDRESS_DST]) {
3305: msg = next;
3306: continue;
3307: }
3308: pk_fixup_sa_addresses(mhp);
3309: src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
3310: dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
3311:
3312: if (sa->sadb_sa_state != SADB_SASTATE_LARVAL &&
3313: sa->sadb_sa_state != SADB_SASTATE_MATURE &&
3314: sa->sadb_sa_state != SADB_SASTATE_DYING) {
3315: msg = next;
3316: continue;
3317: }
3318:
3319: /*
3320: * check in/outbound SAs.
3321: * Select only SAs where src == local and dst == remote (outgoing)
3322: * or src == remote and dst == local (incoming).
3323: */
3324: if ((cmpsaddr(iph1->local, src) != CMPSADDR_MATCH ||
3325: cmpsaddr(iph1->remote, dst) != CMPSADDR_MATCH) &&
3326: (cmpsaddr(iph1->local, dst) != CMPSADDR_MATCH ||
3327: cmpsaddr(iph1->remote, src) != CMPSADDR_MATCH)) {
3328: msg = next;
3329: continue;
3330: }
3331:
3332: proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
3333: iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
3334:
3335: /* Check if there is another valid ISAKMP-SA */
3336: if (new_iph1 != NULL) {
3337:
3338: if (iph2 == NULL) {
3339: /* No handler... still send a pfkey_delete message, but log this !*/
3340: plog(LLV_INFO, LOCATION, NULL,
3341: "Unknown IPsec-SA spi=%u, hmmmm?\n",
3342: ntohl(sa->sadb_sa_spi));
3343: }else{
3344:
3345: /*
3346: * If we have a new ph1, do not purge IPsec-SAs binded
3347: * to a different ISAKMP-SA
3348: */
3349: if (iph2->ph1 != NULL && iph2->ph1 != iph1){
3350: msg = next;
3351: continue;
3352: }
3353:
3354: /* If the ph2handle is established, do not purge IPsec-SA */
3355: if (iph2->status == PHASE2ST_ESTABLISHED ||
3356: iph2->status == PHASE2ST_EXPIRED) {
3357:
3358: plog(LLV_INFO, LOCATION, NULL,
3359: "keeping IPsec-SA spi=%u - found valid ISAKMP-SA spi=%s.\n",
3360: ntohl(sa->sadb_sa_spi),
3361: isakmp_pindex(&(new_iph1->index), new_iph1->msgid));
3362: msg = next;
3363: continue;
3364: }
3365: }
3366: }
3367:
3368:
3369: pfkey_send_delete(lcconf->sock_pfkey,
3370: msg->sadb_msg_satype,
3371: IPSEC_MODE_ANY,
3372: src, dst, sa->sadb_sa_spi);
3373:
3374: /* delete a relative phase 2 handle. */
3375: if (iph2 != NULL) {
3376: delete_spd(iph2, 0);
3377: remph2(iph2);
3378: delph2(iph2);
3379: }
3380:
3381: plog(LLV_INFO, LOCATION, NULL,
3382: "purged IPsec-SA spi=%u.\n",
3383: ntohl(sa->sadb_sa_spi));
3384:
3385: msg = next;
3386: }
3387:
3388: if (buf)
3389: vfree(buf);
3390:
3391: /* Mark the phase1 handler as EXPIRED */
3392: plog(LLV_INFO, LOCATION, NULL,
3393: "purged ISAKMP-SA spi=%s.\n",
3394: isakmp_pindex(&(iph1->index), iph1->msgid));
3395:
3396: isakmp_ph1delete(iph1);
3397: }
3398:
3399: void
3400: delete_spd(iph2, created)
3401: struct ph2handle *iph2;
3402: u_int64_t created;
3403: {
3404: struct policyindex spidx;
3405: struct sockaddr_storage addr;
3406: u_int8_t pref;
3407: struct sockaddr *src;
3408: struct sockaddr *dst;
3409: int error;
3410: int idi2type = 0;/* switch whether copy IDs into id[src,dst]. */
3411:
3412: if (iph2 == NULL)
3413: return;
3414:
3415: /* Delete the SPD entry if we generated it
3416: */
3417: if (! iph2->generated_spidx )
3418: return;
3419:
3420: src = iph2->src;
3421: dst = iph2->dst;
3422:
3423: plog(LLV_INFO, LOCATION, NULL,
3424: "deleting a generated policy.\n");
3425:
3426: memset(&spidx, 0, sizeof(spidx));
3427: iph2->spidx_gen = (caddr_t )&spidx;
3428:
3429: /* make inbound policy */
3430: iph2->src = dst;
3431: iph2->dst = src;
3432: spidx.dir = IPSEC_DIR_INBOUND;
3433: spidx.ul_proto = 0;
3434:
3435: /*
3436: * Note: code from get_proposal_r
3437: */
3438:
3439: #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
3440:
3441: /*
3442: * make destination address in spidx from either ID payload
3443: * or phase 1 address into a address in spidx.
3444: */
3445: if (iph2->id != NULL
3446: && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
3447: || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
3448: || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
3449: || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
3450: /* get a destination address of a policy */
3451: error = ipsecdoi_id2sockaddr(iph2->id,
3452: (struct sockaddr *)&spidx.dst,
3453: &spidx.prefd, &spidx.ul_proto);
3454: if (error)
3455: goto purge;
3456:
3457: #ifdef INET6
3458: /*
3459: * get scopeid from the SA address.
3460: * note that the phase 1 source address is used as
3461: * a destination address to search for a inbound
3462: * policy entry because rcoon is responder.
3463: */
3464: if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
3465: if ((error =
3466: setscopeid((struct sockaddr *)&spidx.dst,
3467: iph2->src)) != 0)
3468: goto purge;
3469: }
3470: #endif
3471:
3472: if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
3473: || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
3474: idi2type = _XIDT(iph2->id);
3475:
3476: } else {
3477:
3478: plog(LLV_DEBUG, LOCATION, NULL,
3479: "get a destination address of SP index "
3480: "from phase1 address "
3481: "due to no ID payloads found "
3482: "OR because ID type is not address.\n");
3483:
3484: /*
3485: * copy the SOURCE address of IKE into the
3486: * DESTINATION address of the key to search the
3487: * SPD because the direction of policy is inbound.
3488: */
3489: memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src));
3490: switch (spidx.dst.ss_family) {
3491: case AF_INET:
3492: spidx.prefd =
3493: sizeof(struct in_addr) << 3;
3494: break;
3495: #ifdef INET6
3496: case AF_INET6:
3497: spidx.prefd =
3498: sizeof(struct in6_addr) << 3;
3499: break;
3500: #endif
3501: default:
3502: spidx.prefd = 0;
3503: break;
3504: }
3505: }
3506:
3507: /* make source address in spidx */
3508: if (iph2->id_p != NULL
3509: && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
3510: || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
3511: || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
3512: || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
3513: /* get a source address of inbound SA */
3514: error = ipsecdoi_id2sockaddr(iph2->id_p,
3515: (struct sockaddr *)&spidx.src,
3516: &spidx.prefs, &spidx.ul_proto);
3517: if (error)
3518: goto purge;
3519:
3520: #ifdef INET6
3521: /*
3522: * get scopeid from the SA address.
3523: * for more detail, see above of this function.
3524: */
3525: if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
3526: error =
3527: setscopeid((struct sockaddr *)&spidx.src,
3528: iph2->dst);
3529: if (error)
3530: goto purge;
3531: }
3532: #endif
3533:
3534: /* make sa_[src,dst] if both ID types are IP address and same */
3535: if (_XIDT(iph2->id_p) == idi2type
3536: && spidx.dst.ss_family == spidx.src.ss_family) {
3537: iph2->sa_src =
3538: dupsaddr((struct sockaddr *)&spidx.dst);
3539: if (iph2->sa_src == NULL) {
3540: plog(LLV_ERROR, LOCATION, NULL,
3541: "allocation failed\n");
3542: goto purge;
3543: }
3544: iph2->sa_dst =
3545: dupsaddr((struct sockaddr *)&spidx.src);
3546: if (iph2->sa_dst == NULL) {
3547: plog(LLV_ERROR, LOCATION, NULL,
3548: "allocation failed\n");
3549: goto purge;
3550: }
3551: }
3552:
3553: } else {
3554: plog(LLV_DEBUG, LOCATION, NULL,
3555: "get a source address of SP index "
3556: "from phase1 address "
3557: "due to no ID payloads found "
3558: "OR because ID type is not address.\n");
3559:
3560: /* see above comment. */
3561: memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst));
3562: switch (spidx.src.ss_family) {
3563: case AF_INET:
3564: spidx.prefs =
3565: sizeof(struct in_addr) << 3;
3566: break;
3567: #ifdef INET6
3568: case AF_INET6:
3569: spidx.prefs =
3570: sizeof(struct in6_addr) << 3;
3571: break;
3572: #endif
3573: default:
3574: spidx.prefs = 0;
3575: break;
3576: }
3577: }
3578:
3579: #undef _XIDT
3580:
3581: plog(LLV_DEBUG, LOCATION, NULL,
3582: "get a src address from ID payload "
3583: "%s prefixlen=%u ul_proto=%u\n",
3584: saddr2str((struct sockaddr *)&spidx.src),
3585: spidx.prefs, spidx.ul_proto);
3586: plog(LLV_DEBUG, LOCATION, NULL,
3587: "get dst address from ID payload "
3588: "%s prefixlen=%u ul_proto=%u\n",
3589: saddr2str((struct sockaddr *)&spidx.dst),
3590: spidx.prefd, spidx.ul_proto);
3591:
3592: /*
3593: * convert the ul_proto if it is 0
3594: * because 0 in ID payload means a wild card.
3595: */
3596: if (spidx.ul_proto == 0)
3597: spidx.ul_proto = IPSEC_ULPROTO_ANY;
3598:
3599: #undef _XIDT
3600:
3601: /* Check if the generated SPD has the same timestamp as the SA.
3602: * If timestamps are different, this means that the SPD entry has been
3603: * refreshed by another SA, and should NOT be deleted with the current SA.
3604: */
3605: if( created ){
3606: struct secpolicy *p;
3607:
3608: p = getsp(&spidx);
3609: if(p != NULL){
3610: /* just do no test if p is NULL, because this probably just means
3611: * that the policy has already be deleted for some reason.
3612: */
3613: if(p->spidx.created != created)
3614: goto purge;
3615: }
3616: }
3617:
3618: /* End of code from get_proposal_r
3619: */
3620:
3621: if (pk_sendspddelete(iph2) < 0) {
3622: plog(LLV_ERROR, LOCATION, NULL,
3623: "pfkey spddelete(inbound) failed.\n");
3624: }else{
3625: plog(LLV_DEBUG, LOCATION, NULL,
3626: "pfkey spddelete(inbound) sent.\n");
3627: }
3628:
3629: #ifdef HAVE_POLICY_FWD
3630: /* make forward policy if required */
3631: if (tunnel_mode_prop(iph2->approval)) {
3632: spidx.dir = IPSEC_DIR_FWD;
3633: if (pk_sendspddelete(iph2) < 0) {
3634: plog(LLV_ERROR, LOCATION, NULL,
3635: "pfkey spddelete(forward) failed.\n");
3636: }else{
3637: plog(LLV_DEBUG, LOCATION, NULL,
3638: "pfkey spddelete(forward) sent.\n");
3639: }
3640: }
3641: #endif
3642:
3643: /* make outbound policy */
3644: iph2->src = src;
3645: iph2->dst = dst;
3646: spidx.dir = IPSEC_DIR_OUTBOUND;
3647: addr = spidx.src;
3648: spidx.src = spidx.dst;
3649: spidx.dst = addr;
3650: pref = spidx.prefs;
3651: spidx.prefs = spidx.prefd;
3652: spidx.prefd = pref;
3653:
3654: if (pk_sendspddelete(iph2) < 0) {
3655: plog(LLV_ERROR, LOCATION, NULL,
3656: "pfkey spddelete(outbound) failed.\n");
3657: }else{
3658: plog(LLV_DEBUG, LOCATION, NULL,
3659: "pfkey spddelete(outbound) sent.\n");
3660: }
3661: purge:
3662: iph2->spidx_gen=NULL;
3663: }
3664:
3665:
3666: #ifdef INET6
3667: u_int32_t
3668: setscopeid(sp_addr0, sa_addr0)
3669: struct sockaddr *sp_addr0, *sa_addr0;
3670: {
3671: struct sockaddr_in6 *sp_addr, *sa_addr;
3672:
3673: sp_addr = (struct sockaddr_in6 *)sp_addr0;
3674: sa_addr = (struct sockaddr_in6 *)sa_addr0;
3675:
3676: if (!IN6_IS_ADDR_LINKLOCAL(&sp_addr->sin6_addr)
3677: && !IN6_IS_ADDR_SITELOCAL(&sp_addr->sin6_addr)
3678: && !IN6_IS_ADDR_MULTICAST(&sp_addr->sin6_addr))
3679: return 0;
3680:
3681: /* this check should not be here ? */
3682: if (sa_addr->sin6_family != AF_INET6) {
3683: plog(LLV_ERROR, LOCATION, NULL,
3684: "can't get scope ID: family mismatch\n");
3685: return -1;
3686: }
3687:
3688: if (!IN6_IS_ADDR_LINKLOCAL(&sa_addr->sin6_addr)) {
3689: plog(LLV_ERROR, LOCATION, NULL,
3690: "scope ID is not supported except of lladdr.\n");
3691: return -1;
3692: }
3693:
3694: sp_addr->sin6_scope_id = sa_addr->sin6_scope_id;
3695:
3696: return 0;
3697: }
3698: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>