]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/conftest/config.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / conftest / config.c
CommitLineData
d1041fa4
MW
1/*
2 * Copyright (C) 2010 Martin Willi
19ef2aec
TB
3 *
4 * Copyright (C) secunet Security Networks AG
d1041fa4
MW
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 "config.h"
18
19#include <daemon.h>
20#include <conftest.h>
21
22typedef struct private_config_t private_config_t;
23
24/**
25 * Private data of an config_t object.
26 */
27struct private_config_t {
28
29 /**
30 * Public config_t interface.
31 */
32 config_t public;
33
34 /**
35 * List of loaded peer configs
36 */
37 linked_list_t *configs;
38};
39
525cc46c
TB
40CALLBACK(ike_filter, bool,
41 void *data, enumerator_t *orig, va_list args)
d1041fa4 42{
525cc46c
TB
43 peer_cfg_t *cfg;
44 ike_cfg_t **out;
45
46 VA_ARGS_VGET(args, out);
47
48 if (orig->enumerate(orig, &cfg))
49 {
50 *out = cfg->get_ike_cfg(cfg);
51 return TRUE;
52 }
53 return FALSE;
d1041fa4
MW
54}
55
56METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
57 private_config_t *this, host_t *me, host_t *other)
58{
59
60 return enumerator_create_filter(
61 this->configs->create_enumerator(this->configs),
525cc46c 62 ike_filter, NULL, NULL);
d1041fa4
MW
63}
64
65METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
66 private_config_t *this, identification_t *me, identification_t *other)
67{
68 return this->configs->create_enumerator(this->configs);
69}
70
71METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
72 private_config_t *this, char *name)
73{
74 enumerator_t *e1, *e2;
75 peer_cfg_t *current, *found = NULL;
76 child_cfg_t *child;
77
78 e1 = this->configs->create_enumerator(this->configs);
79 while (e1->enumerate(e1, &current))
80 {
81 e2 = current->create_child_cfg_enumerator(current);
82 while (e2->enumerate(e2, &child))
83 {
84 if (streq(child->get_name(child), name))
85 {
86 found = current;
87 found->get_ref(found);
88 break;
89 }
90 }
91 e2->destroy(e2);
92 if (found)
93 {
94 break;
95 }
96 }
97 e1->destroy(e1);
98 return found;
99}
100
101/**
102 * Load IKE config for a given section name
103 */
104static ike_cfg_t *load_ike_config(private_config_t *this,
105 settings_t *settings, char *config)
106{
107 enumerator_t *enumerator;
108 ike_cfg_t *ike_cfg;
109 proposal_t *proposal;
110 char *token;
9486a2e5
TB
111 ike_cfg_create_t ike = {
112 .version = IKEV2,
113 .local = settings->get_str(settings, "configs.%s.lhost",
114 "%any", config),
115 .local_port = settings->get_int(settings, "configs.%s.lport",
116 500, config),
117 .remote = settings->get_str(settings, "configs.%s.rhost",
118 "%any", config),
119 .remote_port = settings->get_int(settings, "configs.%s.rport",
120 500, config),
121 .force_encap = settings->get_bool(settings, "configs.%s.fake_nat",
122 FALSE, config),
123 };
124
125 ike_cfg = ike_cfg_create(&ike);
d1041fa4
MW
126 token = settings->get_str(settings, "configs.%s.proposal", NULL, config);
127 if (token)
128 {
129 enumerator = enumerator_create_token(token, ",", " ");
130 while (enumerator->enumerate(enumerator, &token))
131 {
132 proposal = proposal_create_from_string(PROTO_IKE, token);
133 if (proposal)
134 {
135 ike_cfg->add_proposal(ike_cfg, proposal);
136 }
137 else
138 {
139 DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
140 }
141 }
142 enumerator->destroy(enumerator);
143 }
144 else
145 {
146 ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
879e3d12 147 ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
d1041fa4
MW
148 }
149 return ike_cfg;
150}
151/**
152 * Load CHILD config for given section names
153 */
154static child_cfg_t *load_child_config(private_config_t *this,
155 settings_t *settings, char *config, char *child)
156{
8a00a845
TB
157 child_cfg_create_t data = {
158 .mode = MODE_TUNNEL,
159 };
d1041fa4 160 child_cfg_t *child_cfg;
d1041fa4
MW
161 enumerator_t *enumerator;
162 proposal_t *proposal;
163 traffic_selector_t *ts;
d1041fa4 164 char *token;
d1041fa4 165
6b50b911
MW
166 if (settings->get_bool(settings, "configs.%s.%s.transport",
167 FALSE, config, child))
168 {
8a00a845 169 data.mode = MODE_TRANSPORT;
6b50b911 170 }
8a00a845
TB
171 data.tfc = settings->get_int(settings, "configs.%s.%s.tfc_padding",
172 0, config, child);
173 child_cfg = child_cfg_create(child, &data);
d1041fa4
MW
174
175 token = settings->get_str(settings, "configs.%s.%s.proposal",
176 NULL, config, child);
177 if (token)
178 {
179 enumerator = enumerator_create_token(token, ",", " ");
180 while (enumerator->enumerate(enumerator, &token))
181 {
182 proposal = proposal_create_from_string(PROTO_ESP, token);
183 if (proposal)
184 {
185 child_cfg->add_proposal(child_cfg, proposal);
186 }
187 else
188 {
189 DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
190 }
191 }
192 enumerator->destroy(enumerator);
193 }
194 else
195 {
33412158 196 child_cfg->add_proposal(child_cfg, proposal_create_default_aead(PROTO_ESP));
d1041fa4
MW
197 child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
198 }
199
5cb00b3a 200 token = settings->get_str(settings, "configs.%s.%s.lts", NULL, config, child);
d1041fa4
MW
201 if (token)
202 {
203 enumerator = enumerator_create_token(token, ",", " ");
204 while (enumerator->enumerate(enumerator, &token))
205 {
a1db77de 206 ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
1efd6c6f 207 if (ts)
d1041fa4 208 {
d1041fa4
MW
209 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
210 }
211 else
212 {
213 DBG1(DBG_CFG, "invalid local ts: %s, skipped", token);
214 }
215 }
216 enumerator->destroy(enumerator);
217 }
218 else
219 {
220 ts = traffic_selector_create_dynamic(0, 0, 65535);
221 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
222 }
223
5cb00b3a 224 token = settings->get_str(settings, "configs.%s.%s.rts", NULL, config, child);
d1041fa4
MW
225 if (token)
226 {
227 enumerator = enumerator_create_token(token, ",", " ");
228 while (enumerator->enumerate(enumerator, &token))
229 {
a1db77de 230 ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
1efd6c6f 231 if (ts)
d1041fa4 232 {
d1041fa4
MW
233 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
234 }
235 else
236 {
237 DBG1(DBG_CFG, "invalid remote ts: %s, skipped", token);
238 }
239 }
240 enumerator->destroy(enumerator);
241 }
242 else
243 {
244 ts = traffic_selector_create_dynamic(0, 0, 65535);
245 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
246 }
247 return child_cfg;
248}
249
250/**
251 * Load peer config for a given section name
252 */
253static peer_cfg_t *load_peer_config(private_config_t *this,
254 settings_t *settings, char *config)
255{
256 ike_cfg_t *ike_cfg;
257 peer_cfg_t *peer_cfg;
258 auth_cfg_t *auth;
259 child_cfg_t *child_cfg;
260 enumerator_t *enumerator;
261 identification_t *lid, *rid;
ae82265a 262 char *child, *policy, *pool;
a73e040c 263 uintptr_t strength;
2ba5dadb
TB
264 peer_cfg_create_t peer = {
265 .cert_policy = CERT_ALWAYS_SEND,
266 .unique = UNIQUE_NO,
267 .keyingtries = 1,
268 .no_mobike = TRUE,
269 };
d1041fa4
MW
270
271 ike_cfg = load_ike_config(this, settings, config);
2ba5dadb 272 peer_cfg = peer_cfg_create(config, ike_cfg, &peer);
d1041fa4
MW
273
274 auth = auth_cfg_create();
275 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
276 lid = identification_create_from_string(
277 settings->get_str(settings, "configs.%s.lid", "%any", config));
278 auth->add(auth, AUTH_RULE_IDENTITY, lid);
279 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
280
281 auth = auth_cfg_create();
282 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
283 rid = identification_create_from_string(
284 settings->get_str(settings, "configs.%s.rid", "%any", config));
5cb00b3a 285 strength = settings->get_int(settings, "configs.%s.rsa_strength", 0, config);
a73e040c
MW
286 if (strength)
287 {
288 auth->add(auth, AUTH_RULE_RSA_STRENGTH, strength);
289 }
5cb00b3a 290 strength = settings->get_int(settings, "configs.%s.ecdsa_strength", 0, config);
a73e040c
MW
291 if (strength)
292 {
293 auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength);
294 }
58be32e8
MW
295 policy = settings->get_str(settings, "configs.%s.cert_policy", NULL, config);
296 if (policy)
297 {
298 auth->add(auth, AUTH_RULE_CERT_POLICY, strdup(policy));
299 }
d1041fa4
MW
300 auth->add(auth, AUTH_RULE_IDENTITY, rid);
301 peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
ae82265a
TB
302 pool = settings->get_str(settings, "configs.%s.named_pool", NULL, config);
303 if (pool)
304 {
305 peer_cfg->add_pool(peer_cfg, pool);
306 }
d1041fa4
MW
307
308 DBG1(DBG_CFG, "loaded config %s: %Y - %Y", config, lid, rid);
309
310 enumerator = settings->create_section_enumerator(settings,
311 "configs.%s", config);
312 while (enumerator->enumerate(enumerator, &child))
313 {
314 child_cfg = load_child_config(this, settings, config, child);
315 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
316 }
317 enumerator->destroy(enumerator);
318 return peer_cfg;
319}
320
321METHOD(config_t, load, void,
322 private_config_t *this, settings_t *settings)
323{
324 enumerator_t *enumerator;
325 char *config;
326
327 enumerator = settings->create_section_enumerator(settings, "configs");
328 while (enumerator->enumerate(enumerator, &config))
329 {
330 this->configs->insert_last(this->configs,
331 load_peer_config(this, settings, config));
332 }
333 enumerator->destroy(enumerator);
334}
335
336METHOD(config_t, destroy, void,
337 private_config_t *this)
338{
339 this->configs->destroy_offset(this->configs, offsetof(peer_cfg_t, destroy));
340 free(this);
341}
342
343/**
344 * See header
345 */
346config_t *config_create()
347{
348 private_config_t *this;
349
350 INIT(this,
351 .public = {
352 .backend = {
353 .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
354 .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
355 .get_peer_cfg_by_name = _get_peer_cfg_by_name,
356 },
357 .load = _load,
358 .destroy = _destroy,
359 },
360 .configs = linked_list_create(),
361 );
362
363 return &this->public;
364}