Annotation of embedaddon/strongswan/src/libcharon/plugins/ha/ha_tunnel.c, revision 1.1.1.2
1.1 misho 1: /*
2: * Copyright (C) 2009 Martin Willi
3: * HSR Hochschule fuer Technik Rapperswil
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 "ha_tunnel.h"
17: #include "ha_plugin.h"
18:
19: #include <daemon.h>
20: #include <utils/identification.h>
21: #include <processing/jobs/callback_job.h>
22:
23: #define HA_CFG_NAME "ha"
24:
25: typedef struct private_ha_tunnel_t private_ha_tunnel_t;
26: typedef struct ha_backend_t ha_backend_t;
27: typedef struct ha_creds_t ha_creds_t;
28:
29: /**
30: * Serves credentials for the HA SA
31: */
32: struct ha_creds_t {
33:
34: /**
35: * Implements credential_set_t
36: */
37: credential_set_t public;
38:
39: /**
40: * own identity
41: */
42: identification_t *local;
43:
44: /**
45: * peer identity
46: */
47: identification_t *remote;
48:
49: /**
50: * Shared key to serve
51: */
52: shared_key_t *key;
53: };
54:
55: /**
56: * Serves configurations for the HA SA
57: */
58: struct ha_backend_t {
59:
60: /**
61: * Implements backend_t
62: */
63: backend_t public;
64:
65: /**
66: * peer config we serve
67: */
68: peer_cfg_t *cfg;
69: };
70:
71: /**
72: * Private data of an ha_tunnel_t object.
73: */
74: struct private_ha_tunnel_t {
75:
76: /**
77: * Public ha_tunnel_t interface.
78: */
79: ha_tunnel_t public;
80:
81: /**
82: * Reqid of installed trap
83: */
84: uint32_t trap;
85:
86: /**
87: * backend for HA SA
88: */
89: ha_backend_t backend;
90:
91: /**
92: * credential set for HA SA
93: */
94: ha_creds_t creds;
95: };
96:
97: METHOD(ha_tunnel_t, is_sa, bool,
98: private_ha_tunnel_t *this, ike_sa_t *ike_sa)
99: {
100: peer_cfg_t *cfg = this->backend.cfg;
101:
102: return cfg && ike_sa->get_ike_cfg(ike_sa) == cfg->get_ike_cfg(cfg);
103: }
104:
105: /**
106: * Enumerator over HA shared_key
107: */
108: typedef struct {
109: /** Implements enumerator_t */
110: enumerator_t public;
111: /** a single secret we serve */
112: shared_key_t *key;
113: } shared_enum_t;
114:
115: METHOD(enumerator_t, shared_enumerate, bool,
116: shared_enum_t *this, va_list args)
117: {
118: shared_key_t **key;
119: id_match_t *me, *other;
120:
121: VA_ARGS_VGET(args, key, me, other);
122: if (this->key)
123: {
124: if (me)
125: {
126: *me = ID_MATCH_PERFECT;
127: }
128: if (other)
129: {
130: *other = ID_MATCH_PERFECT;
131: }
132: *key = this->key;
133: this->key = NULL;
134: return TRUE;
135: }
136: return FALSE;
137: }
138:
139: METHOD(ha_creds_t, create_shared_enumerator, enumerator_t*,
140: ha_creds_t *this, shared_key_type_t type,
141: identification_t *me, identification_t *other)
142: {
143: shared_enum_t *enumerator;
144:
145: if (type != SHARED_IKE && type != SHARED_ANY)
146: {
147: return NULL;
148: }
149: if (me && !me->equals(me, this->local))
150: {
151: return NULL;
152: }
153: if (other && !other->equals(other, this->remote))
154: {
155: return NULL;
156: }
157:
158: INIT(enumerator,
159: .public = {
160: .enumerate = enumerator_enumerate_default,
161: .venumerate = _shared_enumerate,
162: .destroy = (void*)free,
163: },
164: .key = this->key,
165: );
166:
167: return &enumerator->public;
168: }
169:
170: METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
171: ha_backend_t *this, identification_t *me, identification_t *other)
172: {
173: return enumerator_create_single(this->cfg, NULL);
174: }
175:
176: METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
177: ha_backend_t *this, host_t *me, host_t *other)
178: {
179: return enumerator_create_single(this->cfg->get_ike_cfg(this->cfg), NULL);
180: }
181:
182: /**
183: * Install configs and a a trap for secured HA message exchange
184: */
185: static void setup_tunnel(private_ha_tunnel_t *this,
186: char *local, char *remote, char *secret)
187: {
188: peer_cfg_t *peer_cfg;
189: ike_cfg_t *ike_cfg;
190: auth_cfg_t *auth_cfg;
191: child_cfg_t *child_cfg;
192: traffic_selector_t *ts;
193: ike_cfg_create_t ike = {
194: .version = IKEV2,
195: .local = local,
196: .local_port = charon->socket->get_port(charon->socket, FALSE),
197: .remote = remote,
198: .remote_port = IKEV2_UDP_PORT,
199: .no_certreq = TRUE,
200: };
201: peer_cfg_create_t peer = {
202: .cert_policy = CERT_NEVER_SEND,
203: .unique = UNIQUE_KEEP,
204: .rekey_time = 86400, /* 24h */
205: .jitter_time = 7200, /* 2h */
206: .over_time = 3600, /* 1h */
207: .no_mobike = TRUE,
208: .dpd = 30,
209: };
210: child_cfg_create_t child = {
211: .lifetime = {
212: .time = {
213: .life = 21600, .rekey = 20400, .jitter = 400,
214: },
215: },
216: .mode = MODE_TRANSPORT,
217: };
218:
219: /* setup credentials */
220: this->creds.local = identification_create_from_string(local);
221: this->creds.remote = identification_create_from_string(remote);
222: this->creds.key = shared_key_create(SHARED_IKE,
223: chunk_clone(chunk_create(secret, strlen(secret))));
224: this->creds.public.create_private_enumerator = (void*)return_null;
225: this->creds.public.create_cert_enumerator = (void*)return_null;
226: this->creds.public.create_shared_enumerator = (void*)_create_shared_enumerator;
227: this->creds.public.create_cdp_enumerator = (void*)return_null;
228: this->creds.public.cache_cert = (void*)nop;
229:
230: lib->credmgr->add_set(lib->credmgr, &this->creds.public);
231:
232: /* create config and backend */
233: ike_cfg = ike_cfg_create(&ike);
234: ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
235: ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
236: peer_cfg = peer_cfg_create(HA_CFG_NAME, ike_cfg, &peer);
237:
238: auth_cfg = auth_cfg_create();
239: auth_cfg->add(auth_cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
240: auth_cfg->add(auth_cfg, AUTH_RULE_IDENTITY,
241: identification_create_from_string(local));
242: peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
243:
244: auth_cfg = auth_cfg_create();
245: auth_cfg->add(auth_cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
246: auth_cfg->add(auth_cfg, AUTH_RULE_IDENTITY,
247: identification_create_from_string(remote));
248: peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
249:
250: child_cfg = child_cfg_create(HA_CFG_NAME, &child);
251: ts = traffic_selector_create_dynamic(IPPROTO_UDP, HA_PORT, HA_PORT);
252: child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
253: ts = traffic_selector_create_dynamic(IPPROTO_ICMP, 0, 65535);
254: child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
255: ts = traffic_selector_create_dynamic(IPPROTO_UDP, HA_PORT, HA_PORT);
256: child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
257: ts = traffic_selector_create_dynamic(IPPROTO_ICMP, 0, 65535);
258: child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
259: child_cfg->add_proposal(child_cfg, proposal_create_default_aead(PROTO_ESP));
1.1.1.2 ! misho 260: child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
1.1 misho 261: peer_cfg->add_child_cfg(peer_cfg, child_cfg);
262:
263: this->backend.cfg = peer_cfg;
264: this->backend.public.create_peer_cfg_enumerator = (void*)_create_peer_cfg_enumerator;
265: this->backend.public.create_ike_cfg_enumerator = (void*)_create_ike_cfg_enumerator;
266: this->backend.public.get_peer_cfg_by_name = (void*)return_null;
267:
268: charon->backends->add_backend(charon->backends, &this->backend.public);
269:
270: /* install an acquiring trap */
271: charon->traps->install(charon->traps, peer_cfg, child_cfg);
272: }
273:
274: METHOD(ha_tunnel_t, destroy, void,
275: private_ha_tunnel_t *this)
276: {
277: if (this->backend.cfg)
278: {
279: charon->backends->remove_backend(charon->backends, &this->backend.public);
280: this->backend.cfg->destroy(this->backend.cfg);
281: }
282: if (this->creds.key)
283: {
284: lib->credmgr->remove_set(lib->credmgr, &this->creds.public);
285: this->creds.key->destroy(this->creds.key);
286: }
287: this->creds.local->destroy(this->creds.local);
288: this->creds.remote->destroy(this->creds.remote);
289: charon->traps->uninstall(charon->traps, HA_CFG_NAME, HA_CFG_NAME);
290: free(this);
291: }
292:
293: /**
294: * See header
295: */
296: ha_tunnel_t *ha_tunnel_create(char *local, char *remote, char *secret)
297: {
298: private_ha_tunnel_t *this;
299:
300: INIT(this,
301: .public = {
302: .is_sa = _is_sa,
303: .destroy = _destroy,
304: },
305: );
306:
307: setup_tunnel(this, local, remote, secret);
308:
309: return &this->public;
310: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>