Annotation of embedaddon/strongswan/src/libcharon/config/peer_cfg.c, revision 1.1.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>