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