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
21 #include "android_service.h"
22 #include "../charonservice.h"
23 #include "../vpnservice_builder.h"
28 #include <processing/jobs/callback_job.h>
29 #include <threading/rwlock.h>
30 #include <threading/thread.h>
32 typedef struct private_android_service_t private_android_service_t
;
34 #define TUN_DEFAULT_MTU 1400
37 * private data of Android service
39 struct private_android_service_t
{
44 android_service_t
public;
49 android_creds_t
*creds
;
77 * lock to safely access the TUN device fd
82 * TUN device file descriptor
91 static void send_esp(void *data
, esp_packet_t
*packet
)
93 charon
->sender
->send_no_marker(charon
->sender
, (packet_t
*)packet
);
99 static void deliver_plain(private_android_service_t
*this,
105 encoding
= packet
->get_encoding(packet
);
107 this->lock
->read_lock(this->lock
);
109 { /* the TUN device is already closed */
110 this->lock
->unlock(this->lock
);
111 packet
->destroy(packet
);
114 len
= write(this->tunfd
, encoding
.ptr
, encoding
.len
);
115 this->lock
->unlock(this->lock
);
117 if (len
< 0 || len
!= encoding
.len
)
119 DBG1(DBG_DMN
, "failed to write packet to TUN device: %s",
122 packet
->destroy(packet
);
128 static void receiver_esp_cb(void *data
, packet_t
*packet
)
130 esp_packet_t
*esp_packet
;
132 esp_packet
= esp_packet_create_from_packet(packet
);
133 ipsec
->processor
->queue_inbound(ipsec
->processor
, esp_packet
);
137 * Job handling outbound plaintext packets
139 static job_requeue_t
handle_plain(private_android_service_t
*this)
148 /* check every second if tunfd is still valid */
154 this->lock
->read_lock(this->lock
);
156 { /* the TUN device is already closed */
157 this->lock
->unlock(this->lock
);
158 return JOB_REQUEUE_NONE
;
162 this->lock
->unlock(this->lock
);
164 old
= thread_cancelability(TRUE
);
165 len
= select(tunfd
+ 1, &set
, NULL
, NULL
, &tv
);
166 thread_cancelability(old
);
170 DBG1(DBG_DMN
, "select on TUN device failed: %s", strerror(errno
));
171 return JOB_REQUEUE_NONE
;
174 { /* timeout, check again right away */
175 return JOB_REQUEUE_DIRECT
;
178 raw
= chunk_alloc(TUN_DEFAULT_MTU
);
179 len
= read(tunfd
, raw
.ptr
, raw
.len
);
182 DBG1(DBG_DMN
, "reading from TUN device failed: %s", strerror(errno
));
184 return JOB_REQUEUE_FAIR
;
188 packet
= ip_packet_create(raw
);
191 ipsec
->processor
->queue_outbound(ipsec
->processor
, packet
);
195 DBG1(DBG_DMN
, "invalid IP packet read from TUN device");
197 return JOB_REQUEUE_DIRECT
;
201 * Add a route to the TUN device builder
203 static bool add_route(vpnservice_builder_t
*builder
, host_t
*net
,
206 /* if route is 0.0.0.0/0, split it into two routes 0.0.0.0/1 and
207 * 128.0.0.0/1 because otherwise it would conflict with the current default
209 if (net
->is_anyaddr(net
) && prefix
== 0)
213 success
= add_route(builder
, net
, 1);
214 net
= host_create_from_string("128.0.0.0", 0);
215 success
= success
&& add_route(builder
, net
, 1);
219 return builder
->add_route(builder
, net
, prefix
);
223 * Generate and set routes from installed IPsec policies
225 static bool add_routes(vpnservice_builder_t
*builder
, child_sa_t
*child_sa
)
227 traffic_selector_t
*src_ts
, *dst_ts
;
228 enumerator_t
*enumerator
;
231 enumerator
= child_sa
->create_policy_enumerator(child_sa
);
232 while (success
&& enumerator
->enumerate(enumerator
, &src_ts
, &dst_ts
))
237 dst_ts
->to_subnet(dst_ts
, &net
, &prefix
);
238 success
= add_route(builder
, net
, prefix
);
241 enumerator
->destroy(enumerator
);
246 * Setup a new TUN device for the supplied SAs, also queues a job that
247 * reads packets from this device.
248 * Additional information such as DNS servers are gathered in appropriate
249 * listeners asynchronously. To be sure every required bit of information is
250 * available this should be called after the CHILD_SA has been established.
252 static bool setup_tun_device(private_android_service_t
*this,
253 ike_sa_t
*ike_sa
, child_sa_t
*child_sa
)
255 vpnservice_builder_t
*builder
;
256 enumerator_t
*enumerator
;
257 bool vip_found
= FALSE
, already_registered
= FALSE
;
261 DBG1(DBG_DMN
, "setting up TUN device for CHILD_SA %s{%u}",
262 child_sa
->get_name(child_sa
), child_sa
->get_reqid(child_sa
));
264 builder
= charonservice
->get_vpnservice_builder(charonservice
);
266 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, TRUE
);
267 while (enumerator
->enumerate(enumerator
, &vip
))
269 if (!vip
->is_anyaddr(vip
))
271 if (!builder
->add_address(builder
, vip
))
278 enumerator
->destroy(enumerator
);
282 DBG1(DBG_DMN
, "setting up TUN device failed, no virtual IP found");
285 if (!add_routes(builder
, child_sa
) ||
286 !builder
->set_mtu(builder
, TUN_DEFAULT_MTU
))
291 tunfd
= builder
->establish(builder
);
297 this->lock
->write_lock(this->lock
);
299 { /* close previously opened TUN device */
301 already_registered
= true;
304 this->lock
->unlock(this->lock
);
306 DBG1(DBG_DMN
, "successfully created TUN device");
308 if (!already_registered
)
310 charon
->receiver
->add_esp_cb(charon
->receiver
,
311 (receiver_esp_cb_t
)receiver_esp_cb
, NULL
);
312 ipsec
->processor
->register_inbound(ipsec
->processor
,
313 (ipsec_inbound_cb_t
)deliver_plain
, this);
314 ipsec
->processor
->register_outbound(ipsec
->processor
,
315 (ipsec_outbound_cb_t
)send_esp
, NULL
);
317 lib
->processor
->queue_job(lib
->processor
,
318 (job_t
*)callback_job_create((callback_job_cb_t
)handle_plain
, this,
319 NULL
, (callback_job_cancel_t
)return_false
));
325 * Close the current tun device
327 static void close_tun_device(private_android_service_t
*this)
331 this->lock
->write_lock(this->lock
);
333 { /* already closed (or never created) */
334 this->lock
->unlock(this->lock
);
339 this->lock
->unlock(this->lock
);
341 ipsec
->processor
->unregister_outbound(ipsec
->processor
,
342 (ipsec_outbound_cb_t
)send_esp
);
343 ipsec
->processor
->unregister_inbound(ipsec
->processor
,
344 (ipsec_inbound_cb_t
)deliver_plain
);
345 charon
->receiver
->del_esp_cb(charon
->receiver
,
346 (receiver_esp_cb_t
)receiver_esp_cb
);
350 METHOD(listener_t
, child_updown
, bool,
351 private_android_service_t
*this, ike_sa_t
*ike_sa
, child_sa_t
*child_sa
,
354 if (this->ike_sa
== ike_sa
)
358 /* disable the hooks registered to catch initiation failures */
359 this->public.listener
.ike_updown
= NULL
;
360 if (!setup_tun_device(this, ike_sa
, child_sa
))
362 DBG1(DBG_DMN
, "failed to setup TUN device");
363 charonservice
->update_status(charonservice
,
364 CHARONSERVICE_GENERIC_ERROR
);
368 charonservice
->update_status(charonservice
,
369 CHARONSERVICE_CHILD_STATE_UP
);
373 if (ike_sa
->has_condition(ike_sa
, COND_REAUTHENTICATING
))
374 { /* we ignore this during reauthentication */
377 close_tun_device(this);
378 charonservice
->update_status(charonservice
,
379 CHARONSERVICE_CHILD_STATE_DOWN
);
386 METHOD(listener_t
, ike_updown
, bool,
387 private_android_service_t
*this, ike_sa_t
*ike_sa
, bool up
)
389 /* this callback is only registered during initiation, so if the IKE_SA
390 * goes down we assume an authentication error */
391 if (this->ike_sa
== ike_sa
&& !up
)
393 charonservice
->update_status(charonservice
,
394 CHARONSERVICE_AUTH_ERROR
);
400 METHOD(listener_t
, alert
, bool,
401 private_android_service_t
*this, ike_sa_t
*ike_sa
, alert_t alert
,
404 if (this->ike_sa
== ike_sa
)
408 case ALERT_PEER_ADDR_FAILED
:
409 charonservice
->update_status(charonservice
,
410 CHARONSERVICE_LOOKUP_ERROR
);
412 case ALERT_PEER_AUTH_FAILED
:
413 charonservice
->update_status(charonservice
,
414 CHARONSERVICE_PEER_AUTH_ERROR
);
416 case ALERT_PEER_INIT_UNREACHABLE
:
417 this->lock
->read_lock(this->lock
);
419 { /* only handle this if we are not reestablishing the SA */
420 charonservice
->update_status(charonservice
,
421 CHARONSERVICE_UNREACHABLE_ERROR
);
423 this->lock
->unlock(this->lock
);
432 METHOD(listener_t
, ike_rekey
, bool,
433 private_android_service_t
*this, ike_sa_t
*old
, ike_sa_t
*new)
435 if (this->ike_sa
== old
)
442 METHOD(listener_t
, ike_reestablish
, bool,
443 private_android_service_t
*this, ike_sa_t
*old
, ike_sa_t
*new)
445 if (this->ike_sa
== old
)
448 /* re-register hook to detect initiation failures */
449 this->public.listener
.ike_updown
= _ike_updown
;
450 /* the TUN device will be closed when the new CHILD_SA is established */
455 static job_requeue_t
initiate(private_android_service_t
*this)
457 identification_t
*gateway
, *user
;
459 peer_cfg_t
*peer_cfg
;
460 child_cfg_t
*child_cfg
;
461 traffic_selector_t
*ts
;
464 lifetime_cfg_t lifetime
= {
466 .life
= 10800, /* 3h */
467 .rekey
= 10200, /* 2h50min */
468 .jitter
= 300 /* 5min */
472 ike_cfg
= ike_cfg_create(IKEV2
, TRUE
, TRUE
, "0.0.0.0", FALSE
,
473 charon
->socket
->get_port(charon
->socket
, FALSE
),
474 this->gateway
, FALSE
, IKEV2_UDP_PORT
,
476 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default(PROTO_IKE
));
478 peer_cfg
= peer_cfg_create("android", ike_cfg
, CERT_SEND_IF_ASKED
,
479 UNIQUE_REPLACE
, 0, /* keyingtries */
480 36000, 0, /* rekey 10h, reauth none */
481 600, 600, /* jitter, over 10min */
482 TRUE
, FALSE
, /* mobike, aggressive */
483 0, 0, /* DPD delay, timeout */
484 FALSE
, NULL
, NULL
); /* mediation */
485 peer_cfg
->add_virtual_ip(peer_cfg
, host_create_from_string("0.0.0.0", 0));
487 /* local auth config */
488 if (streq("ikev2-eap", this->type
))
490 auth
= auth_cfg_create();
491 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_EAP
);
492 user
= identification_create_from_string(this->username
);
493 auth
->add(auth
, AUTH_RULE_IDENTITY
, user
);
495 this->creds
->add_username_password(this->creds
, this->username
,
497 memwipe(this->password
, strlen(this->password
));
498 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, TRUE
);
500 else if (streq("ikev2-cert", this->type
))
503 identification_t
*id
;
505 cert
= this->creds
->load_user_certificate(this->creds
);
508 peer_cfg
->destroy(peer_cfg
);
509 charonservice
->update_status(charonservice
,
510 CHARONSERVICE_GENERIC_ERROR
);
511 return JOB_REQUEUE_NONE
;
514 auth
= auth_cfg_create();
515 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PUBKEY
);
516 auth
->add(auth
, AUTH_RULE_SUBJECT_CERT
, cert
);
517 id
= cert
->get_subject(cert
);
518 auth
->add(auth
, AUTH_RULE_IDENTITY
, id
->clone(id
));
519 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, TRUE
);
522 /* remote auth config */
523 auth
= auth_cfg_create();
524 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PUBKEY
);
525 gateway
= identification_create_from_string(this->gateway
);
526 auth
->add(auth
, AUTH_RULE_IDENTITY
, gateway
);
527 auth
->add(auth
, AUTH_RULE_IDENTITY_LOOSE
, TRUE
);
528 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, FALSE
);
530 child_cfg
= child_cfg_create("android", &lifetime
, NULL
, TRUE
, MODE_TUNNEL
,
531 ACTION_NONE
, ACTION_RESTART
, ACTION_RESTART
,
532 FALSE
, 0, 0, NULL
, NULL
, 0);
533 /* create an ESP proposal with the algorithms currently supported by
534 * libipsec, no PFS for now */
535 child_cfg
->add_proposal(child_cfg
, proposal_create_from_string(PROTO_ESP
,
536 "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
537 ts
= traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE
, "0.0.0.0",
538 0, "255.255.255.255", 65535);
539 child_cfg
->add_traffic_selector(child_cfg
, TRUE
, ts
);
540 ts
= traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE
, "0.0.0.0",
541 0, "255.255.255.255", 65535);
542 child_cfg
->add_traffic_selector(child_cfg
, FALSE
, ts
);
543 peer_cfg
->add_child_cfg(peer_cfg
, child_cfg
);
545 /* get us an IKE_SA */
546 ike_sa
= charon
->ike_sa_manager
->checkout_by_config(charon
->ike_sa_manager
,
550 peer_cfg
->destroy(peer_cfg
);
551 charonservice
->update_status(charonservice
,
552 CHARONSERVICE_GENERIC_ERROR
);
553 return JOB_REQUEUE_NONE
;
555 if (!ike_sa
->get_peer_cfg(ike_sa
))
557 ike_sa
->set_peer_cfg(ike_sa
, peer_cfg
);
559 peer_cfg
->destroy(peer_cfg
);
561 /* store the IKE_SA so we can track its progress */
562 this->ike_sa
= ike_sa
;
564 /* get an additional reference because initiate consumes one */
565 child_cfg
->get_ref(child_cfg
);
566 if (ike_sa
->initiate(ike_sa
, child_cfg
, 0, NULL
, NULL
) != SUCCESS
)
568 DBG1(DBG_CFG
, "failed to initiate tunnel");
569 charon
->ike_sa_manager
->checkin_and_destroy(charon
->ike_sa_manager
,
571 return JOB_REQUEUE_NONE
;
573 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, ike_sa
);
574 return JOB_REQUEUE_NONE
;
577 METHOD(android_service_t
, destroy
, void,
578 private_android_service_t
*this)
580 charon
->bus
->remove_listener(charon
->bus
, &this->public.listener
);
581 /* make sure the tun device is actually closed */
582 close_tun_device(this);
583 this->lock
->destroy(this->lock
);
586 free(this->username
);
589 memwipe(this->password
, strlen(this->password
));
590 free(this->password
);
598 android_service_t
*android_service_create(android_creds_t
*creds
, char *type
,
599 char *gateway
, char *username
,
602 private_android_service_t
*this;
607 .ike_rekey
= _ike_rekey
,
608 .ike_reestablish
= _ike_reestablish
,
609 .ike_updown
= _ike_updown
,
610 .child_updown
= _child_updown
,
615 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
616 .username
= username
,
617 .password
= password
,
624 charon
->bus
->add_listener(charon
->bus
, &this->public.listener
);
626 lib
->processor
->queue_job(lib
->processor
,
627 (job_t
*)callback_job_create((callback_job_cb_t
)initiate
, this,
629 return &this->public;