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>