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>