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