Annotation of embedaddon/strongswan/src/libcharon/plugins/attr/attr_provider.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2010 Tobias Brunner
3: * Copyright (C) 2009 Martin Willi
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: #include "attr_provider.h"
18:
19: #include <time.h>
20:
21: #include <daemon.h>
22: #include <utils/debug.h>
23: #include <collections/linked_list.h>
24: #include <threading/rwlock.h>
25:
26: #define SERVER_MAX 2
27:
28: typedef struct private_attr_provider_t private_attr_provider_t;
29: typedef struct attribute_entry_t attribute_entry_t;
30:
31: /**
32: * private data of attr_provider
33: */
34: struct private_attr_provider_t {
35:
36: /**
37: * public functions
38: */
39: attr_provider_t public;
40:
41: /**
42: * List of attributes, attribute_entry_t
43: */
44: linked_list_t *attributes;
45:
46: /**
47: * Lock for attribute list
48: */
49: rwlock_t *lock;
50: };
51:
52: struct attribute_entry_t {
53: /** type of attribute */
54: configuration_attribute_type_t type;
55: /** attribute value */
56: chunk_t value;
57: /** associated IKE version */
58: ike_version_t ike;
59: };
60:
61: /**
62: * Destroy an entry
63: */
64: static void attribute_destroy(attribute_entry_t *this)
65: {
66: free(this->value.ptr);
67: free(this);
68: }
69:
70: /**
71: * Data for attribute enumerator
72: */
73: typedef struct {
74: rwlock_t *lock;
75: ike_version_t ike;
76: } enumerator_data_t;
77:
78: CALLBACK(attr_enum_filter, bool,
79: enumerator_data_t *data, enumerator_t *orig, va_list args)
80: {
81: configuration_attribute_type_t *type;
82: attribute_entry_t *entry;
83: chunk_t *value;
84:
85: VA_ARGS_VGET(args, type, value);
86:
87: while (orig->enumerate(orig, &entry))
88: {
89: if (entry->ike == IKE_ANY || entry->ike == data->ike)
90: {
91: *type = entry->type;
92: *value = entry->value;
93: return TRUE;
94: }
95: }
96: return FALSE;
97: }
98:
99: CALLBACK(attr_enum_destroy, void,
100: enumerator_data_t *data)
101: {
102: data->lock->unlock(data->lock);
103: free(data);
104: }
105:
106: METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
107: private_attr_provider_t *this, linked_list_t *pools,
108: ike_sa_t *ike_sa, linked_list_t *vips)
109: {
110: enumerator_data_t *data;
111:
112: if (vips->get_count(vips))
113: {
114: INIT(data,
115: .lock = this->lock,
116: .ike = ike_sa->get_version(ike_sa),
117: );
118: this->lock->read_lock(this->lock);
119: return enumerator_create_filter(
120: this->attributes->create_enumerator(this->attributes),
121: attr_enum_filter, data, attr_enum_destroy);
122: }
123: return enumerator_create_empty();
124: }
125:
126: METHOD(attr_provider_t, destroy, void,
127: private_attr_provider_t *this)
128: {
129: this->attributes->destroy_function(this->attributes,
130: (void*)attribute_destroy);
131: this->lock->destroy(this->lock);
132: free(this);
133: }
134:
135: /**
136: * Add an attribute entry to the list
137: */
138: static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
139: configuration_attribute_type_t type)
140: {
141: attribute_entry_t *entry;
142: host_t *host;
143: char *str;
144:
145: str = lib->settings->get_str(lib->settings, "%s.%s%d", NULL, lib->ns,
146: key, nr);
147: if (str)
148: {
149: host = host_create_from_string(str, 0);
150: if (host)
151: {
152: if (host->get_family(host) == AF_INET6)
153: {
154: switch (type)
155: {
156: case INTERNAL_IP4_DNS:
157: type = INTERNAL_IP6_DNS;
158: break;
159: case INTERNAL_IP4_NBNS:
160: type = INTERNAL_IP6_NBNS;
161: break;
162: default:
163: break;
164: }
165: }
166: INIT(entry,
167: .type = type,
168: .value = chunk_clone(host->get_address(host)),
169: .ike = IKE_ANY,
170: );
171: host->destroy(host);
172: DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B",
173: configuration_attribute_type_names, entry->type, &entry->value);
174: this->attributes->insert_last(this->attributes, entry);
175: }
176: }
177: }
178:
179: /**
180: * Key to attribute type mappings, for v4 and v6 attributes
181: */
182: typedef struct {
183: char *name;
184: configuration_attribute_type_t v4;
185: configuration_attribute_type_t v6;
186: ike_version_t ike;
187: } attribute_type_key_t;
188:
189: static attribute_type_key_t keys[] = {
190: {"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS, IKE_ANY},
191: {"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS, IKE_ANY},
192: {"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS, IKE_ANY},
193: {"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP, IKE_ANY},
194: {"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK, IKE_ANY},
195: {"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, IKE_ANY},
196: {"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET, IKE_ANY},
197: {"p-cscf", P_CSCF_IP4_ADDRESS, P_CSCF_IP6_ADDRESS, IKEV2},
198: {"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE, IKEV1},
199: {"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN, IKEV1},
200: };
201:
202: /**
203: * Load (numerical) entries from the plugins.attr namespace
204: */
205: static void load_entries(private_attr_provider_t *this)
206: {
207: enumerator_t *enumerator, *tokens;
208: char *key, *value, *token;
209: int i;
210:
211: for (i = 1; i <= SERVER_MAX; i++)
212: {
213: add_legacy_entry(this, "dns", i, INTERNAL_IP4_DNS);
214: add_legacy_entry(this, "nbns", i, INTERNAL_IP4_NBNS);
215: }
216:
217: enumerator = lib->settings->create_key_value_enumerator(lib->settings,
218: "%s.plugins.attr", lib->ns);
219: while (enumerator->enumerate(enumerator, &key, &value))
220: {
221: configuration_attribute_type_t type;
222: attribute_type_key_t *mapped = NULL;
223: attribute_entry_t *entry;
224: chunk_t data;
225: host_t *host;
226: char *pos;
227: int i, mask = -1, family;
228:
229: if (streq(key, "load"))
230: {
231: continue;
232: }
233: type = atoi(key);
234: if (!type)
235: {
236: for (i = 0; i < countof(keys); i++)
237: {
238: if (streq(key, keys[i].name))
239: {
240: mapped = &keys[i];
241: break;
242: }
243: }
244: if (!mapped)
245: {
246: DBG1(DBG_CFG, "mapping attribute type %s failed", key);
247: continue;
248: }
249: }
250: tokens = enumerator_create_token(value, ",", " ");
251: while (tokens->enumerate(tokens, &token))
252: {
253: pos = strchr(token, '/');
254: if (pos)
255: {
256: *(pos++) = '\0';
257: mask = atoi(pos);
258: }
259: host = host_create_from_string(token, 0);
260: if (!host)
261: {
262: if (mapped)
263: {
264: DBG1(DBG_CFG, "invalid host in key %s: %s", key, token);
265: continue;
266: }
267: /* store numeric attributes that are no IP addresses as strings */
268: data = chunk_clone(chunk_from_str(token));
269: }
270: else
271: {
272: family = host->get_family(host);
273: if (mask == -1)
274: {
275: data = chunk_clone(host->get_address(host));
276: }
277: else
278: {
279: if (family == AF_INET)
280: { /* IPv4 attributes contain a subnet mask */
281: uint32_t netmask = 0;
282:
283: if (mask)
284: { /* shifting uint32_t by 32 or more is undefined */
285: mask = 32 - mask;
286: netmask = htonl((0xFFFFFFFF >> mask) << mask);
287: }
288: data = chunk_cat("cc", host->get_address(host),
289: chunk_from_thing(netmask));
290: }
291: else
292: { /* IPv6 addresses the prefix only */
293: data = chunk_cat("cc", host->get_address(host),
294: chunk_from_chars(mask));
295: }
296: }
297: host->destroy(host);
298: if (mapped)
299: {
300: switch (family)
301: {
302: case AF_INET:
303: type = mapped->v4;
304: break;
305: case AF_INET6:
306: type = mapped->v6;
307: break;
308: }
309: }
310: }
311: INIT(entry,
312: .type = type,
313: .value = data,
314: .ike = mapped ? mapped->ike : IKE_ANY,
315: );
316: DBG2(DBG_CFG, "loaded attribute %N: %#B",
317: configuration_attribute_type_names, entry->type, &entry->value);
318: this->attributes->insert_last(this->attributes, entry);
319: }
320: tokens->destroy(tokens);
321: }
322: enumerator->destroy(enumerator);
323: }
324:
325: METHOD(attr_provider_t, reload, void,
326: private_attr_provider_t *this)
327: {
328: this->lock->write_lock(this->lock);
329:
330: this->attributes->destroy_function(this->attributes, (void*)attribute_destroy);
331: this->attributes = linked_list_create();
332:
333: load_entries(this);
334:
335: DBG1(DBG_CFG, "loaded %d entr%s for attr plugin configuration",
336: this->attributes->get_count(this->attributes),
337: this->attributes->get_count(this->attributes) == 1 ? "y" : "ies");
338:
339: this->lock->unlock(this->lock);
340: }
341:
342: /*
343: * see header file
344: */
345: attr_provider_t *attr_provider_create()
346: {
347: private_attr_provider_t *this;
348:
349: INIT(this,
350: .public = {
351: .provider = {
352: .acquire_address = (void*)return_null,
353: .release_address = (void*)return_false,
354: .create_attribute_enumerator = _create_attribute_enumerator,
355: },
356: .reload = _reload,
357: .destroy = _destroy,
358: },
359: .attributes = linked_list_create(),
360: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
361: );
362:
363: load_entries(this);
364:
365: return &this->public;
366: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>