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