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