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