Annotation of embedaddon/strongswan/src/libcharon/plugins/ha/ha_tunnel.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  * Copyright (C) 2009 Martin Willi
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      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 "ha_tunnel.h"
                     17: #include "ha_plugin.h"
                     18: 
                     19: #include <daemon.h>
                     20: #include <utils/identification.h>
                     21: #include <processing/jobs/callback_job.h>
                     22: 
                     23: #define HA_CFG_NAME "ha"
                     24: 
                     25: typedef struct private_ha_tunnel_t private_ha_tunnel_t;
                     26: typedef struct ha_backend_t ha_backend_t;
                     27: typedef struct ha_creds_t ha_creds_t;
                     28: 
                     29: /**
                     30:  * Serves credentials for the HA SA
                     31:  */
                     32: struct ha_creds_t {
                     33: 
                     34:        /**
                     35:         * Implements credential_set_t
                     36:         */
                     37:        credential_set_t public;
                     38: 
                     39:        /**
                     40:         * own identity
                     41:         */
                     42:        identification_t *local;
                     43: 
                     44:        /**
                     45:         * peer identity
                     46:         */
                     47:        identification_t *remote;
                     48: 
                     49:        /**
                     50:         * Shared key to serve
                     51:         */
                     52:        shared_key_t *key;
                     53: };
                     54: 
                     55: /**
                     56:  * Serves configurations for the HA SA
                     57:  */
                     58: struct ha_backend_t {
                     59: 
                     60:        /**
                     61:         * Implements backend_t
                     62:         */
                     63:        backend_t public;
                     64: 
                     65:        /**
                     66:         * peer config we serve
                     67:         */
                     68:        peer_cfg_t *cfg;
                     69: };
                     70: 
                     71: /**
                     72:  * Private data of an ha_tunnel_t object.
                     73:  */
                     74: struct private_ha_tunnel_t {
                     75: 
                     76:        /**
                     77:         * Public ha_tunnel_t interface.
                     78:         */
                     79:        ha_tunnel_t public;
                     80: 
                     81:        /**
                     82:         * Reqid of installed trap
                     83:         */
                     84:        uint32_t trap;
                     85: 
                     86:        /**
                     87:         * backend for HA SA
                     88:         */
                     89:        ha_backend_t backend;
                     90: 
                     91:        /**
                     92:         * credential set for HA SA
                     93:         */
                     94:        ha_creds_t creds;
                     95: };
                     96: 
                     97: METHOD(ha_tunnel_t, is_sa, bool,
                     98:        private_ha_tunnel_t *this, ike_sa_t *ike_sa)
                     99: {
                    100:        peer_cfg_t *cfg = this->backend.cfg;
                    101: 
                    102:        return cfg && ike_sa->get_ike_cfg(ike_sa) == cfg->get_ike_cfg(cfg);
                    103: }
                    104: 
                    105: /**
                    106:  * Enumerator over HA shared_key
                    107:  */
                    108: typedef struct {
                    109:        /** Implements enumerator_t */
                    110:        enumerator_t public;
                    111:        /** a single secret we serve */
                    112:        shared_key_t *key;
                    113: } shared_enum_t;
                    114: 
                    115: METHOD(enumerator_t, shared_enumerate, bool,
                    116:        shared_enum_t *this, va_list args)
                    117: {
                    118:        shared_key_t **key;
                    119:        id_match_t *me, *other;
                    120: 
                    121:        VA_ARGS_VGET(args, key, me, other);
                    122:        if (this->key)
                    123:        {
                    124:                if (me)
                    125:                {
                    126:                        *me = ID_MATCH_PERFECT;
                    127:                }
                    128:                if (other)
                    129:                {
                    130:                        *other = ID_MATCH_PERFECT;
                    131:                }
                    132:                *key = this->key;
                    133:                this->key = NULL;
                    134:                return TRUE;
                    135:        }
                    136:        return FALSE;
                    137: }
                    138: 
                    139: METHOD(ha_creds_t, create_shared_enumerator, enumerator_t*,
                    140:        ha_creds_t *this, shared_key_type_t type,
                    141:        identification_t *me, identification_t *other)
                    142: {
                    143:        shared_enum_t *enumerator;
                    144: 
                    145:        if (type != SHARED_IKE && type != SHARED_ANY)
                    146:        {
                    147:                return NULL;
                    148:        }
                    149:        if (me && !me->equals(me, this->local))
                    150:        {
                    151:                return NULL;
                    152:        }
                    153:        if (other && !other->equals(other, this->remote))
                    154:        {
                    155:                return NULL;
                    156:        }
                    157: 
                    158:        INIT(enumerator,
                    159:                .public = {
                    160:                        .enumerate = enumerator_enumerate_default,
                    161:                        .venumerate = _shared_enumerate,
                    162:                        .destroy = (void*)free,
                    163:                },
                    164:                .key = this->key,
                    165:        );
                    166: 
                    167:        return &enumerator->public;
                    168: }
                    169: 
                    170: METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
                    171:        ha_backend_t *this, identification_t *me, identification_t *other)
                    172: {
                    173:        return enumerator_create_single(this->cfg, NULL);
                    174: }
                    175: 
                    176: METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
                    177:        ha_backend_t *this, host_t *me, host_t *other)
                    178: {
                    179:        return enumerator_create_single(this->cfg->get_ike_cfg(this->cfg), NULL);
                    180: }
                    181: 
                    182: /**
                    183:  * Install configs and a a trap for secured HA message exchange
                    184:  */
                    185: static void setup_tunnel(private_ha_tunnel_t *this,
                    186:                                                 char *local, char *remote, char *secret)
                    187: {
                    188:        peer_cfg_t *peer_cfg;
                    189:        ike_cfg_t *ike_cfg;
                    190:        auth_cfg_t *auth_cfg;
                    191:        child_cfg_t *child_cfg;
                    192:        traffic_selector_t *ts;
                    193:        ike_cfg_create_t ike = {
                    194:                .version = IKEV2,
                    195:                .local = local,
                    196:                .local_port = charon->socket->get_port(charon->socket, FALSE),
                    197:                .remote = remote,
                    198:                .remote_port = IKEV2_UDP_PORT,
                    199:                .no_certreq = TRUE,
                    200:        };
                    201:        peer_cfg_create_t peer = {
                    202:                .cert_policy = CERT_NEVER_SEND,
                    203:                .unique = UNIQUE_KEEP,
                    204:                .rekey_time = 86400, /* 24h */
                    205:                .jitter_time = 7200, /* 2h */
                    206:                .over_time = 3600, /* 1h */
                    207:                .no_mobike = TRUE,
                    208:                .dpd = 30,
                    209:        };
                    210:        child_cfg_create_t child = {
                    211:                .lifetime = {
                    212:                        .time = {
                    213:                                .life = 21600, .rekey = 20400, .jitter = 400,
                    214:                        },
                    215:                },
                    216:                .mode = MODE_TRANSPORT,
                    217:        };
                    218: 
                    219:        /* setup credentials */
                    220:        this->creds.local = identification_create_from_string(local);
                    221:        this->creds.remote = identification_create_from_string(remote);
                    222:        this->creds.key = shared_key_create(SHARED_IKE,
                    223:                                                        chunk_clone(chunk_create(secret, strlen(secret))));
                    224:        this->creds.public.create_private_enumerator = (void*)return_null;
                    225:        this->creds.public.create_cert_enumerator = (void*)return_null;
                    226:        this->creds.public.create_shared_enumerator = (void*)_create_shared_enumerator;
                    227:        this->creds.public.create_cdp_enumerator = (void*)return_null;
                    228:        this->creds.public.cache_cert = (void*)nop;
                    229: 
                    230:        lib->credmgr->add_set(lib->credmgr, &this->creds.public);
                    231: 
                    232:        /* create config and backend */
                    233:        ike_cfg = ike_cfg_create(&ike);
                    234:        ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
                    235:        ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
                    236:        peer_cfg = peer_cfg_create(HA_CFG_NAME, ike_cfg, &peer);
                    237: 
                    238:        auth_cfg = auth_cfg_create();
                    239:        auth_cfg->add(auth_cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
                    240:        auth_cfg->add(auth_cfg, AUTH_RULE_IDENTITY,
                    241:                                  identification_create_from_string(local));
                    242:        peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
                    243: 
                    244:        auth_cfg = auth_cfg_create();
                    245:        auth_cfg->add(auth_cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
                    246:        auth_cfg->add(auth_cfg, AUTH_RULE_IDENTITY,
                    247:                                  identification_create_from_string(remote));
                    248:        peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
                    249: 
                    250:        child_cfg = child_cfg_create(HA_CFG_NAME, &child);
                    251:        ts = traffic_selector_create_dynamic(IPPROTO_UDP, HA_PORT, HA_PORT);
                    252:        child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
                    253:        ts = traffic_selector_create_dynamic(IPPROTO_ICMP, 0, 65535);
                    254:        child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
                    255:        ts = traffic_selector_create_dynamic(IPPROTO_UDP, HA_PORT, HA_PORT);
                    256:        child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
                    257:        ts = traffic_selector_create_dynamic(IPPROTO_ICMP, 0, 65535);
                    258:        child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
                    259:        child_cfg->add_proposal(child_cfg, proposal_create_default_aead(PROTO_ESP));
1.1.1.2 ! misho     260:        child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
1.1       misho     261:        peer_cfg->add_child_cfg(peer_cfg, child_cfg);
                    262: 
                    263:        this->backend.cfg = peer_cfg;
                    264:        this->backend.public.create_peer_cfg_enumerator = (void*)_create_peer_cfg_enumerator;
                    265:        this->backend.public.create_ike_cfg_enumerator = (void*)_create_ike_cfg_enumerator;
                    266:        this->backend.public.get_peer_cfg_by_name = (void*)return_null;
                    267: 
                    268:        charon->backends->add_backend(charon->backends, &this->backend.public);
                    269: 
                    270:        /* install an acquiring trap */
                    271:        charon->traps->install(charon->traps, peer_cfg, child_cfg);
                    272: }
                    273: 
                    274: METHOD(ha_tunnel_t, destroy, void,
                    275:        private_ha_tunnel_t *this)
                    276: {
                    277:        if (this->backend.cfg)
                    278:        {
                    279:                charon->backends->remove_backend(charon->backends, &this->backend.public);
                    280:                this->backend.cfg->destroy(this->backend.cfg);
                    281:        }
                    282:        if (this->creds.key)
                    283:        {
                    284:                lib->credmgr->remove_set(lib->credmgr, &this->creds.public);
                    285:                this->creds.key->destroy(this->creds.key);
                    286:        }
                    287:        this->creds.local->destroy(this->creds.local);
                    288:        this->creds.remote->destroy(this->creds.remote);
                    289:        charon->traps->uninstall(charon->traps, HA_CFG_NAME, HA_CFG_NAME);
                    290:        free(this);
                    291: }
                    292: 
                    293: /**
                    294:  * See header
                    295:  */
                    296: ha_tunnel_t *ha_tunnel_create(char *local, char *remote, char *secret)
                    297: {
                    298:        private_ha_tunnel_t *this;
                    299: 
                    300:        INIT(this,
                    301:                .public = {
                    302:                        .is_sa = _is_sa,
                    303:                        .destroy = _destroy,
                    304:                },
                    305:        );
                    306: 
                    307:        setup_tunnel(this, local, remote, secret);
                    308: 
                    309:        return &this->public;
                    310: }

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