File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / sainfo.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:39:10 2012 UTC (12 years, 4 months ago) by misho
Branches: ipsec-tools, MAIN
CVS tags: v0_8_2p2, v0_8_1p0, v0_8_1, v0_8_0p0, v0_8_0, HEAD
ipsec-tools

    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>