android: Set CHILD_STATE_DOWN whenever the CHILD_SA goes down
[strongswan.git] / src / frontends / android / jni / libandroidbridge / backend / android_service.c
1 /*
2 * Copyright (C) 2010-2013 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * 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 #include <errno.h>
19 #include <unistd.h>
20
21 #include "android_service.h"
22 #include "../charonservice.h"
23 #include "../vpnservice_builder.h"
24
25 #include <daemon.h>
26 #include <library.h>
27 #include <ipsec.h>
28 #include <processing/jobs/callback_job.h>
29 #include <threading/rwlock.h>
30 #include <threading/thread.h>
31
32 typedef struct private_android_service_t private_android_service_t;
33
34 #define TUN_DEFAULT_MTU 1400
35
36 /**
37 * private data of Android service
38 */
39 struct private_android_service_t {
40
41 /**
42 * public interface
43 */
44 android_service_t public;
45
46 /**
47 * credential set
48 */
49 android_creds_t *creds;
50
51 /**
52 * current IKE_SA
53 */
54 ike_sa_t *ike_sa;
55
56 /**
57 * the type of VPN
58 */
59 char *type;
60
61 /**
62 * gateway
63 */
64 char *gateway;
65
66 /**
67 * username
68 */
69 char *username;
70
71 /**
72 * password
73 */
74 char *password;
75
76 /**
77 * lock to safely access the TUN device fd
78 */
79 rwlock_t *lock;
80
81 /**
82 * TUN device file descriptor
83 */
84 int tunfd;
85
86 };
87
88 /**
89 * Outbound callback
90 */
91 static void send_esp(void *data, esp_packet_t *packet)
92 {
93 charon->sender->send_no_marker(charon->sender, (packet_t*)packet);
94 }
95
96 /**
97 * Inbound callback
98 */
99 static void deliver_plain(private_android_service_t *this,
100 ip_packet_t *packet)
101 {
102 chunk_t encoding;
103 ssize_t len;
104
105 encoding = packet->get_encoding(packet);
106
107 this->lock->read_lock(this->lock);
108 if (this->tunfd < 0)
109 { /* the TUN device is already closed */
110 this->lock->unlock(this->lock);
111 packet->destroy(packet);
112 return;
113 }
114 len = write(this->tunfd, encoding.ptr, encoding.len);
115 this->lock->unlock(this->lock);
116
117 if (len < 0 || len != encoding.len)
118 {
119 DBG1(DBG_DMN, "failed to write packet to TUN device: %s",
120 strerror(errno));
121 }
122 packet->destroy(packet);
123 }
124
125 /**
126 * Receiver callback
127 */
128 static void receiver_esp_cb(void *data, packet_t *packet)
129 {
130 esp_packet_t *esp_packet;
131
132 esp_packet = esp_packet_create_from_packet(packet);
133 ipsec->processor->queue_inbound(ipsec->processor, esp_packet);
134 }
135
136 /**
137 * Job handling outbound plaintext packets
138 */
139 static job_requeue_t handle_plain(private_android_service_t *this)
140 {
141 ip_packet_t *packet;
142 chunk_t raw;
143 fd_set set;
144 ssize_t len;
145 int tunfd;
146 bool old;
147 timeval_t tv = {
148 /* check every second if tunfd is still valid */
149 .tv_sec = 1,
150 };
151
152 FD_ZERO(&set);
153
154 this->lock->read_lock(this->lock);
155 if (this->tunfd < 0)
156 { /* the TUN device is already closed */
157 this->lock->unlock(this->lock);
158 return JOB_REQUEUE_NONE;
159 }
160 tunfd = this->tunfd;
161 FD_SET(tunfd, &set);
162 this->lock->unlock(this->lock);
163
164 old = thread_cancelability(TRUE);
165 len = select(tunfd + 1, &set, NULL, NULL, &tv);
166 thread_cancelability(old);
167
168 if (len < 0)
169 {
170 if (errno == EBADF)
171 { /* the TUN device got closed just before calling select(), retry */
172 return JOB_REQUEUE_FAIR;
173 }
174 DBG1(DBG_DMN, "select on TUN device failed: %s", strerror(errno));
175 return JOB_REQUEUE_NONE;
176 }
177 else if (len == 0)
178 { /* timeout, check again right away */
179 return JOB_REQUEUE_DIRECT;
180 }
181
182 raw = chunk_alloc(TUN_DEFAULT_MTU);
183 len = read(tunfd, raw.ptr, raw.len);
184 if (len < 0)
185 {
186 DBG1(DBG_DMN, "reading from TUN device failed: %s", strerror(errno));
187 chunk_free(&raw);
188 return JOB_REQUEUE_FAIR;
189 }
190 raw.len = len;
191
192 packet = ip_packet_create(raw);
193 if (packet)
194 {
195 ipsec->processor->queue_outbound(ipsec->processor, packet);
196 }
197 else
198 {
199 DBG1(DBG_DMN, "invalid IP packet read from TUN device");
200 }
201 return JOB_REQUEUE_DIRECT;
202 }
203
204 /**
205 * Add a route to the TUN device builder
206 */
207 static bool add_route(vpnservice_builder_t *builder, host_t *net,
208 u_int8_t prefix)
209 {
210 /* if route is 0.0.0.0/0, split it into two routes 0.0.0.0/1 and
211 * 128.0.0.0/1 because otherwise it would conflict with the current default
212 * route. likewise for IPv6 with ::/0. */
213 if (net->is_anyaddr(net) && prefix == 0)
214 {
215 bool success;
216
217 success = add_route(builder, net, 1);
218 if (net->get_family(net) == AF_INET)
219 {
220 net = host_create_from_string("128.0.0.0", 0);
221 }
222 else
223 {
224 net = host_create_from_string("8000::", 0);
225 }
226 success = success && add_route(builder, net, 1);
227 net->destroy(net);
228 return success;
229 }
230 return builder->add_route(builder, net, prefix);
231 }
232
233 /**
234 * Generate and set routes from installed IPsec policies
235 */
236 static bool add_routes(vpnservice_builder_t *builder, child_sa_t *child_sa)
237 {
238 traffic_selector_t *src_ts, *dst_ts;
239 enumerator_t *enumerator;
240 bool success = TRUE;
241
242 enumerator = child_sa->create_policy_enumerator(child_sa);
243 while (success && enumerator->enumerate(enumerator, &src_ts, &dst_ts))
244 {
245 host_t *net;
246 u_int8_t prefix;
247
248 dst_ts->to_subnet(dst_ts, &net, &prefix);
249 success = add_route(builder, net, prefix);
250 net->destroy(net);
251 }
252 enumerator->destroy(enumerator);
253 return success;
254 }
255
256 /**
257 * Setup a new TUN device for the supplied SAs, also queues a job that
258 * reads packets from this device.
259 * Additional information such as DNS servers are gathered in appropriate
260 * listeners asynchronously. To be sure every required bit of information is
261 * available this should be called after the CHILD_SA has been established.
262 */
263 static bool setup_tun_device(private_android_service_t *this,
264 ike_sa_t *ike_sa, child_sa_t *child_sa)
265 {
266 vpnservice_builder_t *builder;
267 enumerator_t *enumerator;
268 bool vip_found = FALSE, already_registered = FALSE;
269 host_t *vip;
270 int tunfd;
271
272 DBG1(DBG_DMN, "setting up TUN device for CHILD_SA %s{%u}",
273 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa));
274
275 builder = charonservice->get_vpnservice_builder(charonservice);
276
277 enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
278 while (enumerator->enumerate(enumerator, &vip))
279 {
280 if (!vip->is_anyaddr(vip))
281 {
282 if (!builder->add_address(builder, vip))
283 {
284 break;
285 }
286 vip_found = TRUE;
287 }
288 }
289 enumerator->destroy(enumerator);
290
291 if (!vip_found)
292 {
293 DBG1(DBG_DMN, "setting up TUN device failed, no virtual IP found");
294 return FALSE;
295 }
296 if (!add_routes(builder, child_sa) ||
297 !builder->set_mtu(builder, TUN_DEFAULT_MTU))
298 {
299 return FALSE;
300 }
301
302 tunfd = builder->establish(builder);
303 if (tunfd == -1)
304 {
305 return FALSE;
306 }
307
308 this->lock->write_lock(this->lock);
309 if (this->tunfd > 0)
310 { /* close previously opened TUN device */
311 close(this->tunfd);
312 already_registered = true;
313 }
314 this->tunfd = tunfd;
315 this->lock->unlock(this->lock);
316
317 DBG1(DBG_DMN, "successfully created TUN device");
318
319 if (!already_registered)
320 {
321 charon->receiver->add_esp_cb(charon->receiver,
322 (receiver_esp_cb_t)receiver_esp_cb, NULL);
323 ipsec->processor->register_inbound(ipsec->processor,
324 (ipsec_inbound_cb_t)deliver_plain, this);
325 ipsec->processor->register_outbound(ipsec->processor,
326 (ipsec_outbound_cb_t)send_esp, NULL);
327
328 lib->processor->queue_job(lib->processor,
329 (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this,
330 NULL, (callback_job_cancel_t)return_false));
331 }
332 return TRUE;
333 }
334
335 /**
336 * Close the current tun device
337 */
338 static void close_tun_device(private_android_service_t *this)
339 {
340 int tunfd;
341
342 this->lock->write_lock(this->lock);
343 if (this->tunfd < 0)
344 { /* already closed (or never created) */
345 this->lock->unlock(this->lock);
346 return;
347 }
348 tunfd = this->tunfd;
349 this->tunfd = -1;
350 this->lock->unlock(this->lock);
351
352 ipsec->processor->unregister_outbound(ipsec->processor,
353 (ipsec_outbound_cb_t)send_esp);
354 ipsec->processor->unregister_inbound(ipsec->processor,
355 (ipsec_inbound_cb_t)deliver_plain);
356 charon->receiver->del_esp_cb(charon->receiver,
357 (receiver_esp_cb_t)receiver_esp_cb);
358 close(tunfd);
359 }
360
361 METHOD(listener_t, child_updown, bool,
362 private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
363 bool up)
364 {
365 if (this->ike_sa == ike_sa)
366 {
367 if (up)
368 {
369 /* disable the hooks registered to catch initiation failures */
370 this->public.listener.ike_updown = NULL;
371 if (!setup_tun_device(this, ike_sa, child_sa))
372 {
373 DBG1(DBG_DMN, "failed to setup TUN device");
374 charonservice->update_status(charonservice,
375 CHARONSERVICE_GENERIC_ERROR);
376 return FALSE;
377
378 }
379 charonservice->update_status(charonservice,
380 CHARONSERVICE_CHILD_STATE_UP);
381 }
382 else
383 {
384 charonservice->update_status(charonservice,
385 CHARONSERVICE_CHILD_STATE_DOWN);
386 }
387 }
388 return TRUE;
389 }
390
391 METHOD(listener_t, ike_updown, bool,
392 private_android_service_t *this, ike_sa_t *ike_sa, bool up)
393 {
394 /* this callback is only registered during initiation, so if the IKE_SA
395 * goes down we assume an authentication error */
396 if (this->ike_sa == ike_sa && !up)
397 {
398 charonservice->update_status(charonservice,
399 CHARONSERVICE_AUTH_ERROR);
400 return FALSE;
401 }
402 return TRUE;
403 }
404
405 METHOD(listener_t, alert, bool,
406 private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
407 va_list args)
408 {
409 if (this->ike_sa == ike_sa)
410 {
411 switch (alert)
412 {
413 case ALERT_PEER_ADDR_FAILED:
414 charonservice->update_status(charonservice,
415 CHARONSERVICE_LOOKUP_ERROR);
416 break;
417 case ALERT_PEER_AUTH_FAILED:
418 charonservice->update_status(charonservice,
419 CHARONSERVICE_PEER_AUTH_ERROR);
420 break;
421 case ALERT_PEER_INIT_UNREACHABLE:
422 this->lock->read_lock(this->lock);
423 if (this->tunfd < 0)
424 { /* only handle this if we are not reestablishing the SA */
425 charonservice->update_status(charonservice,
426 CHARONSERVICE_UNREACHABLE_ERROR);
427 }
428 this->lock->unlock(this->lock);
429 break;
430 default:
431 break;
432 }
433 }
434 return TRUE;
435 }
436
437 METHOD(listener_t, ike_rekey, bool,
438 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
439 {
440 if (this->ike_sa == old)
441 {
442 this->ike_sa = new;
443 }
444 return TRUE;
445 }
446
447 METHOD(listener_t, ike_reestablish, bool,
448 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
449 {
450 if (this->ike_sa == old)
451 {
452 this->ike_sa = new;
453 /* re-register hook to detect initiation failures */
454 this->public.listener.ike_updown = _ike_updown;
455 /* the TUN device will be closed when the new CHILD_SA is established */
456 }
457 return TRUE;
458 }
459
460 static void add_auth_cfg_eap(private_android_service_t *this,
461 peer_cfg_t *peer_cfg, bool byod)
462 {
463 identification_t *user;
464 auth_cfg_t *auth;
465
466 auth = auth_cfg_create();
467 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
468 if (byod)
469 { /* use EAP-TTLS if BYOD is enabled */
470 auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TTLS);
471 }
472
473 user = identification_create_from_string(this->username);
474 auth->add(auth, AUTH_RULE_IDENTITY, user);
475
476 this->creds->add_username_password(this->creds, this->username,
477 this->password);
478 memwipe(this->password, strlen(this->password));
479 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
480 }
481
482 static bool add_auth_cfg_cert(private_android_service_t *this,
483 peer_cfg_t *peer_cfg)
484 {
485 certificate_t *cert;
486 identification_t *id;
487 auth_cfg_t *auth;
488
489 cert = this->creds->load_user_certificate(this->creds);
490 if (!cert)
491 {
492 return FALSE;
493 }
494
495 auth = auth_cfg_create();
496 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
497 auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
498
499 id = cert->get_subject(cert);
500 auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
501 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
502 return TRUE;
503 }
504
505 static job_requeue_t initiate(private_android_service_t *this)
506 {
507 identification_t *gateway;
508 ike_cfg_t *ike_cfg;
509 peer_cfg_t *peer_cfg;
510 child_cfg_t *child_cfg;
511 traffic_selector_t *ts;
512 ike_sa_t *ike_sa;
513 auth_cfg_t *auth;
514 lifetime_cfg_t lifetime = {
515 .time = {
516 .life = 10800, /* 3h */
517 .rekey = 10200, /* 2h50min */
518 .jitter = 300 /* 5min */
519 }
520 };
521
522 ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0",
523 charon->socket->get_port(charon->socket, FALSE),
524 this->gateway, IKEV2_UDP_PORT,
525 FRAGMENTATION_NO, 0);
526 ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
527 ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
528
529 peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
530 UNIQUE_REPLACE, 0, /* keyingtries */
531 36000, 0, /* rekey 10h, reauth none */
532 600, 600, /* jitter, over 10min */
533 TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
534 0, 0, /* DPD delay, timeout */
535 FALSE, NULL, NULL); /* mediation */
536 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET));
537 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET6));
538
539 /* local auth config */
540 if (streq("ikev2-cert", this->type) ||
541 streq("ikev2-cert-eap", this->type))
542 {
543 if (!add_auth_cfg_cert(this, peer_cfg))
544 {
545 peer_cfg->destroy(peer_cfg);
546 charonservice->update_status(charonservice,
547 CHARONSERVICE_GENERIC_ERROR);
548 return JOB_REQUEUE_NONE;
549 }
550 }
551 if (streq("ikev2-eap", this->type) ||
552 streq("ikev2-cert-eap", this->type) ||
553 streq("ikev2-byod-eap", this->type))
554 {
555 add_auth_cfg_eap(this, peer_cfg, strpfx(this->type, "ikev2-byod"));
556 }
557
558 /* remote auth config */
559 auth = auth_cfg_create();
560 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
561 gateway = identification_create_from_string(this->gateway);
562 auth->add(auth, AUTH_RULE_IDENTITY, gateway);
563 auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE);
564 peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
565
566 child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
567 ACTION_NONE, ACTION_RESTART, ACTION_RESTART,
568 FALSE, 0, 0, NULL, NULL, 0);
569 /* create an ESP proposal with the algorithms currently supported by
570 * libipsec, no PFS for now */
571 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
572 "aes128gcm16-aes256gcm16"));
573 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
574 "aes128-sha256"));
575 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
576 "aes256-sha384"));
577 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
578 "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
579 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
580 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
581 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
582 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
583 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
584 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
585 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
586 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
587 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
588
589 /* get us an IKE_SA */
590 ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
591 peer_cfg);
592 if (!ike_sa)
593 {
594 peer_cfg->destroy(peer_cfg);
595 charonservice->update_status(charonservice,
596 CHARONSERVICE_GENERIC_ERROR);
597 return JOB_REQUEUE_NONE;
598 }
599 if (!ike_sa->get_peer_cfg(ike_sa))
600 {
601 ike_sa->set_peer_cfg(ike_sa, peer_cfg);
602 }
603 peer_cfg->destroy(peer_cfg);
604
605 /* store the IKE_SA so we can track its progress */
606 this->ike_sa = ike_sa;
607
608 /* get an additional reference because initiate consumes one */
609 child_cfg->get_ref(child_cfg);
610 if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
611 {
612 DBG1(DBG_CFG, "failed to initiate tunnel");
613 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
614 ike_sa);
615 return JOB_REQUEUE_NONE;
616 }
617 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
618 return JOB_REQUEUE_NONE;
619 }
620
621 METHOD(android_service_t, destroy, void,
622 private_android_service_t *this)
623 {
624 charon->bus->remove_listener(charon->bus, &this->public.listener);
625 /* make sure the tun device is actually closed */
626 close_tun_device(this);
627 this->lock->destroy(this->lock);
628 free(this->type);
629 free(this->gateway);
630 free(this->username);
631 if (this->password)
632 {
633 memwipe(this->password, strlen(this->password));
634 free(this->password);
635 }
636 free(this);
637 }
638
639 /**
640 * See header
641 */
642 android_service_t *android_service_create(android_creds_t *creds, char *type,
643 char *gateway, char *username,
644 char *password)
645 {
646 private_android_service_t *this;
647
648 INIT(this,
649 .public = {
650 .listener = {
651 .ike_rekey = _ike_rekey,
652 .ike_reestablish = _ike_reestablish,
653 .ike_updown = _ike_updown,
654 .child_updown = _child_updown,
655 .alert = _alert,
656 },
657 .destroy = _destroy,
658 },
659 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
660 .username = username,
661 .password = password,
662 .gateway = gateway,
663 .creds = creds,
664 .type = type,
665 .tunfd = -1,
666 );
667
668 charon->bus->add_listener(charon->bus, &this->public.listener);
669
670 lib->processor->queue_job(lib->processor,
671 (job_t*)callback_job_create((callback_job_cb_t)initiate, this,
672 NULL, NULL));
673 return &this->public;
674 }