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