ike-sa-manager: Remove IKE_SA checkout by CHILD_SA reqid
[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, *id);
430 if (ike_sa)
431 {
432 if (ike_sa->reauth(ike_sa) == DESTROY_ME)
433 {
434 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
435 ike_sa);
436 }
437 else
438 {
439 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
440 }
441 }
442 return JOB_REQUEUE_NONE;
443 }
444
445 METHOD(listener_t, child_updown, bool,
446 private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
447 bool up)
448 {
449 if (this->ike_sa == ike_sa)
450 {
451 if (up)
452 {
453 /* disable the hooks registered to catch initiation failures */
454 this->public.listener.ike_updown = NULL;
455 /* CHILD_SA is up so we can disable the DNS proxy we enabled to
456 * reestablish the SA */
457 this->lock->write_lock(this->lock);
458 this->use_dns_proxy = FALSE;
459 this->lock->unlock(this->lock);
460 if (!setup_tun_device(this, ike_sa, child_sa))
461 {
462 DBG1(DBG_DMN, "failed to setup TUN device");
463 charonservice->update_status(charonservice,
464 CHARONSERVICE_GENERIC_ERROR);
465 return FALSE;
466
467 }
468 charonservice->update_status(charonservice,
469 CHARONSERVICE_CHILD_STATE_UP);
470 }
471 else
472 {
473 charonservice->update_status(charonservice,
474 CHARONSERVICE_CHILD_STATE_DOWN);
475 }
476 }
477 return TRUE;
478 }
479
480 METHOD(listener_t, ike_updown, bool,
481 private_android_service_t *this, ike_sa_t *ike_sa, bool up)
482 {
483 /* this callback is only registered during initiation, so if the IKE_SA
484 * goes down we assume some kind of authentication error, more specific
485 * errors are catched in the alert() handler */
486 if (this->ike_sa == ike_sa && !up)
487 {
488 charonservice->update_status(charonservice,
489 CHARONSERVICE_AUTH_ERROR);
490 return FALSE;
491 }
492 return TRUE;
493 }
494
495 METHOD(listener_t, alert, bool,
496 private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
497 va_list args)
498 {
499 if (this->ike_sa == ike_sa)
500 {
501 switch (alert)
502 {
503 case ALERT_PEER_ADDR_FAILED:
504 charonservice->update_status(charonservice,
505 CHARONSERVICE_LOOKUP_ERROR);
506 break;
507 case ALERT_PEER_AUTH_FAILED:
508 charonservice->update_status(charonservice,
509 CHARONSERVICE_PEER_AUTH_ERROR);
510 break;
511 case ALERT_KEEP_ON_CHILD_SA_FAILURE:
512 {
513 u_int32_t *id = malloc_thing(u_int32_t);
514
515 /* because close_ike_on_child_failure is set this is only
516 * triggered when CHILD_SA rekeying failed. reestablish it in
517 * the hope that the initial setup works again. */
518 *id = ike_sa->get_unique_id(ike_sa);
519 lib->processor->queue_job(lib->processor,
520 (job_t*)callback_job_create_with_prio(
521 (callback_job_cb_t)reestablish, id, free,
522 (callback_job_cancel_t)return_false, JOB_PRIO_HIGH));
523 break;
524 }
525 case ALERT_PEER_INIT_UNREACHABLE:
526 this->lock->read_lock(this->lock);
527 if (this->tunfd < 0)
528 {
529 u_int32_t *id = malloc_thing(u_int32_t);
530
531 /* always fail if we are not able to initiate the IKE_SA
532 * initially */
533 charonservice->update_status(charonservice,
534 CHARONSERVICE_UNREACHABLE_ERROR);
535 /* terminate the IKE_SA so no further keying tries are
536 * attempted */
537 *id = ike_sa->get_unique_id(ike_sa);
538 lib->processor->queue_job(lib->processor,
539 (job_t*)callback_job_create_with_prio(
540 (callback_job_cb_t)terminate, id, free,
541 (callback_job_cancel_t)return_false, JOB_PRIO_HIGH));
542 }
543 else
544 {
545 peer_cfg_t *peer_cfg;
546 u_int32_t tries, try;
547
548 /* when reestablishing and if keyingtries is not %forever
549 * the IKE_SA is destroyed after the set number of tries,
550 * so notify the GUI */
551 peer_cfg = ike_sa->get_peer_cfg(ike_sa);
552 tries = peer_cfg->get_keyingtries(peer_cfg);
553 try = va_arg(args, u_int32_t);
554 if (tries != 0 && try == tries-1)
555 {
556 charonservice->update_status(charonservice,
557 CHARONSERVICE_UNREACHABLE_ERROR);
558 }
559 }
560 this->lock->unlock(this->lock);
561 break;
562 default:
563 break;
564 }
565 }
566 return TRUE;
567 }
568
569 METHOD(listener_t, ike_rekey, bool,
570 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
571 {
572 if (this->ike_sa == old)
573 {
574 this->ike_sa = new;
575 }
576 return TRUE;
577 }
578
579 METHOD(listener_t, ike_reestablish_pre, bool,
580 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
581 {
582 if (this->ike_sa == old)
583 {
584 /* enable DNS proxy so hosts are properly resolved while the TUN device
585 * is still active */
586 this->lock->write_lock(this->lock);
587 this->use_dns_proxy = TRUE;
588 this->lock->unlock(this->lock);
589 /* if DNS servers are installed that are only reachable through the VPN
590 * the DNS proxy doesn't help, so uninstall DNS servers */
591 if (!setup_tun_device_without_dns(this))
592 {
593 DBG1(DBG_DMN, "failed to setup TUN device without DNS");
594 charonservice->update_status(charonservice,
595 CHARONSERVICE_GENERIC_ERROR);
596 }
597 }
598 return TRUE;
599 }
600
601 METHOD(listener_t, ike_reestablish_post, bool,
602 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
603 bool initiated)
604 {
605 if (this->ike_sa == old && initiated)
606 {
607 this->ike_sa = new;
608 /* re-register hook to detect initiation failures */
609 this->public.listener.ike_updown = _ike_updown;
610 /* if the IKE_SA got deleted by the responder we get the child_down()
611 * event on the old IKE_SA after this hook has been called, so they
612 * get ignored and thus we trigger the event here */
613 charonservice->update_status(charonservice,
614 CHARONSERVICE_CHILD_STATE_DOWN);
615 }
616 return TRUE;
617 }
618
619 static void add_auth_cfg_pw(private_android_service_t *this,
620 peer_cfg_t *peer_cfg, bool byod)
621 {
622 identification_t *user;
623 auth_cfg_t *auth;
624
625 auth = auth_cfg_create();
626 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
627 if (byod)
628 { /* use EAP-TTLS if BYOD is enabled */
629 auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TTLS);
630 }
631
632 user = identification_create_from_string(this->username);
633 auth->add(auth, AUTH_RULE_IDENTITY, user);
634
635 this->creds->add_username_password(this->creds, this->username,
636 this->password);
637 memwipe(this->password, strlen(this->password));
638 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
639 }
640
641 static bool add_auth_cfg_cert(private_android_service_t *this,
642 peer_cfg_t *peer_cfg)
643 {
644 certificate_t *cert;
645 identification_t *id;
646 auth_cfg_t *auth;
647
648 cert = this->creds->load_user_certificate(this->creds);
649 if (!cert)
650 {
651 return FALSE;
652 }
653
654 auth = auth_cfg_create();
655 if (strpfx("ikev2-eap-tls", this->type))
656 {
657 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
658 auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TLS);
659 id = identification_create_from_string("%any");
660 auth->add(auth, AUTH_RULE_AAA_IDENTITY, id);
661 }
662 else
663 {
664 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
665 }
666 auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
667
668 id = cert->get_subject(cert);
669 auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
670 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
671 return TRUE;
672 }
673
674 static job_requeue_t initiate(private_android_service_t *this)
675 {
676 identification_t *gateway;
677 ike_cfg_t *ike_cfg;
678 peer_cfg_t *peer_cfg;
679 child_cfg_t *child_cfg;
680 traffic_selector_t *ts;
681 ike_sa_t *ike_sa;
682 auth_cfg_t *auth;
683 lifetime_cfg_t lifetime = {
684 .time = {
685 .life = 3600, /* 1h */
686 .rekey = 3000, /* 50min */
687 .jitter = 300 /* 5min */
688 }
689 };
690
691 ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0",
692 charon->socket->get_port(charon->socket, FALSE),
693 this->gateway, IKEV2_UDP_PORT,
694 FRAGMENTATION_YES, 0);
695 ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
696 ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
697
698 peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
699 UNIQUE_REPLACE, 0, /* keyingtries */
700 36000, 0, /* rekey 10h, reauth none */
701 600, 600, /* jitter, over 10min */
702 TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
703 0, 0, /* DPD delay, timeout */
704 FALSE, NULL, NULL); /* mediation */
705 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET));
706 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET6));
707
708 /* local auth config */
709 if (streq("ikev2-cert", this->type) ||
710 streq("ikev2-cert-eap", this->type) ||
711 streq("ikev2-eap-tls", this->type))
712 {
713 if (!add_auth_cfg_cert(this, peer_cfg))
714 {
715 peer_cfg->destroy(peer_cfg);
716 charonservice->update_status(charonservice,
717 CHARONSERVICE_GENERIC_ERROR);
718 return JOB_REQUEUE_NONE;
719 }
720 }
721 if (streq("ikev2-eap", this->type) ||
722 streq("ikev2-cert-eap", this->type) ||
723 streq("ikev2-byod-eap", this->type))
724 {
725 add_auth_cfg_pw(this, peer_cfg, strpfx(this->type, "ikev2-byod"));
726 }
727
728 /* remote auth config */
729 auth = auth_cfg_create();
730 gateway = identification_create_from_string(this->gateway);
731 auth->add(auth, AUTH_RULE_IDENTITY, gateway);
732 auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE);
733 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
734 peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
735
736 child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
737 ACTION_NONE, ACTION_RESTART, ACTION_RESTART,
738 FALSE, 0, 0, NULL, NULL, 0);
739 /* create ESP proposals with and without DH groups, let responder decide
740 * if PFS is used */
741 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
742 "aes128gcm16-aes256gcm16-ecp256"));
743 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
744 "aes128-sha256-ecp256-modp3072"));
745 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
746 "aes256-sha384-ecp521-modp8192"));
747 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
748 "aes128-aes192-aes256-sha1-sha256-sha384-sha512-"
749 "ecp256-ecp384-ecp521-"
750 "modp2048-modp3072-modp4096-modp1024"));
751 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
752 "aes128gcm16-aes256gcm16"));
753 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
754 "aes128-sha256"));
755 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
756 "aes256-sha384"));
757 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
758 "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
759 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
760 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
761 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
762 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
763 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
764 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
765 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
766 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
767 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
768
769 /* get us an IKE_SA */
770 ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
771 peer_cfg);
772 if (!ike_sa)
773 {
774 peer_cfg->destroy(peer_cfg);
775 charonservice->update_status(charonservice,
776 CHARONSERVICE_GENERIC_ERROR);
777 return JOB_REQUEUE_NONE;
778 }
779 if (!ike_sa->get_peer_cfg(ike_sa))
780 {
781 ike_sa->set_peer_cfg(ike_sa, peer_cfg);
782 }
783 peer_cfg->destroy(peer_cfg);
784
785 /* store the IKE_SA so we can track its progress */
786 this->ike_sa = ike_sa;
787
788 /* get an additional reference because initiate consumes one */
789 child_cfg->get_ref(child_cfg);
790 if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
791 {
792 DBG1(DBG_CFG, "failed to initiate tunnel");
793 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
794 ike_sa);
795 return JOB_REQUEUE_NONE;
796 }
797 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
798 return JOB_REQUEUE_NONE;
799 }
800
801 METHOD(android_service_t, destroy, void,
802 private_android_service_t *this)
803 {
804 charon->bus->remove_listener(charon->bus, &this->public.listener);
805 /* make sure the tun device is actually closed */
806 close_tun_device(this);
807 this->dns_proxy->destroy(this->dns_proxy);
808 this->lock->destroy(this->lock);
809 free(this->type);
810 free(this->gateway);
811 free(this->username);
812 if (this->password)
813 {
814 memwipe(this->password, strlen(this->password));
815 free(this->password);
816 }
817 free(this);
818 }
819
820 /**
821 * See header
822 */
823 android_service_t *android_service_create(android_creds_t *creds, char *type,
824 char *gateway, char *username,
825 char *password)
826 {
827 private_android_service_t *this;
828
829 INIT(this,
830 .public = {
831 .listener = {
832 .ike_rekey = _ike_rekey,
833 .ike_reestablish_pre = _ike_reestablish_pre,
834 .ike_reestablish_post = _ike_reestablish_post,
835 .ike_updown = _ike_updown,
836 .child_updown = _child_updown,
837 .alert = _alert,
838 },
839 .destroy = _destroy,
840 },
841 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
842 .dns_proxy = android_dns_proxy_create(),
843 .username = username,
844 .password = password,
845 .gateway = gateway,
846 .creds = creds,
847 .type = type,
848 .tunfd = -1,
849 );
850 /* only allow queries for the VPN gateway */
851 this->dns_proxy->add_hostname(this->dns_proxy, gateway);
852
853 charon->bus->add_listener(charon->bus, &this->public.listener);
854
855 lib->processor->queue_job(lib->processor,
856 (job_t*)callback_job_create((callback_job_cb_t)initiate, this,
857 NULL, NULL));
858 return &this->public;
859 }