Added IKE config option to fake NAT situations
[strongswan.git] / src / conftest / config.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 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 "config.h"
17
18 #include <daemon.h>
19 #include <conftest.h>
20
21 typedef struct private_config_t private_config_t;
22
23 /**
24 * Private data of an config_t object.
25 */
26 struct private_config_t {
27
28 /**
29 * Public config_t interface.
30 */
31 config_t public;
32
33 /**
34 * List of loaded peer configs
35 */
36 linked_list_t *configs;
37 };
38
39 /**
40 * filter function for ike configs
41 */
42 static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out)
43 {
44 *out = (*in)->get_ike_cfg(*in);
45 return TRUE;
46 }
47
48 METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
49 private_config_t *this, host_t *me, host_t *other)
50 {
51
52 return enumerator_create_filter(
53 this->configs->create_enumerator(this->configs),
54 (void*)ike_filter, NULL, NULL);
55 }
56
57 METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
58 private_config_t *this, identification_t *me, identification_t *other)
59 {
60 return this->configs->create_enumerator(this->configs);
61 }
62
63 METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
64 private_config_t *this, char *name)
65 {
66 enumerator_t *e1, *e2;
67 peer_cfg_t *current, *found = NULL;
68 child_cfg_t *child;
69
70 e1 = this->configs->create_enumerator(this->configs);
71 while (e1->enumerate(e1, &current))
72 {
73 e2 = current->create_child_cfg_enumerator(current);
74 while (e2->enumerate(e2, &child))
75 {
76 if (streq(child->get_name(child), name))
77 {
78 found = current;
79 found->get_ref(found);
80 break;
81 }
82 }
83 e2->destroy(e2);
84 if (found)
85 {
86 break;
87 }
88 }
89 e1->destroy(e1);
90 return found;
91 }
92
93 /**
94 * Load IKE config for a given section name
95 */
96 static ike_cfg_t *load_ike_config(private_config_t *this,
97 settings_t *settings, char *config)
98 {
99 enumerator_t *enumerator;
100 ike_cfg_t *ike_cfg;
101 proposal_t *proposal;
102 char *token;
103
104 ike_cfg = ike_cfg_create(TRUE,
105 settings->get_bool(settings, "configs.%s.fake_nat", FALSE, config),
106 settings->get_str(settings, "configs.%s.lhost", "%any", config), 500,
107 settings->get_str(settings, "configs.%s.rhost", "%any", config), 500);
108 token = settings->get_str(settings, "configs.%s.proposal", NULL, config);
109 if (token)
110 {
111 enumerator = enumerator_create_token(token, ",", " ");
112 while (enumerator->enumerate(enumerator, &token))
113 {
114 proposal = proposal_create_from_string(PROTO_IKE, token);
115 if (proposal)
116 {
117 ike_cfg->add_proposal(ike_cfg, proposal);
118 }
119 else
120 {
121 DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
122 }
123 }
124 enumerator->destroy(enumerator);
125 }
126 else
127 {
128 ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
129 }
130 return ike_cfg;
131 }
132 /**
133 * Load CHILD config for given section names
134 */
135 static child_cfg_t *load_child_config(private_config_t *this,
136 settings_t *settings, char *config, char *child)
137 {
138 child_cfg_t *child_cfg;
139 lifetime_cfg_t lifetime = {};
140 enumerator_t *enumerator;
141 proposal_t *proposal;
142 traffic_selector_t *ts;
143 host_t *net;
144 char *token;
145 int bits;
146
147 child_cfg = child_cfg_create(child, &lifetime, NULL, FALSE,
148 settings->get_bool(settings, "configs.%s.%s.transport",
149 FALSE, config, child),
150 ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL, NULL);
151
152 token = settings->get_str(settings, "configs.%s.%s.proposal",
153 NULL, config, child);
154 if (token)
155 {
156 enumerator = enumerator_create_token(token, ",", " ");
157 while (enumerator->enumerate(enumerator, &token))
158 {
159 proposal = proposal_create_from_string(PROTO_ESP, token);
160 if (proposal)
161 {
162 child_cfg->add_proposal(child_cfg, proposal);
163 }
164 else
165 {
166 DBG1(DBG_CFG, "parsing proposal '%s' failed, skipped", token);
167 }
168 }
169 enumerator->destroy(enumerator);
170 }
171 else
172 {
173 child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
174 }
175
176 token = settings->get_str(settings, "configs.%s.%s.lts", NULL, config);
177 if (token)
178 {
179 enumerator = enumerator_create_token(token, ",", " ");
180 while (enumerator->enumerate(enumerator, &token))
181 {
182 net = host_create_from_subnet(token, &bits);
183 if (net)
184 {
185 ts = traffic_selector_create_from_subnet(net, bits, 0, 0);
186 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
187 }
188 else
189 {
190 DBG1(DBG_CFG, "invalid local ts: %s, skipped", token);
191 }
192 }
193 enumerator->destroy(enumerator);
194 }
195 else
196 {
197 ts = traffic_selector_create_dynamic(0, 0, 65535);
198 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
199 }
200
201 token = settings->get_str(settings, "configs.%s.%s.rts", NULL, config);
202 if (token)
203 {
204 enumerator = enumerator_create_token(token, ",", " ");
205 while (enumerator->enumerate(enumerator, &token))
206 {
207 net = host_create_from_subnet(token, &bits);
208 if (net)
209 {
210 ts = traffic_selector_create_from_subnet(net, bits, 0, 0);
211 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
212 }
213 else
214 {
215 DBG1(DBG_CFG, "invalid remote ts: %s, skipped", token);
216 }
217 }
218 enumerator->destroy(enumerator);
219 }
220 else
221 {
222 ts = traffic_selector_create_dynamic(0, 0, 65535);
223 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
224 }
225 return child_cfg;
226 }
227
228 /**
229 * Load peer config for a given section name
230 */
231 static peer_cfg_t *load_peer_config(private_config_t *this,
232 settings_t *settings, char *config)
233 {
234 ike_cfg_t *ike_cfg;
235 peer_cfg_t *peer_cfg;
236 auth_cfg_t *auth;
237 child_cfg_t *child_cfg;
238 enumerator_t *enumerator;
239 identification_t *lid, *rid;
240 char *child;
241
242 ike_cfg = load_ike_config(this, settings, config);
243 peer_cfg = peer_cfg_create(config, 2, ike_cfg, CERT_ALWAYS_SEND,
244 UNIQUE_NO, 1, 0, 0, 0, 0, TRUE, 0,
245 NULL, NULL, FALSE, NULL, NULL);
246
247 auth = auth_cfg_create();
248 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
249 lid = identification_create_from_string(
250 settings->get_str(settings, "configs.%s.lid", "%any", config));
251 auth->add(auth, AUTH_RULE_IDENTITY, lid);
252 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
253
254 auth = auth_cfg_create();
255 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
256 rid = identification_create_from_string(
257 settings->get_str(settings, "configs.%s.rid", "%any", config));
258 auth->add(auth, AUTH_RULE_IDENTITY, rid);
259 peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
260
261 DBG1(DBG_CFG, "loaded config %s: %Y - %Y", config, lid, rid);
262
263 enumerator = settings->create_section_enumerator(settings,
264 "configs.%s", config);
265 while (enumerator->enumerate(enumerator, &child))
266 {
267 child_cfg = load_child_config(this, settings, config, child);
268 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
269 }
270 enumerator->destroy(enumerator);
271 return peer_cfg;
272 }
273
274 METHOD(config_t, load, void,
275 private_config_t *this, settings_t *settings)
276 {
277 enumerator_t *enumerator;
278 char *config;
279
280 enumerator = settings->create_section_enumerator(settings, "configs");
281 while (enumerator->enumerate(enumerator, &config))
282 {
283 this->configs->insert_last(this->configs,
284 load_peer_config(this, settings, config));
285 }
286 enumerator->destroy(enumerator);
287 }
288
289 METHOD(config_t, destroy, void,
290 private_config_t *this)
291 {
292 this->configs->destroy_offset(this->configs, offsetof(peer_cfg_t, destroy));
293 free(this);
294 }
295
296 /**
297 * See header
298 */
299 config_t *config_create()
300 {
301 private_config_t *this;
302
303 INIT(this,
304 .public = {
305 .backend = {
306 .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
307 .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
308 .get_peer_cfg_by_name = _get_peer_cfg_by_name,
309 },
310 .load = _load,
311 .destroy = _destroy,
312 },
313 .configs = linked_list_create(),
314 );
315
316 return &this->public;
317 }