Annotation of embedaddon/strongswan/src/libcharon/plugins/uci/uci_config.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008 Thomas Kallenberg
                      3:  * Copyright (C) 2008 Tobias Brunner
                      4:  * Copyright (C) 2008 Martin Willi
                      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: #define _GNU_SOURCE
                     19: #include <string.h>
                     20: 
                     21: #include "uci_config.h"
                     22: #include "uci_parser.h"
                     23: 
                     24: #include <daemon.h>
                     25: 
                     26: typedef struct private_uci_config_t private_uci_config_t;
                     27: 
                     28: /**
                     29:  * Private data of an uci_config_t object
                     30:  */
                     31: struct private_uci_config_t {
                     32: 
                     33:        /**
                     34:         * Public part
                     35:         */
                     36:        uci_config_t public;
                     37: 
                     38:        /**
                     39:         * UCI parser context
                     40:         */
                     41:        uci_parser_t *parser;
                     42: };
                     43: 
                     44: /**
                     45:  * enumerator implementation for create_peer_cfg_enumerator
                     46:  */
                     47: typedef struct {
                     48:        /** implements enumerator */
                     49:        enumerator_t public;
                     50:        /** currently enumerated peer config */
                     51:        peer_cfg_t *peer_cfg;
                     52:        /** inner uci_parser section enumerator */
                     53:        enumerator_t *inner;
                     54: } peer_enumerator_t;
                     55: 
                     56: /**
                     57:  * create a proposal from a string, with fallback to default
                     58:  */
                     59: static proposal_t *create_proposal(char *string, protocol_id_t proto)
                     60: {
                     61:        proposal_t *proposal = NULL;
                     62: 
                     63:        if (string)
                     64:        {
                     65:                proposal = proposal_create_from_string(proto, string);
                     66:        }
                     67:        if (!proposal)
                     68:        {       /* UCI default is aes/sha1 only */
                     69:                if (proto == PROTO_IKE)
                     70:                {
                     71:                        proposal = proposal_create_from_string(proto,
                     72:                                                                "aes128-aes192-aes256-sha1-modp1536-modp2048");
                     73:                }
                     74:                else
                     75:                {
                     76:                        proposal = proposal_create_from_string(proto,
                     77:                                                                "aes128-aes192-aes256-sha1");
                     78:                }
                     79:        }
                     80:        return proposal;
                     81: }
                     82: 
                     83: /**
                     84:  * create an traffic selector, fallback to dynamic
                     85:  */
                     86: static traffic_selector_t *create_ts(char *string)
                     87: {
                     88:        if (string)
                     89:        {
                     90:                traffic_selector_t *ts;
                     91: 
                     92:                ts = traffic_selector_create_from_cidr(string, 0, 0, 65535);
                     93:                if (ts)
                     94:                {
                     95:                        return ts;
                     96:                }
                     97:        }
                     98:        return traffic_selector_create_dynamic(0, 0, 65535);
                     99: }
                    100: 
                    101: /**
                    102:  * create a rekey time from a string with hours, with fallback
                    103:  */
                    104: static u_int create_rekey(char *string)
                    105: {
                    106:        u_int rekey = 0;
                    107: 
                    108:        if (string)
                    109:        {
                    110:                rekey = atoi(string);
                    111:                if (rekey)
                    112:                {
                    113:                        return rekey * 3600;
                    114:                }
                    115:        }
                    116:        /* every 12 hours */
                    117:        return 12 * 3600;
                    118: }
                    119: 
                    120: METHOD(enumerator_t, peer_enumerator_enumerate, bool,
                    121:        peer_enumerator_t *this, va_list args)
                    122: {
                    123:        char *name, *ike_proposal, *esp_proposal, *ike_rekey, *esp_rekey;
                    124:        char *local_id, *local_net, *remote_id, *remote_net;
                    125:        peer_cfg_t **cfg;
                    126:        child_cfg_t *child_cfg;
                    127:        ike_cfg_t *ike_cfg;
                    128:        auth_cfg_t *auth;
                    129:        ike_cfg_create_t ike = {
                    130:                .version = IKEV2,
                    131:                .local = "0.0.0.0",
                    132:                .local_port = charon->socket->get_port(charon->socket, FALSE),
                    133:                .remote = "0.0.0.0",
                    134:                .remote_port = IKEV2_UDP_PORT,
                    135:                .no_certreq = TRUE,
                    136:        };
                    137:        peer_cfg_create_t peer = {
                    138:                .cert_policy = CERT_SEND_IF_ASKED,
                    139:                .unique = UNIQUE_NO,
                    140:                .keyingtries = 1,
                    141:                .jitter_time = 1800,
                    142:                .over_time = 900,
                    143:                .dpd = 60,
                    144:        };
                    145:        child_cfg_create_t child = {
                    146:                .lifetime = {
                    147:                        .time = {
                    148:                                .life = create_rekey(esp_rekey) + 300,
                    149:                                .rekey = create_rekey(esp_rekey),
                    150:                                .jitter = 300
                    151:                        },
                    152:                },
                    153:                .mode = MODE_TUNNEL,
                    154:        };
                    155: 
                    156:        VA_ARGS_VGET(args, cfg);
                    157: 
                    158:        /* defaults */
                    159:        name = "unnamed";
                    160:        local_id = NULL;
                    161:        remote_id = NULL;
                    162:        local_net = NULL;
                    163:        remote_net = NULL;
                    164:        ike_proposal = NULL;
                    165:        esp_proposal = NULL;
                    166:        ike_rekey = NULL;
                    167:        esp_rekey = NULL;
                    168: 
                    169:        if (this->inner->enumerate(this->inner, &name, &local_id, &remote_id,
                    170:                        &ike.local, &ike.remote, &local_net, &remote_net,
                    171:                        &ike_proposal, &esp_proposal, &ike_rekey, &esp_rekey))
                    172:        {
                    173: 
                    174:                DESTROY_IF(this->peer_cfg);
                    175:                ike_cfg = ike_cfg_create(&ike);
                    176:                ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
                    177:                peer.rekey_time = create_rekey(ike_rekey);
                    178:                this->peer_cfg = peer_cfg_create(name, ike_cfg, &peer);
                    179:                auth = auth_cfg_create();
                    180:                auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
                    181:                auth->add(auth, AUTH_RULE_IDENTITY,
                    182:                                  identification_create_from_string(local_id));
                    183:                this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, TRUE);
                    184: 
                    185:                auth = auth_cfg_create();
                    186:                auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
                    187:                if (remote_id)
                    188:                {
                    189:                        auth->add(auth, AUTH_RULE_IDENTITY,
                    190:                                          identification_create_from_string(remote_id));
                    191:                }
                    192:                this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, FALSE);
                    193: 
                    194:                child_cfg = child_cfg_create(name, &child);
                    195:                child_cfg->add_proposal(child_cfg, create_proposal(esp_proposal, PROTO_ESP));
                    196:                child_cfg->add_traffic_selector(child_cfg, TRUE, create_ts(local_net));
                    197:                child_cfg->add_traffic_selector(child_cfg, FALSE, create_ts(remote_net));
                    198:                this->peer_cfg->add_child_cfg(this->peer_cfg, child_cfg);
                    199:                *cfg = this->peer_cfg;
                    200:                return TRUE;
                    201:        }
                    202:        return FALSE;
                    203: }
                    204: 
                    205: 
                    206: METHOD(enumerator_t, peer_enumerator_destroy, void,
                    207:        peer_enumerator_t *this)
                    208: {
                    209:        DESTROY_IF(this->peer_cfg);
                    210:        this->inner->destroy(this->inner);
                    211:        free(this);
                    212: }
                    213: 
                    214: METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
                    215:        private_uci_config_t *this, identification_t *me, identification_t *other)
                    216: {
                    217:        peer_enumerator_t *e;
                    218: 
                    219:        INIT(e,
                    220:                .public = {
                    221:                        .enumerate = enumerator_enumerate_default,
                    222:                        .venumerate = _peer_enumerator_enumerate,
                    223:                        .destroy = _peer_enumerator_destroy,
                    224:                },
                    225:                .inner = this->parser->create_section_enumerator(this->parser,
                    226:                                        "local_id", "remote_id", "local_addr", "remote_addr",
                    227:                                        "local_net", "remote_net", "ike_proposal", "esp_proposal",
                    228:                                        "ike_rekey", "esp_rekey", NULL),
                    229:        );
                    230:        if (!e->inner)
                    231:        {
                    232:                free(e);
                    233:                return NULL;
                    234:        }
                    235:        return &e->public;
                    236: }
                    237: 
                    238: /**
                    239:  * enumerator implementation for create_ike_cfg_enumerator
                    240:  */
                    241: typedef struct {
                    242:        /** implements enumerator */
                    243:        enumerator_t public;
                    244:        /** currently enumerated ike config */
                    245:        ike_cfg_t *ike_cfg;
                    246:        /** inner uci_parser section enumerator */
                    247:        enumerator_t *inner;
                    248: } ike_enumerator_t;
                    249: 
                    250: METHOD(enumerator_t, ike_enumerator_enumerate, bool,
                    251:        ike_enumerator_t *this, va_list args)
                    252: {
                    253:        ike_cfg_t **cfg;
                    254:        ike_cfg_create_t ike = {
                    255:                .version = IKEV2,
                    256:                .local = "0.0.0.0",
                    257:                .local_port = charon->socket->get_port(charon->socket, FALSE),
                    258:                .remote = "0.0.0.0",
                    259:                .remote_port = IKEV2_UDP_PORT,
                    260:                .no_certreq = TRUE,
                    261:        };
                    262:        char *ike_proposal;
                    263: 
                    264:        VA_ARGS_VGET(args, cfg);
                    265: 
                    266:        /* defaults */
                    267:        ike_proposal = NULL;
                    268: 
                    269:        if (this->inner->enumerate(this->inner, NULL,
                    270:                                                           &ike.local, &ike.remote, &ike_proposal))
                    271:        {
                    272:                DESTROY_IF(this->ike_cfg);
                    273:                this->ike_cfg = ike_cfg_create(&ike);
                    274:                this->ike_cfg->add_proposal(this->ike_cfg,
                    275:                                                                        create_proposal(ike_proposal, PROTO_IKE));
                    276: 
                    277:                *cfg = this->ike_cfg;
                    278:                return TRUE;
                    279:        }
                    280:        return FALSE;
                    281: }
                    282: 
                    283: METHOD(enumerator_t, ike_enumerator_destroy, void,
                    284:        ike_enumerator_t *this)
                    285: {
                    286:        DESTROY_IF(this->ike_cfg);
                    287:        this->inner->destroy(this->inner);
                    288:        free(this);
                    289: }
                    290: 
                    291: METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
                    292:        private_uci_config_t *this, host_t *me, host_t *other)
                    293: {
                    294:        ike_enumerator_t *e;
                    295: 
                    296:        INIT(e,
                    297:                .public = {
                    298:                        .enumerate = enumerator_enumerate_default,
                    299:                        .venumerate = _ike_enumerator_enumerate,
                    300:                        .destroy = _ike_enumerator_destroy,
                    301:                },
                    302:                .inner = this->parser->create_section_enumerator(this->parser,
                    303:                                                        "local_addr", "remote_addr", "ike_proposal", NULL),
                    304:        );
                    305:        if (!e->inner)
                    306:        {
                    307:                free(e);
                    308:                return NULL;
                    309:        }
                    310:        return &e->public;
                    311: }
                    312: 
                    313: METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
                    314:        private_uci_config_t *this, char *name)
                    315: {
                    316:        enumerator_t *enumerator;
                    317:        peer_cfg_t *current, *found = NULL;
                    318: 
                    319:        enumerator = create_peer_cfg_enumerator(this, NULL, NULL);
                    320:        if (enumerator)
                    321:        {
                    322:                while (enumerator->enumerate(enumerator, &current))
                    323:                {
                    324:                        if (streq(name, current->get_name(current)))
                    325:                        {
                    326:                                found = current->get_ref(current);
                    327:                                break;
                    328:                        }
                    329:                }
                    330:                enumerator->destroy(enumerator);
                    331:        }
                    332:        return found;
                    333: }
                    334: 
                    335: METHOD(uci_config_t, destroy, void,
                    336:        private_uci_config_t *this)
                    337: {
                    338:        free(this);
                    339: }
                    340: 
                    341: /**
                    342:  * Described in header.
                    343:  */
                    344: uci_config_t *uci_config_create(uci_parser_t *parser)
                    345: {
                    346:        private_uci_config_t *this;
                    347: 
                    348:        INIT(this,
                    349:                .public = {
                    350:                        .backend = {
                    351:                                .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
                    352:                                .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
                    353:                                .get_peer_cfg_by_name = _get_peer_cfg_by_name,
                    354:                        },
                    355:                        .destroy = _destroy,
                    356:                },
                    357:                .parser = parser,
                    358:        );
                    359: 
                    360:        return &this->public;
                    361: }

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