Annotation of embedaddon/ipsec-tools/src/racoon/backupsa.c, revision 1.1
1.1 ! misho 1: /* $NetBSD: backupsa.c,v 1.10 2010/04/02 15:15:00 christos Exp $ */
! 2:
! 3: /* $KAME: backupsa.c,v 1.16 2001/12/31 20:13:40 thorpej Exp $ */
! 4:
! 5: /*
! 6: * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
! 7: * All rights reserved.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: * 2. Redistributions in binary form must reproduce the above copyright
! 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
! 17: * 3. Neither the name of the project nor the names of its contributors
! 18: * may be used to endorse or promote products derived from this software
! 19: * without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 31: * SUCH DAMAGE.
! 32: */
! 33:
! 34: #include "config.h"
! 35:
! 36: #include <sys/types.h>
! 37: #include <sys/param.h>
! 38: #include <sys/socket.h>
! 39:
! 40: #include <stdlib.h>
! 41: #include <stdio.h>
! 42: #include <string.h>
! 43: #include <ctype.h>
! 44:
! 45: #include <netinet/in.h>
! 46: #include PATH_IPSEC_H
! 47:
! 48: #if TIME_WITH_SYS_TIME
! 49: # include <sys/time.h>
! 50: # include <time.h>
! 51: #else
! 52: # if HAVE_SYS_TIME_H
! 53: # include <sys/time.h>
! 54: # else
! 55: # include <time.h>
! 56: # endif
! 57: #endif
! 58:
! 59: #include "var.h"
! 60: #include "misc.h"
! 61: #include "vmbuf.h"
! 62: #include "str2val.h"
! 63: #include "plog.h"
! 64: #include "debug.h"
! 65:
! 66: #include "localconf.h"
! 67: #include "sockmisc.h"
! 68: #include "safefile.h"
! 69: #include "backupsa.h"
! 70: #include "libpfkey.h"
! 71:
! 72: /*
! 73: * (time string)%(sa parameter)
! 74: * (time string) := ex. Nov 24 18:22:48 1986
! 75: * (sa parameter) :=
! 76: * src dst satype spi mode reqid wsize \
! 77: * e_type e_keylen a_type a_keylen flags \
! 78: * l_alloc l_bytes l_addtime l_usetime seq keymat
! 79: */
! 80: static char *format = "%b %d %T %Y"; /* time format */
! 81: static char *strmon[12] = {
! 82: "Jan", "Feb", "Mar", "Apr", "May", "Jun",
! 83: "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
! 84: };
! 85:
! 86: static char *str2tmx __P((char *, struct tm *));
! 87: static int str2num __P((char *, int));
! 88:
! 89: /*
! 90: * output the sa parameter.
! 91: */
! 92: int
! 93: backupsa_to_file(sa_args)
! 94: struct pfkey_send_sa_args *sa_args;
! 95: {
! 96: char buf[1024];
! 97: struct tm *tm;
! 98: time_t t;
! 99: char *p, *k;
! 100: int len, l, i;
! 101: FILE *fp;
! 102:
! 103: p = buf;
! 104: len = sizeof(buf);
! 105:
! 106: t = time(NULL);
! 107: tm = localtime(&t);
! 108: l = strftime(p, len, format, tm);
! 109: p += l;
! 110: len -= l;
! 111: if (len < 0)
! 112: goto err;
! 113:
! 114: l = snprintf(p, len, "%%");
! 115: if (l < 0 || l >= len)
! 116: goto err;
! 117: p += l;
! 118: len -= l;
! 119: if (len < 0)
! 120: goto err;
! 121:
! 122: i = getnameinfo(sa_args->src, sysdep_sa_len(sa_args->src), p, len, NULL, 0, NIFLAGS);
! 123: if (i != 0)
! 124: goto err;
! 125: l = strlen(p);
! 126: p += l;
! 127: len -= l;
! 128: if (len < 0)
! 129: goto err;
! 130:
! 131: l = snprintf(p, len, " ");
! 132: if (l < 0 || l >= len)
! 133: goto err;
! 134: p += l;
! 135: len -= l;
! 136: if (len < 0)
! 137: goto err;
! 138:
! 139: i = getnameinfo(sa_args->dst, sysdep_sa_len(sa_args->dst), p, len, NULL, 0, NIFLAGS);
! 140: if (i != 0)
! 141: goto err;
! 142: l = strlen(p);
! 143: p += l;
! 144: len -= l;
! 145: if (len < 0)
! 146: goto err;
! 147:
! 148: l = snprintf(p, len,
! 149: " %u %lu %u %u %u "
! 150: "%u %u %u %u %u "
! 151: "%u %llu %llu %llu %u",
! 152: sa_args->satype, (unsigned long)ntohl(sa_args->spi),
! 153: sa_args->mode, sa_args->reqid, sa_args->wsize, sa_args->e_type,
! 154: sa_args->e_keylen, sa_args->a_type, sa_args->a_keylen,
! 155: sa_args->flags, sa_args->l_alloc,
! 156: (unsigned long long)sa_args->l_bytes,
! 157: (unsigned long long)sa_args->l_addtime,
! 158: (unsigned long long)sa_args->l_usetime, sa_args->seq);
! 159:
! 160: if (l < 0 || l >= len)
! 161: goto err;
! 162: p += l;
! 163: len -= l;
! 164: if (len < 0)
! 165: goto err;
! 166:
! 167: k = val2str(sa_args->keymat, sa_args->e_keylen + sa_args->a_keylen);
! 168: l = snprintf(p, len, " %s", k);
! 169: racoon_free(k);
! 170: if (l < 0 || l >= len)
! 171: goto err;
! 172: p += l;
! 173: len -= l;
! 174: if (len < 0)
! 175: goto err;
! 176:
! 177: /* open the file and write the SA parameter */
! 178: if (safefile(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], 1) != 0 ||
! 179: (fp = fopen(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], "a")) == NULL) {
! 180: plog(LLV_ERROR, LOCATION, NULL,
! 181: "failed to open the backup file %s.\n",
! 182: lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]);
! 183: return -1;
! 184: }
! 185: fprintf(fp, "%s\n", buf);
! 186: fclose(fp);
! 187:
! 188: return 0;
! 189:
! 190: err:
! 191: plog(LLV_ERROR, LOCATION, NULL,
! 192: "SA cannot be saved to a file.\n");
! 193: return -1;
! 194: }
! 195:
! 196: int
! 197: backupsa_from_file()
! 198: {
! 199: FILE *fp;
! 200: char buf[512];
! 201: struct tm tm;
! 202: time_t created, current;
! 203: char *p, *q;
! 204: size_t keymatlen;
! 205: int line;
! 206: struct pfkey_send_sa_args sa_args;
! 207:
! 208: memset(&sa_args, 0, sizeof(sa_args));
! 209:
! 210: if (safefile(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], 1) == 0)
! 211: fp = fopen(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], "r");
! 212: else
! 213: fp = NULL;
! 214: if (fp == NULL) {
! 215: plog(LLV_ERROR, LOCATION, NULL,
! 216: "failed to open the backup file %s.\n",
! 217: lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]);
! 218: return -1;
! 219: }
! 220:
! 221: current = time(NULL);
! 222:
! 223: for(line = 1; fgets(buf, sizeof(buf), fp) != NULL; line++) {
! 224: /* comment line */
! 225: if (buf[0] == '#')
! 226: continue;
! 227:
! 228: memset(&tm, 0, sizeof(tm));
! 229: p = str2tmx(buf, &tm);
! 230: if (*p != '%') {
! 231: err:
! 232: plog(LLV_ERROR, LOCATION, NULL,
! 233: "illegal format line#%d in %s: %s\n",
! 234: line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA],
! 235: buf);
! 236: goto next;
! 237: }
! 238: created = mktime(&tm);
! 239: p++;
! 240:
! 241: for (q = p; *q != '\0' && !isspace((int)*q); q++)
! 242: ;
! 243: *q = '\0';
! 244: if ((sa_args.src = str2saddr(p, NULL)) == NULL)
! 245: goto next;
! 246: p = q + 1;
! 247:
! 248: for (q = p; *q != '\0' && !isspace((int)*q); q++)
! 249: ;
! 250: *q = '\0';
! 251: if ((sa_args.dst = str2saddr(p, NULL)) == NULL)
! 252: goto next;
! 253: p = q + 1;
! 254:
! 255: #define GETNEXTNUM(value, function) \
! 256: do { \
! 257: char *y; \
! 258: for (q = p; *q != '\0' && !isspace((int)*q); q++) \
! 259: ; \
! 260: *q = '\0'; \
! 261: (value) = function(p, &y, 10); \
! 262: if ((value) == 0 && *y != '\0') \
! 263: goto next; \
! 264: p = q + 1; \
! 265: } while (/*CONSTCOND*/0);
! 266:
! 267: GETNEXTNUM(sa_args.satype, strtoul);
! 268: GETNEXTNUM(sa_args.spi, strtoul);
! 269: sa_args.spi = ntohl(sa_args.spi);
! 270: GETNEXTNUM(sa_args.mode, strtoul);
! 271: GETNEXTNUM(sa_args.reqid, strtoul);
! 272: GETNEXTNUM(sa_args.wsize, strtoul);
! 273: GETNEXTNUM(sa_args.e_type, strtoul);
! 274: GETNEXTNUM(sa_args.e_keylen, strtoul);
! 275: GETNEXTNUM(sa_args.a_type, strtoul);
! 276: GETNEXTNUM(sa_args.a_keylen, strtoul);
! 277: GETNEXTNUM(sa_args.flags, strtoul);
! 278: GETNEXTNUM(sa_args.l_alloc, strtoul);
! 279: GETNEXTNUM(sa_args.l_bytes, strtouq);
! 280: GETNEXTNUM(sa_args.l_addtime, strtouq);
! 281: GETNEXTNUM(sa_args.l_usetime, strtouq);
! 282: GETNEXTNUM(sa_args.seq, strtoul);
! 283:
! 284: #undef GETNEXTNUM
! 285:
! 286: sa_args.keymat = str2val(p, 16, &keymatlen);
! 287: if (sa_args.keymat == NULL) {
! 288: plog(LLV_ERROR, LOCATION, NULL,
! 289: "illegal format(keymat) line#%d in %s: %s\n",
! 290: line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA],
! 291: buf);
! 292: goto next;
! 293: }
! 294:
! 295: if (created + sa_args.l_addtime < current) {
! 296: plog(LLV_DEBUG, LOCATION, NULL,
! 297: "ignore this line#%d in %s due to expiration\n",
! 298: line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]);
! 299: goto next;
! 300: }
! 301: sa_args.l_addtime -= current - created;
! 302:
! 303: if (pfkey_send_add2(&sa_args) < 0) {
! 304: plog(LLV_ERROR, LOCATION, NULL,
! 305: "restore SA failed line#%d in %s: %s\n",
! 306: line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA],
! 307: ipsec_strerror());
! 308: }
! 309:
! 310: next:
! 311: if (sa_args.src != NULL) {
! 312: racoon_free(sa_args.src);
! 313: sa_args.src = NULL;
! 314: }
! 315: if (sa_args.dst != NULL) {
! 316: racoon_free(sa_args.dst);
! 317: sa_args.dst = NULL;
! 318: }
! 319: if (sa_args.keymat != NULL) {
! 320: racoon_free(sa_args.keymat);
! 321: sa_args.keymat = NULL;
! 322: }
! 323: }
! 324:
! 325: fclose(fp);
! 326:
! 327: /*
! 328: * There is a possibility that an abnormal system down will happen
! 329: * again before new negotiation will be started. so racoon clears
! 330: * the backup file here. it's ok that old SAs are remained in the
! 331: * file. any old SA will not be installed because racoon checks the
! 332: * lifetime and compare with current time.
! 333: */
! 334:
! 335: return 0;
! 336: }
! 337:
! 338: int
! 339: backupsa_clean()
! 340: {
! 341: FILE *fp;
! 342:
! 343: /* simply return if the file is not defined. */
! 344: if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
! 345: return 0;
! 346:
! 347: fp = fopen(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], "w+");
! 348: if (fp == NULL) {
! 349: plog(LLV_ERROR, LOCATION, NULL,
! 350: "failed to clean the backup file %s.\n",
! 351: lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]);
! 352: return -1;
! 353: }
! 354: fclose(fp);
! 355: return 0;
! 356: }
! 357:
! 358: /*
! 359: * convert fixed string into the tm structure.
! 360: * The fixed string is like 'Nov 24 18:22:48 1986'.
! 361: * static char *format = "%b %d %T %Y";
! 362: */
! 363: static char *
! 364: str2tmx(char *p, struct tm *tm)
! 365: {
! 366: int i, len;
! 367:
! 368: /* Month */
! 369: for (i = 0; i < sizeof(strmon)/sizeof(strmon[0]); i++) {
! 370: if (strncasecmp(p, strmon[i], strlen(strmon[i])) == 0) {
! 371: tm->tm_mon = i;
! 372: break;
! 373: }
! 374: }
! 375: if (i == sizeof(strmon)/sizeof(strmon[0]))
! 376: return 0;
! 377: p += strlen(strmon[i]);
! 378: if (*p++ != ' ')
! 379: return 0;
! 380:
! 381: /* Day */
! 382: len = 2;
! 383: tm->tm_mday = str2num(p, len);
! 384: if (tm->tm_mday == -1 || tm->tm_mday > 31)
! 385: return 0;
! 386: p += len;
! 387: if (*p++ != ' ')
! 388: return 0;
! 389:
! 390: /* Hour */
! 391: len = 2;
! 392: tm->tm_hour = str2num(p, len);
! 393: if (tm->tm_hour == -1 || tm->tm_hour > 24)
! 394: return 0;
! 395: p += len;
! 396: if (*p++ != ':')
! 397: return 0;
! 398:
! 399: /* Min */
! 400: len = 2;
! 401: tm->tm_min = str2num(p, len);
! 402: if (tm->tm_min == -1 || tm->tm_min > 60)
! 403: return 0;
! 404: p += len;
! 405: if (*p++ != ':')
! 406: return 0;
! 407:
! 408: /* Sec */
! 409: len = 2;
! 410: tm->tm_sec = str2num(p, len);
! 411: if (tm->tm_sec == -1 || tm->tm_sec > 60)
! 412: return 0;
! 413: p += len;
! 414: if (*p++ != ' ')
! 415: return 0;
! 416:
! 417: /* Year */
! 418: len = 4;
! 419: tm->tm_year = str2num(p, len);
! 420: if (tm->tm_year == -1 || tm->tm_year < 1900)
! 421: return 0;
! 422: tm->tm_year -= 1900;
! 423: p += len;
! 424:
! 425: return p;
! 426: }
! 427:
! 428: static int
! 429: str2num(p, len)
! 430: char *p;
! 431: int len;
! 432: {
! 433: int res, i;
! 434:
! 435: res = 0;
! 436: for (i = len; i > 0; i--) {
! 437: if (!isdigit((int)*p))
! 438: return -1;
! 439: res *= 10;
! 440: res += *p - '0';
! 441: p++;
! 442: }
! 443:
! 444: return res;
! 445: }
! 446:
! 447: #ifdef TEST
! 448: #include <stdio.h>
! 449: int
! 450: main()
! 451: {
! 452: struct tm tm;
! 453: time_t t;
! 454: char *buf = "Nov 24 18:22:48 1986 ";
! 455: const char *p;
! 456:
! 457: memset(&tm, 0, sizeof(tm));
! 458: p = str2tmx(buf, &tm);
! 459: printf("[%x]\n", *p);
! 460: t = mktime(&tm);
! 461: if (t == -1)
! 462: printf("mktime failed.");
! 463: if ((p = ctime(&t)) == NULL)
! 464: p = "?";
! 465: printf("[%s]\n", p);
! 466:
! 467: exit(0);
! 468: }
! 469: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>