Annotation of embedaddon/ipsec-tools/src/racoon/sainfo.c, revision 1.1

1.1     ! misho       1: /*     $NetBSD: sainfo.c,v 1.14 2011/02/02 15:21:34 vanhu Exp $        */
        !             2: 
        !             3: /*     $KAME: sainfo.c,v 1.16 2003/06/27 07:32:39 sakane 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/param.h>
        !            37: #include <sys/types.h>
        !            38: #include <sys/socket.h>
        !            39: #include <sys/queue.h>
        !            40: 
        !            41: #include <netinet/in.h>
        !            42: #include <netinet/in.h> 
        !            43: #include PATH_IPSEC_H
        !            44: 
        !            45: #include <stdlib.h>
        !            46: #include <stdio.h>
        !            47: #include <string.h>
        !            48: #include <errno.h>
        !            49: 
        !            50: #include "var.h"
        !            51: #include "misc.h"
        !            52: #include "vmbuf.h"
        !            53: #include "plog.h"
        !            54: #include "sockmisc.h"
        !            55: #include "debug.h"
        !            56: 
        !            57: #include "localconf.h"
        !            58: #include "isakmp_var.h"
        !            59: #include "isakmp.h"
        !            60: #include "ipsec_doi.h"
        !            61: #include "oakley.h"
        !            62: #include "handler.h"
        !            63: #include "algorithm.h"
        !            64: #include "sainfo.h"
        !            65: #include "gcmalloc.h"
        !            66: 
        !            67: typedef LIST_HEAD(_sitree, sainfo) sainfo_tailq_head_t;
        !            68: static sainfo_tailq_head_t sitree, sitree_save;
        !            69: 
        !            70: /* %%%
        !            71:  * modules for ipsec sa info
        !            72:  */
        !            73: /*
        !            74:  * return matching entry.
        !            75:  * no matching entry found and if there is anonymous entry, return it.
        !            76:  * else return NULL.
        !            77:  * First pass is for sainfo from a specified peer, second for others.
        !            78:  */
        !            79: struct sainfo *
        !            80: getsainfo(loc, rmt, peer, client, remoteid)
        !            81:        const vchar_t *loc, *rmt, *peer, *client;
        !            82:        uint32_t remoteid;
        !            83: {
        !            84:        struct sainfo *s = NULL;
        !            85: 
        !            86:        /* debug level output */
        !            87:        if(loglevel >= LLV_DEBUG) {
        !            88:                char *dloc, *drmt, *dpeer, *dclient;
        !            89: 
        !            90:                if (loc == NULL)
        !            91:                        dloc = strdup("ANONYMOUS");
        !            92:                else
        !            93:                        dloc = ipsecdoi_id2str(loc);
        !            94: 
        !            95:                if (rmt == SAINFO_ANONYMOUS)
        !            96:                        drmt = strdup("ANONYMOUS");
        !            97:                else if (rmt == SAINFO_CLIENTADDR)
        !            98:                        drmt = strdup("CLIENTADDR");
        !            99:                else
        !           100:                        drmt = ipsecdoi_id2str(rmt);
        !           101: 
        !           102:                if (peer == NULL)
        !           103:                        dpeer = strdup("NULL");
        !           104:                else
        !           105:                        dpeer = ipsecdoi_id2str(peer);
        !           106: 
        !           107:                if (client == NULL)
        !           108:                        dclient = strdup("NULL");
        !           109:                else
        !           110:                        dclient = ipsecdoi_id2str(client);
        !           111: 
        !           112:                plog(LLV_DEBUG, LOCATION, NULL,
        !           113:                        "getsainfo params: loc=\'%s\' rmt=\'%s\' peer=\'%s\' client=\'%s\' id=%u\n",
        !           114:                        dloc, drmt, dpeer, dclient, remoteid );
        !           115:  
        !           116:                 racoon_free(dloc);
        !           117:                 racoon_free(drmt);
        !           118:                 racoon_free(dpeer);
        !           119:                 racoon_free(dclient);
        !           120:        }
        !           121: 
        !           122:        LIST_FOREACH(s, &sitree, chain) {
        !           123:                const char *sainfostr = sainfo2str(s);
        !           124:                plog(LLV_DEBUG, LOCATION, NULL,
        !           125:                        "evaluating sainfo: %s\n", sainfostr);
        !           126: 
        !           127:                if(s->remoteid != remoteid) {
        !           128:                        plog(LLV_DEBUG, LOCATION, NULL,
        !           129:                                "remoteid mismatch: %u != %u\n",
        !           130:                                s->remoteid, remoteid);
        !           131:                                continue;
        !           132:                }
        !           133: 
        !           134:                /* compare 'from' id value */
        !           135:                if (s->id_i != NULL)
        !           136:                        if (ipsecdoi_chkcmpids(peer, s->id_i, 0))
        !           137:                                continue;
        !           138: 
        !           139:                /* compare ids - client */
        !           140:                if( s->iddst == SAINFO_CLIENTADDR ) {
        !           141:                        /*
        !           142:                         * This sainfo section enforces client address
        !           143:                         * checking. Prevent match if the client value
        !           144:                         * ( modecfg or tunnel address ) is NULL.
        !           145:                         */
        !           146: 
        !           147:                        if (client == NULL)
        !           148:                                continue;
        !           149: 
        !           150:                        if( rmt == SAINFO_CLIENTADDR ) {
        !           151:                                /*
        !           152:                                 * In the case where a supplied rmt value is
        !           153:                                 * also SAINFO_CLIENTADDR, we are comparing
        !           154:                                 * with another sainfo to check for duplicate.
        !           155:                                 * Only compare the local values to determine
        !           156:                                 * a match.
        !           157:                                 */
        !           158: 
        !           159:                                 if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0))
        !           160:                                        return s;
        !           161:                        }
        !           162:                        else {
        !           163:                                /*
        !           164:                                 * In the case where a supplied rmt value is
        !           165:                                 * not SAINFO_CLIENTADDR, do a standard match
        !           166:                                 * for local values and enforce that the rmt
        !           167:                                 * id matches the client address value.
        !           168:                                 */
        !           169: 
        !           170:                                if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) &&
        !           171:                                    !ipsecdoi_chkcmpids(rmt, client, 0))
        !           172:                                        return s;
        !           173:                        }
        !           174: 
        !           175:                        continue;
        !           176:                }
        !           177: 
        !           178: 
        !           179:                /* compare ids - standard */
        !           180:                if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) &&
        !           181:                    !ipsecdoi_chkcmpids(rmt, s->iddst, 0))
        !           182:                        return s;
        !           183:        }
        !           184: 
        !           185:        return NULL;
        !           186: }
        !           187: 
        !           188: struct sainfo *
        !           189: newsainfo()
        !           190: {
        !           191:        struct sainfo *new;
        !           192: 
        !           193:        new = racoon_calloc(1, sizeof(*new));
        !           194:        if (new == NULL)
        !           195:                return NULL;
        !           196: 
        !           197:        new->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
        !           198:        new->lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX;
        !           199: 
        !           200:        return new;
        !           201: }
        !           202: 
        !           203: void
        !           204: delsainfo(si)
        !           205:        struct sainfo *si;
        !           206: {
        !           207:        int i;
        !           208: 
        !           209:        for (i = 0; i < MAXALGCLASS; i++)
        !           210:                delsainfoalg(si->algs[i]);
        !           211: 
        !           212:        if (si->idsrc)
        !           213:                vfree(si->idsrc);
        !           214:        if (si->iddst != NULL &&
        !           215:                si->iddst != SAINFO_CLIENTADDR)
        !           216:                vfree(si->iddst);
        !           217: 
        !           218: #ifdef ENABLE_HYBRID
        !           219:        if (si->group)
        !           220:                vfree(si->group);
        !           221: #endif
        !           222: 
        !           223:        racoon_free(si);
        !           224: }
        !           225: 
        !           226: int prisainfo(s)
        !           227:        struct sainfo *s;
        !           228: {
        !           229:        /*
        !           230:         * determine the matching priority
        !           231:         * of an sainfo section
        !           232:         */
        !           233: 
        !           234:        int pri = 0;
        !           235: 
        !           236:        if(s->remoteid)
        !           237:                pri += 3;
        !           238: 
        !           239:        if(s->id_i)
        !           240:                pri += 3;
        !           241: 
        !           242:        if(s->idsrc)
        !           243:                pri++;
        !           244: 
        !           245:        if(s->iddst)
        !           246:                pri++;
        !           247: 
        !           248:        return pri;
        !           249: }
        !           250: 
        !           251: void
        !           252: inssainfo(new)
        !           253:        struct sainfo *new;
        !           254: {
        !           255:        if(LIST_EMPTY(&sitree)) {
        !           256: 
        !           257:                /* first in list */
        !           258:                LIST_INSERT_HEAD(&sitree, new, chain);
        !           259:        }
        !           260:        else {
        !           261:                int npri, spri;
        !           262:                struct sainfo *s, *n;
        !           263: 
        !           264:                /*
        !           265:                 * insert our new sainfo section
        !           266:                 * into our list which is sorted
        !           267:                 * based on the match priority
        !           268:                 */
        !           269: 
        !           270:                npri = prisainfo(new);
        !           271: 
        !           272:                s = LIST_FIRST(&sitree);
        !           273:                while (1) {
        !           274: 
        !           275:                        spri = prisainfo(s);
        !           276:                        n = LIST_NEXT(s, chain);
        !           277: 
        !           278:                        if(npri > spri)
        !           279:                        {
        !           280:                                /* higher priority */
        !           281:                                LIST_INSERT_BEFORE(s, new, chain);
        !           282:                                return;
        !           283:                        }
        !           284: 
        !           285:                        if(n == NULL)
        !           286:                        {
        !           287:                                /* last in list */
        !           288:                                LIST_INSERT_AFTER(s, new, chain);
        !           289:                                return;
        !           290:                        }
        !           291: 
        !           292:                        s = n;
        !           293:                }
        !           294:        }
        !           295: }
        !           296: 
        !           297: void
        !           298: remsainfo(si)
        !           299:        struct sainfo *si;
        !           300: {
        !           301:        LIST_REMOVE(si, chain);
        !           302: }
        !           303: 
        !           304: void
        !           305: flushsainfo()
        !           306: {
        !           307:        struct sainfo *s, *next;
        !           308: 
        !           309:        for (s = LIST_FIRST(&sitree); s; s = next) {
        !           310:                next = LIST_NEXT(s, chain);
        !           311:                remsainfo(s);
        !           312:                delsainfo(s);
        !           313:        }
        !           314: }
        !           315: 
        !           316: void
        !           317: initsainfo()
        !           318: {
        !           319:        LIST_INIT(&sitree);
        !           320: }
        !           321: 
        !           322: struct sainfoalg *
        !           323: newsainfoalg()
        !           324: {
        !           325:        struct sainfoalg *new;
        !           326: 
        !           327:        new = racoon_calloc(1, sizeof(*new));
        !           328:        if (new == NULL)
        !           329:                return NULL;
        !           330: 
        !           331:        return new;
        !           332: }
        !           333: 
        !           334: void
        !           335: delsainfoalg(alg)
        !           336:        struct sainfoalg *alg;
        !           337: {
        !           338:        struct sainfoalg *a, *next;
        !           339: 
        !           340:        for (a = alg; a; a = next) {
        !           341:                next = a->next;
        !           342:                racoon_free(a);
        !           343:        }
        !           344: }
        !           345: 
        !           346: void
        !           347: inssainfoalg(head, new)
        !           348:        struct sainfoalg **head;
        !           349:        struct sainfoalg *new;
        !           350: {
        !           351:        struct sainfoalg *a;
        !           352: 
        !           353:        for (a = *head; a && a->next; a = a->next)
        !           354:                ;
        !           355:        if (a)
        !           356:                a->next = new;
        !           357:        else
        !           358:                *head = new;
        !           359: }
        !           360: 
        !           361: const char *
        !           362: sainfo2str(si)
        !           363:        const struct sainfo *si;
        !           364: {
        !           365:         static char buf[256];
        !           366: 
        !           367:         char *idloc = NULL, *idrmt = NULL, *id_i;
        !           368:  
        !           369:         if (si->idsrc == SAINFO_ANONYMOUS)
        !           370:                 idloc = strdup("ANONYMOUS");
        !           371:         else
        !           372:                 idloc = ipsecdoi_id2str(si->idsrc);
        !           373:  
        !           374:         if (si->iddst == SAINFO_ANONYMOUS)
        !           375:                 idrmt = strdup("ANONYMOUS");
        !           376:        else if (si->iddst == SAINFO_CLIENTADDR)
        !           377:                 idrmt = strdup("CLIENTADDR");
        !           378:         else
        !           379:                 idrmt = ipsecdoi_id2str(si->iddst);
        !           380:  
        !           381:         if (si->id_i == NULL)
        !           382:                 id_i = strdup("ANY");
        !           383:         else
        !           384:                 id_i = ipsecdoi_id2str(si->id_i);
        !           385:  
        !           386:         snprintf(buf, 255, "loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%u",
        !           387:                idloc, idrmt, id_i, si->remoteid);
        !           388:  
        !           389:         racoon_free(idloc);
        !           390:         racoon_free(idrmt);
        !           391:         racoon_free(id_i);
        !           392:  
        !           393:         return buf;
        !           394: }
        !           395: 
        !           396: void sainfo_start_reload(void){
        !           397:        sitree_save=sitree;
        !           398:        initsainfo();
        !           399: }
        !           400: 
        !           401: void sainfo_finish_reload(void){
        !           402:        sainfo_tailq_head_t sitree_tmp;
        !           403: 
        !           404:        sitree_tmp=sitree;
        !           405:        sitree=sitree_save;
        !           406:        flushsainfo();
        !           407:        sitree=sitree_tmp;
        !           408: }
        !           409: 
        !           410: void save_sainfotree_restore(void){
        !           411:        flushsainfo();
        !           412:        sitree=sitree_save;
        !           413: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>