Annotation of embedaddon/strongswan/src/libcharon/plugins/uci/uci_config.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2008 Thomas Kallenberg
3: * Copyright (C) 2008 Tobias Brunner
4: * Copyright (C) 2008 Martin Willi
5: * HSR Hochschule fuer Technik Rapperswil
6: *
7: * This program is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2 of the License, or (at your
10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11: *
12: * This program is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15: * for more details.
16: */
17:
18: #define _GNU_SOURCE
19: #include <string.h>
20:
21: #include "uci_config.h"
22: #include "uci_parser.h"
23:
24: #include <daemon.h>
25:
26: typedef struct private_uci_config_t private_uci_config_t;
27:
28: /**
29: * Private data of an uci_config_t object
30: */
31: struct private_uci_config_t {
32:
33: /**
34: * Public part
35: */
36: uci_config_t public;
37:
38: /**
39: * UCI parser context
40: */
41: uci_parser_t *parser;
42: };
43:
44: /**
45: * enumerator implementation for create_peer_cfg_enumerator
46: */
47: typedef struct {
48: /** implements enumerator */
49: enumerator_t public;
50: /** currently enumerated peer config */
51: peer_cfg_t *peer_cfg;
52: /** inner uci_parser section enumerator */
53: enumerator_t *inner;
54: } peer_enumerator_t;
55:
56: /**
57: * create a proposal from a string, with fallback to default
58: */
59: static proposal_t *create_proposal(char *string, protocol_id_t proto)
60: {
61: proposal_t *proposal = NULL;
62:
63: if (string)
64: {
65: proposal = proposal_create_from_string(proto, string);
66: }
67: if (!proposal)
68: { /* UCI default is aes/sha1 only */
69: if (proto == PROTO_IKE)
70: {
71: proposal = proposal_create_from_string(proto,
72: "aes128-aes192-aes256-sha1-modp1536-modp2048");
73: }
74: else
75: {
76: proposal = proposal_create_from_string(proto,
77: "aes128-aes192-aes256-sha1");
78: }
79: }
80: return proposal;
81: }
82:
83: /**
84: * create an traffic selector, fallback to dynamic
85: */
86: static traffic_selector_t *create_ts(char *string)
87: {
88: if (string)
89: {
90: traffic_selector_t *ts;
91:
92: ts = traffic_selector_create_from_cidr(string, 0, 0, 65535);
93: if (ts)
94: {
95: return ts;
96: }
97: }
98: return traffic_selector_create_dynamic(0, 0, 65535);
99: }
100:
101: /**
102: * create a rekey time from a string with hours, with fallback
103: */
104: static u_int create_rekey(char *string)
105: {
106: u_int rekey = 0;
107:
108: if (string)
109: {
110: rekey = atoi(string);
111: if (rekey)
112: {
113: return rekey * 3600;
114: }
115: }
116: /* every 12 hours */
117: return 12 * 3600;
118: }
119:
120: METHOD(enumerator_t, peer_enumerator_enumerate, bool,
121: peer_enumerator_t *this, va_list args)
122: {
123: char *name, *ike_proposal, *esp_proposal, *ike_rekey, *esp_rekey;
124: char *local_id, *local_net, *remote_id, *remote_net;
125: peer_cfg_t **cfg;
126: child_cfg_t *child_cfg;
127: ike_cfg_t *ike_cfg;
128: auth_cfg_t *auth;
129: ike_cfg_create_t ike = {
130: .version = IKEV2,
131: .local = "0.0.0.0",
132: .local_port = charon->socket->get_port(charon->socket, FALSE),
133: .remote = "0.0.0.0",
134: .remote_port = IKEV2_UDP_PORT,
135: .no_certreq = TRUE,
136: };
137: peer_cfg_create_t peer = {
138: .cert_policy = CERT_SEND_IF_ASKED,
139: .unique = UNIQUE_NO,
140: .keyingtries = 1,
141: .jitter_time = 1800,
142: .over_time = 900,
143: .dpd = 60,
144: };
145: child_cfg_create_t child = {
146: .lifetime = {
147: .time = {
148: .life = create_rekey(esp_rekey) + 300,
149: .rekey = create_rekey(esp_rekey),
150: .jitter = 300
151: },
152: },
153: .mode = MODE_TUNNEL,
154: };
155:
156: VA_ARGS_VGET(args, cfg);
157:
158: /* defaults */
159: name = "unnamed";
160: local_id = NULL;
161: remote_id = NULL;
162: local_net = NULL;
163: remote_net = NULL;
164: ike_proposal = NULL;
165: esp_proposal = NULL;
166: ike_rekey = NULL;
167: esp_rekey = NULL;
168:
169: if (this->inner->enumerate(this->inner, &name, &local_id, &remote_id,
170: &ike.local, &ike.remote, &local_net, &remote_net,
171: &ike_proposal, &esp_proposal, &ike_rekey, &esp_rekey))
172: {
173:
174: DESTROY_IF(this->peer_cfg);
175: ike_cfg = ike_cfg_create(&ike);
176: ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
177: peer.rekey_time = create_rekey(ike_rekey);
178: this->peer_cfg = peer_cfg_create(name, ike_cfg, &peer);
179: auth = auth_cfg_create();
180: auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
181: auth->add(auth, AUTH_RULE_IDENTITY,
182: identification_create_from_string(local_id));
183: this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, TRUE);
184:
185: auth = auth_cfg_create();
186: auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
187: if (remote_id)
188: {
189: auth->add(auth, AUTH_RULE_IDENTITY,
190: identification_create_from_string(remote_id));
191: }
192: this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, FALSE);
193:
194: child_cfg = child_cfg_create(name, &child);
195: child_cfg->add_proposal(child_cfg, create_proposal(esp_proposal, PROTO_ESP));
196: child_cfg->add_traffic_selector(child_cfg, TRUE, create_ts(local_net));
197: child_cfg->add_traffic_selector(child_cfg, FALSE, create_ts(remote_net));
198: this->peer_cfg->add_child_cfg(this->peer_cfg, child_cfg);
199: *cfg = this->peer_cfg;
200: return TRUE;
201: }
202: return FALSE;
203: }
204:
205:
206: METHOD(enumerator_t, peer_enumerator_destroy, void,
207: peer_enumerator_t *this)
208: {
209: DESTROY_IF(this->peer_cfg);
210: this->inner->destroy(this->inner);
211: free(this);
212: }
213:
214: METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
215: private_uci_config_t *this, identification_t *me, identification_t *other)
216: {
217: peer_enumerator_t *e;
218:
219: INIT(e,
220: .public = {
221: .enumerate = enumerator_enumerate_default,
222: .venumerate = _peer_enumerator_enumerate,
223: .destroy = _peer_enumerator_destroy,
224: },
225: .inner = this->parser->create_section_enumerator(this->parser,
226: "local_id", "remote_id", "local_addr", "remote_addr",
227: "local_net", "remote_net", "ike_proposal", "esp_proposal",
228: "ike_rekey", "esp_rekey", NULL),
229: );
230: if (!e->inner)
231: {
232: free(e);
233: return NULL;
234: }
235: return &e->public;
236: }
237:
238: /**
239: * enumerator implementation for create_ike_cfg_enumerator
240: */
241: typedef struct {
242: /** implements enumerator */
243: enumerator_t public;
244: /** currently enumerated ike config */
245: ike_cfg_t *ike_cfg;
246: /** inner uci_parser section enumerator */
247: enumerator_t *inner;
248: } ike_enumerator_t;
249:
250: METHOD(enumerator_t, ike_enumerator_enumerate, bool,
251: ike_enumerator_t *this, va_list args)
252: {
253: ike_cfg_t **cfg;
254: ike_cfg_create_t ike = {
255: .version = IKEV2,
256: .local = "0.0.0.0",
257: .local_port = charon->socket->get_port(charon->socket, FALSE),
258: .remote = "0.0.0.0",
259: .remote_port = IKEV2_UDP_PORT,
260: .no_certreq = TRUE,
261: };
262: char *ike_proposal;
263:
264: VA_ARGS_VGET(args, cfg);
265:
266: /* defaults */
267: ike_proposal = NULL;
268:
269: if (this->inner->enumerate(this->inner, NULL,
270: &ike.local, &ike.remote, &ike_proposal))
271: {
272: DESTROY_IF(this->ike_cfg);
273: this->ike_cfg = ike_cfg_create(&ike);
274: this->ike_cfg->add_proposal(this->ike_cfg,
275: create_proposal(ike_proposal, PROTO_IKE));
276:
277: *cfg = this->ike_cfg;
278: return TRUE;
279: }
280: return FALSE;
281: }
282:
283: METHOD(enumerator_t, ike_enumerator_destroy, void,
284: ike_enumerator_t *this)
285: {
286: DESTROY_IF(this->ike_cfg);
287: this->inner->destroy(this->inner);
288: free(this);
289: }
290:
291: METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
292: private_uci_config_t *this, host_t *me, host_t *other)
293: {
294: ike_enumerator_t *e;
295:
296: INIT(e,
297: .public = {
298: .enumerate = enumerator_enumerate_default,
299: .venumerate = _ike_enumerator_enumerate,
300: .destroy = _ike_enumerator_destroy,
301: },
302: .inner = this->parser->create_section_enumerator(this->parser,
303: "local_addr", "remote_addr", "ike_proposal", NULL),
304: );
305: if (!e->inner)
306: {
307: free(e);
308: return NULL;
309: }
310: return &e->public;
311: }
312:
313: METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
314: private_uci_config_t *this, char *name)
315: {
316: enumerator_t *enumerator;
317: peer_cfg_t *current, *found = NULL;
318:
319: enumerator = create_peer_cfg_enumerator(this, NULL, NULL);
320: if (enumerator)
321: {
322: while (enumerator->enumerate(enumerator, ¤t))
323: {
324: if (streq(name, current->get_name(current)))
325: {
326: found = current->get_ref(current);
327: break;
328: }
329: }
330: enumerator->destroy(enumerator);
331: }
332: return found;
333: }
334:
335: METHOD(uci_config_t, destroy, void,
336: private_uci_config_t *this)
337: {
338: free(this);
339: }
340:
341: /**
342: * Described in header.
343: */
344: uci_config_t *uci_config_create(uci_parser_t *parser)
345: {
346: private_uci_config_t *this;
347:
348: INIT(this,
349: .public = {
350: .backend = {
351: .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
352: .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
353: .get_peer_cfg_by_name = _get_peer_cfg_by_name,
354: },
355: .destroy = _destroy,
356: },
357: .parser = parser,
358: );
359:
360: return &this->public;
361: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>