960edbee55ac656298231d7d9de5d243047fc9ee
[strongswan.git] / src / frontends / android / jni / libandroidbridge / backend / android_service.c
1 /*
2 * Copyright (C) 2010-2014 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 "android_dns_proxy.h"
23 #include "../charonservice.h"
24 #include "../vpnservice_builder.h"
25
26 #include <daemon.h>
27 #include <library.h>
28 #include <ipsec.h>
29 #include <processing/jobs/callback_job.h>
30 #include <threading/rwlock.h>
31 #include <threading/thread.h>
32
33 typedef struct private_android_service_t private_android_service_t;
34
35 #define TUN_DEFAULT_MTU 1400
36
37 /**
38 * private data of Android service
39 */
40 struct private_android_service_t {
41
42 /**
43 * public interface
44 */
45 android_service_t public;
46
47 /**
48 * credential set
49 */
50 android_creds_t *creds;
51
52 /**
53 * current IKE_SA
54 */
55 ike_sa_t *ike_sa;
56
57 /**
58 * the type of VPN
59 */
60 char *type;
61
62 /**
63 * gateway
64 */
65 char *gateway;
66
67 /**
68 * username
69 */
70 char *username;
71
72 /**
73 * password
74 */
75 char *password;
76
77 /**
78 * lock to safely access the TUN device fd
79 */
80 rwlock_t *lock;
81
82 /**
83 * TUN device file descriptor
84 */
85 int tunfd;
86
87 /**
88 * DNS proxy
89 */
90 android_dns_proxy_t *dns_proxy;
91
92 /**
93 * Whether to use the DNS proxy or not
94 */
95 bool use_dns_proxy;
96 };
97
98 /**
99 * Outbound callback
100 */
101 static void send_esp(void *data, esp_packet_t *packet)
102 {
103 charon->sender->send_no_marker(charon->sender, (packet_t*)packet);
104 }
105
106 /**
107 * Inbound callback
108 */
109 static void deliver_plain(private_android_service_t *this,
110 ip_packet_t *packet)
111 {
112 chunk_t encoding;
113 ssize_t len;
114
115 encoding = packet->get_encoding(packet);
116
117 this->lock->read_lock(this->lock);
118 if (this->tunfd < 0)
119 { /* the TUN device is already closed */
120 this->lock->unlock(this->lock);
121 packet->destroy(packet);
122 return;
123 }
124 len = write(this->tunfd, encoding.ptr, encoding.len);
125 this->lock->unlock(this->lock);
126
127 if (len < 0 || len != encoding.len)
128 {
129 DBG1(DBG_DMN, "failed to write packet to TUN device: %s",
130 strerror(errno));
131 }
132 packet->destroy(packet);
133 }
134
135 /**
136 * Receiver callback
137 */
138 static void receiver_esp_cb(void *data, packet_t *packet)
139 {
140 esp_packet_t *esp_packet;
141
142 esp_packet = esp_packet_create_from_packet(packet);
143 ipsec->processor->queue_inbound(ipsec->processor, esp_packet);
144 }
145
146 /**
147 * Job handling outbound plaintext packets
148 */
149 static job_requeue_t handle_plain(private_android_service_t *this)
150 {
151 ip_packet_t *packet;
152 chunk_t raw;
153 fd_set set;
154 ssize_t len;
155 int tunfd;
156 bool old, dns_proxy;
157 timeval_t tv = {
158 /* check every second if tunfd is still valid */
159 .tv_sec = 1,
160 };
161
162 FD_ZERO(&set);
163
164 this->lock->read_lock(this->lock);
165 if (this->tunfd < 0)
166 { /* the TUN device is already closed */
167 this->lock->unlock(this->lock);
168 return JOB_REQUEUE_NONE;
169 }
170 tunfd = this->tunfd;
171 FD_SET(tunfd, &set);
172 /* cache this while we have the lock */
173 dns_proxy = this->use_dns_proxy;
174 this->lock->unlock(this->lock);
175
176 old = thread_cancelability(TRUE);
177 len = select(tunfd + 1, &set, NULL, NULL, &tv);
178 thread_cancelability(old);
179
180 if (len < 0)
181 {
182 if (errno == EBADF)
183 { /* the TUN device got closed just before calling select(), retry */
184 return JOB_REQUEUE_FAIR;
185 }
186 DBG1(DBG_DMN, "select on TUN device failed: %s", strerror(errno));
187 return JOB_REQUEUE_NONE;
188 }
189 else if (len == 0)
190 { /* timeout, check again right away */
191 return JOB_REQUEUE_DIRECT;
192 }
193
194 raw = chunk_alloc(TUN_DEFAULT_MTU);
195 len = read(tunfd, raw.ptr, raw.len);
196 if (len < 0)
197 {
198 DBG1(DBG_DMN, "reading from TUN device failed: %s", strerror(errno));
199 chunk_free(&raw);
200 return JOB_REQUEUE_FAIR;
201 }
202 raw.len = len;
203
204 packet = ip_packet_create(raw);
205 if (packet)
206 {
207 if (!dns_proxy || !this->dns_proxy->handle(this->dns_proxy, packet))
208 {
209 ipsec->processor->queue_outbound(ipsec->processor, packet);
210 }
211 }
212 else
213 {
214 DBG1(DBG_DMN, "invalid IP packet read from TUN device");
215 }
216 return JOB_REQUEUE_DIRECT;
217 }
218
219 /**
220 * Add a route to the TUN device builder
221 */
222 static bool add_route(vpnservice_builder_t *builder, host_t *net,
223 u_int8_t prefix)
224 {
225 /* if route is 0.0.0.0/0, split it into two routes 0.0.0.0/1 and
226 * 128.0.0.0/1 because otherwise it would conflict with the current default
227 * route. likewise for IPv6 with ::/0. */
228 if (net->is_anyaddr(net) && prefix == 0)
229 {
230 bool success;
231
232 success = add_route(builder, net, 1);
233 if (net->get_family(net) == AF_INET)
234 {
235 net = host_create_from_string("128.0.0.0", 0);
236 }
237 else
238 {
239 net = host_create_from_string("8000::", 0);
240 }
241 success = success && add_route(builder, net, 1);
242 net->destroy(net);
243 return success;
244 }
245 return builder->add_route(builder, net, prefix);
246 }
247
248 /**
249 * Generate and set routes from installed IPsec policies
250 */
251 static bool add_routes(vpnservice_builder_t *builder, child_sa_t *child_sa)
252 {
253 traffic_selector_t *src_ts, *dst_ts;
254 enumerator_t *enumerator;
255 bool success = TRUE;
256
257 enumerator = child_sa->create_policy_enumerator(child_sa);
258 while (success && enumerator->enumerate(enumerator, &src_ts, &dst_ts))
259 {
260 host_t *net;
261 u_int8_t prefix;
262
263 dst_ts->to_subnet(dst_ts, &net, &prefix);
264 success = add_route(builder, net, prefix);
265 net->destroy(net);
266 }
267 enumerator->destroy(enumerator);
268 return success;
269 }
270
271 /**
272 * Setup a new TUN device for the supplied SAs, also queues a job that
273 * reads packets from this device.
274 * Additional information such as DNS servers are gathered in appropriate
275 * listeners asynchronously. To be sure every required bit of information is
276 * available this should be called after the CHILD_SA has been established.
277 */
278 static bool setup_tun_device(private_android_service_t *this,
279 ike_sa_t *ike_sa, child_sa_t *child_sa)
280 {
281 vpnservice_builder_t *builder;
282 enumerator_t *enumerator;
283 bool vip_found = FALSE, already_registered = FALSE;
284 host_t *vip;
285 int tunfd;
286
287 DBG1(DBG_DMN, "setting up TUN device for CHILD_SA %s{%u}",
288 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa));
289
290 builder = charonservice->get_vpnservice_builder(charonservice);
291
292 enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
293 while (enumerator->enumerate(enumerator, &vip))
294 {
295 if (!vip->is_anyaddr(vip))
296 {
297 if (!builder->add_address(builder, vip))
298 {
299 break;
300 }
301 vip_found = TRUE;
302 }
303 }
304 enumerator->destroy(enumerator);
305
306 if (!vip_found)
307 {
308 DBG1(DBG_DMN, "setting up TUN device failed, no virtual IP found");
309 return FALSE;
310 }
311 if (!add_routes(builder, child_sa) ||
312 !builder->set_mtu(builder, TUN_DEFAULT_MTU))
313 {
314 return FALSE;
315 }
316
317 tunfd = builder->establish(builder);
318 if (tunfd == -1)
319 {
320 return FALSE;
321 }
322
323 this->lock->write_lock(this->lock);
324 if (this->tunfd > 0)
325 { /* close previously opened TUN device */
326 close(this->tunfd);
327 already_registered = true;
328 }
329 this->tunfd = tunfd;
330 this->lock->unlock(this->lock);
331
332 DBG1(DBG_DMN, "successfully created TUN device");
333
334 if (!already_registered)
335 {
336 charon->receiver->add_esp_cb(charon->receiver,
337 (receiver_esp_cb_t)receiver_esp_cb, NULL);
338 ipsec->processor->register_inbound(ipsec->processor,
339 (ipsec_inbound_cb_t)deliver_plain, this);
340 ipsec->processor->register_outbound(ipsec->processor,
341 (ipsec_outbound_cb_t)send_esp, NULL);
342 this->dns_proxy->register_cb(this->dns_proxy,
343 (dns_proxy_response_cb_t)deliver_plain, this);
344
345 lib->processor->queue_job(lib->processor,
346 (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this,
347 NULL, (callback_job_cancel_t)return_false));
348 }
349 return TRUE;
350 }
351
352 /**
353 * Setup a new TUN device based on the existing one, but without DNS server.
354 */
355 static bool setup_tun_device_without_dns(private_android_service_t *this)
356 {
357 vpnservice_builder_t *builder;
358 int tunfd;
359
360 DBG1(DBG_DMN, "setting up TUN device without DNS");
361
362 builder = charonservice->get_vpnservice_builder(charonservice);
363
364 tunfd = builder->establish_no_dns(builder);
365 if (tunfd == -1)
366 {
367 return FALSE;
368 }
369
370 this->lock->write_lock(this->lock);
371 if (this->tunfd > 0)
372 { /* close previously opened TUN device, this should always be the case */
373 close(this->tunfd);
374 }
375 this->tunfd = tunfd;
376 this->lock->unlock(this->lock);
377
378 DBG1(DBG_DMN, "successfully created TUN device without DNS");
379 return TRUE;
380 }
381
382 /**
383 * Close the current tun device
384 */
385 static void close_tun_device(private_android_service_t *this)
386 {
387 int tunfd;
388
389 this->lock->write_lock(this->lock);
390 if (this->tunfd < 0)
391 { /* already closed (or never created) */
392 this->lock->unlock(this->lock);
393 return;
394 }
395 tunfd = this->tunfd;
396 this->tunfd = -1;
397 this->lock->unlock(this->lock);
398
399 this->dns_proxy->unregister_cb(this->dns_proxy,
400 (dns_proxy_response_cb_t)deliver_plain);
401 ipsec->processor->unregister_outbound(ipsec->processor,
402 (ipsec_outbound_cb_t)send_esp);
403 ipsec->processor->unregister_inbound(ipsec->processor,
404 (ipsec_inbound_cb_t)deliver_plain);
405 charon->receiver->del_esp_cb(charon->receiver,
406 (receiver_esp_cb_t)receiver_esp_cb);
407 close(tunfd);
408 }
409
410 /**
411 * Terminate the IKE_SA with the given unique ID
412 */
413 CALLBACK(terminate, job_requeue_t,
414 u_int32_t *id)
415 {
416 charon->controller->terminate_ike(charon->controller, *id,
417 controller_cb_empty, NULL, 0);
418 return JOB_REQUEUE_NONE;
419 }
420
421 /**
422 * Reestablish the IKE_SA with the given unique ID
423 */
424 CALLBACK(reestablish, job_requeue_t,
425 u_int32_t *id)
426 {
427 ike_sa_t *ike_sa;
428
429 ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
430 *id, FALSE);
431 if (ike_sa)
432 {
433 if (ike_sa->reauth(ike_sa) == DESTROY_ME)
434 {
435 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
436 ike_sa);
437 }
438 else
439 {
440 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
441 }
442 }
443 return JOB_REQUEUE_NONE;
444 }
445
446 METHOD(listener_t, child_updown, bool,
447 private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
448 bool up)
449 {
450 if (this->ike_sa == ike_sa)
451 {
452 if (up)
453 {
454 /* disable the hooks registered to catch initiation failures */
455 this->public.listener.ike_updown = NULL;
456 /* CHILD_SA is up so we can disable the DNS proxy we enabled to
457 * reestablish the SA */
458 this->lock->write_lock(this->lock);
459 this->use_dns_proxy = FALSE;
460 this->lock->unlock(this->lock);
461 if (!setup_tun_device(this, ike_sa, child_sa))
462 {
463 DBG1(DBG_DMN, "failed to setup TUN device");
464 charonservice->update_status(charonservice,
465 CHARONSERVICE_GENERIC_ERROR);
466 return FALSE;
467
468 }
469 charonservice->update_status(charonservice,
470 CHARONSERVICE_CHILD_STATE_UP);
471 }
472 else
473 {
474 charonservice->update_status(charonservice,
475 CHARONSERVICE_CHILD_STATE_DOWN);
476 }
477 }
478 return TRUE;
479 }
480
481 METHOD(listener_t, ike_updown, bool,
482 private_android_service_t *this, ike_sa_t *ike_sa, bool up)
483 {
484 /* this callback is only registered during initiation, so if the IKE_SA
485 * goes down we assume some kind of authentication error, more specific
486 * errors are catched in the alert() handler */
487 if (this->ike_sa == ike_sa && !up)
488 {
489 charonservice->update_status(charonservice,
490 CHARONSERVICE_AUTH_ERROR);
491 return FALSE;
492 }
493 return TRUE;
494 }
495
496 METHOD(listener_t, alert, bool,
497 private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
498 va_list args)
499 {
500 if (this->ike_sa == ike_sa)
501 {
502 switch (alert)
503 {
504 case ALERT_PEER_ADDR_FAILED:
505 charonservice->update_status(charonservice,
506 CHARONSERVICE_LOOKUP_ERROR);
507 break;
508 case ALERT_PEER_AUTH_FAILED:
509 charonservice->update_status(charonservice,
510 CHARONSERVICE_PEER_AUTH_ERROR);
511 break;
512 case ALERT_KEEP_ON_CHILD_SA_FAILURE:
513 {
514 u_int32_t *id = malloc_thing(u_int32_t);
515
516 /* because close_ike_on_child_failure is set this is only
517 * triggered when CHILD_SA rekeying failed. reestablish it in
518 * the hope that the initial setup works again. */
519 *id = ike_sa->get_unique_id(ike_sa);
520 lib->processor->queue_job(lib->processor,
521 (job_t*)callback_job_create_with_prio(
522 (callback_job_cb_t)reestablish, id, free,
523 (callback_job_cancel_t)return_false, JOB_PRIO_HIGH));
524 break;
525 }
526 case ALERT_PEER_INIT_UNREACHABLE:
527 this->lock->read_lock(this->lock);
528 if (this->tunfd < 0)
529 {
530 u_int32_t *id = malloc_thing(u_int32_t);
531
532 /* always fail if we are not able to initiate the IKE_SA
533 * initially */
534 charonservice->update_status(charonservice,
535 CHARONSERVICE_UNREACHABLE_ERROR);
536 /* terminate the IKE_SA so no further keying tries are
537 * attempted */
538 *id = ike_sa->get_unique_id(ike_sa);
539 lib->processor->queue_job(lib->processor,
540 (job_t*)callback_job_create_with_prio(
541 (callback_job_cb_t)terminate, id, free,
542 (callback_job_cancel_t)return_false, JOB_PRIO_HIGH));
543 }
544 else
545 {
546 peer_cfg_t *peer_cfg;
547 u_int32_t tries, try;
548
549 /* when reestablishing and if keyingtries is not %forever
550 * the IKE_SA is destroyed after the set number of tries,
551 * so notify the GUI */
552 peer_cfg = ike_sa->get_peer_cfg(ike_sa);
553 tries = peer_cfg->get_keyingtries(peer_cfg);
554 try = va_arg(args, u_int32_t);
555 if (tries != 0 && try == tries-1)
556 {
557 charonservice->update_status(charonservice,
558 CHARONSERVICE_UNREACHABLE_ERROR);
559 }
560 }
561 this->lock->unlock(this->lock);
562 break;
563 default:
564 break;
565 }
566 }
567 return TRUE;
568 }
569
570 METHOD(listener_t, ike_rekey, bool,
571 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
572 {
573 if (this->ike_sa == old)
574 {
575 this->ike_sa = new;
576 }
577 return TRUE;
578 }
579
580 METHOD(listener_t, ike_reestablish_pre, bool,
581 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
582 {
583 if (this->ike_sa == old)
584 {
585 /* enable DNS proxy so hosts are properly resolved while the TUN device
586 * is still active */
587 this->lock->write_lock(this->lock);
588 this->use_dns_proxy = TRUE;
589 this->lock->unlock(this->lock);
590 /* if DNS servers are installed that are only reachable through the VPN
591 * the DNS proxy doesn't help, so uninstall DNS servers */
592 if (!setup_tun_device_without_dns(this))
593 {
594 DBG1(DBG_DMN, "failed to setup TUN device without DNS");
595 charonservice->update_status(charonservice,
596 CHARONSERVICE_GENERIC_ERROR);
597 }
598 }
599 return TRUE;
600 }
601
602 METHOD(listener_t, ike_reestablish_post, bool,
603 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
604 bool initiated)
605 {
606 if (this->ike_sa == old && initiated)
607 {
608 this->ike_sa = new;
609 /* re-register hook to detect initiation failures */
610 this->public.listener.ike_updown = _ike_updown;
611 /* if the IKE_SA got deleted by the responder we get the child_down()
612 * event on the old IKE_SA after this hook has been called, so they
613 * get ignored and thus we trigger the event here */
614 charonservice->update_status(charonservice,
615 CHARONSERVICE_CHILD_STATE_DOWN);
616 }
617 return TRUE;
618 }
619
620 static void add_auth_cfg_pw(private_android_service_t *this,
621 peer_cfg_t *peer_cfg, bool byod)
622 {
623 identification_t *user;
624 auth_cfg_t *auth;
625
626 auth = auth_cfg_create();
627 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
628 if (byod)
629 { /* use EAP-TTLS if BYOD is enabled */
630 auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TTLS);
631 }
632
633 user = identification_create_from_string(this->username);
634 auth->add(auth, AUTH_RULE_IDENTITY, user);
635
636 this->creds->add_username_password(this->creds, this->username,
637 this->password);
638 memwipe(this->password, strlen(this->password));
639 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
640 }
641
642 static bool add_auth_cfg_cert(private_android_service_t *this,
643 peer_cfg_t *peer_cfg)
644 {
645 certificate_t *cert;
646 identification_t *id;
647 auth_cfg_t *auth;
648
649 cert = this->creds->load_user_certificate(this->creds);
650 if (!cert)
651 {
652 return FALSE;
653 }
654
655 auth = auth_cfg_create();
656 if (strpfx("ikev2-eap-tls", this->type))
657 {
658 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
659 auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TLS);
660 id = identification_create_from_string("%any");
661 auth->add(auth, AUTH_RULE_AAA_IDENTITY, id);
662 }
663 else
664 {
665 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
666 }
667 auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
668
669 id = cert->get_subject(cert);
670 auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
671 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
672 return TRUE;
673 }
674
675 static job_requeue_t initiate(private_android_service_t *this)
676 {
677 identification_t *gateway;
678 ike_cfg_t *ike_cfg;
679 peer_cfg_t *peer_cfg;
680 child_cfg_t *child_cfg;
681 traffic_selector_t *ts;
682 ike_sa_t *ike_sa;
683 auth_cfg_t *auth;
684 lifetime_cfg_t lifetime = {
685 .time = {
686 .life = 3600, /* 1h */
687 .rekey = 3000, /* 50min */
688 .jitter = 300 /* 5min */
689 }
690 };
691
692 ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0",
693 charon->socket->get_port(charon->socket, FALSE),
694 this->gateway, IKEV2_UDP_PORT,
695 FRAGMENTATION_NO, 0);
696 ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
697 ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
698
699 peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
700 UNIQUE_REPLACE, 0, /* keyingtries */
701 36000, 0, /* rekey 10h, reauth none */
702 600, 600, /* jitter, over 10min */
703 TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
704 0, 0, /* DPD delay, timeout */
705 FALSE, NULL, NULL); /* mediation */
706 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET));
707 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET6));
708
709 /* local auth config */
710 if (streq("ikev2-cert", this->type) ||
711 streq("ikev2-cert-eap", this->type) ||
712 streq("ikev2-eap-tls", this->type))
713 {
714 if (!add_auth_cfg_cert(this, peer_cfg))
715 {
716 peer_cfg->destroy(peer_cfg);
717 charonservice->update_status(charonservice,
718 CHARONSERVICE_GENERIC_ERROR);
719 return JOB_REQUEUE_NONE;
720 }
721 }
722 if (streq("ikev2-eap", this->type) ||
723 streq("ikev2-cert-eap", this->type) ||
724 streq("ikev2-byod-eap", this->type))
725 {
726 add_auth_cfg_pw(this, peer_cfg, strpfx(this->type, "ikev2-byod"));
727 }
728
729 /* remote auth config */
730 auth = auth_cfg_create();
731 gateway = identification_create_from_string(this->gateway);
732 auth->add(auth, AUTH_RULE_IDENTITY, gateway);
733 auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE);
734 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
735 peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
736
737 child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
738 ACTION_NONE, ACTION_RESTART, ACTION_RESTART,
739 FALSE, 0, 0, NULL, NULL, 0);
740 /* create ESP proposals with and without DH groups, let responder decide
741 * if PFS is used */
742 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
743 "aes128gcm16-aes256gcm16-ecp256"));
744 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
745 "aes128-sha256-ecp256-modp3072"));
746 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
747 "aes256-sha384-ecp521-modp8192"));
748 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
749 "aes128-aes192-aes256-sha1-sha256-sha384-sha512-"
750 "ecp256-ecp384-ecp521-"
751 "modp2048-modp3072-modp4096-modp1024"));
752 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
753 "aes128gcm16-aes256gcm16"));
754 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
755 "aes128-sha256"));
756 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
757 "aes256-sha384"));
758 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
759 "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
760 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
761 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
762 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
763 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
764 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
765 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
766 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
767 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
768 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
769
770 /* get us an IKE_SA */
771 ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
772 peer_cfg);
773 if (!ike_sa)
774 {
775 peer_cfg->destroy(peer_cfg);
776 charonservice->update_status(charonservice,
777 CHARONSERVICE_GENERIC_ERROR);
778 return JOB_REQUEUE_NONE;
779 }
780 if (!ike_sa->get_peer_cfg(ike_sa))
781 {
782 ike_sa->set_peer_cfg(ike_sa, peer_cfg);
783 }
784 peer_cfg->destroy(peer_cfg);
785
786 /* store the IKE_SA so we can track its progress */
787 this->ike_sa = ike_sa;
788
789 /* get an additional reference because initiate consumes one */
790 child_cfg->get_ref(child_cfg);
791 if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
792 {
793 DBG1(DBG_CFG, "failed to initiate tunnel");
794 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
795 ike_sa);
796 return JOB_REQUEUE_NONE;
797 }
798 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
799 return JOB_REQUEUE_NONE;
800 }
801
802 METHOD(android_service_t, destroy, void,
803 private_android_service_t *this)
804 {
805 charon->bus->remove_listener(charon->bus, &this->public.listener);
806 /* make sure the tun device is actually closed */
807 close_tun_device(this);
808 this->dns_proxy->destroy(this->dns_proxy);
809 this->lock->destroy(this->lock);
810 free(this->type);
811 free(this->gateway);
812 free(this->username);
813 if (this->password)
814 {
815 memwipe(this->password, strlen(this->password));
816 free(this->password);
817 }
818 free(this);
819 }
820
821 /**
822 * See header
823 */
824 android_service_t *android_service_create(android_creds_t *creds, char *type,
825 char *gateway, char *username,
826 char *password)
827 {
828 private_android_service_t *this;
829
830 INIT(this,
831 .public = {
832 .listener = {
833 .ike_rekey = _ike_rekey,
834 .ike_reestablish_pre = _ike_reestablish_pre,
835 .ike_reestablish_post = _ike_reestablish_post,
836 .ike_updown = _ike_updown,
837 .child_updown = _child_updown,
838 .alert = _alert,
839 },
840 .destroy = _destroy,
841 },
842 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
843 .dns_proxy = android_dns_proxy_create(),
844 .username = username,
845 .password = password,
846 .gateway = gateway,
847 .creds = creds,
848 .type = type,
849 .tunfd = -1,
850 );
851 /* only allow queries for the VPN gateway */
852 this->dns_proxy->add_hostname(this->dns_proxy, gateway);
853
854 charon->bus->add_listener(charon->bus, &this->public.listener);
855
856 lib->processor->queue_job(lib->processor,
857 (job_t*)callback_job_create((callback_job_cb_t)initiate, this,
858 NULL, NULL));
859 return &this->public;
860 }