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