Annotation of embedaddon/strongswan/src/libcharon/config/peer_cfg.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2007-2019 Tobias Brunner
        !             3:  * Copyright (C) 2005-2009 Martin Willi
        !             4:  * Copyright (C) 2005 Jan Hutter
        !             5:  * HSR Hochschule fuer Technik Rapperswil
        !             6:  *
        !             7:  * This program is free software; you can redistribute it and/or modify it
        !             8:  * under the terms of the GNU General Public License as published by the
        !             9:  * Free Software Foundation; either version 2 of the License, or (at your
        !            10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            11:  *
        !            12:  * This program is distributed in the hope that it will be useful, but
        !            13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            15:  * for more details.
        !            16:  */
        !            17: 
        !            18: #include <string.h>
        !            19: 
        !            20: #include "peer_cfg.h"
        !            21: 
        !            22: #include <daemon.h>
        !            23: 
        !            24: #include <threading/rwlock.h>
        !            25: #include <collections/linked_list.h>
        !            26: #include <utils/identification.h>
        !            27: 
        !            28: ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
        !            29:        "CERT_ALWAYS_SEND",
        !            30:        "CERT_SEND_IF_ASKED",
        !            31:        "CERT_NEVER_SEND",
        !            32: );
        !            33: 
        !            34: ENUM(unique_policy_names, UNIQUE_NEVER, UNIQUE_KEEP,
        !            35:        "UNIQUE_NEVER",
        !            36:        "UNIQUE_NO",
        !            37:        "UNIQUE_REPLACE",
        !            38:        "UNIQUE_KEEP",
        !            39: );
        !            40: 
        !            41: typedef struct private_peer_cfg_t private_peer_cfg_t;
        !            42: 
        !            43: /**
        !            44:  * Private data of an peer_cfg_t object
        !            45:  */
        !            46: struct private_peer_cfg_t {
        !            47: 
        !            48:        /**
        !            49:         * Public part
        !            50:         */
        !            51:        peer_cfg_t public;
        !            52: 
        !            53:        /**
        !            54:         * Number of references hold by others to this peer_cfg
        !            55:         */
        !            56:        refcount_t refcount;
        !            57: 
        !            58:        /**
        !            59:         * Name of the peer_cfg, used to query it
        !            60:         */
        !            61:        char *name;
        !            62: 
        !            63:        /**
        !            64:         * IKE config associated to this peer config
        !            65:         */
        !            66:        ike_cfg_t *ike_cfg;
        !            67: 
        !            68:        /**
        !            69:         * list of child configs associated to this peer config
        !            70:         */
        !            71:        linked_list_t *child_cfgs;
        !            72: 
        !            73:        /**
        !            74:         * lock to access list of child_cfgs
        !            75:         */
        !            76:        rwlock_t *lock;
        !            77: 
        !            78:        /**
        !            79:         * should we send a certificate
        !            80:         */
        !            81:        cert_policy_t cert_policy;
        !            82: 
        !            83:        /**
        !            84:         * uniqueness of an IKE_SA
        !            85:         */
        !            86:        unique_policy_t unique;
        !            87: 
        !            88:        /**
        !            89:         * number of tries after giving up if peer does not respond
        !            90:         */
        !            91:        uint32_t keyingtries;
        !            92: 
        !            93:        /**
        !            94:         * enable support for MOBIKE
        !            95:         */
        !            96:        bool use_mobike;
        !            97: 
        !            98:        /**
        !            99:         * Use aggressive mode?
        !           100:         */
        !           101:        bool aggressive;
        !           102: 
        !           103:        /**
        !           104:         * Use pull or push in mode config?
        !           105:         */
        !           106:        bool pull_mode;
        !           107: 
        !           108:        /**
        !           109:         * Time before starting rekeying
        !           110:         */
        !           111:        uint32_t rekey_time;
        !           112: 
        !           113:        /**
        !           114:         * Time before starting reauthentication
        !           115:         */
        !           116:        uint32_t reauth_time;
        !           117: 
        !           118:        /**
        !           119:         * Time, which specifies the range of a random value subtracted from above.
        !           120:         */
        !           121:        uint32_t jitter_time;
        !           122: 
        !           123:        /**
        !           124:         * Delay before deleting a rekeying/reauthenticating SA
        !           125:         */
        !           126:        uint32_t over_time;
        !           127: 
        !           128:        /**
        !           129:         * DPD check interval
        !           130:         */
        !           131:        uint32_t dpd;
        !           132: 
        !           133:        /**
        !           134:         * DPD timeout interval (used for IKEv1 only)
        !           135:         */
        !           136:        uint32_t dpd_timeout;
        !           137: 
        !           138:        /**
        !           139:         * List of virtual IPs (host_t*) to request
        !           140:         */
        !           141:        linked_list_t *vips;
        !           142: 
        !           143:        /**
        !           144:         * List of pool names to use for virtual IP lookup
        !           145:         */
        !           146:        linked_list_t *pools;
        !           147: 
        !           148:        /**
        !           149:         * local authentication configs (rulesets)
        !           150:         */
        !           151:        linked_list_t *local_auth;
        !           152: 
        !           153:        /**
        !           154:         * remote authentication configs (constraints)
        !           155:         */
        !           156:        linked_list_t *remote_auth;
        !           157: 
        !           158:        /**
        !           159:         * Optional interface ID to use for inbound CHILD_SA
        !           160:         */
        !           161:        uint32_t if_id_in;
        !           162: 
        !           163:        /**
        !           164:         * Optional interface ID to use for outbound CHILD_SA
        !           165:         */
        !           166:        uint32_t if_id_out;
        !           167: 
        !           168:        /**
        !           169:         * PPK ID
        !           170:         */
        !           171:        identification_t *ppk_id;
        !           172: 
        !           173:        /**
        !           174:         * Whether a PPK is required
        !           175:         */
        !           176:        bool ppk_required;
        !           177: 
        !           178: #ifdef ME
        !           179:        /**
        !           180:         * Is this a mediation connection?
        !           181:         */
        !           182:        bool mediation;
        !           183: 
        !           184:        /**
        !           185:         * Name of the mediation connection to mediate through
        !           186:         */
        !           187:        char *mediated_by;
        !           188: 
        !           189:        /**
        !           190:         * ID of our peer at the mediation server (= leftid of the peer's conn with
        !           191:         * the mediation server)
        !           192:         */
        !           193:        identification_t *peer_id;
        !           194: #endif /* ME */
        !           195: };
        !           196: 
        !           197: METHOD(peer_cfg_t, get_name, char*,
        !           198:        private_peer_cfg_t *this)
        !           199: {
        !           200:        return this->name;
        !           201: }
        !           202: 
        !           203: METHOD(peer_cfg_t, get_ike_version, ike_version_t,
        !           204:        private_peer_cfg_t *this)
        !           205: {
        !           206:        return this->ike_cfg->get_version(this->ike_cfg);
        !           207: }
        !           208: 
        !           209: METHOD(peer_cfg_t, get_ike_cfg, ike_cfg_t*,
        !           210:        private_peer_cfg_t *this)
        !           211: {
        !           212:        return this->ike_cfg;
        !           213: }
        !           214: 
        !           215: METHOD(peer_cfg_t, add_child_cfg, void,
        !           216:        private_peer_cfg_t *this, child_cfg_t *child_cfg)
        !           217: {
        !           218:        this->lock->write_lock(this->lock);
        !           219:        this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
        !           220:        this->lock->unlock(this->lock);
        !           221: }
        !           222: 
        !           223: typedef struct {
        !           224:        enumerator_t public;
        !           225:        linked_list_t *removed;
        !           226:        linked_list_t *added;
        !           227:        enumerator_t *wrapped;
        !           228:        bool add;
        !           229: } child_cfgs_replace_enumerator_t;
        !           230: 
        !           231: METHOD(enumerator_t, child_cfgs_replace_enumerate, bool,
        !           232:        child_cfgs_replace_enumerator_t *this, va_list args)
        !           233: {
        !           234:        child_cfg_t *child_cfg, **chd;
        !           235:        bool *added;
        !           236: 
        !           237:        VA_ARGS_VGET(args, chd, added);
        !           238: 
        !           239:        if (!this->wrapped)
        !           240:        {
        !           241:                this->wrapped = this->removed->create_enumerator(this->removed);
        !           242:        }
        !           243:        while (TRUE)
        !           244:        {
        !           245:                if (this->wrapped->enumerate(this->wrapped, &child_cfg))
        !           246:                {
        !           247:                        if (chd)
        !           248:                        {
        !           249:                                *chd = child_cfg;
        !           250:                        }
        !           251:                        if (added)
        !           252:                        {
        !           253:                                *added = this->add;
        !           254:                        }
        !           255:                        return TRUE;
        !           256:                }
        !           257:                if (this->add)
        !           258:                {
        !           259:                        break;
        !           260:                }
        !           261:                this->wrapped->destroy(this->wrapped);
        !           262:                this->wrapped = this->added->create_enumerator(this->added);
        !           263:                this->add = TRUE;
        !           264:        }
        !           265:        return FALSE;
        !           266: }
        !           267: 
        !           268: METHOD(enumerator_t, child_cfgs_replace_enumerator_destroy, void,
        !           269:        child_cfgs_replace_enumerator_t *this)
        !           270: {
        !           271:        DESTROY_IF(this->wrapped);
        !           272:        this->removed->destroy_offset(this->removed, offsetof(child_cfg_t, destroy));
        !           273:        this->added->destroy_offset(this->added, offsetof(child_cfg_t, destroy));
        !           274:        free(this);
        !           275: }
        !           276: 
        !           277: METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*,
        !           278:        private_peer_cfg_t *this, peer_cfg_t *other_pub)
        !           279: {
        !           280:        private_peer_cfg_t *other = (private_peer_cfg_t*)other_pub;
        !           281:        linked_list_t *new_cfgs, *removed, *added;
        !           282:        enumerator_t *mine, *others;
        !           283:        child_cfg_t *my_cfg, *other_cfg;
        !           284:        child_cfgs_replace_enumerator_t *enumerator;
        !           285:        bool found;
        !           286: 
        !           287:        added = linked_list_create();
        !           288: 
        !           289:        other->lock->read_lock(other->lock);
        !           290:        new_cfgs = linked_list_create_from_enumerator(
        !           291:                                        other->child_cfgs->create_enumerator(other->child_cfgs));
        !           292:        new_cfgs->invoke_offset(new_cfgs, offsetof(child_cfg_t, get_ref));
        !           293:        other->lock->unlock(other->lock);
        !           294: 
        !           295:        this->lock->write_lock(this->lock);
        !           296:        removed = this->child_cfgs;
        !           297:        this->child_cfgs = new_cfgs;
        !           298:        others = new_cfgs->create_enumerator(new_cfgs);
        !           299:        mine = removed->create_enumerator(removed);
        !           300:        while (others->enumerate(others, &other_cfg))
        !           301:        {
        !           302:                found = FALSE;
        !           303:                while (mine->enumerate(mine, &my_cfg))
        !           304:                {
        !           305:                        if (my_cfg->equals(my_cfg, other_cfg))
        !           306:                        {
        !           307:                                removed->remove_at(removed, mine);
        !           308:                                my_cfg->destroy(my_cfg);
        !           309:                                found = TRUE;
        !           310:                                break;
        !           311:                        }
        !           312:                }
        !           313:                removed->reset_enumerator(removed, mine);
        !           314:                if (!found)
        !           315:                {
        !           316:                        added->insert_last(added, other_cfg->get_ref(other_cfg));
        !           317:                }
        !           318:        }
        !           319:        others->destroy(others);
        !           320:        mine->destroy(mine);
        !           321:        this->lock->unlock(this->lock);
        !           322: 
        !           323:        INIT(enumerator,
        !           324:                .public = {
        !           325:                        .enumerate = enumerator_enumerate_default,
        !           326:                        .venumerate = _child_cfgs_replace_enumerate,
        !           327:                        .destroy = _child_cfgs_replace_enumerator_destroy,
        !           328:                },
        !           329:                .removed = removed,
        !           330:                .added = added,
        !           331:        );
        !           332:        return &enumerator->public;
        !           333: }
        !           334: 
        !           335: /**
        !           336:  * child_cfg enumerator
        !           337:  */
        !           338: typedef struct {
        !           339:        enumerator_t public;
        !           340:        enumerator_t *wrapped;
        !           341:        rwlock_t *lock;
        !           342: } child_cfg_enumerator_t;
        !           343: 
        !           344: METHOD(peer_cfg_t, remove_child_cfg, void,
        !           345:        private_peer_cfg_t *this, child_cfg_enumerator_t *enumerator)
        !           346: {
        !           347:        this->child_cfgs->remove_at(this->child_cfgs, enumerator->wrapped);
        !           348: }
        !           349: 
        !           350: METHOD(enumerator_t, child_cfg_enumerator_destroy, void,
        !           351:        child_cfg_enumerator_t *this)
        !           352: {
        !           353:        this->lock->unlock(this->lock);
        !           354:        this->wrapped->destroy(this->wrapped);
        !           355:        free(this);
        !           356: }
        !           357: 
        !           358: METHOD(enumerator_t, child_cfg_enumerate, bool,
        !           359:        child_cfg_enumerator_t *this, va_list args)
        !           360: {
        !           361:        child_cfg_t **chd;
        !           362: 
        !           363:        VA_ARGS_VGET(args, chd);
        !           364:        return this->wrapped->enumerate(this->wrapped, chd);
        !           365: }
        !           366: 
        !           367: METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
        !           368:        private_peer_cfg_t *this)
        !           369: {
        !           370:        child_cfg_enumerator_t *enumerator;
        !           371: 
        !           372:        INIT(enumerator,
        !           373:                .public = {
        !           374:                        .enumerate = enumerator_enumerate_default,
        !           375:                        .venumerate = _child_cfg_enumerate,
        !           376:                        .destroy = _child_cfg_enumerator_destroy,
        !           377:                },
        !           378:                .lock = this->lock,
        !           379:                .wrapped = this->child_cfgs->create_enumerator(this->child_cfgs),
        !           380:        );
        !           381: 
        !           382:        this->lock->read_lock(this->lock);
        !           383:        return &enumerator->public;
        !           384: }
        !           385: 
        !           386: /**
        !           387:  * Check how good a list of TS matches a given child config
        !           388:  */
        !           389: static int get_ts_match(child_cfg_t *cfg, bool local,
        !           390:                                                linked_list_t *sup_list, linked_list_t *hosts)
        !           391: {
        !           392:        linked_list_t *cfg_list;
        !           393:        enumerator_t *sup_enum, *cfg_enum;
        !           394:        traffic_selector_t *sup_ts, *cfg_ts, *subset;
        !           395:        int match = 0, round;
        !           396: 
        !           397:        /* fetch configured TS list, narrowing dynamic TS */
        !           398:        cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, hosts, TRUE);
        !           399: 
        !           400:        /* use a round counter to rate leading TS with higher priority */
        !           401:        round = sup_list->get_count(sup_list);
        !           402: 
        !           403:        sup_enum = sup_list->create_enumerator(sup_list);
        !           404:        while (sup_enum->enumerate(sup_enum, &sup_ts))
        !           405:        {
        !           406:                cfg_enum = cfg_list->create_enumerator(cfg_list);
        !           407:                while (cfg_enum->enumerate(cfg_enum, &cfg_ts))
        !           408:                {
        !           409:                        if (cfg_ts->equals(cfg_ts, sup_ts))
        !           410:                        {       /* equality is honored better than matches */
        !           411:                                match += round * 5;
        !           412:                        }
        !           413:                        else
        !           414:                        {
        !           415:                                subset = cfg_ts->get_subset(cfg_ts, sup_ts);
        !           416:                                if (subset)
        !           417:                                {
        !           418:                                        subset->destroy(subset);
        !           419:                                        match += round * 1;
        !           420:                                }
        !           421:                        }
        !           422:                }
        !           423:                cfg_enum->destroy(cfg_enum);
        !           424:                round--;
        !           425:        }
        !           426:        sup_enum->destroy(sup_enum);
        !           427: 
        !           428:        cfg_list->destroy_offset(cfg_list, offsetof(traffic_selector_t, destroy));
        !           429: 
        !           430:        return match;
        !           431: }
        !           432: 
        !           433: METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*,
        !           434:        private_peer_cfg_t *this, linked_list_t *my_ts, linked_list_t *other_ts,
        !           435:        linked_list_t *my_hosts, linked_list_t *other_hosts)
        !           436: {
        !           437:        child_cfg_t *current, *found = NULL;
        !           438:        enumerator_t *enumerator;
        !           439:        int best = 0;
        !           440: 
        !           441:        DBG2(DBG_CFG, "looking for a child config for %#R === %#R", my_ts, other_ts);
        !           442:        enumerator = create_child_cfg_enumerator(this);
        !           443:        while (enumerator->enumerate(enumerator, &current))
        !           444:        {
        !           445:                int my_prio, other_prio;
        !           446: 
        !           447:                my_prio = get_ts_match(current, TRUE, my_ts, my_hosts);
        !           448:                other_prio = get_ts_match(current, FALSE, other_ts, other_hosts);
        !           449: 
        !           450:                if (my_prio && other_prio)
        !           451:                {
        !           452:                        DBG2(DBG_CFG, "  candidate \"%s\" with prio %d+%d",
        !           453:                                 current->get_name(current), my_prio, other_prio);
        !           454:                        if (my_prio + other_prio > best)
        !           455:                        {
        !           456:                                best = my_prio + other_prio;
        !           457:                                DESTROY_IF(found);
        !           458:                                found = current->get_ref(current);
        !           459:                        }
        !           460:                }
        !           461:        }
        !           462:        enumerator->destroy(enumerator);
        !           463:        if (found)
        !           464:        {
        !           465:                DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d",
        !           466:                         found->get_name(found), best);
        !           467:        }
        !           468:        return found;
        !           469: }
        !           470: 
        !           471: METHOD(peer_cfg_t, get_cert_policy, cert_policy_t,
        !           472:        private_peer_cfg_t *this)
        !           473: {
        !           474:        return this->cert_policy;
        !           475: }
        !           476: 
        !           477: METHOD(peer_cfg_t, get_unique_policy, unique_policy_t,
        !           478:        private_peer_cfg_t *this)
        !           479: {
        !           480:        return this->unique;
        !           481: }
        !           482: 
        !           483: METHOD(peer_cfg_t, get_keyingtries, uint32_t,
        !           484:        private_peer_cfg_t *this)
        !           485: {
        !           486:        return this->keyingtries;
        !           487: }
        !           488: 
        !           489: METHOD(peer_cfg_t, get_rekey_time, uint32_t,
        !           490:        private_peer_cfg_t *this, bool jitter)
        !           491: {
        !           492:        if (this->rekey_time == 0)
        !           493:        {
        !           494:                return 0;
        !           495:        }
        !           496:        if (this->jitter_time == 0 || !jitter)
        !           497:        {
        !           498:                return this->rekey_time;
        !           499:        }
        !           500:        return this->rekey_time - (random() % this->jitter_time);
        !           501: }
        !           502: 
        !           503: METHOD(peer_cfg_t, get_reauth_time, uint32_t,
        !           504:        private_peer_cfg_t *this, bool jitter)
        !           505: {
        !           506:        if (this->reauth_time == 0)
        !           507:        {
        !           508:                return 0;
        !           509:        }
        !           510:        if (this->jitter_time == 0 || !jitter)
        !           511:        {
        !           512:                return this->reauth_time;
        !           513:        }
        !           514:        return this->reauth_time - (random() % this->jitter_time);
        !           515: }
        !           516: 
        !           517: METHOD(peer_cfg_t, get_over_time, uint32_t,
        !           518:        private_peer_cfg_t *this)
        !           519: {
        !           520:        return this->over_time;
        !           521: }
        !           522: 
        !           523: METHOD(peer_cfg_t, use_mobike, bool,
        !           524:        private_peer_cfg_t *this)
        !           525: {
        !           526:        return this->use_mobike;
        !           527: }
        !           528: 
        !           529: METHOD(peer_cfg_t, use_aggressive, bool,
        !           530:        private_peer_cfg_t *this)
        !           531: {
        !           532:        return this->aggressive;
        !           533: }
        !           534: 
        !           535: METHOD(peer_cfg_t, use_pull_mode, bool,
        !           536:        private_peer_cfg_t *this)
        !           537: {
        !           538:        return this->pull_mode;
        !           539: }
        !           540: 
        !           541: METHOD(peer_cfg_t, get_dpd, uint32_t,
        !           542:        private_peer_cfg_t *this)
        !           543: {
        !           544:        return this->dpd;
        !           545: }
        !           546: 
        !           547: METHOD(peer_cfg_t, get_dpd_timeout, uint32_t,
        !           548:        private_peer_cfg_t *this)
        !           549: {
        !           550:        return this->dpd_timeout;
        !           551: }
        !           552: 
        !           553: METHOD(peer_cfg_t, add_virtual_ip, void,
        !           554:        private_peer_cfg_t *this, host_t *vip)
        !           555: {
        !           556:        this->vips->insert_last(this->vips, vip);
        !           557: }
        !           558: 
        !           559: METHOD(peer_cfg_t, create_virtual_ip_enumerator, enumerator_t*,
        !           560:        private_peer_cfg_t *this)
        !           561: {
        !           562:        return this->vips->create_enumerator(this->vips);
        !           563: }
        !           564: 
        !           565: METHOD(peer_cfg_t, add_pool, void,
        !           566:        private_peer_cfg_t *this, char *name)
        !           567: {
        !           568:        this->pools->insert_last(this->pools, strdup(name));
        !           569: }
        !           570: 
        !           571: METHOD(peer_cfg_t, create_pool_enumerator, enumerator_t*,
        !           572:        private_peer_cfg_t *this)
        !           573: {
        !           574:        return this->pools->create_enumerator(this->pools);
        !           575: }
        !           576: 
        !           577: METHOD(peer_cfg_t, add_auth_cfg, void,
        !           578:        private_peer_cfg_t *this, auth_cfg_t *cfg, bool local)
        !           579: {
        !           580:        if (local)
        !           581:        {
        !           582:                this->local_auth->insert_last(this->local_auth, cfg);
        !           583:        }
        !           584:        else
        !           585:        {
        !           586:                this->remote_auth->insert_last(this->remote_auth, cfg);
        !           587:        }
        !           588: }
        !           589: 
        !           590: METHOD(peer_cfg_t, create_auth_cfg_enumerator, enumerator_t*,
        !           591:        private_peer_cfg_t *this, bool local)
        !           592: {
        !           593:        if (local)
        !           594:        {
        !           595:                return this->local_auth->create_enumerator(this->local_auth);
        !           596:        }
        !           597:        return this->remote_auth->create_enumerator(this->remote_auth);
        !           598: }
        !           599: 
        !           600: METHOD(peer_cfg_t, get_if_id, uint32_t,
        !           601:        private_peer_cfg_t *this, bool inbound)
        !           602: {
        !           603:        return inbound ? this->if_id_in : this->if_id_out;
        !           604: }
        !           605: 
        !           606: METHOD(peer_cfg_t, get_ppk_id, identification_t*,
        !           607:        private_peer_cfg_t *this)
        !           608: {
        !           609:        return this->ppk_id;
        !           610: }
        !           611: 
        !           612: METHOD(peer_cfg_t, ppk_required, bool,
        !           613:        private_peer_cfg_t *this)
        !           614: {
        !           615:        return this->ppk_required;
        !           616: }
        !           617: 
        !           618: #ifdef ME
        !           619: METHOD(peer_cfg_t, is_mediation, bool,
        !           620:        private_peer_cfg_t *this)
        !           621: {
        !           622:        return this->mediation;
        !           623: }
        !           624: 
        !           625: METHOD(peer_cfg_t, get_mediated_by, char*,
        !           626:        private_peer_cfg_t *this)
        !           627: {
        !           628:        return this->mediated_by;
        !           629: }
        !           630: 
        !           631: METHOD(peer_cfg_t, get_peer_id, identification_t*,
        !           632:        private_peer_cfg_t *this)
        !           633: {
        !           634:        return this->peer_id;
        !           635: }
        !           636: #endif /* ME */
        !           637: 
        !           638: /**
        !           639:  * check auth configs for equality
        !           640:  */
        !           641: static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
        !           642: {
        !           643:        enumerator_t *e1, *e2;
        !           644:        auth_cfg_t *cfg1, *cfg2;
        !           645:        bool equal = TRUE;
        !           646: 
        !           647:        if (this->local_auth->get_count(this->local_auth) !=
        !           648:                other->local_auth->get_count(other->local_auth))
        !           649:        {
        !           650:                return FALSE;
        !           651:        }
        !           652:        if (this->remote_auth->get_count(this->remote_auth) !=
        !           653:                other->remote_auth->get_count(other->remote_auth))
        !           654:        {
        !           655:                return FALSE;
        !           656:        }
        !           657: 
        !           658:        e1 = this->local_auth->create_enumerator(this->local_auth);
        !           659:        e2 = other->local_auth->create_enumerator(other->local_auth);
        !           660:        while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
        !           661:        {
        !           662:                if (!cfg1->equals(cfg1, cfg2))
        !           663:                {
        !           664:                        equal = FALSE;
        !           665:                        break;
        !           666:                }
        !           667:        }
        !           668:        e1->destroy(e1);
        !           669:        e2->destroy(e2);
        !           670: 
        !           671:        if (!equal)
        !           672:        {
        !           673:                return FALSE;
        !           674:        }
        !           675: 
        !           676:        e1 = this->remote_auth->create_enumerator(this->remote_auth);
        !           677:        e2 = other->remote_auth->create_enumerator(other->remote_auth);
        !           678:        while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
        !           679:        {
        !           680:                if (!cfg1->equals(cfg1, cfg2))
        !           681:                {
        !           682:                        equal = FALSE;
        !           683:                        break;
        !           684:                }
        !           685:        }
        !           686:        e1->destroy(e1);
        !           687:        e2->destroy(e2);
        !           688: 
        !           689:        return equal;
        !           690: }
        !           691: 
        !           692: /**
        !           693:  * Check if two identities are equal, or both are not set
        !           694:  */
        !           695: static bool id_equal(identification_t *this, identification_t *other)
        !           696: {
        !           697:        return this == other || (this && other && this->equals(this, other));
        !           698: }
        !           699: 
        !           700: METHOD(peer_cfg_t, equals, bool,
        !           701:        private_peer_cfg_t *this, private_peer_cfg_t *other)
        !           702: {
        !           703:        if (this == other)
        !           704:        {
        !           705:                return TRUE;
        !           706:        }
        !           707:        if (this->public.equals != other->public.equals)
        !           708:        {
        !           709:                return FALSE;
        !           710:        }
        !           711:        if (!this->vips->equals_offset(this->vips, other->vips,
        !           712:                                                                   offsetof(host_t, ip_equals)))
        !           713:        {
        !           714:                return FALSE;
        !           715:        }
        !           716:        if (!this->pools->equals_function(this->pools, other->pools, (void*)streq))
        !           717:        {
        !           718:                return FALSE;
        !           719:        }
        !           720:        return (
        !           721:                get_ike_version(this) == get_ike_version(other) &&
        !           722:                this->cert_policy == other->cert_policy &&
        !           723:                this->unique == other->unique &&
        !           724:                this->keyingtries == other->keyingtries &&
        !           725:                this->use_mobike == other->use_mobike &&
        !           726:                this->rekey_time == other->rekey_time &&
        !           727:                this->reauth_time == other->reauth_time &&
        !           728:                this->jitter_time == other->jitter_time &&
        !           729:                this->over_time == other->over_time &&
        !           730:                this->dpd == other->dpd &&
        !           731:                this->aggressive == other->aggressive &&
        !           732:                this->pull_mode == other->pull_mode &&
        !           733:                auth_cfg_equal(this, other) &&
        !           734:                this->if_id_in == other->if_id_in &&
        !           735:                this->if_id_out == other->if_id_out &&
        !           736:                this->ppk_required == other->ppk_required &&
        !           737:                id_equal(this->ppk_id, other->ppk_id)
        !           738: #ifdef ME
        !           739:                && this->mediation == other->mediation &&
        !           740:                streq(this->mediated_by, other->mediated_by) &&
        !           741:                id_equal(this->peer_id, other->peer_id)
        !           742: #endif /* ME */
        !           743:                );
        !           744: }
        !           745: 
        !           746: METHOD(peer_cfg_t, get_ref, peer_cfg_t*,
        !           747:        private_peer_cfg_t *this)
        !           748: {
        !           749:        ref_get(&this->refcount);
        !           750:        return &this->public;
        !           751: }
        !           752: 
        !           753: METHOD(peer_cfg_t, destroy, void,
        !           754:        private_peer_cfg_t *this)
        !           755: {
        !           756:        if (ref_put(&this->refcount))
        !           757:        {
        !           758:                this->ike_cfg->destroy(this->ike_cfg);
        !           759:                this->child_cfgs->destroy_offset(this->child_cfgs,
        !           760:                                                                                offsetof(child_cfg_t, destroy));
        !           761:                this->local_auth->destroy_offset(this->local_auth,
        !           762:                                                                                offsetof(auth_cfg_t, destroy));
        !           763:                this->remote_auth->destroy_offset(this->remote_auth,
        !           764:                                                                                offsetof(auth_cfg_t, destroy));
        !           765:                this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
        !           766:                this->pools->destroy_function(this->pools, free);
        !           767: #ifdef ME
        !           768:                DESTROY_IF(this->peer_id);
        !           769:                free(this->mediated_by);
        !           770: #endif /* ME */
        !           771:                DESTROY_IF(this->ppk_id);
        !           772:                this->lock->destroy(this->lock);
        !           773:                free(this->name);
        !           774:                free(this);
        !           775:        }
        !           776: }
        !           777: 
        !           778: /*
        !           779:  * Described in header-file
        !           780:  */
        !           781: peer_cfg_t *peer_cfg_create(char *name, ike_cfg_t *ike_cfg,
        !           782:                                                        peer_cfg_create_t *data)
        !           783: {
        !           784:        private_peer_cfg_t *this;
        !           785: 
        !           786:        if (data->rekey_time && data->jitter_time > data->rekey_time)
        !           787:        {
        !           788:                data->jitter_time = data->rekey_time;
        !           789:        }
        !           790:        if (data->reauth_time && data->jitter_time > data->reauth_time)
        !           791:        {
        !           792:                data->jitter_time = data->reauth_time;
        !           793:        }
        !           794:        if (data->dpd && data->dpd_timeout && data->dpd > data->dpd_timeout)
        !           795:        {
        !           796:                data->dpd_timeout = data->dpd;
        !           797:        }
        !           798: 
        !           799:        INIT(this,
        !           800:                .public = {
        !           801:                        .get_name = _get_name,
        !           802:                        .get_ike_version = _get_ike_version,
        !           803:                        .get_ike_cfg = _get_ike_cfg,
        !           804:                        .add_child_cfg = _add_child_cfg,
        !           805:                        .remove_child_cfg = (void*)_remove_child_cfg,
        !           806:                        .replace_child_cfgs = _replace_child_cfgs,
        !           807:                        .create_child_cfg_enumerator = _create_child_cfg_enumerator,
        !           808:                        .select_child_cfg = _select_child_cfg,
        !           809:                        .get_cert_policy = _get_cert_policy,
        !           810:                        .get_unique_policy = _get_unique_policy,
        !           811:                        .get_keyingtries = _get_keyingtries,
        !           812:                        .get_rekey_time = _get_rekey_time,
        !           813:                        .get_reauth_time = _get_reauth_time,
        !           814:                        .get_over_time = _get_over_time,
        !           815:                        .use_mobike = _use_mobike,
        !           816:                        .use_aggressive = _use_aggressive,
        !           817:                        .use_pull_mode = _use_pull_mode,
        !           818:                        .get_dpd = _get_dpd,
        !           819:                        .get_dpd_timeout = _get_dpd_timeout,
        !           820:                        .add_virtual_ip = _add_virtual_ip,
        !           821:                        .create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
        !           822:                        .add_pool = _add_pool,
        !           823:                        .create_pool_enumerator = _create_pool_enumerator,
        !           824:                        .add_auth_cfg = _add_auth_cfg,
        !           825:                        .create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
        !           826:                        .get_if_id = _get_if_id,
        !           827:                        .get_ppk_id = _get_ppk_id,
        !           828:                        .ppk_required = _ppk_required,
        !           829:                        .equals = (void*)_equals,
        !           830:                        .get_ref = _get_ref,
        !           831:                        .destroy = _destroy,
        !           832: #ifdef ME
        !           833:                        .is_mediation = _is_mediation,
        !           834:                        .get_mediated_by = _get_mediated_by,
        !           835:                        .get_peer_id = _get_peer_id,
        !           836: #endif /* ME */
        !           837:                },
        !           838:                .name = strdup(name),
        !           839:                .ike_cfg = ike_cfg,
        !           840:                .child_cfgs = linked_list_create(),
        !           841:                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
        !           842:                .cert_policy = data->cert_policy,
        !           843:                .unique = data->unique,
        !           844:                .keyingtries = data->keyingtries,
        !           845:                .rekey_time = data->rekey_time,
        !           846:                .reauth_time = data->reauth_time,
        !           847:                .jitter_time = data->jitter_time,
        !           848:                .over_time = data->over_time,
        !           849:                .use_mobike = !data->no_mobike,
        !           850:                .aggressive = data->aggressive,
        !           851:                .pull_mode = !data->push_mode,
        !           852:                .dpd = data->dpd,
        !           853:                .dpd_timeout = data->dpd_timeout,
        !           854:                .if_id_in = data->if_id_in,
        !           855:                .if_id_out = data->if_id_out,
        !           856:                .ppk_id = data->ppk_id,
        !           857:                .ppk_required = data->ppk_required,
        !           858:                .vips = linked_list_create(),
        !           859:                .pools = linked_list_create(),
        !           860:                .local_auth = linked_list_create(),
        !           861:                .remote_auth = linked_list_create(),
        !           862:                .refcount = 1,
        !           863: #ifdef ME
        !           864:                .mediation = data->mediation,
        !           865:                .mediated_by = strdupnull(data->mediated_by),
        !           866:                .peer_id = data->peer_id,
        !           867: #endif /* ME */
        !           868:        );
        !           869: 
        !           870:        return &this->public;
        !           871: }

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