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