Annotation of embedaddon/ipsec-tools/src/racoon/backupsa.c, revision 1.1.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>