Return to stroke_handler.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / stroke |
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: }