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

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2010 Martin Willi
        !             3:  * Copyright (C) 2010 revosec AG
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify it
        !             6:  * under the terms of the GNU General Public License as published by the
        !             7:  * Free Software Foundation; either version 2 of the License, or (at your
        !             8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            16: #include "config.h"
        !            17: 
        !            18: #include <daemon.h>
        !            19: #include <conftest.h>
        !            20: 
        !            21: typedef struct private_config_t private_config_t;
        !            22: 
        !            23: /**
        !            24:  * Private data of an config_t object.
        !            25:  */
        !            26: struct private_config_t {
        !            27: 
        !            28:        /**
        !            29:         * Public config_t interface.
        !            30:         */
        !            31:        config_t public;
        !            32: 
        !            33:        /**
        !            34:         * List of loaded peer configs
        !            35:         */
        !            36:        linked_list_t *configs;
        !            37: };
        !            38: 
        !            39: CALLBACK(ike_filter, bool,
        !            40:        void *data, enumerator_t *orig, va_list args)
        !            41: {
        !            42:        peer_cfg_t *cfg;
        !            43:        ike_cfg_t **out;
        !            44: 
        !            45:        VA_ARGS_VGET(args, out);
        !            46: 
        !            47:        if (orig->enumerate(orig, &cfg))
        !            48:        {
        !            49:                *out = cfg->get_ike_cfg(cfg);
        !            50:                return TRUE;
        !            51:        }
        !            52:        return FALSE;
        !            53: }
        !            54: 
        !            55: METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
        !            56:        private_config_t *this, host_t *me, host_t *other)
        !            57: {
        !            58: 
        !            59:        return enumerator_create_filter(
        !            60:                                                        this->configs->create_enumerator(this->configs),
        !            61:                                                        ike_filter, NULL, NULL);
        !            62: }
        !            63: 
        !            64: METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
        !            65:        private_config_t *this, identification_t *me, identification_t *other)
        !            66: {
        !            67:        return this->configs->create_enumerator(this->configs);
        !            68: }
        !            69: 
        !            70: METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
        !            71:        private_config_t *this, char *name)
        !            72: {
        !            73:        enumerator_t *e1, *e2;
        !            74:        peer_cfg_t *current, *found = NULL;
        !            75:        child_cfg_t *child;
        !            76: 
        !            77:        e1 = this->configs->create_enumerator(this->configs);
        !            78:        while (e1->enumerate(e1, &current))
        !            79:        {
        !            80:                e2 = current->create_child_cfg_enumerator(current);
        !            81:                while (e2->enumerate(e2, &child))
        !            82:                {
        !            83:                        if (streq(child->get_name(child), name))
        !            84:                        {
        !            85:                                found = current;
        !            86:                                found->get_ref(found);
        !            87:                                break;
        !            88:                        }
        !            89:                }
        !            90:                e2->destroy(e2);
        !            91:                if (found)
        !            92:                {
        !            93:                        break;
        !            94:                }
        !            95:        }
        !            96:        e1->destroy(e1);
        !            97:        return found;
        !            98: }
        !            99: 
        !           100: /**
        !           101:  * Load IKE config for a given section name
        !           102:  */
        !           103: static ike_cfg_t *load_ike_config(private_config_t *this,
        !           104:                                                                  settings_t *settings, char *config)
        !           105: {
        !           106:        enumerator_t *enumerator;
        !           107:        ike_cfg_t *ike_cfg;
        !           108:        proposal_t *proposal;
        !           109:        char *token;
        !           110:        ike_cfg_create_t ike = {
        !           111:                .version = IKEV2,
        !           112:                .local = settings->get_str(settings, "configs.%s.lhost",
        !           113:                                                                   "%any", config),
        !           114:                .local_port = settings->get_int(settings, "configs.%s.lport",
        !           115:                                                                        500, config),
        !           116:                .remote = settings->get_str(settings, "configs.%s.rhost",
        !           117:                                                                        "%any", config),
        !           118:                .remote_port = settings->get_int(settings, "configs.%s.rport",
        !           119:                                                                        500, config),
        !           120:                .force_encap = settings->get_bool(settings, "configs.%s.fake_nat",
        !           121:                                                                        FALSE, config),
        !           122:        };
        !           123: 
        !           124:        ike_cfg = ike_cfg_create(&ike);
        !           125:        token = settings->get_str(settings, "configs.%s.proposal", NULL, config);
        !           126:        if (token)
        !           127:        {
        !           128:                enumerator = enumerator_create_token(token, ",", " ");
        !           129:                while (enumerator->enumerate(enumerator, &token))
        !           130:                {
        !           131:                        proposal = proposal_create_from_string(PROTO_IKE, token);
        !           132:                        if (proposal)
        !           133:                        {
        !           134:                                ike_cfg->add_proposal(ike_cfg, proposal);
        !           135:                        }
        !           136:                        else
        !           137:                        {
        !           138:                                DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
        !           139:                        }
        !           140:                }
        !           141:                enumerator->destroy(enumerator);
        !           142:        }
        !           143:        else
        !           144:        {
        !           145:                ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
        !           146:                ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
        !           147:        }
        !           148:        return ike_cfg;
        !           149: }
        !           150: /**
        !           151:  * Load CHILD config for given section names
        !           152:  */
        !           153: static child_cfg_t *load_child_config(private_config_t *this,
        !           154:                                                        settings_t *settings, char *config, char *child)
        !           155: {
        !           156:        child_cfg_create_t data = {
        !           157:                .mode = MODE_TUNNEL,
        !           158:        };
        !           159:        child_cfg_t *child_cfg;
        !           160:        enumerator_t *enumerator;
        !           161:        proposal_t *proposal;
        !           162:        traffic_selector_t *ts;
        !           163:        char *token;
        !           164: 
        !           165:        if (settings->get_bool(settings, "configs.%s.%s.transport",
        !           166:                                                   FALSE, config, child))
        !           167:        {
        !           168:                data.mode = MODE_TRANSPORT;
        !           169:        }
        !           170:        data.tfc = settings->get_int(settings, "configs.%s.%s.tfc_padding",
        !           171:                                                                  0, config, child);
        !           172:        child_cfg = child_cfg_create(child, &data);
        !           173: 
        !           174:        token = settings->get_str(settings, "configs.%s.%s.proposal",
        !           175:                                                          NULL, config, child);
        !           176:        if (token)
        !           177:        {
        !           178:                enumerator = enumerator_create_token(token, ",", " ");
        !           179:                while (enumerator->enumerate(enumerator, &token))
        !           180:                {
        !           181:                        proposal = proposal_create_from_string(PROTO_ESP, token);
        !           182:                        if (proposal)
        !           183:                        {
        !           184:                                child_cfg->add_proposal(child_cfg, proposal);
        !           185:                        }
        !           186:                        else
        !           187:                        {
        !           188:                                DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
        !           189:                        }
        !           190:                }
        !           191:                enumerator->destroy(enumerator);
        !           192:        }
        !           193:        else
        !           194:        {
        !           195:                child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
        !           196:                child_cfg->add_proposal(child_cfg,
        !           197:                                                                proposal_create_default_aead(PROTO_ESP));
        !           198:        }
        !           199: 
        !           200:        token = settings->get_str(settings, "configs.%s.%s.lts", NULL, config, child);
        !           201:        if (token)
        !           202:        {
        !           203:                enumerator = enumerator_create_token(token, ",", " ");
        !           204:                while (enumerator->enumerate(enumerator, &token))
        !           205:                {
        !           206:                        ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
        !           207:                        if (ts)
        !           208:                        {
        !           209:                                child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
        !           210:                        }
        !           211:                        else
        !           212:                        {
        !           213:                                DBG1(DBG_CFG, "invalid local ts: %s, skipped", token);
        !           214:                        }
        !           215:                }
        !           216:                enumerator->destroy(enumerator);
        !           217:        }
        !           218:        else
        !           219:        {
        !           220:                ts = traffic_selector_create_dynamic(0, 0, 65535);
        !           221:                child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
        !           222:        }
        !           223: 
        !           224:        token = settings->get_str(settings, "configs.%s.%s.rts", NULL, config, child);
        !           225:        if (token)
        !           226:        {
        !           227:                enumerator = enumerator_create_token(token, ",", " ");
        !           228:                while (enumerator->enumerate(enumerator, &token))
        !           229:                {
        !           230:                        ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
        !           231:                        if (ts)
        !           232:                        {
        !           233:                                child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
        !           234:                        }
        !           235:                        else
        !           236:                        {
        !           237:                                DBG1(DBG_CFG, "invalid remote ts: %s, skipped", token);
        !           238:                        }
        !           239:                }
        !           240:                enumerator->destroy(enumerator);
        !           241:        }
        !           242:        else
        !           243:        {
        !           244:                ts = traffic_selector_create_dynamic(0, 0, 65535);
        !           245:                child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
        !           246:        }
        !           247:        return child_cfg;
        !           248: }
        !           249: 
        !           250: /**
        !           251:  * Load peer config for a given section name
        !           252:  */
        !           253: static peer_cfg_t *load_peer_config(private_config_t *this,
        !           254:                                                                        settings_t *settings, char *config)
        !           255: {
        !           256:        ike_cfg_t *ike_cfg;
        !           257:        peer_cfg_t *peer_cfg;
        !           258:        auth_cfg_t *auth;
        !           259:        child_cfg_t *child_cfg;
        !           260:        enumerator_t *enumerator;
        !           261:        identification_t *lid, *rid;
        !           262:        char *child, *policy, *pool;
        !           263:        uintptr_t strength;
        !           264:        peer_cfg_create_t peer = {
        !           265:                .cert_policy = CERT_ALWAYS_SEND,
        !           266:                .unique = UNIQUE_NO,
        !           267:                .keyingtries = 1,
        !           268:                .no_mobike = TRUE,
        !           269:        };
        !           270: 
        !           271:        ike_cfg = load_ike_config(this, settings, config);
        !           272:        peer_cfg = peer_cfg_create(config, ike_cfg, &peer);
        !           273: 
        !           274:        auth = auth_cfg_create();
        !           275:        auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
        !           276:        lid = identification_create_from_string(
        !           277:                                settings->get_str(settings, "configs.%s.lid", "%any", config));
        !           278:        auth->add(auth, AUTH_RULE_IDENTITY, lid);
        !           279:        peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
        !           280: 
        !           281:        auth = auth_cfg_create();
        !           282:        auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
        !           283:        rid = identification_create_from_string(
        !           284:                                settings->get_str(settings, "configs.%s.rid", "%any", config));
        !           285:        strength = settings->get_int(settings, "configs.%s.rsa_strength", 0, config);
        !           286:        if (strength)
        !           287:        {
        !           288:                auth->add(auth, AUTH_RULE_RSA_STRENGTH, strength);
        !           289:        }
        !           290:        strength = settings->get_int(settings, "configs.%s.ecdsa_strength", 0, config);
        !           291:        if (strength)
        !           292:        {
        !           293:                auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength);
        !           294:        }
        !           295:        policy = settings->get_str(settings, "configs.%s.cert_policy", NULL, config);
        !           296:        if (policy)
        !           297:        {
        !           298:                auth->add(auth, AUTH_RULE_CERT_POLICY, strdup(policy));
        !           299:        }
        !           300:        auth->add(auth, AUTH_RULE_IDENTITY, rid);
        !           301:        peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
        !           302:        pool = settings->get_str(settings, "configs.%s.named_pool", NULL, config);
        !           303:        if (pool)
        !           304:        {
        !           305:                peer_cfg->add_pool(peer_cfg, pool);
        !           306:        }
        !           307: 
        !           308:        DBG1(DBG_CFG, "loaded config %s: %Y - %Y", config, lid, rid);
        !           309: 
        !           310:        enumerator = settings->create_section_enumerator(settings,
        !           311:                                                                                                         "configs.%s", config);
        !           312:        while (enumerator->enumerate(enumerator, &child))
        !           313:        {
        !           314:                child_cfg = load_child_config(this, settings, config, child);
        !           315:                peer_cfg->add_child_cfg(peer_cfg, child_cfg);
        !           316:        }
        !           317:        enumerator->destroy(enumerator);
        !           318:        return peer_cfg;
        !           319: }
        !           320: 
        !           321: METHOD(config_t, load, void,
        !           322:        private_config_t *this, settings_t *settings)
        !           323: {
        !           324:        enumerator_t *enumerator;
        !           325:        char *config;
        !           326: 
        !           327:        enumerator = settings->create_section_enumerator(settings, "configs");
        !           328:        while (enumerator->enumerate(enumerator, &config))
        !           329:        {
        !           330:                this->configs->insert_last(this->configs,
        !           331:                                                                load_peer_config(this, settings, config));
        !           332:        }
        !           333:        enumerator->destroy(enumerator);
        !           334: }
        !           335: 
        !           336: METHOD(config_t, destroy, void,
        !           337:        private_config_t *this)
        !           338: {
        !           339:        this->configs->destroy_offset(this->configs, offsetof(peer_cfg_t, destroy));
        !           340:        free(this);
        !           341: }
        !           342: 
        !           343: /**
        !           344:  * See header
        !           345:  */
        !           346: config_t *config_create()
        !           347: {
        !           348:        private_config_t *this;
        !           349: 
        !           350:        INIT(this,
        !           351:                .public = {
        !           352:                        .backend = {
        !           353:                                .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
        !           354:                                .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
        !           355:                                .get_peer_cfg_by_name = _get_peer_cfg_by_name,
        !           356:                        },
        !           357:                        .load = _load,
        !           358:                        .destroy = _destroy,
        !           359:                },
        !           360:                .configs = linked_list_create(),
        !           361:        );
        !           362: 
        !           363:        return &this->public;
        !           364: }

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