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>