]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libhydra/plugins/attr/attr_provider.c
Revert alloc_str changes
[thirdparty/strongswan.git] / src / libhydra / plugins / attr / attr_provider.c
CommitLineData
7f56b494 1/*
7ac6060e 2 * Copyright (C) 2010 Tobias Brunner
7f56b494
MW
3 * Copyright (C) 2009 Martin Willi
4 * 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.
7f56b494
MW
15 */
16
17#include "attr_provider.h"
18
19#include <time.h>
20
7ac6060e
TB
21#include <hydra.h>
22#include <debug.h>
23#include <utils/linked_list.h>
96409be3 24#include <threading/rwlock.h>
7f56b494
MW
25
26#define SERVER_MAX 2
27
28typedef struct private_attr_provider_t private_attr_provider_t;
29typedef struct attribute_entry_t attribute_entry_t;
30
31/**
32 * private data of attr_provider
33 */
34struct private_attr_provider_t {
7daf5226 35
7f56b494
MW
36 /**
37 * public functions
38 */
39 attr_provider_t public;
7daf5226 40
7f56b494
MW
41 /**
42 * List of attributes, attribute_entry_t
43 */
44 linked_list_t *attributes;
96409be3
MW
45
46 /**
47 * Lock for attribute list
48 */
49 rwlock_t *lock;
7f56b494
MW
50};
51
52struct attribute_entry_t {
53 /** type of attribute */
54 configuration_attribute_type_t type;
55 /** attribute value */
56 chunk_t value;
57};
58
96409be3
MW
59/**
60 * Destroy an entry
61 */
62static void attribute_destroy(attribute_entry_t *this)
63{
64 free(this->value.ptr);
65 free(this);
66}
67
7f56b494
MW
68/**
69 * convert enumerator value from attribute_entry
70 */
71static bool attr_enum_filter(void *null, attribute_entry_t **in,
72 configuration_attribute_type_t *type, void* none, chunk_t *value)
73{
74 *type = (*in)->type;
75 *value = (*in)->value;
76 return TRUE;
77}
78
00b4b4b0
MW
79METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
80 private_attr_provider_t *this, char *pool,
81 identification_t *id, host_t *vip)
7f56b494 82{
b5a2055f
MW
83 if (vip)
84 {
96409be3 85 this->lock->read_lock(this->lock);
b5a2055f 86 return enumerator_create_filter(
96409be3
MW
87 this->attributes->create_enumerator(this->attributes),
88 (void*)attr_enum_filter, this->lock, (void*)this->lock->unlock);
b5a2055f
MW
89 }
90 return enumerator_create_empty();
7f56b494
MW
91}
92
00b4b4b0
MW
93METHOD(attr_provider_t, destroy, void,
94 private_attr_provider_t *this)
7f56b494 95{
96409be3
MW
96 this->attributes->destroy_function(this->attributes,
97 (void*)attribute_destroy);
98 this->lock->destroy(this->lock);
7f56b494
MW
99 free(this);
100}
101
102/**
103 * Add an attribute entry to the list
104 */
d674c2ac
MW
105static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
106 configuration_attribute_type_t type)
7f56b494
MW
107{
108 attribute_entry_t *entry;
109 host_t *host;
110 char *str;
7daf5226 111
5b0bcfb1
MW
112 str = lib->settings->get_str(lib->settings, "%s.%s%d", NULL, hydra->daemon,
113 key, nr);
7f56b494
MW
114 if (str)
115 {
116 host = host_create_from_string(str, 0);
117 if (host)
118 {
119 entry = malloc_thing(attribute_entry_t);
7daf5226 120
7f56b494
MW
121 if (host->get_family(host) == AF_INET6)
122 {
123 switch (type)
124 {
125 case INTERNAL_IP4_DNS:
126 type = INTERNAL_IP6_DNS;
127 break;
128 case INTERNAL_IP4_NBNS:
129 type = INTERNAL_IP6_NBNS;
130 break;
131 default:
132 break;
133 }
134 }
135 entry->type = type;
136 entry->value = chunk_clone(host->get_address(host));
137 host->destroy(host);
96409be3
MW
138 DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B",
139 configuration_attribute_type_names, entry->type, &entry->value);
7f56b494
MW
140 this->attributes->insert_last(this->attributes, entry);
141 }
142 }
143}
144
d674c2ac
MW
145/**
146 * Key to attribute type mappings, for v4 and v6 attributes
147 */
148static struct {
149 char *name;
150 configuration_attribute_type_t v4;
151 configuration_attribute_type_t v6;
152} keys[] = {
153 {"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS},
154 {"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS},
155 {"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS},
156 {"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP},
157 {"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK},
158 {"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER},
1e723d73 159 {"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET},
d674c2ac
MW
160};
161
162/**
163 * Load (numerical) entries from the plugins.attr namespace
164 */
165static void load_entries(private_attr_provider_t *this)
166{
167 enumerator_t *enumerator, *tokens;
168 char *key, *value, *token;
96409be3
MW
169 int i;
170
171 for (i = 1; i <= SERVER_MAX; i++)
172 {
173 add_legacy_entry(this, "dns", i, INTERNAL_IP4_DNS);
174 add_legacy_entry(this, "nbns", i, INTERNAL_IP4_NBNS);
175 }
d674c2ac
MW
176
177 enumerator = lib->settings->create_key_value_enumerator(lib->settings,
7ac6060e 178 "%s.plugins.attr", hydra->daemon);
d674c2ac
MW
179 while (enumerator->enumerate(enumerator, &key, &value))
180 {
181 configuration_attribute_type_t type;
182 attribute_entry_t *entry;
183 host_t *host;
1e723d73
MW
184 char *pos;
185 int i, mask = -1;
d674c2ac
MW
186
187 type = atoi(key);
188 tokens = enumerator_create_token(value, ",", " ");
189 while (tokens->enumerate(tokens, &token))
190 {
1e723d73
MW
191 pos = strchr(token, '/');
192 if (pos)
193 {
194 *(pos++) = '\0';
195 mask = atoi(pos);
196 }
d674c2ac
MW
197 host = host_create_from_string(token, 0);
198 if (!host)
199 {
894936ce 200 DBG1(DBG_CFG, "invalid host in key %s: %s", key, token);
d674c2ac
MW
201 continue;
202 }
203 if (!type)
204 {
205 for (i = 0; i < countof(keys); i++)
206 {
207 if (streq(key, keys[i].name))
208 {
209 if (host->get_family(host) == AF_INET)
210 {
211 type = keys[i].v4;
212 }
213 else
214 {
215 type = keys[i].v6;
216 }
217 }
218 }
219 if (!type)
220 {
894936ce 221 DBG1(DBG_CFG, "mapping attribute type %s failed", key);
d674c2ac
MW
222 break;
223 }
224 }
225 entry = malloc_thing(attribute_entry_t);
226 entry->type = type;
1e723d73
MW
227 if (mask == -1)
228 {
229 entry->value = chunk_clone(host->get_address(host));
230 }
231 else
232 {
233 if (host->get_family(host) == AF_INET)
234 { /* IPv4 attributes contain a subnet mask */
235 u_int32_t netmask;
236
237 mask = 32 - mask;
238 netmask = htonl((0xFFFFFFFF >> mask) << mask);
239 entry->value = chunk_cat("cc", host->get_address(host),
240 chunk_from_thing(netmask));
241 }
242 else
243 { /* IPv6 addresses the prefix only */
244 entry->value = chunk_cat("cc", host->get_address(host),
245 chunk_from_chars(mask));
246 }
247 }
d674c2ac 248 host->destroy(host);
96409be3
MW
249 DBG2(DBG_CFG, "loaded attribute %N: %#B",
250 configuration_attribute_type_names, entry->type, &entry->value);
d674c2ac
MW
251 this->attributes->insert_last(this->attributes, entry);
252 }
253 tokens->destroy(tokens);
254 }
255 enumerator->destroy(enumerator);
256}
257
96409be3
MW
258METHOD(attr_provider_t, reload, void,
259 private_attr_provider_t *this)
260{
261 this->lock->write_lock(this->lock);
262
263 this->attributes->destroy_function(this->attributes, (void*)attribute_destroy);
264 this->attributes = linked_list_create();
265
266 load_entries(this);
267
268 DBG1(DBG_CFG, "loaded %d entr%s for attr plugin configuration",
269 this->attributes->get_count(this->attributes),
270 this->attributes->get_count(this->attributes) == 1 ? "y" : "ies");
271
272 this->lock->unlock(this->lock);
273}
274
7f56b494
MW
275/*
276 * see header file
277 */
278attr_provider_t *attr_provider_create(database_t *db)
279{
280 private_attr_provider_t *this;
7daf5226 281
00b4b4b0
MW
282 INIT(this,
283 .public = {
284 .provider = {
285 .acquire_address = (void*)return_null,
286 .release_address = (void*)return_false,
287 .create_attribute_enumerator = _create_attribute_enumerator,
288 },
96409be3 289 .reload = _reload,
00b4b4b0
MW
290 .destroy = _destroy,
291 },
292 .attributes = linked_list_create(),
96409be3 293 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
00b4b4b0 294 );
7daf5226 295
d674c2ac
MW
296 load_entries(this);
297
7f56b494
MW
298 return &this->public;
299}
300