2 * Copyright (C) 2010-2012 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * Hochschule fuer Technik Rapperswil
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>.
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
18 #include "android_service.h"
19 #include "../charonservice.h"
20 #include "../vpnservice_builder.h"
24 #include <processing/jobs/callback_job.h>
25 #include <threading/rwlock.h>
27 typedef struct private_android_service_t private_android_service_t
;
29 #define TUN_DEFAULT_MTU 1400
32 * private data of Android service
34 struct private_android_service_t
{
39 android_service_t
public;
62 * lock to safely access the TUN device fd
67 * TUN device file descriptor
74 * Setup a new TUN device for the supplied SAs.
75 * Additional information such as DNS servers are gathered in appropriate
76 * listeners asynchronously. To be sure every required bit of information is
77 * available this should be called after the CHILD_SA has been established.
79 static bool setup_tun_device(private_android_service_t
*this,
80 ike_sa_t
*ike_sa
, child_sa_t
*child_sa
)
82 vpnservice_builder_t
*builder
;
85 DBG1(DBG_DMN
, "setting up TUN device for CHILD_SA %s{%u}",
86 child_sa
->get_name(child_sa
), child_sa
->get_reqid(child_sa
));
88 builder
= charonservice
->get_vpnservice_builder(charonservice
);
89 if (!builder
->set_mtu(builder
, TUN_DEFAULT_MTU
))
94 tunfd
= builder
->establish(builder
);
100 this->lock
->write_lock(this->lock
);
102 this->lock
->unlock(this->lock
);
104 DBG1(DBG_DMN
, "successfully created TUN device");
109 * Close the current tun device
111 static void close_tun_device(private_android_service_t
*this)
115 this->lock
->write_lock(this->lock
);
117 { /* already closed (or never created) */
118 this->lock
->unlock(this->lock
);
123 this->lock
->unlock(this->lock
);
127 METHOD(listener_t
, child_updown
, bool,
128 private_android_service_t
*this, ike_sa_t
*ike_sa
, child_sa_t
*child_sa
,
131 if (this->ike_sa
== ike_sa
)
135 /* disable the hooks registered to catch initiation failures */
136 this->public.listener
.ike_updown
= NULL
;
137 this->public.listener
.ike_state_change
= NULL
;
138 if (!setup_tun_device(this, ike_sa
, child_sa
))
140 DBG1(DBG_DMN
, "failed to setup TUN device");
141 charonservice
->update_status(charonservice
,
142 CHARONSERVICE_GENERIC_ERROR
);
146 charonservice
->update_status(charonservice
,
147 CHARONSERVICE_CHILD_STATE_UP
);
151 close_tun_device(this);
152 charonservice
->update_status(charonservice
,
153 CHARONSERVICE_CHILD_STATE_DOWN
);
160 METHOD(listener_t
, ike_updown
, bool,
161 private_android_service_t
*this, ike_sa_t
*ike_sa
, bool up
)
163 /* this callback is only registered during initiation, so if the IKE_SA
164 * goes down we assume an authentication error */
165 if (this->ike_sa
== ike_sa
&& !up
)
167 charonservice
->update_status(charonservice
,
168 CHARONSERVICE_AUTH_ERROR
);
174 METHOD(listener_t
, ike_state_change
, bool,
175 private_android_service_t
*this, ike_sa_t
*ike_sa
, ike_sa_state_t state
)
177 /* this call back is only registered during initiation */
178 if (this->ike_sa
== ike_sa
&& state
== IKE_DESTROYING
)
180 charonservice
->update_status(charonservice
,
181 CHARONSERVICE_UNREACHABLE_ERROR
);
187 METHOD(listener_t
, alert
, bool,
188 private_android_service_t
*this, ike_sa_t
*ike_sa
, alert_t alert
,
191 if (this->ike_sa
== ike_sa
)
195 case ALERT_PEER_ADDR_FAILED
:
196 charonservice
->update_status(charonservice
,
197 CHARONSERVICE_LOOKUP_ERROR
);
199 case ALERT_PEER_AUTH_FAILED
:
200 charonservice
->update_status(charonservice
,
201 CHARONSERVICE_PEER_AUTH_ERROR
);
210 METHOD(listener_t
, ike_rekey
, bool,
211 private_android_service_t
*this, ike_sa_t
*old
, ike_sa_t
*new)
213 if (this->ike_sa
== old
)
220 static job_requeue_t
initiate(private_android_service_t
*this)
222 identification_t
*gateway
, *user
;
224 peer_cfg_t
*peer_cfg
;
225 child_cfg_t
*child_cfg
;
226 traffic_selector_t
*ts
;
229 lifetime_cfg_t lifetime
= {
231 .life
= 10800, /* 3h */
232 .rekey
= 10200, /* 2h50min */
233 .jitter
= 300 /* 5min */
237 ike_cfg
= ike_cfg_create(TRUE
, TRUE
, this->local_address
, FALSE
,
238 charon
->socket
->get_port(charon
->socket
, FALSE
),
239 this->gateway
, FALSE
, IKEV2_UDP_PORT
);
240 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default(PROTO_IKE
));
242 peer_cfg
= peer_cfg_create("android", IKEV2
, ike_cfg
, CERT_SEND_IF_ASKED
,
243 UNIQUE_REPLACE
, 1, /* keyingtries */
244 36000, 0, /* rekey 10h, reauth none */
245 600, 600, /* jitter, over 10min */
246 TRUE
, FALSE
, /* mobike, aggressive */
247 0, 0, /* DPD delay, timeout */
248 host_create_from_string("0.0.0.0", 0) /* virt */,
249 NULL
, FALSE
, NULL
, NULL
); /* pool, mediation */
252 auth
= auth_cfg_create();
253 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_EAP
);
254 user
= identification_create_from_string(this->username
);
255 auth
->add(auth
, AUTH_RULE_IDENTITY
, user
);
256 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, TRUE
);
257 auth
= auth_cfg_create();
258 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PUBKEY
);
259 gateway
= identification_create_from_string(this->gateway
);
260 auth
->add(auth
, AUTH_RULE_IDENTITY
, gateway
);
261 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, FALSE
);
263 child_cfg
= child_cfg_create("android", &lifetime
, NULL
, TRUE
, MODE_TUNNEL
,
264 ACTION_NONE
, ACTION_NONE
, ACTION_NONE
, FALSE
,
265 0, 0, NULL
, NULL
, 0);
266 child_cfg
->add_proposal(child_cfg
, proposal_create_default(PROTO_ESP
));
267 ts
= traffic_selector_create_dynamic(0, 0, 65535);
268 child_cfg
->add_traffic_selector(child_cfg
, TRUE
, ts
);
269 ts
= traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE
, "0.0.0.0",
270 0, "255.255.255.255", 65535);
271 child_cfg
->add_traffic_selector(child_cfg
, FALSE
, ts
);
272 peer_cfg
->add_child_cfg(peer_cfg
, child_cfg
);
274 /* get us an IKE_SA */
275 ike_sa
= charon
->ike_sa_manager
->checkout_by_config(charon
->ike_sa_manager
,
279 peer_cfg
->destroy(peer_cfg
);
280 charonservice
->update_status(charonservice
,
281 CHARONSERVICE_GENERIC_ERROR
);
282 return JOB_REQUEUE_NONE
;
284 if (!ike_sa
->get_peer_cfg(ike_sa
))
286 ike_sa
->set_peer_cfg(ike_sa
, peer_cfg
);
288 peer_cfg
->destroy(peer_cfg
);
290 /* store the IKE_SA so we can track its progress */
291 this->ike_sa
= ike_sa
;
293 /* get an additional reference because initiate consumes one */
294 child_cfg
->get_ref(child_cfg
);
295 if (ike_sa
->initiate(ike_sa
, child_cfg
, 0, NULL
, NULL
) != SUCCESS
)
297 DBG1(DBG_CFG
, "failed to initiate tunnel");
298 charon
->ike_sa_manager
->checkin_and_destroy(charon
->ike_sa_manager
,
300 return JOB_REQUEUE_NONE
;
302 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, ike_sa
);
303 return JOB_REQUEUE_NONE
;
306 METHOD(android_service_t
, destroy
, void,
307 private_android_service_t
*this)
309 charon
->bus
->remove_listener(charon
->bus
, &this->public.listener
);
310 /* make sure the tun device is actually closed */
311 close_tun_device(this);
312 this->lock
->destroy(this->lock
);
313 free(this->local_address
);
314 free(this->username
);
322 android_service_t
*android_service_create(char *local_address
, char *gateway
,
325 private_android_service_t
*this;
330 .ike_rekey
= _ike_rekey
,
331 .ike_updown
= _ike_updown
,
332 .ike_state_change
= _ike_state_change
,
333 .child_updown
= _child_updown
,
338 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
339 .local_address
= local_address
,
340 .username
= username
,
345 charon
->bus
->add_listener(charon
->bus
, &this->public.listener
);
347 lib
->processor
->queue_job(lib
->processor
,
348 (job_t
*)callback_job_create((callback_job_cb_t
)initiate
, this,
350 return &this->public;