Annotation of embedaddon/strongswan/src/libcharon/plugins/ha/ha_child.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2008 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_child.h"
        !            17: 
        !            18: typedef struct private_ha_child_t private_ha_child_t;
        !            19: 
        !            20: /**
        !            21:  * Private data of an ha_child_t object.
        !            22:  */
        !            23: struct private_ha_child_t {
        !            24: 
        !            25:        /**
        !            26:         * Public ha_child_t interface.
        !            27:         */
        !            28:        ha_child_t public;
        !            29: 
        !            30:        /**
        !            31:         * socket we use for syncing
        !            32:         */
        !            33:        ha_socket_t *socket;
        !            34: 
        !            35:        /**
        !            36:         * tunnel securing sync messages
        !            37:         */
        !            38:        ha_tunnel_t *tunnel;
        !            39: 
        !            40:        /**
        !            41:         * Segment handling
        !            42:         */
        !            43:        ha_segments_t *segments;
        !            44: 
        !            45:        /**
        !            46:         * Kernel helper
        !            47:         */
        !            48:        ha_kernel_t *kernel;
        !            49: };
        !            50: 
        !            51: METHOD(listener_t, child_keys, bool,
        !            52:        private_ha_child_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
        !            53:        bool initiator, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r)
        !            54: {
        !            55:        ha_message_t *m;
        !            56:        chunk_t secret;
        !            57:        proposal_t *proposal;
        !            58:        uint16_t alg, len;
        !            59:        linked_list_t *local_ts, *remote_ts;
        !            60:        enumerator_t *enumerator;
        !            61:        traffic_selector_t *ts;
        !            62:        u_int seg_i, seg_o;
        !            63: 
        !            64:        if (this->tunnel && this->tunnel->is_sa(this->tunnel, ike_sa))
        !            65:        {       /* do not sync SA between nodes */
        !            66:                return TRUE;
        !            67:        }
        !            68: 
        !            69:        m = ha_message_create(HA_CHILD_ADD);
        !            70: 
        !            71:        m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
        !            72:        m->add_attribute(m, HA_INITIATOR, (uint8_t)initiator);
        !            73:        m->add_attribute(m, HA_INBOUND_SPI, child_sa->get_spi(child_sa, TRUE));
        !            74:        m->add_attribute(m, HA_OUTBOUND_SPI, child_sa->get_spi(child_sa, FALSE));
        !            75:        m->add_attribute(m, HA_INBOUND_CPI, child_sa->get_cpi(child_sa, TRUE));
        !            76:        m->add_attribute(m, HA_OUTBOUND_CPI, child_sa->get_cpi(child_sa, FALSE));
        !            77:        m->add_attribute(m, HA_IPSEC_MODE, child_sa->get_mode(child_sa));
        !            78:        m->add_attribute(m, HA_IPCOMP, child_sa->get_ipcomp(child_sa));
        !            79:        m->add_attribute(m, HA_CONFIG_NAME, child_sa->get_name(child_sa));
        !            80: 
        !            81:        proposal = child_sa->get_proposal(child_sa);
        !            82:        if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &len))
        !            83:        {
        !            84:                m->add_attribute(m, HA_ALG_ENCR, alg);
        !            85:                if (len)
        !            86:                {
        !            87:                        m->add_attribute(m, HA_ALG_ENCR_LEN, len);
        !            88:                }
        !            89:        }
        !            90:        if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL))
        !            91:        {
        !            92:                m->add_attribute(m, HA_ALG_INTEG, alg);
        !            93:        }
        !            94:        if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &alg, NULL))
        !            95:        {
        !            96:                m->add_attribute(m, HA_ALG_DH, alg);
        !            97:        }
        !            98:        if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, &alg, NULL))
        !            99:        {
        !           100:                m->add_attribute(m, HA_ESN, alg);
        !           101:        }
        !           102:        m->add_attribute(m, HA_NONCE_I, nonce_i);
        !           103:        m->add_attribute(m, HA_NONCE_R, nonce_r);
        !           104:        if (dh && dh->get_shared_secret(dh, &secret))
        !           105:        {
        !           106:                m->add_attribute(m, HA_SECRET, secret);
        !           107:                chunk_clear(&secret);
        !           108:        }
        !           109: 
        !           110:        local_ts = linked_list_create();
        !           111:        remote_ts = linked_list_create();
        !           112: 
        !           113:        enumerator = child_sa->create_ts_enumerator(child_sa, TRUE);
        !           114:        while (enumerator->enumerate(enumerator, &ts))
        !           115:        {
        !           116:                m->add_attribute(m, HA_LOCAL_TS, ts);
        !           117:                local_ts->insert_last(local_ts, ts);
        !           118:        }
        !           119:        enumerator->destroy(enumerator);
        !           120: 
        !           121:        enumerator = child_sa->create_ts_enumerator(child_sa, FALSE);
        !           122:        while (enumerator->enumerate(enumerator, &ts))
        !           123:        {
        !           124:                m->add_attribute(m, HA_REMOTE_TS, ts);
        !           125:                remote_ts->insert_last(remote_ts, ts);
        !           126:        }
        !           127:        enumerator->destroy(enumerator);
        !           128: 
        !           129:        seg_i = this->kernel->get_segment_spi(this->kernel,
        !           130:                        ike_sa->get_my_host(ike_sa), child_sa->get_spi(child_sa, TRUE));
        !           131:        seg_o = this->kernel->get_segment_spi(this->kernel,
        !           132:                        ike_sa->get_other_host(ike_sa), child_sa->get_spi(child_sa, FALSE));
        !           133:        DBG1(DBG_CFG, "handling HA CHILD_SA %s{%d} %#R === %#R "
        !           134:                "(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa),
        !           135:                child_sa->get_unique_id(child_sa), local_ts, remote_ts,
        !           136:                seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "",
        !           137:                seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : "");
        !           138: 
        !           139:        local_ts->destroy(local_ts);
        !           140:        remote_ts->destroy(remote_ts);
        !           141: 
        !           142:        this->socket->push(this->socket, m);
        !           143:        m->destroy(m);
        !           144: 
        !           145:        return TRUE;
        !           146: }
        !           147: 
        !           148: METHOD(listener_t, child_state_change, bool,
        !           149:        private_ha_child_t *this, ike_sa_t *ike_sa,
        !           150:        child_sa_t *child_sa, child_sa_state_t state)
        !           151: {
        !           152:        if (!ike_sa ||
        !           153:                ike_sa->get_state(ike_sa) == IKE_PASSIVE ||
        !           154:                ike_sa->get_state(ike_sa) == IKE_DESTROYING)
        !           155:        {       /* only sync active IKE_SAs */
        !           156:                return TRUE;
        !           157:        }
        !           158:        if (this->tunnel && this->tunnel->is_sa(this->tunnel, ike_sa))
        !           159:        {       /* do not sync SA between nodes */
        !           160:                return TRUE;
        !           161:        }
        !           162: 
        !           163: 
        !           164:        if (state == CHILD_DESTROYING)
        !           165:        {
        !           166:                ha_message_t *m;
        !           167: 
        !           168:                m = ha_message_create(HA_CHILD_DELETE);
        !           169: 
        !           170:                m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
        !           171:                m->add_attribute(m, HA_INBOUND_SPI,
        !           172:                                                 child_sa->get_spi(child_sa, TRUE));
        !           173:                this->socket->push(this->socket, m);
        !           174:                m->destroy(m);
        !           175:        }
        !           176:        return TRUE;
        !           177: }
        !           178: 
        !           179: METHOD(ha_child_t, destroy, void,
        !           180:        private_ha_child_t *this)
        !           181: {
        !           182:        free(this);
        !           183: }
        !           184: 
        !           185: /**
        !           186:  * See header
        !           187:  */
        !           188: ha_child_t *ha_child_create(ha_socket_t *socket, ha_tunnel_t *tunnel,
        !           189:                                                        ha_segments_t *segments, ha_kernel_t *kernel)
        !           190: {
        !           191:        private_ha_child_t *this;
        !           192: 
        !           193:        INIT(this,
        !           194:                .public = {
        !           195:                        .listener = {
        !           196:                                .child_keys = _child_keys,
        !           197:                                .child_state_change = _child_state_change,
        !           198:                        },
        !           199:                        .destroy = _destroy,
        !           200:                },
        !           201:                .socket = socket,
        !           202:                .tunnel = tunnel,
        !           203:                .segments = segments,
        !           204:                .kernel = kernel,
        !           205:        );
        !           206: 
        !           207:        return &this->public;
        !           208: }

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