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