File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / remoteconf.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: remoteconf.c,v 1.26 2011/03/14 15:50:36 vanhu Exp $	*/
    2: 
    3: /* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 manubsd 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: #include <sys/queue.h>
   40: 
   41: #include <netinet/in.h>
   42: #include <netinet/in_systm.h>
   43: #include <netinet/ip.h>
   44: 
   45: #include PATH_IPSEC_H
   46: 
   47: #include <stdlib.h>
   48: #include <stdio.h>
   49: #include <string.h>
   50: #include <errno.h>
   51: 
   52: #include "var.h"
   53: #include "misc.h"
   54: #include "vmbuf.h"
   55: #include "plog.h"
   56: #include "sockmisc.h"
   57: #include "genlist.h"
   58: #include "debug.h"
   59: 
   60: #include "isakmp_var.h"
   61: #ifdef ENABLE_HYBRID
   62: #include "isakmp_xauth.h"
   63: #endif
   64: #include "isakmp.h"
   65: #include "ipsec_doi.h"
   66: #include "crypto_openssl.h"
   67: #include "oakley.h"
   68: #include "remoteconf.h"
   69: #include "localconf.h"
   70: #include "grabmyaddr.h"
   71: #include "policy.h"
   72: #include "proposal.h"
   73: #include "vendorid.h"
   74: #include "gcmalloc.h"
   75: #include "strnames.h"
   76: #include "algorithm.h"
   77: #include "nattraversal.h"
   78: #include "isakmp_frag.h"
   79: #include "handler.h"
   80: #include "genlist.h"
   81: #include "rsalist.h"
   82: 
   83: typedef TAILQ_HEAD(_rmtree, remoteconf) remoteconf_tailq_head_t;
   84: static remoteconf_tailq_head_t rmtree, rmtree_save;
   85: 
   86: /*
   87:  * Script hook names and script hook paths
   88:  */
   89: char *script_names[SCRIPT_MAX + 1] = {
   90: 	"phase1_up", "phase1_down", "phase1_dead" };
   91: 
   92: /*%%%*/
   93: 
   94: int
   95: rmconf_match_identity(rmconf, id_p)
   96: 	struct remoteconf *rmconf;
   97: 	vchar_t *id_p;
   98: {
   99: 	struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *) id_p->v;
  100: 	struct sockaddr *sa;
  101: 	caddr_t sa1, sa2;
  102: 	vchar_t ident;
  103: 	struct idspec *id;
  104: 	struct genlist_entry *gpb;
  105: 
  106: 	/* compare with the ID if specified. */
  107: 	if (!genlist_next(rmconf->idvl_p, 0))
  108: 		return 0;
  109: 
  110: 	for (id = genlist_next(rmconf->idvl_p, &gpb); id; id = genlist_next(0, &gpb)) {
  111: 		/* No ID specified in configuration, so it is ok */
  112: 		if (id->id == 0)
  113: 			return 0;
  114: 
  115: 		/* check the type of both IDs */
  116: 		if (id->idtype != doi2idtype(id_b->type))
  117: 			continue;  /* ID type mismatch */
  118: 
  119: 		/* compare defined ID with the ID sent by peer. */
  120: 		switch (id->idtype) {
  121: 		case IDTYPE_ASN1DN:
  122: 			ident.v = id_p->v + sizeof(*id_b);
  123: 			ident.l = id_p->l - sizeof(*id_b);
  124: 			if (eay_cmp_asn1dn(id->id, &ident) == 0)
  125: 				return 0;
  126: 			break;
  127: 		case IDTYPE_ADDRESS:
  128: 			sa = (struct sockaddr *)id->id->v;
  129: 			sa2 = (caddr_t)(id_b + 1);
  130: 			switch (sa->sa_family) {
  131: 			case AF_INET:
  132: 				if (id_p->l - sizeof(*id_b) != sizeof(struct in_addr))
  133: 					continue;  /* ID value mismatch */
  134: 				sa1 = (caddr_t) &((struct sockaddr_in *)sa)->sin_addr;
  135: 				if (memcmp(sa1, sa2, sizeof(struct in_addr)) == 0)
  136: 					return 0;
  137: 				break;
  138: #ifdef INET6
  139: 			case AF_INET6:
  140: 				if (id_p->l - sizeof(*id_b) != sizeof(struct in6_addr))
  141: 					continue;  /* ID value mismatch */
  142: 				sa1 = (caddr_t) &((struct sockaddr_in6 *)sa)->sin6_addr;
  143: 				if (memcmp(sa1, sa2, sizeof(struct in6_addr)) == 0)
  144: 					return 0;
  145: 				break;
  146: #endif
  147: 			default:
  148: 				break;
  149: 			}
  150: 			break;
  151: 		default:
  152: 			if (memcmp(id->id->v, id_b + 1, id->id->l) == 0)
  153: 				return 0;
  154: 			break;
  155: 		}
  156: 	}
  157: 
  158: 	plog(LLV_WARNING, LOCATION, NULL, "No ID match.\n");
  159: 	if (rmconf->verify_identifier)
  160: 		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
  161: 
  162: 	return 0;
  163: }
  164: 
  165: static int
  166: rmconf_match_etype_and_approval(rmconf, etype, approval)
  167: 	struct remoteconf *rmconf;
  168: 	int etype;
  169: 	struct isakmpsa *approval;
  170: {
  171: 	struct isakmpsa *p;
  172: 
  173: 	if (check_etypeok(rmconf, (void *) (intptr_t) etype) == 0)
  174: 		return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
  175: 
  176: 	if (approval == NULL)
  177: 		return 0;
  178: 
  179: 	if (etype == ISAKMP_ETYPE_AGG &&
  180: 	    approval->dh_group != rmconf->dh_group)
  181: 		return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
  182: 
  183: 	if (checkisakmpsa(rmconf->pcheck_level, approval,
  184: 			  rmconf->proposal) == NULL)
  185: 		return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
  186: 
  187: 	return 0;
  188: }
  189: 
  190: enum rmconf_match_t {
  191: 	MATCH_NONE		= 0,
  192: 	MATCH_BASIC		= 0x0000001,
  193: 	MATCH_ADDRESS		= 0x0000002,
  194: 	MATCH_SA		= 0x0000004,
  195: 	MATCH_IDENTITY		= 0x0000008,
  196: 	MATCH_AUTH_IDENTITY	= 0x0000010,
  197: };
  198: 
  199: static int
  200: rmconf_match_type(rmsel, rmconf)
  201: 	struct rmconfselector *rmsel;
  202: 	struct remoteconf *rmconf;
  203: {
  204: 	int ret = MATCH_NONE, tmp;
  205: 
  206: 	/* No match at all: unwanted anonymous */
  207: 	if ((rmsel->flags & GETRMCONF_F_NO_ANONYMOUS) &&
  208: 	    rmconf->remote->sa_family == AF_UNSPEC){
  209: 		plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  210: 		     "Not matched: Anonymous conf.\n");
  211: 		return MATCH_NONE;
  212: 	}
  213: 
  214: 	if ((rmsel->flags & GETRMCONF_F_NO_PASSIVE) && rmconf->passive){
  215: 		plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  216: 		     "Not matched: passive conf.\n");
  217: 		return MATCH_NONE;
  218: 	}
  219: 
  220: 	ret |= MATCH_BASIC;
  221: 
  222: 	/* Check address */
  223: 	if (rmsel->remote != NULL) {
  224: 		if (rmconf->remote->sa_family != AF_UNSPEC) {
  225: 			if (cmpsaddr(rmsel->remote, rmconf->remote) == CMPSADDR_MISMATCH){
  226: 				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  227: 				     "Not matched: address mismatch.\n");
  228: 				return MATCH_NONE;
  229: 			}
  230: 
  231: 			/* Address matched */
  232: 			ret |= MATCH_ADDRESS;
  233: 		}
  234: 	}
  235: 
  236: 	/* Check etype and approval */
  237: 	if (rmsel->etype != ISAKMP_ETYPE_NONE) {
  238: 		tmp=rmconf_match_etype_and_approval(rmconf, rmsel->etype,
  239: 						    rmsel->approval);
  240: 		if (tmp != 0){
  241: 			plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  242: 			     "Not matched: etype (%d)/approval mismatch (%d).\n", rmsel->etype, tmp);
  243: 			return MATCH_NONE;
  244: 		}
  245: 		ret |= MATCH_SA;
  246: 	}
  247: 
  248: 	/* Check identity */
  249: 	if (rmsel->identity != NULL && rmconf->verify_identifier) {
  250: 		if (rmconf_match_identity(rmconf, rmsel->identity) != 0){
  251: 			plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  252: 			     "Not matched: identity mismatch.\n");
  253: 			return MATCH_NONE;
  254: 		}
  255: 		ret |= MATCH_IDENTITY;
  256: 	}
  257: 
  258: 	/* Check certificate request */
  259: 	if (rmsel->certificate_request != NULL) {
  260: 		if (oakley_get_certtype(rmsel->certificate_request) !=
  261: 		    oakley_get_certtype(rmconf->mycert)){
  262: 			plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  263: 			     "Not matched: cert type mismatch.\n");
  264: 			return MATCH_NONE;
  265: 		}
  266: 
  267: 		if (rmsel->certificate_request->l > 1) {
  268: 			vchar_t *issuer;
  269: 
  270: 			issuer = eay_get_x509asn1issuername(rmconf->mycert);
  271: 			if (rmsel->certificate_request->l - 1 != issuer->l ||
  272: 			    memcmp(rmsel->certificate_request->v + 1,
  273: 				   issuer->v, issuer->l) != 0) {
  274: 				vfree(issuer);
  275: 				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  276: 				     "Not matched: cert issuer mismatch.\n");
  277: 				return MATCH_NONE;
  278: 			}
  279: 			vfree(issuer);
  280: 		} else {
  281: 			if (!rmconf->match_empty_cr){
  282: 				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  283: 				     "Not matched: empty certificate request.\n");
  284: 				return MATCH_NONE;
  285: 			}
  286: 		}
  287: 
  288: 		ret |= MATCH_AUTH_IDENTITY;
  289: 	}
  290: 
  291: 	return ret;
  292: }
  293: 
  294: void rmconf_selector_from_ph1(rmsel, iph1)
  295: 	struct rmconfselector *rmsel;
  296: 	struct ph1handle *iph1;
  297: {
  298: 	memset(rmsel, 0, sizeof(*rmsel));
  299: 	rmsel->flags = 0;
  300: 	rmsel->remote = iph1->remote;
  301: 	rmsel->etype = iph1->etype;
  302: 	rmsel->approval = iph1->approval;
  303: 	rmsel->identity = iph1->id_p;
  304: 	rmsel->certificate_request = iph1->cr_p;
  305: }
  306: 
  307: int
  308: enumrmconf(rmsel, enum_func, enum_arg)
  309: 	struct rmconfselector *rmsel;
  310: 	int (* enum_func)(struct remoteconf *rmconf, void *arg);
  311: 	void *enum_arg;
  312: {
  313: 	struct remoteconf *p;
  314: 	int ret = 0;
  315: 
  316: 	RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) {
  317: 		plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  318: 		     "Checking remote conf \"%s\" %s.\n", p->name,
  319: 		     p->remote->sa_family == AF_UNSPEC ?
  320: 		     "anonymous" : saddr2str(p->remote));
  321: 
  322: 		if (rmsel != NULL) {
  323: 			if (rmconf_match_type(rmsel, p) == MATCH_NONE){
  324: 				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
  325: 				     "Not matched.\n");
  326: 				continue;
  327: 			}
  328: 		}
  329: 
  330: 		plog(LLV_DEBUG2, LOCATION, NULL,
  331: 		     "enumrmconf: \"%s\" matches.\n", p->name);
  332: 
  333: 		ret = (*enum_func)(p, enum_arg);
  334: 		if (ret)
  335: 			break;
  336: 	}
  337: 
  338: 	return ret;
  339: }
  340: 
  341: struct rmconf_find_context {
  342: 	struct rmconfselector sel;
  343: 
  344: 	struct remoteconf *rmconf;
  345: 	int match_type;
  346: 	int num_found;
  347: };
  348: 
  349: static int
  350: rmconf_find(rmconf, ctx)
  351: 	struct remoteconf *rmconf;
  352: 	void *ctx;
  353: {
  354: 	struct rmconf_find_context *fctx = (struct rmconf_find_context *) ctx;
  355: 	int match_type;
  356: 
  357: 	/* First matching remote conf? */
  358: 	match_type = rmconf_match_type(&fctx->sel, rmconf);
  359: 
  360: 	if (fctx->rmconf != NULL) {
  361: 		/* More ambiguous matches are ignored. */
  362: 		if (match_type < fctx->match_type)
  363: 			return 0;
  364: 
  365: 		if (match_type == fctx->match_type) {
  366: 			/* Ambiguous match */
  367: 			fctx->num_found++;
  368: 			return 0;
  369: 		}
  370: 	}
  371: 
  372: 	/* More exact match found */
  373: 	fctx->match_type = match_type;
  374: 	fctx->num_found = 1;
  375: 	fctx->rmconf = rmconf;
  376: 
  377: 	return 0;
  378: }
  379: 
  380: /*
  381:  * search remote configuration.
  382:  * don't use port number to search if its value is either IPSEC_PORT_ANY.
  383:  * If matching anonymous entry, then new entry is copied from anonymous entry.
  384:  * If no anonymous entry found, then return NULL.
  385:  * OUT:	NULL:	NG
  386:  *	Other:	remote configuration entry.
  387:  */
  388: 
  389: struct remoteconf *
  390: getrmconf(remote, flags)
  391: 	struct sockaddr *remote;
  392: 	int flags;
  393: {
  394: 	struct rmconf_find_context ctx;
  395: 	int n = 0;
  396: 
  397: 	memset(&ctx, 0, sizeof(ctx));
  398: 	ctx.sel.flags = flags;
  399: 	ctx.sel.remote = remote;
  400: 
  401: 	if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) {
  402: 		plog(LLV_ERROR, LOCATION, remote,
  403: 		     "multiple exact configurations.\n");
  404: 		return NULL;
  405: 	}
  406: 
  407: 	if (ctx.rmconf == NULL) {
  408: 		plog(LLV_DEBUG, LOCATION, remote,
  409: 		     "no remote configuration found.\n");
  410: 		return NULL;
  411: 	}
  412: 
  413: 	if (ctx.num_found != 1) {
  414: 		plog(LLV_DEBUG, LOCATION, remote,
  415: 		     "multiple non-exact configurations found.\n");
  416: 		return NULL;
  417: 	}
  418: 
  419: 	plog(LLV_DEBUG, LOCATION, remote,
  420: 	     "configuration \"%s\" selected.\n",
  421: 	     ctx.rmconf->name);
  422: 
  423: 	return ctx.rmconf;
  424: }
  425: 
  426: struct remoteconf *
  427: getrmconf_by_ph1(iph1)
  428: 	struct ph1handle *iph1;
  429: {
  430: 	struct rmconf_find_context ctx;
  431: 
  432: 	memset(&ctx, 0, sizeof(ctx));
  433: 	rmconf_selector_from_ph1(&ctx.sel, iph1);
  434: 	if (loglevel >= LLV_DEBUG) {
  435: 		char *idstr = NULL;
  436: 
  437: 		if (iph1->id_p != NULL)
  438: 			idstr = ipsecdoi_id2str(iph1->id_p);
  439: 
  440: 		plog(LLV_DEBUG, LOCATION, iph1->remote,
  441: 			"getrmconf_by_ph1: remote %s, identity %s.\n",
  442: 			saddr2str(iph1->remote), idstr ? idstr : "<any>");
  443: 
  444: 		if (idstr)
  445: 			racoon_free(idstr);
  446: 	}
  447: 
  448: 	if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) {
  449: 		plog(LLV_ERROR, LOCATION, iph1->remote,
  450: 		     "multiple exact configurations.\n");
  451: 		return RMCONF_ERR_MULTIPLE;
  452: 	}
  453: 
  454: 	if (ctx.rmconf == NULL) {
  455: 		plog(LLV_DEBUG, LOCATION, iph1->remote,
  456: 		     "no remote configuration found\n");
  457: 		return NULL;
  458: 	}
  459: 
  460: 	if (ctx.num_found != 1) {
  461: 		plog(LLV_DEBUG, LOCATION, iph1->remote,
  462: 		     "multiple non-exact configurations found.\n");
  463: 		return RMCONF_ERR_MULTIPLE;
  464: 	}
  465: 
  466: 	plog(LLV_DEBUG, LOCATION, iph1->remote,
  467: 	     "configuration \"%s\" selected.\n",
  468: 	     ctx.rmconf->name);
  469: 
  470: 	return ctx.rmconf;
  471: }
  472: 
  473: struct remoteconf *
  474: getrmconf_by_name(name)
  475: 	const char *name;
  476: {
  477: 	struct remoteconf *p;
  478: 
  479: 	plog(LLV_DEBUG, LOCATION, NULL,
  480: 	     "getrmconf_by_name: remote \"%s\".\n",
  481: 	     name);
  482: 
  483: 	RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) {
  484: 		if (p->name == NULL)
  485: 			continue;
  486: 
  487: 		if (strcmp(name, p->name) == 0)
  488: 			return p;
  489: 	}
  490: 
  491: 	return NULL;
  492: }
  493: 
  494: struct remoteconf *
  495: newrmconf()
  496: {
  497: 	struct remoteconf *new;
  498: 	int i;
  499: 
  500: 	new = racoon_calloc(1, sizeof(*new));
  501: 	if (new == NULL)
  502: 		return NULL;
  503: 
  504: 	new->proposal = NULL;
  505: 
  506: 	/* set default */
  507: 	new->doitype = IPSEC_DOI;
  508: 	new->sittype = IPSECDOI_SIT_IDENTITY_ONLY;
  509: 	new->idvtype = IDTYPE_UNDEFINED;
  510: 	new->idvl_p = genlist_init();
  511: 	new->nonce_size = DEFAULT_NONCE_SIZE;
  512: 	new->passive = FALSE;
  513: 	new->ike_frag = FALSE;
  514: 	new->esp_frag = IP_MAXPACKET;
  515: 	new->ini_contact = TRUE;
  516: 	new->mode_cfg = FALSE;
  517: 	new->pcheck_level = PROP_CHECK_STRICT;
  518: 	new->verify_identifier = FALSE;
  519: 	new->verify_cert = TRUE;
  520: 	new->cacertfile = NULL;
  521: 	new->send_cert = TRUE;
  522: 	new->send_cr = TRUE;
  523: 	new->match_empty_cr = FALSE;
  524: 	new->support_proxy = FALSE;
  525: 	for (i = 0; i <= SCRIPT_MAX; i++)
  526: 		new->script[i] = NULL;
  527: 	new->gen_policy = FALSE;
  528: 	new->nat_traversal = FALSE;
  529: 	new->rsa_private = genlist_init();
  530: 	new->rsa_public = genlist_init();
  531: 	new->idv = NULL;
  532: 	new->key = NULL;
  533: 
  534: 	new->dpd = TRUE; /* Enable DPD support by default */
  535: 	new->dpd_interval = 0; /* Disable DPD checks by default */
  536: 	new->dpd_retry = 5;
  537: 	new->dpd_maxfails = 5;
  538: 
  539: 	new->rekey = REKEY_ON;
  540: 
  541: 	new->weak_phase1_check = 0;
  542: 
  543: #ifdef ENABLE_HYBRID
  544: 	new->xauth = NULL;
  545: #endif
  546: 
  547: 	new->lifetime = oakley_get_defaultlifetime();
  548: 
  549: 	return new;
  550: }
  551: 
  552: void *
  553: dupidvl(entry, arg)
  554: 	void *entry;
  555: 	void *arg;
  556: {
  557: 	struct idspec *id;
  558: 	struct idspec *old = (struct idspec *) entry;
  559: 	id = newidspec();
  560: 	if (!id) return (void *) -1;
  561: 
  562: 	if (set_identifier(&id->id, old->idtype, old->id) != 0) {
  563: 		racoon_free(id);
  564: 		return (void *) -1;
  565: 	}
  566: 
  567: 	id->idtype = old->idtype;
  568: 
  569: 	genlist_append(arg, id);
  570: 	return NULL;
  571: }
  572: 
  573: void *
  574: duprsa(entry, arg)
  575: 	void *entry;
  576: 	void *arg;
  577: {
  578: 	struct rsa_key *new;
  579: 
  580: 	new = rsa_key_dup((struct rsa_key *)entry);
  581: 	if (new == NULL)
  582: 		return (void *) -1;
  583: 	genlist_append(arg, new);
  584: 
  585: 	/* keep genlist_foreach going */
  586: 	return NULL;
  587: }
  588: 
  589: /* Creates shallow copy of a remote config. Used for "inherit" keyword. */
  590: struct remoteconf *
  591: duprmconf_shallow (rmconf)
  592: 	struct remoteconf *rmconf;
  593: {
  594: 	struct remoteconf *new;
  595: 	struct proposalspec *prspec;
  596: 
  597: 	new = racoon_calloc(1, sizeof(*new));
  598: 	if (new == NULL)
  599: 		return NULL;
  600: 
  601: 	memcpy(new, rmconf, sizeof(*new));
  602: 	new->name = NULL;
  603: 	new->inherited_from = rmconf;
  604: 
  605: 	new->proposal = NULL; /* will be filled by set_isakmp_proposal() */
  606: 
  607: 	return new;
  608: }
  609: 
  610: /* Copies pointer structures of an inherited remote config. 
  611:  * Used by "inherit" mechanism in a two step copy method, necessary to
  612:  * prevent both double free() and memory leak during config reload.
  613:  */
  614: int
  615: duprmconf_finish (new)
  616: 	struct remoteconf *new;
  617: {
  618: 	struct remoteconf *rmconf;
  619: 	int i;
  620: 
  621: 	if (new->inherited_from == NULL)
  622: 		return 0; /* nothing todo, no inheritance */
  623: 
  624: 	rmconf = new->inherited_from;
  625: 
  626: 	/* duplicate dynamic structures unless value overridden */
  627: 	if (new->etypes != NULL && new->etypes == rmconf->etypes)
  628: 		new->etypes = dupetypes(new->etypes);
  629: 	if (new->idvl_p == rmconf->idvl_p) {
  630: 		new->idvl_p = genlist_init();
  631: 		genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p);
  632: 	}
  633: 
  634: 	if (new->rsa_private == rmconf->rsa_private) {
  635: 		new->rsa_private = genlist_init();
  636: 		genlist_foreach(rmconf->rsa_private, duprsa, new->rsa_private);
  637: 	}
  638: 	if (new->rsa_public == rmconf->rsa_public) {
  639: 		new->rsa_public = genlist_init();
  640: 		genlist_foreach(rmconf->rsa_public, duprsa, new->rsa_public);
  641: 	}
  642: 	if (new->remote != NULL && new->remote == rmconf->remote) {
  643: 		new->remote = racoon_malloc(sizeof(*new->remote));
  644: 		if (new->remote == NULL) {
  645: 			plog(LLV_ERROR, LOCATION, NULL, 
  646: 			    "duprmconf_finish: malloc failed (remote)\n");
  647: 			exit(1);
  648: 		}
  649: 		memcpy(new->remote, rmconf->remote, sizeof(*new->remote));
  650: 	}
  651: 	if (new->spspec != NULL && new->spspec == rmconf->spspec) {
  652: 		dupspspec_list(new, rmconf);
  653: 	}
  654: 
  655: 	/* proposal has been deep copied already from spspec's, see
  656: 	 * cfparse.y:set_isakmp_proposal, which in turn calls
  657: 	 * cfparse.y:expand_isakmpspec where the copying happens.
  658: 	 */
  659: 
  660: #ifdef ENABLE_HYBRID
  661: 	if (new->xauth != NULL && new->xauth == rmconf->xauth) {
  662: 		new->xauth = xauth_rmconf_dup(new->xauth);
  663: 		if (new->xauth == NULL)
  664: 			exit(1);
  665: 	}
  666: #endif
  667: 
  668:         /* duplicate strings unless value overridden */ 
  669: 	if (new->mycertfile != NULL && new->mycertfile == rmconf->mycertfile) { 
  670: 		new->mycertfile = racoon_strdup(new->mycertfile); 
  671: 		STRDUP_FATAL(new->mycertfile); 
  672: 	} 
  673: 	if (new->myprivfile != NULL && new->myprivfile == rmconf->myprivfile) { 
  674: 		new->myprivfile = racoon_strdup(new->myprivfile); 
  675: 		STRDUP_FATAL(new->myprivfile); 
  676: 	} 
  677: 	if (new->peerscertfile != NULL && new->peerscertfile == rmconf->peerscertfile) { 
  678: 		new->peerscertfile = racoon_strdup(new->peerscertfile); 
  679: 		STRDUP_FATAL(new->peerscertfile); 
  680: 	} 
  681: 	if (new->cacertfile != NULL && new->cacertfile == rmconf->cacertfile) { 
  682: 		new->cacertfile = racoon_strdup(new->cacertfile); 
  683: 		STRDUP_FATAL(new->cacertfile); 
  684: 	} 
  685: 	if (new->idv != NULL && new->idv == rmconf->idv) {
  686: 		new->idv = vdup(new->idv); 
  687: 		STRDUP_FATAL(new->idv); 
  688: 	}
  689: 	if (new->key != NULL && new->key == rmconf->key) {
  690: 		new->key = vdup(new->key); 
  691: 		STRDUP_FATAL(new->key); 
  692: 	}
  693: 	if (new->mycert != NULL && new->mycert == rmconf->mycert) {
  694: 		new->mycert = vdup(new->mycert);
  695: 		STRDUP_FATAL(new->mycert); 
  696: 	}
  697: 	if (new->peerscert != NULL && new->peerscert == rmconf->peerscert) {
  698: 		new->peerscert = vdup(new->peerscert);
  699: 		STRDUP_FATAL(new->peerscert); 
  700: 	}
  701: 	if (new->cacert != NULL && new->cacert == rmconf->cacert) {
  702: 		new->cacert = vdup(new->cacert);
  703: 		STRDUP_FATAL(new->cacert); 
  704: 	}
  705: 	for (i = 0; i <= SCRIPT_MAX; i++)
  706: 		if (new->script[i] != NULL && new->script[i] == rmconf->script[i]) {
  707: 			new->script[i] = vdup(new->script[i]);
  708: 			STRDUP_FATAL(new->script[i]);
  709: 		}
  710: 
  711: 	return 0;
  712: }
  713: 
  714: static void
  715: idspec_free(void *data)
  716: {
  717: 	vfree (((struct idspec *)data)->id);
  718: 	free (data);
  719: }
  720: 
  721: void
  722: delrmconf(rmconf)
  723: 	struct remoteconf *rmconf;
  724: {
  725: 	int i;
  726: 
  727: #ifdef ENABLE_HYBRID
  728: 	if (rmconf->xauth)
  729: 		xauth_rmconf_delete(&rmconf->xauth);
  730: #endif
  731: 	if (rmconf->etypes){
  732: 		deletypes(rmconf->etypes);
  733: 		rmconf->etypes=NULL;
  734: 	}
  735: 	if (rmconf->idv)
  736: 		vfree(rmconf->idv);
  737: 	if (rmconf->key)
  738: 		vfree(rmconf->key);
  739: 	if (rmconf->idvl_p)
  740: 		genlist_free(rmconf->idvl_p, idspec_free);
  741: 	if (rmconf->dhgrp)
  742: 		oakley_dhgrp_free(rmconf->dhgrp);
  743: 	if (rmconf->proposal)
  744: 		delisakmpsa(rmconf->proposal);
  745: 	flushspspec(rmconf);
  746: 	if (rmconf->mycert)
  747: 		vfree(rmconf->mycert);
  748: 	if (rmconf->mycertfile)
  749: 		racoon_free(rmconf->mycertfile);
  750: 	if (rmconf->myprivfile)
  751: 		racoon_free(rmconf->myprivfile);
  752: 	if (rmconf->peerscert)
  753: 		vfree(rmconf->peerscert);
  754: 	if (rmconf->peerscertfile)
  755: 		racoon_free(rmconf->peerscertfile);
  756: 	if (rmconf->cacert)
  757: 		vfree(rmconf->cacert);
  758: 	if (rmconf->cacertfile)
  759: 		racoon_free(rmconf->cacertfile);
  760: 	if (rmconf->rsa_private)
  761: 		genlist_free(rmconf->rsa_private, rsa_key_free);
  762: 	if (rmconf->rsa_public)
  763: 		genlist_free(rmconf->rsa_public, rsa_key_free);
  764: 	if (rmconf->name)
  765: 		racoon_free(rmconf->name);
  766: 	if (rmconf->remote)
  767: 		racoon_free(rmconf->remote);
  768: 	for (i = 0; i <= SCRIPT_MAX; i++)
  769: 		if (rmconf->script[i])
  770: 			vfree(rmconf->script[i]);
  771: 
  772: 	racoon_free(rmconf);
  773: }
  774: 
  775: void
  776: delisakmpsa(sa)
  777: 	struct isakmpsa *sa;
  778: {
  779: 	if (sa->dhgrp)
  780: 		oakley_dhgrp_free(sa->dhgrp);
  781: 	if (sa->next)
  782: 		delisakmpsa(sa->next);
  783: #ifdef HAVE_GSSAPI
  784: 	if (sa->gssid)
  785: 		vfree(sa->gssid);
  786: #endif
  787: 	racoon_free(sa);
  788: }
  789: 
  790: struct etypes *
  791: dupetypes(orig)
  792: 	struct etypes *orig;
  793: {
  794: 	struct etypes *new;
  795: 
  796: 	if (!orig)
  797: 		return NULL;
  798: 
  799: 	new = racoon_malloc(sizeof(struct etypes));
  800: 	if (new == NULL)
  801: 		return NULL;
  802: 
  803: 	new->type = orig->type;
  804: 	new->next = NULL;
  805: 
  806: 	if (orig->next)
  807: 		new->next=dupetypes(orig->next);
  808: 
  809: 	return new;
  810: }
  811: 
  812: void
  813: deletypes(e)
  814: 	struct etypes *e;
  815: {
  816: 	if (e->next)
  817: 		deletypes(e->next);
  818: 	racoon_free(e);
  819: }
  820: 
  821: /*
  822:  * insert into head of list.
  823:  */
  824: void
  825: insrmconf(new)
  826: 	struct remoteconf *new;
  827: {
  828: 	if (new->name == NULL) {
  829: 		new->name = racoon_strdup(saddr2str(new->remote));
  830: 	}
  831: 	if (new->remote == NULL) {
  832: 		new->remote = newsaddr(sizeof(struct sockaddr));
  833: 		new->remote->sa_family = AF_UNSPEC;
  834: 	}
  835: 
  836: 	TAILQ_INSERT_HEAD(&rmtree, new, chain);
  837: }
  838: 
  839: void
  840: remrmconf(rmconf)
  841: 	struct remoteconf *rmconf;
  842: {
  843: 	TAILQ_REMOVE(&rmtree, rmconf, chain);
  844: }
  845: 
  846: void
  847: flushrmconf()
  848: {
  849: 	struct remoteconf *p, *next;
  850: 
  851: 	for (p = TAILQ_FIRST(&rmtree); p; p = next) {
  852: 		next = TAILQ_NEXT(p, chain);
  853: 		remrmconf(p);
  854: 		delrmconf(p);
  855: 	}
  856: }
  857: 
  858: void
  859: initrmconf()
  860: {
  861: 	TAILQ_INIT(&rmtree);
  862: }
  863: 
  864: void
  865: rmconf_start_reload()
  866: {
  867: 	rmtree_save=rmtree;
  868: 	initrmconf();
  869: }
  870: 
  871: void
  872: rmconf_finish_reload()
  873: {
  874: 	remoteconf_tailq_head_t rmtree_tmp;
  875: 
  876: 	rmtree_tmp=rmtree;
  877: 	rmtree=rmtree_save;
  878: 	flushrmconf();
  879: 	initrmconf();
  880: 	rmtree=rmtree_tmp;
  881: }
  882: 
  883: 
  884: 
  885: /* check exchange type to be acceptable */
  886: int
  887: check_etypeok(rmconf, ctx)
  888: 	struct remoteconf *rmconf;
  889: 	void *ctx;
  890: {
  891: 	u_int8_t etype = (u_int8_t) (intptr_t) ctx;
  892: 	struct etypes *e;
  893: 
  894: 	for (e = rmconf->etypes; e != NULL; e = e->next) {
  895: 		if (e->type == etype)
  896: 			return 1;
  897: 		plog(LLV_DEBUG2, LOCATION, NULL,
  898: 		     "Etype mismatch: got %d, expected %d.\n", e->type, etype);
  899: 	}
  900: 
  901: 	return 0;
  902: }
  903: 
  904: /*%%%*/
  905: struct isakmpsa *
  906: newisakmpsa()
  907: {
  908: 	struct isakmpsa *new;
  909: 
  910: 	new = racoon_calloc(1, sizeof(*new));
  911: 	if (new == NULL)
  912: 		return NULL;
  913: 
  914: 	/*
  915: 	 * Just for sanity, make sure this is initialized.  This is
  916: 	 * filled in for real when the ISAKMP proposal is configured.
  917: 	 */
  918: 	new->vendorid = VENDORID_UNKNOWN;
  919: 
  920: 	new->next = NULL;
  921: #ifdef HAVE_GSSAPI
  922: 	new->gssid = NULL;
  923: #endif
  924: 
  925: 	return new;
  926: }
  927: 
  928: /*
  929:  * insert into tail of list.
  930:  */
  931: void
  932: insisakmpsa(new, rmconf)
  933: 	struct isakmpsa *new;
  934: 	struct remoteconf *rmconf;
  935: {
  936: 	struct isakmpsa *p;
  937: 
  938: 	if (rmconf->proposal == NULL) {
  939: 		rmconf->proposal = new;
  940: 		return;
  941: 	}
  942: 
  943: 	for (p = rmconf->proposal; p->next != NULL; p = p->next)
  944: 		;
  945: 	p->next = new;
  946: }
  947: 
  948: static void *
  949: dump_peers_identifiers (void *entry, void *arg)
  950: {
  951: 	struct idspec *id = (struct idspec*) entry;
  952: 	char buf[1024], *pbuf;
  953: 	pbuf = buf;
  954: 	pbuf += sprintf (pbuf, "\tpeers_identifier %s",
  955: 			 s_idtype (id->idtype));
  956: 	if (id->id)
  957: 		pbuf += sprintf (pbuf, " \"%s\"", id->id->v);
  958: 	plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
  959: 	return NULL;
  960: }
  961: 
  962: static int
  963: dump_rmconf_single (struct remoteconf *p, void *data)
  964: {
  965: 	struct etypes *etype = p->etypes;
  966: 	struct isakmpsa *prop = p->proposal;
  967: 	char buf[1024], *pbuf;
  968: 
  969: 	pbuf = buf;
  970: 
  971: 	pbuf += sprintf(pbuf, "remote \"%s\"", p->name);
  972: 	if (p->inherited_from)
  973: 		pbuf += sprintf(pbuf, " inherit \"%s\"",
  974: 				p->inherited_from->name);
  975: 	plog(LLV_INFO, LOCATION, NULL, "%s {\n", buf);
  976: 	pbuf = buf;
  977: 	pbuf += sprintf(pbuf, "\texchange_type ");
  978: 	while (etype) {
  979: 		pbuf += sprintf (pbuf, "%s%s", s_etype(etype->type),
  980: 				 etype->next != NULL ? ", " : ";\n");
  981: 		etype = etype->next;
  982: 	}
  983: 	plog(LLV_INFO, LOCATION, NULL, "%s", buf);
  984: 	plog(LLV_INFO, LOCATION, NULL, "\tdoi %s;\n", s_doi(p->doitype));
  985: 	pbuf = buf;
  986: 	pbuf += sprintf(pbuf, "\tmy_identifier %s", s_idtype (p->idvtype));
  987: 	if (p->idvtype == IDTYPE_ASN1DN) {
  988: 		plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
  989: 		plog(LLV_INFO, LOCATION, NULL,
  990: 		     "\tcertificate_type %s \"%s\" \"%s\";\n",
  991: 		     oakley_get_certtype(p->mycert) == ISAKMP_CERT_X509SIGN
  992: 		       ? "x509" : "*UNKNOWN*",
  993: 		     p->mycertfile, p->myprivfile);
  994: 
  995: 		switch (oakley_get_certtype(p->peerscert)) {
  996: 		case ISAKMP_CERT_NONE:
  997: 			plog(LLV_INFO, LOCATION, NULL,
  998: 			     "\t/* peers certificate from payload */\n");
  999: 			break;
 1000: 		case ISAKMP_CERT_X509SIGN:
 1001: 			plog(LLV_INFO, LOCATION, NULL,
 1002: 			     "\tpeers_certfile \"%s\";\n", p->peerscertfile);
 1003: 			break;
 1004: 		case ISAKMP_CERT_DNS:
 1005: 			plog(LLV_INFO, LOCATION, NULL,
 1006: 			     "\tpeers_certfile dnssec;\n");
 1007: 			break;
 1008: 		default:
 1009: 			plog(LLV_INFO, LOCATION, NULL,
 1010: 			     "\tpeers_certfile *UNKNOWN* (%d)\n",
 1011: 			     oakley_get_certtype(p->peerscert));
 1012: 			break;
 1013: 		}
 1014: 	}
 1015: 	else {
 1016: 		if (p->idv)
 1017: 			pbuf += sprintf (pbuf, " \"%s\"", p->idv->v);
 1018: 		plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
 1019: 		genlist_foreach(p->idvl_p, &dump_peers_identifiers, NULL);
 1020: 	}
 1021: 
 1022: 	plog(LLV_INFO, LOCATION, NULL, "\trekey %s;\n",
 1023: 		p->rekey == REKEY_FORCE ? "force" : s_switch (p->rekey));
 1024: 	plog(LLV_INFO, LOCATION, NULL, "\tsend_cert %s;\n",
 1025: 		s_switch (p->send_cert));
 1026: 	plog(LLV_INFO, LOCATION, NULL, "\tsend_cr %s;\n",
 1027: 		s_switch (p->send_cr));
 1028: 	plog(LLV_INFO, LOCATION, NULL, "\tmatch_empty_cr %s;\n",
 1029: 		s_switch (p->match_empty_cr));
 1030: 	plog(LLV_INFO, LOCATION, NULL, "\tverify_cert %s;\n",
 1031: 		s_switch (p->verify_cert));
 1032: 	plog(LLV_INFO, LOCATION, NULL, "\tverify_identifier %s;\n",
 1033: 		s_switch (p->verify_identifier));
 1034: 	plog(LLV_INFO, LOCATION, NULL, "\tnat_traversal %s;\n",
 1035: 		p->nat_traversal == NATT_FORCE ?
 1036: 			"force" : s_switch (p->nat_traversal));
 1037: 	plog(LLV_INFO, LOCATION, NULL, "\tnonce_size %d;\n",
 1038: 		p->nonce_size);
 1039: 	plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n",
 1040: 		s_switch (p->passive));
 1041: 	plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n",
 1042: 		p->ike_frag == ISAKMP_FRAG_FORCE ?
 1043: 			"force" : s_switch (p->ike_frag));
 1044: 	plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag);
 1045: 	plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n",
 1046: 		s_switch (p->ini_contact));
 1047: 	plog(LLV_INFO, LOCATION, NULL, "\tgenerate_policy %s;\n",
 1048: 		s_switch (p->gen_policy));
 1049: 	plog(LLV_INFO, LOCATION, NULL, "\tsupport_proxy %s;\n",
 1050: 		s_switch (p->support_proxy));
 1051: 
 1052: 	while (prop) {
 1053: 		plog(LLV_INFO, LOCATION, NULL, "\n");
 1054: 		plog(LLV_INFO, LOCATION, NULL,
 1055: 			"\t/* prop_no=%d, trns_no=%d */\n",
 1056: 			prop->prop_no, prop->trns_no);
 1057: 		plog(LLV_INFO, LOCATION, NULL, "\tproposal {\n");
 1058: 		plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime time %lu sec;\n",
 1059: 			(long)prop->lifetime);
 1060: 		plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime bytes %zd;\n",
 1061: 			prop->lifebyte);
 1062: 		plog(LLV_INFO, LOCATION, NULL, "\t\tdh_group %s;\n",
 1063: 			alg_oakley_dhdef_name(prop->dh_group));
 1064: 		plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n",
 1065: 			alg_oakley_encdef_name(prop->enctype));
 1066: 		plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n",
 1067: 			alg_oakley_hashdef_name(prop->hashtype));
 1068: 		plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n",
 1069: 			alg_oakley_authdef_name(prop->authmethod));
 1070: 		plog(LLV_INFO, LOCATION, NULL, "\t}\n");
 1071: 		prop = prop->next;
 1072: 	}
 1073: 	plog(LLV_INFO, LOCATION, NULL, "}\n");
 1074: 	plog(LLV_INFO, LOCATION, NULL, "\n");
 1075: 
 1076: 	return 0;
 1077: }
 1078: 
 1079: void
 1080: dumprmconf()
 1081: {
 1082: 	enumrmconf(NULL, dump_rmconf_single, NULL);
 1083: }
 1084: 
 1085: struct idspec *
 1086: newidspec()
 1087: {
 1088: 	struct idspec *new;
 1089: 
 1090: 	new = racoon_calloc(1, sizeof(*new));
 1091: 	if (new == NULL)
 1092: 		return NULL;
 1093: 	new->idtype = IDTYPE_ADDRESS;
 1094: 
 1095: 	return new;
 1096: }
 1097: 
 1098: vchar_t *
 1099: script_path_add(path)
 1100: 	vchar_t *path;
 1101: {
 1102: 	char *script_dir;
 1103: 	vchar_t *new_path;
 1104: 	vchar_t *new_storage;
 1105: 	vchar_t **sp;
 1106: 	size_t len;
 1107: 	size_t size;
 1108: 
 1109: 	script_dir = lcconf->pathinfo[LC_PATHTYPE_SCRIPT];
 1110: 
 1111: 	/* Try to find the script in the script directory */
 1112: 	if ((path->v[0] != '/') && (script_dir != NULL)) {
 1113: 		len = strlen(script_dir) + sizeof("/") + path->l + 1;
 1114: 
 1115: 		if ((new_path = vmalloc(len)) == NULL) {
 1116: 			plog(LLV_ERROR, LOCATION, NULL,
 1117: 			    "Cannot allocate memory: %s\n", strerror(errno));
 1118: 			return NULL;
 1119: 		}
 1120: 
 1121: 		new_path->v[0] = '\0';
 1122: 		(void)strlcat(new_path->v, script_dir, len);
 1123: 		(void)strlcat(new_path->v, "/", len);
 1124: 		(void)strlcat(new_path->v, path->v, len);
 1125: 
 1126: 		vfree(path);
 1127: 		path = new_path;
 1128: 	}
 1129: 
 1130: 	return path;
 1131: }
 1132: 
 1133: 
 1134: struct isakmpsa *
 1135: dupisakmpsa(struct isakmpsa *sa)
 1136: {
 1137: 	struct isakmpsa *res = NULL;
 1138: 
 1139: 	if(sa == NULL)
 1140: 		return NULL;
 1141: 
 1142: 	res = newisakmpsa();
 1143: 	if(res == NULL)
 1144: 		return NULL;
 1145: 
 1146: 	*res = *sa;
 1147: #ifdef HAVE_GSSAPI
 1148: 	if (sa->gssid != NULL)
 1149: 		res->gssid = vdup(sa->gssid);
 1150: #endif
 1151: 	res->next = NULL;
 1152: 
 1153: 	if(sa->dhgrp != NULL)
 1154: 		oakley_setdhgroup(sa->dh_group, &res->dhgrp);
 1155: 
 1156: 	return res;
 1157: 
 1158: }
 1159: 
 1160: #ifdef ENABLE_HYBRID
 1161: int
 1162: isakmpsa_switch_authmethod(authmethod)
 1163: 	int authmethod;
 1164: {
 1165: 	switch(authmethod) {
 1166: 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
 1167: 		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I;
 1168: 		break;
 1169: 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
 1170: 		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I;
 1171: 		break;
 1172: 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
 1173: 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I;
 1174: 		break;
 1175: 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
 1176: 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I;
 1177: 		break;
 1178: 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
 1179: 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I;
 1180: 		break;
 1181: 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
 1182: 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I;
 1183: 		break;
 1184: 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
 1185: 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I;
 1186: 		break;
 1187: 	default:
 1188: 		break;
 1189: 	}
 1190: 
 1191: 	return authmethod;
 1192: }
 1193: #endif
 1194: 
 1195: /*
 1196:  * Given a proposed ISAKMP SA, and a list of acceptable
 1197:  * ISAKMP SAs, it compares using pcheck_level policy and
 1198:  * returns first match (if any).
 1199:  */
 1200: struct isakmpsa *
 1201: checkisakmpsa(pcheck_level, proposal, acceptable)
 1202: 	int pcheck_level;
 1203: 	struct isakmpsa *proposal, *acceptable;
 1204: {
 1205: 	struct isakmpsa *p;
 1206: 
 1207: 	for (p = acceptable; p != NULL; p = p->next){
 1208: 		plog(LLV_DEBUG2, LOCATION, NULL,
 1209: 		     "checkisakmpsa:\nauthmethod: %d / %d\n",
 1210: 		     isakmpsa_switch_authmethod(proposal->authmethod), isakmpsa_switch_authmethod(p->authmethod));
 1211: 		if (isakmpsa_switch_authmethod(proposal->authmethod) != isakmpsa_switch_authmethod(p->authmethod) ||
 1212: 		    proposal->enctype != p->enctype ||
 1213:                     proposal->dh_group != p->dh_group ||
 1214: 		    proposal->hashtype != p->hashtype)
 1215: 			continue;
 1216: 
 1217: 		switch (pcheck_level) {
 1218: 		case PROP_CHECK_OBEY:
 1219: 			break;
 1220: 
 1221: 		case PROP_CHECK_CLAIM:
 1222: 		case PROP_CHECK_STRICT:
 1223: 			if (proposal->encklen < p->encklen ||
 1224: #if 0
 1225: 			    proposal->lifebyte > p->lifebyte ||
 1226: #endif
 1227: 			    proposal->lifetime > p->lifetime)
 1228: 				continue;
 1229: 			break;
 1230: 
 1231: 		case PROP_CHECK_EXACT:
 1232: 			if (proposal->encklen != p->encklen ||
 1233: #if 0
 1234:                             proposal->lifebyte != p->lifebyte ||
 1235: #endif
 1236: 			    proposal->lifetime != p->lifetime)
 1237: 				continue;
 1238: 			break;
 1239: 
 1240: 		default:
 1241: 			continue;
 1242: 		}
 1243: 
 1244: 		return p;
 1245: 	}
 1246: 
 1247: 	return NULL;
 1248: }

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