2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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>.
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
16 #include "ha_tunnel.h"
17 #include "ha_plugin.h"
20 #include <utils/identification.h>
21 #include <processing/jobs/callback_job.h>
23 typedef struct private_ha_tunnel_t private_ha_tunnel_t
;
24 typedef struct ha_backend_t ha_backend_t
;
25 typedef struct ha_creds_t ha_creds_t
;
28 * Serves credentials for the HA SA
33 * Implements credential_set_t
35 credential_set_t
public;
40 identification_t
*local
;
45 identification_t
*remote
;
54 * Serves configurations for the HA SA
59 * Implements backend_t
64 * peer config we serve
70 * Private data of an ha_tunnel_t object.
72 struct private_ha_tunnel_t
{
75 * Public ha_tunnel_t interface.
80 * Reqid of installed trap
90 * credential set for HA SA
95 METHOD(ha_tunnel_t
, is_sa
, bool,
96 private_ha_tunnel_t
*this, ike_sa_t
*ike_sa
)
98 peer_cfg_t
*cfg
= this->backend
.cfg
;
100 return cfg
&& ike_sa
->get_ike_cfg(ike_sa
) == cfg
->get_ike_cfg(cfg
);
104 * Enumerator over HA shared_key
107 /** Implements enumerator_t */
109 /** a single secret we serve */
113 METHOD(enumerator_t
, shared_enumerate
, bool,
114 shared_enum_t
*this, shared_key_t
**key
, id_match_t
*me
, id_match_t
*other
)
120 *me
= ID_MATCH_PERFECT
;
124 *other
= ID_MATCH_PERFECT
;
133 METHOD(ha_creds_t
, create_shared_enumerator
, enumerator_t
*,
134 ha_creds_t
*this, shared_key_type_t type
,
135 identification_t
*me
, identification_t
*other
)
137 shared_enum_t
*enumerator
;
139 if (type
!= SHARED_IKE
&& type
!= SHARED_ANY
)
143 if (me
&& !me
->equals(me
, this->local
))
147 if (other
&& !other
->equals(other
, this->remote
))
154 .enumerate
= (void*)_shared_enumerate
,
155 .destroy
= (void*)free
,
160 return &enumerator
->public;
163 METHOD(backend_t
, create_peer_cfg_enumerator
, enumerator_t
*,
164 ha_backend_t
*this, identification_t
*me
, identification_t
*other
)
166 return enumerator_create_single(this->cfg
, NULL
);
169 METHOD(backend_t
, create_ike_cfg_enumerator
, enumerator_t
*,
170 ha_backend_t
*this, host_t
*me
, host_t
*other
)
172 return enumerator_create_single(this->cfg
->get_ike_cfg(this->cfg
), NULL
);
176 * Install configs and a a trap for secured HA message exchange
178 static void setup_tunnel(private_ha_tunnel_t
*this,
179 char *local
, char *remote
, char *secret
)
181 peer_cfg_t
*peer_cfg
;
183 auth_cfg_t
*auth_cfg
;
184 child_cfg_t
*child_cfg
;
185 traffic_selector_t
*ts
;
186 lifetime_cfg_t lifetime
= {
188 .life
= 21600, .rekey
= 20400, .jitter
= 400,
192 /* setup credentials */
193 this->creds
.local
= identification_create_from_string(local
);
194 this->creds
.remote
= identification_create_from_string(remote
);
195 this->creds
.key
= shared_key_create(SHARED_IKE
,
196 chunk_clone(chunk_create(secret
, strlen(secret
))));
197 this->creds
.public.create_private_enumerator
= (void*)return_null
;
198 this->creds
.public.create_cert_enumerator
= (void*)return_null
;
199 this->creds
.public.create_shared_enumerator
= (void*)_create_shared_enumerator
;
200 this->creds
.public.create_cdp_enumerator
= (void*)return_null
;
201 this->creds
.public.cache_cert
= (void*)nop
;
203 lib
->credmgr
->add_set(lib
->credmgr
, &this->creds
.public);
205 /* create config and backend */
206 ike_cfg
= ike_cfg_create(FALSE
, FALSE
, local
, FALSE
,
207 charon
->socket
->get_port(charon
->socket
, FALSE
),
208 remote
, FALSE
, IKEV2_UDP_PORT
);
209 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default(PROTO_IKE
));
210 peer_cfg
= peer_cfg_create("ha", IKEV2
, ike_cfg
, CERT_NEVER_SEND
,
211 UNIQUE_KEEP
, 0, 86400, 0, 7200, 3600, FALSE
, FALSE
, 30,
212 0, NULL
, NULL
, FALSE
, NULL
, NULL
);
214 auth_cfg
= auth_cfg_create();
215 auth_cfg
->add(auth_cfg
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PSK
);
216 auth_cfg
->add(auth_cfg
, AUTH_RULE_IDENTITY
,
217 identification_create_from_string(local
));
218 peer_cfg
->add_auth_cfg(peer_cfg
, auth_cfg
, TRUE
);
220 auth_cfg
= auth_cfg_create();
221 auth_cfg
->add(auth_cfg
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PSK
);
222 auth_cfg
->add(auth_cfg
, AUTH_RULE_IDENTITY
,
223 identification_create_from_string(remote
));
224 peer_cfg
->add_auth_cfg(peer_cfg
, auth_cfg
, FALSE
);
226 child_cfg
= child_cfg_create("ha", &lifetime
, NULL
, TRUE
, MODE_TRANSPORT
,
227 ACTION_NONE
, ACTION_NONE
, ACTION_NONE
, FALSE
,
228 0, 0, NULL
, NULL
, 0);
229 ts
= traffic_selector_create_dynamic(IPPROTO_UDP
, HA_PORT
, HA_PORT
);
230 child_cfg
->add_traffic_selector(child_cfg
, TRUE
, ts
);
231 ts
= traffic_selector_create_dynamic(IPPROTO_ICMP
, 0, 65535);
232 child_cfg
->add_traffic_selector(child_cfg
, TRUE
, ts
);
233 ts
= traffic_selector_create_dynamic(IPPROTO_UDP
, HA_PORT
, HA_PORT
);
234 child_cfg
->add_traffic_selector(child_cfg
, FALSE
, ts
);
235 ts
= traffic_selector_create_dynamic(IPPROTO_ICMP
, 0, 65535);
236 child_cfg
->add_traffic_selector(child_cfg
, FALSE
, ts
);
237 child_cfg
->add_proposal(child_cfg
, proposal_create_default(PROTO_ESP
));
238 peer_cfg
->add_child_cfg(peer_cfg
, child_cfg
);
240 this->backend
.cfg
= peer_cfg
;
241 this->backend
.public.create_peer_cfg_enumerator
= (void*)_create_peer_cfg_enumerator
;
242 this->backend
.public.create_ike_cfg_enumerator
= (void*)_create_ike_cfg_enumerator
;
243 this->backend
.public.get_peer_cfg_by_name
= (void*)return_null
;
245 charon
->backends
->add_backend(charon
->backends
, &this->backend
.public);
247 /* install an acquiring trap */
248 this->trap
= charon
->traps
->install(charon
->traps
, peer_cfg
, child_cfg
);
251 METHOD(ha_tunnel_t
, destroy
, void,
252 private_ha_tunnel_t
*this)
254 if (this->backend
.cfg
)
256 charon
->backends
->remove_backend(charon
->backends
, &this->backend
.public);
257 this->backend
.cfg
->destroy(this->backend
.cfg
);
261 lib
->credmgr
->remove_set(lib
->credmgr
, &this->creds
.public);
262 this->creds
.key
->destroy(this->creds
.key
);
264 this->creds
.local
->destroy(this->creds
.local
);
265 this->creds
.remote
->destroy(this->creds
.remote
);
268 charon
->traps
->uninstall(charon
->traps
, this->trap
);
276 ha_tunnel_t
*ha_tunnel_create(char *local
, char *remote
, char *secret
)
278 private_ha_tunnel_t
*this;
287 setup_tunnel(this, local
, remote
, secret
);
289 return &this->public;