Annotation of embedaddon/strongswan/src/libcharon/plugins/uci/uci_config.c, revision 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>