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

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:        {
1.1.1.2 ! misho     195:                child_cfg->add_proposal(child_cfg, proposal_create_default_aead(PROTO_ESP));
1.1       misho     196:                child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
                    197:        }
                    198: 
                    199:        token = settings->get_str(settings, "configs.%s.%s.lts", NULL, config, child);
                    200:        if (token)
                    201:        {
                    202:                enumerator = enumerator_create_token(token, ",", " ");
                    203:                while (enumerator->enumerate(enumerator, &token))
                    204:                {
                    205:                        ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
                    206:                        if (ts)
                    207:                        {
                    208:                                child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
                    209:                        }
                    210:                        else
                    211:                        {
                    212:                                DBG1(DBG_CFG, "invalid local ts: %s, skipped", token);
                    213:                        }
                    214:                }
                    215:                enumerator->destroy(enumerator);
                    216:        }
                    217:        else
                    218:        {
                    219:                ts = traffic_selector_create_dynamic(0, 0, 65535);
                    220:                child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
                    221:        }
                    222: 
                    223:        token = settings->get_str(settings, "configs.%s.%s.rts", NULL, config, child);
                    224:        if (token)
                    225:        {
                    226:                enumerator = enumerator_create_token(token, ",", " ");
                    227:                while (enumerator->enumerate(enumerator, &token))
                    228:                {
                    229:                        ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
                    230:                        if (ts)
                    231:                        {
                    232:                                child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
                    233:                        }
                    234:                        else
                    235:                        {
                    236:                                DBG1(DBG_CFG, "invalid remote ts: %s, skipped", token);
                    237:                        }
                    238:                }
                    239:                enumerator->destroy(enumerator);
                    240:        }
                    241:        else
                    242:        {
                    243:                ts = traffic_selector_create_dynamic(0, 0, 65535);
                    244:                child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
                    245:        }
                    246:        return child_cfg;
                    247: }
                    248: 
                    249: /**
                    250:  * Load peer config for a given section name
                    251:  */
                    252: static peer_cfg_t *load_peer_config(private_config_t *this,
                    253:                                                                        settings_t *settings, char *config)
                    254: {
                    255:        ike_cfg_t *ike_cfg;
                    256:        peer_cfg_t *peer_cfg;
                    257:        auth_cfg_t *auth;
                    258:        child_cfg_t *child_cfg;
                    259:        enumerator_t *enumerator;
                    260:        identification_t *lid, *rid;
                    261:        char *child, *policy, *pool;
                    262:        uintptr_t strength;
                    263:        peer_cfg_create_t peer = {
                    264:                .cert_policy = CERT_ALWAYS_SEND,
                    265:                .unique = UNIQUE_NO,
                    266:                .keyingtries = 1,
                    267:                .no_mobike = TRUE,
                    268:        };
                    269: 
                    270:        ike_cfg = load_ike_config(this, settings, config);
                    271:        peer_cfg = peer_cfg_create(config, ike_cfg, &peer);
                    272: 
                    273:        auth = auth_cfg_create();
                    274:        auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
                    275:        lid = identification_create_from_string(
                    276:                                settings->get_str(settings, "configs.%s.lid", "%any", config));
                    277:        auth->add(auth, AUTH_RULE_IDENTITY, lid);
                    278:        peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
                    279: 
                    280:        auth = auth_cfg_create();
                    281:        auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
                    282:        rid = identification_create_from_string(
                    283:                                settings->get_str(settings, "configs.%s.rid", "%any", config));
                    284:        strength = settings->get_int(settings, "configs.%s.rsa_strength", 0, config);
                    285:        if (strength)
                    286:        {
                    287:                auth->add(auth, AUTH_RULE_RSA_STRENGTH, strength);
                    288:        }
                    289:        strength = settings->get_int(settings, "configs.%s.ecdsa_strength", 0, config);
                    290:        if (strength)
                    291:        {
                    292:                auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength);
                    293:        }
                    294:        policy = settings->get_str(settings, "configs.%s.cert_policy", NULL, config);
                    295:        if (policy)
                    296:        {
                    297:                auth->add(auth, AUTH_RULE_CERT_POLICY, strdup(policy));
                    298:        }
                    299:        auth->add(auth, AUTH_RULE_IDENTITY, rid);
                    300:        peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
                    301:        pool = settings->get_str(settings, "configs.%s.named_pool", NULL, config);
                    302:        if (pool)
                    303:        {
                    304:                peer_cfg->add_pool(peer_cfg, pool);
                    305:        }
                    306: 
                    307:        DBG1(DBG_CFG, "loaded config %s: %Y - %Y", config, lid, rid);
                    308: 
                    309:        enumerator = settings->create_section_enumerator(settings,
                    310:                                                                                                         "configs.%s", config);
                    311:        while (enumerator->enumerate(enumerator, &child))
                    312:        {
                    313:                child_cfg = load_child_config(this, settings, config, child);
                    314:                peer_cfg->add_child_cfg(peer_cfg, child_cfg);
                    315:        }
                    316:        enumerator->destroy(enumerator);
                    317:        return peer_cfg;
                    318: }
                    319: 
                    320: METHOD(config_t, load, void,
                    321:        private_config_t *this, settings_t *settings)
                    322: {
                    323:        enumerator_t *enumerator;
                    324:        char *config;
                    325: 
                    326:        enumerator = settings->create_section_enumerator(settings, "configs");
                    327:        while (enumerator->enumerate(enumerator, &config))
                    328:        {
                    329:                this->configs->insert_last(this->configs,
                    330:                                                                load_peer_config(this, settings, config));
                    331:        }
                    332:        enumerator->destroy(enumerator);
                    333: }
                    334: 
                    335: METHOD(config_t, destroy, void,
                    336:        private_config_t *this)
                    337: {
                    338:        this->configs->destroy_offset(this->configs, offsetof(peer_cfg_t, destroy));
                    339:        free(this);
                    340: }
                    341: 
                    342: /**
                    343:  * See header
                    344:  */
                    345: config_t *config_create()
                    346: {
                    347:        private_config_t *this;
                    348: 
                    349:        INIT(this,
                    350:                .public = {
                    351:                        .backend = {
                    352:                                .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
                    353:                                .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
                    354:                                .get_peer_cfg_by_name = _get_peer_cfg_by_name,
                    355:                        },
                    356:                        .load = _load,
                    357:                        .destroy = _destroy,
                    358:                },
                    359:                .configs = linked_list_create(),
                    360:        );
                    361: 
                    362:        return &this->public;
                    363: }

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