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