Annotation of embedaddon/strongswan/src/libcharon/plugins/stroke/stroke_handler.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2012 Martin Willi
                      3:  * Copyright (C) 2012 revosec AG
                      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 "stroke_handler.h"
                     17: 
                     18: #include <daemon.h>
                     19: #include <collections/linked_list.h>
                     20: #include <threading/rwlock.h>
                     21: 
                     22: typedef struct private_stroke_handler_t private_stroke_handler_t;
                     23: 
                     24: /**
                     25:  * Private data of an stroke_handler_t object.
                     26:  */
                     27: struct private_stroke_handler_t {
                     28: 
                     29:        /**
                     30:         * Public stroke_handler_t interface.
                     31:         */
                     32:        stroke_handler_t public;
                     33: 
                     34:        /**
                     35:         * List of connection specific attributes, as attributes_t
                     36:         */
                     37:        linked_list_t *attrs;
                     38: 
                     39:        /**
                     40:         * rwlock to lock access to pools
                     41:         */
                     42:        rwlock_t *lock;
                     43: };
                     44: 
                     45: /**
                     46:  * Attributes assigned to a connection
                     47:  */
                     48: typedef struct {
                     49:        /** name of the connection */
                     50:        char *name;
                     51:        /** list of DNS attributes, as host_t */
                     52:        linked_list_t *dns;
                     53: } attributes_t;
                     54: 
                     55: /**
                     56:  * Destroy an attributes_t entry
                     57:  */
                     58: static void attributes_destroy(attributes_t *this)
                     59: {
                     60:        this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
                     61:        free(this->name);
                     62:        free(this);
                     63: }
                     64: 
                     65: CALLBACK(attr_filter, bool,
                     66:        void *lock, enumerator_t *orig, va_list args)
                     67: {
                     68:        configuration_attribute_type_t *type;
                     69:        chunk_t *data;
                     70:        host_t *host;
                     71: 
                     72:        VA_ARGS_VGET(args, type, data);
                     73: 
                     74:        while (orig->enumerate(orig, &host))
                     75:        {
                     76:                switch (host->get_family(host))
                     77:                {
                     78:                        case AF_INET:
                     79:                                *type = INTERNAL_IP4_DNS;
                     80:                                break;
                     81:                        case AF_INET6:
                     82:                                *type = INTERNAL_IP6_DNS;
                     83:                                break;
                     84:                        default:
                     85:                                continue;
                     86:                }
                     87:                if (host->is_anyaddr(host))
                     88:                {
                     89:                        *data = chunk_empty;
                     90:                }
                     91:                else
                     92:                {
                     93:                        *data = host->get_address(host);
                     94:                }
                     95:                return TRUE;
                     96:        }
                     97:        return FALSE;
                     98: }
                     99: 
                    100: METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
                    101:        private_stroke_handler_t *this, ike_sa_t *ike_sa,
                    102:        linked_list_t *vips)
                    103: {
                    104:        peer_cfg_t *peer_cfg;
                    105:        enumerator_t *enumerator;
                    106:        attributes_t *attr;
                    107: 
                    108:        ike_sa = charon->bus->get_sa(charon->bus);
                    109:        if (ike_sa)
                    110:        {
                    111:                peer_cfg = ike_sa->get_peer_cfg(ike_sa);
                    112:                this->lock->read_lock(this->lock);
                    113:                enumerator = this->attrs->create_enumerator(this->attrs);
                    114:                while (enumerator->enumerate(enumerator, &attr))
                    115:                {
                    116:                        if (streq(attr->name, peer_cfg->get_name(peer_cfg)))
                    117:                        {
                    118:                                enumerator->destroy(enumerator);
                    119:                                return enumerator_create_filter(
                    120:                                                                        attr->dns->create_enumerator(attr->dns),
                    121:                                                                        attr_filter, this->lock,
                    122:                                                                        (void*)this->lock->unlock);
                    123:                        }
                    124:                }
                    125:                enumerator->destroy(enumerator);
                    126:                this->lock->unlock(this->lock);
                    127:        }
                    128:        return enumerator_create_empty();
                    129: }
                    130: 
                    131: METHOD(stroke_handler_t, add_attributes, void,
                    132:        private_stroke_handler_t *this, stroke_msg_t *msg)
                    133: {
                    134:        if (msg->add_conn.me.dns)
                    135:        {
                    136:                enumerator_t *enumerator;
                    137:                attributes_t *attr = NULL;
                    138:                host_t *host;
                    139:                char *token;
                    140: 
                    141:                enumerator = enumerator_create_token(msg->add_conn.me.dns, ",", " ");
                    142:                while (enumerator->enumerate(enumerator, &token))
                    143:                {
                    144:                        if (streq(token, "%config") || streq(token, "%config4"))
                    145:                        {
                    146:                                host = host_create_any(AF_INET);
                    147:                        }
                    148:                        else if (streq(token, "%config6"))
                    149:                        {
                    150:                                host = host_create_any(AF_INET6);
                    151:                        }
                    152:                        else
                    153:                        {
                    154:                                host = host_create_from_string(token, 0);
                    155:                        }
                    156:                        if (host)
                    157:                        {
                    158:                                if (!attr)
                    159:                                {
                    160:                                        INIT(attr,
                    161:                                                .name = strdup(msg->add_conn.name),
                    162:                                                .dns = linked_list_create(),
                    163:                                        );
                    164:                                }
                    165:                                attr->dns->insert_last(attr->dns, host);
                    166:                        }
                    167:                        else
                    168:                        {
                    169:                                DBG1(DBG_CFG, "ignoring invalid DNS address '%s'", token);
                    170:                        }
                    171:                }
                    172:                enumerator->destroy(enumerator);
                    173:                if (attr)
                    174:                {
                    175:                        this->lock->write_lock(this->lock);
                    176:                        this->attrs->insert_last(this->attrs, attr);
                    177:                        this->lock->unlock(this->lock);
                    178:                }
                    179:        }
                    180: }
                    181: 
                    182: METHOD(stroke_handler_t, del_attributes, void,
                    183:        private_stroke_handler_t *this, stroke_msg_t *msg)
                    184: {
                    185:        enumerator_t *enumerator;
                    186:        attributes_t *attr;
                    187: 
                    188:        this->lock->write_lock(this->lock);
                    189:        enumerator = this->attrs->create_enumerator(this->attrs);
                    190:        while (enumerator->enumerate(enumerator, &attr))
                    191:        {
                    192:                if (streq(msg->del_conn.name, attr->name))
                    193:                {
                    194:                        this->attrs->remove_at(this->attrs, enumerator);
                    195:                        attributes_destroy(attr);
                    196:                        break;
                    197:                }
                    198:        }
                    199:        enumerator->destroy(enumerator);
                    200:        this->lock->unlock(this->lock);
                    201: }
                    202: 
                    203: METHOD(stroke_handler_t, destroy, void,
                    204:        private_stroke_handler_t *this)
                    205: {
                    206:        this->lock->destroy(this->lock);
                    207:        this->attrs->destroy_function(this->attrs, (void*)attributes_destroy);
                    208:        free(this);
                    209: }
                    210: 
                    211: /**
                    212:  * See header
                    213:  */
                    214: stroke_handler_t *stroke_handler_create()
                    215: {
                    216:        private_stroke_handler_t *this;
                    217: 
                    218:        INIT(this,
                    219:                .public = {
                    220:                        .handler = {
                    221:                                .handle = (void*)return_false,
                    222:                                .release = (void*)return_false,
                    223:                                .create_attribute_enumerator = _create_attribute_enumerator,
                    224:                        },
                    225:                        .add_attributes = _add_attributes,
                    226:                        .del_attributes = _del_attributes,
                    227:                        .destroy = _destroy,
                    228:                },
                    229:                .attrs = linked_list_create(),
                    230:                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
                    231:        );
                    232: 
                    233:        return &this->public;
                    234: }

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