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