Annotation of embedaddon/strongswan/src/conftest/config.c, revision 1.1.1.1
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: {
195: child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
196: child_cfg->add_proposal(child_cfg,
197: proposal_create_default_aead(PROTO_ESP));
198: }
199:
200: token = settings->get_str(settings, "configs.%s.%s.lts", NULL, config, child);
201: if (token)
202: {
203: enumerator = enumerator_create_token(token, ",", " ");
204: while (enumerator->enumerate(enumerator, &token))
205: {
206: ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
207: if (ts)
208: {
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:
224: token = settings->get_str(settings, "configs.%s.%s.rts", NULL, config, child);
225: if (token)
226: {
227: enumerator = enumerator_create_token(token, ",", " ");
228: while (enumerator->enumerate(enumerator, &token))
229: {
230: ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
231: if (ts)
232: {
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: */
253: static 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;
262: char *child, *policy, *pool;
263: uintptr_t strength;
264: peer_cfg_create_t peer = {
265: .cert_policy = CERT_ALWAYS_SEND,
266: .unique = UNIQUE_NO,
267: .keyingtries = 1,
268: .no_mobike = TRUE,
269: };
270:
271: ike_cfg = load_ike_config(this, settings, config);
272: peer_cfg = peer_cfg_create(config, ike_cfg, &peer);
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));
285: strength = settings->get_int(settings, "configs.%s.rsa_strength", 0, config);
286: if (strength)
287: {
288: auth->add(auth, AUTH_RULE_RSA_STRENGTH, strength);
289: }
290: strength = settings->get_int(settings, "configs.%s.ecdsa_strength", 0, config);
291: if (strength)
292: {
293: auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength);
294: }
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: }
300: auth->add(auth, AUTH_RULE_IDENTITY, rid);
301: peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
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: }
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:
321: METHOD(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:
336: METHOD(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: */
346: config_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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>