]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/frontends/android/jni/libandroidbridge/backend/android_service.c
android: Enable EAP-TLS plugin in the app
[thirdparty/strongswan.git] / src / frontends / android / jni / libandroidbridge / backend / android_service.c
CommitLineData
66211196 1/*
cc1712a8 2 * Copyright (C) 2010-2014 Tobias Brunner
66211196
TB
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
2483f6a4 18#include <errno.h>
d9531100
TB
19#include <unistd.h>
20
66211196 21#include "android_service.h"
cc1712a8 22#include "android_dns_proxy.h"
66211196 23#include "../charonservice.h"
a2993d72 24#include "../vpnservice_builder.h"
66211196
TB
25
26#include <daemon.h>
27#include <library.h>
3b3cf0c8 28#include <ipsec.h>
66211196 29#include <processing/jobs/callback_job.h>
a2993d72 30#include <threading/rwlock.h>
2483f6a4 31#include <threading/thread.h>
66211196
TB
32
33typedef struct private_android_service_t private_android_service_t;
34
a2993d72
TB
35#define TUN_DEFAULT_MTU 1400
36
66211196
TB
37/**
38 * private data of Android service
39 */
40struct private_android_service_t {
41
42 /**
43 * public interface
44 */
45 android_service_t public;
46
c89cc226
TB
47 /**
48 * credential set
49 */
50 android_creds_t *creds;
51
66211196
TB
52 /**
53 * current IKE_SA
54 */
55 ike_sa_t *ike_sa;
56
c89cc226
TB
57 /**
58 * the type of VPN
59 */
60 char *type;
61
66211196
TB
62 /**
63 * gateway
64 */
65 char *gateway;
66
67 /**
68 * username
69 */
70 char *username;
71
c89cc226
TB
72 /**
73 * password
74 */
75 char *password;
76
a2993d72
TB
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
cc1712a8
TB
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;
66211196
TB
96};
97
3b3cf0c8
TB
98/**
99 * Outbound callback
100 */
101static void send_esp(void *data, esp_packet_t *packet)
102{
103 charon->sender->send_no_marker(charon->sender, (packet_t*)packet);
104}
105
d9531100
TB
106/**
107 * Inbound callback
108 */
109static 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
3b3cf0c8
TB
135/**
136 * Receiver callback
137 */
138static 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
2483f6a4
TB
146/**
147 * Job handling outbound plaintext packets
148 */
149static 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;
cc1712a8 156 bool old, dns_proxy;
d7d2a5ec
TB
157 timeval_t tv = {
158 /* check every second if tunfd is still valid */
159 .tv_sec = 1,
160 };
2483f6a4
TB
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);
cc1712a8
TB
172 /* cache this while we have the lock */
173 dns_proxy = this->use_dns_proxy;
2483f6a4
TB
174 this->lock->unlock(this->lock);
175
176 old = thread_cancelability(TRUE);
d7d2a5ec 177 len = select(tunfd + 1, &set, NULL, NULL, &tv);
2483f6a4
TB
178 thread_cancelability(old);
179
180 if (len < 0)
181 {
e88b529a
TB
182 if (errno == EBADF)
183 { /* the TUN device got closed just before calling select(), retry */
184 return JOB_REQUEUE_FAIR;
185 }
2483f6a4
TB
186 DBG1(DBG_DMN, "select on TUN device failed: %s", strerror(errno));
187 return JOB_REQUEUE_NONE;
188 }
d7d2a5ec
TB
189 else if (len == 0)
190 { /* timeout, check again right away */
191 return JOB_REQUEUE_DIRECT;
192 }
2483f6a4
TB
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 {
cc1712a8
TB
207 if (!dns_proxy || !this->dns_proxy->handle(this->dns_proxy, packet))
208 {
209 ipsec->processor->queue_outbound(ipsec->processor, packet);
210 }
2483f6a4
TB
211 }
212 else
213 {
214 DBG1(DBG_DMN, "invalid IP packet read from TUN device");
215 }
216 return JOB_REQUEUE_DIRECT;
217}
218
30ba2ff7
TB
219/**
220 * Add a route to the TUN device builder
221 */
222static 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
ee66565d 227 * route. likewise for IPv6 with ::/0. */
30ba2ff7
TB
228 if (net->is_anyaddr(net) && prefix == 0)
229 {
230 bool success;
231
232 success = add_route(builder, net, 1);
ee66565d
TB
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 }
30ba2ff7
TB
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 */
251static 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
a2993d72 271/**
2483f6a4
TB
272 * Setup a new TUN device for the supplied SAs, also queues a job that
273 * reads packets from this device.
a2993d72
TB
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 */
278static 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;
101d26ba 282 enumerator_t *enumerator;
d7d2a5ec 283 bool vip_found = FALSE, already_registered = FALSE;
62e6630b 284 host_t *vip;
a2993d72
TB
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));
101d26ba
MW
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)
62e6630b
TB
307 {
308 DBG1(DBG_DMN, "setting up TUN device failed, no virtual IP found");
309 return FALSE;
310 }
101d26ba 311 if (!add_routes(builder, child_sa) ||
62e6630b 312 !builder->set_mtu(builder, TUN_DEFAULT_MTU))
a2993d72
TB
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);
d7d2a5ec
TB
324 if (this->tunfd > 0)
325 { /* close previously opened TUN device */
326 close(this->tunfd);
327 already_registered = true;
328 }
a2993d72
TB
329 this->tunfd = tunfd;
330 this->lock->unlock(this->lock);
331
332 DBG1(DBG_DMN, "successfully created TUN device");
3b3cf0c8 333
d7d2a5ec
TB
334 if (!already_registered)
335 {
336 charon->receiver->add_esp_cb(charon->receiver,
3b3cf0c8 337 (receiver_esp_cb_t)receiver_esp_cb, NULL);
d7d2a5ec 338 ipsec->processor->register_inbound(ipsec->processor,
d9531100 339 (ipsec_inbound_cb_t)deliver_plain, this);
d7d2a5ec 340 ipsec->processor->register_outbound(ipsec->processor,
3b3cf0c8 341 (ipsec_outbound_cb_t)send_esp, NULL);
cc1712a8
TB
342 this->dns_proxy->register_cb(this->dns_proxy,
343 (dns_proxy_response_cb_t)deliver_plain, this);
3b3cf0c8 344
d7d2a5ec
TB
345 lib->processor->queue_job(lib->processor,
346 (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this,
2483f6a4 347 NULL, (callback_job_cancel_t)return_false));
d7d2a5ec 348 }
a2993d72
TB
349 return TRUE;
350}
351
c66f5f84
TB
352/**
353 * Setup a new TUN device based on the existing one, but without DNS server.
354 */
355static 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
a2993d72
TB
382/**
383 * Close the current tun device
384 */
385static 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);
3b3cf0c8 398
cc1712a8
TB
399 this->dns_proxy->unregister_cb(this->dns_proxy,
400 (dns_proxy_response_cb_t)deliver_plain);
3b3cf0c8
TB
401 ipsec->processor->unregister_outbound(ipsec->processor,
402 (ipsec_outbound_cb_t)send_esp);
d9531100
TB
403 ipsec->processor->unregister_inbound(ipsec->processor,
404 (ipsec_inbound_cb_t)deliver_plain);
3b3cf0c8
TB
405 charon->receiver->del_esp_cb(charon->receiver,
406 (receiver_esp_cb_t)receiver_esp_cb);
a2993d72
TB
407 close(tunfd);
408}
409
5fd9e5fd
TB
410/**
411 * Terminate the IKE_SA with the given unique ID
412 */
413CALLBACK(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
ac1b3a6d
TB
421/**
422 * Reestablish the IKE_SA with the given unique ID
423 */
424CALLBACK(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,
430 *id, FALSE);
431 if (ike_sa)
432 {
433 if (ike_sa->reauth(ike_sa) == DESTROY_ME)
434 {
435 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
436 ike_sa);
437 }
438 else
439 {
440 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
441 }
442 }
443 return JOB_REQUEUE_NONE;
444}
445
66211196
TB
446METHOD(listener_t, child_updown, bool,
447 private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
448 bool up)
449{
450 if (this->ike_sa == ike_sa)
451 {
452 if (up)
453 {
454 /* disable the hooks registered to catch initiation failures */
455 this->public.listener.ike_updown = NULL;
cc1712a8
TB
456 /* CHILD_SA is up so we can disable the DNS proxy we enabled to
457 * reestablish the SA */
458 this->lock->write_lock(this->lock);
459 this->use_dns_proxy = FALSE;
460 this->lock->unlock(this->lock);
a2993d72
TB
461 if (!setup_tun_device(this, ike_sa, child_sa))
462 {
463 DBG1(DBG_DMN, "failed to setup TUN device");
464 charonservice->update_status(charonservice,
465 CHARONSERVICE_GENERIC_ERROR);
466 return FALSE;
467
468 }
66211196
TB
469 charonservice->update_status(charonservice,
470 CHARONSERVICE_CHILD_STATE_UP);
471 }
472 else
473 {
474 charonservice->update_status(charonservice,
475 CHARONSERVICE_CHILD_STATE_DOWN);
66211196
TB
476 }
477 }
478 return TRUE;
479}
480
481METHOD(listener_t, ike_updown, bool,
482 private_android_service_t *this, ike_sa_t *ike_sa, bool up)
483{
484 /* this callback is only registered during initiation, so if the IKE_SA
08d545e2
TB
485 * goes down we assume some kind of authentication error, more specific
486 * errors are catched in the alert() handler */
66211196
TB
487 if (this->ike_sa == ike_sa && !up)
488 {
489 charonservice->update_status(charonservice,
490 CHARONSERVICE_AUTH_ERROR);
491 return FALSE;
492 }
493 return TRUE;
494}
495
66211196
TB
496METHOD(listener_t, alert, bool,
497 private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
498 va_list args)
499{
500 if (this->ike_sa == ike_sa)
501 {
502 switch (alert)
503 {
504 case ALERT_PEER_ADDR_FAILED:
505 charonservice->update_status(charonservice,
506 CHARONSERVICE_LOOKUP_ERROR);
507 break;
508 case ALERT_PEER_AUTH_FAILED:
509 charonservice->update_status(charonservice,
510 CHARONSERVICE_PEER_AUTH_ERROR);
511 break;
a39c28bb 512 case ALERT_KEEP_ON_CHILD_SA_FAILURE:
ac1b3a6d
TB
513 {
514 u_int32_t *id = malloc_thing(u_int32_t);
515
a39c28bb 516 /* because close_ike_on_child_failure is set this is only
ac1b3a6d
TB
517 * triggered when CHILD_SA rekeying failed. reestablish it in
518 * the hope that the initial setup works again. */
519 *id = ike_sa->get_unique_id(ike_sa);
520 lib->processor->queue_job(lib->processor,
521 (job_t*)callback_job_create_with_prio(
522 (callback_job_cb_t)reestablish, id, free,
523 (callback_job_cancel_t)return_false, JOB_PRIO_HIGH));
a39c28bb 524 break;
ac1b3a6d 525 }
272ce5b5 526 case ALERT_PEER_INIT_UNREACHABLE:
2b6088c7
TB
527 this->lock->read_lock(this->lock);
528 if (this->tunfd < 0)
5fd9e5fd
TB
529 {
530 u_int32_t *id = malloc_thing(u_int32_t);
531
532 /* always fail if we are not able to initiate the IKE_SA
533 * initially */
2b6088c7
TB
534 charonservice->update_status(charonservice,
535 CHARONSERVICE_UNREACHABLE_ERROR);
5fd9e5fd
TB
536 /* terminate the IKE_SA so no further keying tries are
537 * attempted */
538 *id = ike_sa->get_unique_id(ike_sa);
539 lib->processor->queue_job(lib->processor,
540 (job_t*)callback_job_create_with_prio(
541 (callback_job_cb_t)terminate, id, free,
542 (callback_job_cancel_t)return_false, JOB_PRIO_HIGH));
2b6088c7 543 }
ffff7219
TB
544 else
545 {
546 peer_cfg_t *peer_cfg;
547 u_int32_t tries, try;
548
549 /* when reestablishing and if keyingtries is not %forever
550 * the IKE_SA is destroyed after the set number of tries,
551 * so notify the GUI */
552 peer_cfg = ike_sa->get_peer_cfg(ike_sa);
553 tries = peer_cfg->get_keyingtries(peer_cfg);
554 try = va_arg(args, u_int32_t);
555 if (tries != 0 && try == tries-1)
556 {
557 charonservice->update_status(charonservice,
558 CHARONSERVICE_UNREACHABLE_ERROR);
559 }
560 }
2b6088c7 561 this->lock->unlock(this->lock);
272ce5b5 562 break;
66211196
TB
563 default:
564 break;
565 }
566 }
567 return TRUE;
568}
569
570METHOD(listener_t, ike_rekey, bool,
571 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
572{
573 if (this->ike_sa == old)
574 {
575 this->ike_sa = new;
576 }
577 return TRUE;
578}
579
cc1712a8
TB
580METHOD(listener_t, ike_reestablish_pre, bool,
581 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
582{
583 if (this->ike_sa == old)
584 {
585 /* enable DNS proxy so hosts are properly resolved while the TUN device
586 * is still active */
587 this->lock->write_lock(this->lock);
588 this->use_dns_proxy = TRUE;
589 this->lock->unlock(this->lock);
c66f5f84
TB
590 /* if DNS servers are installed that are only reachable through the VPN
591 * the DNS proxy doesn't help, so uninstall DNS servers */
592 if (!setup_tun_device_without_dns(this))
593 {
594 DBG1(DBG_DMN, "failed to setup TUN device without DNS");
595 charonservice->update_status(charonservice,
596 CHARONSERVICE_GENERIC_ERROR);
597 }
cc1712a8
TB
598 }
599 return TRUE;
600}
601
614359a7
TB
602METHOD(listener_t, ike_reestablish_post, bool,
603 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
604 bool initiated)
d7d2a5ec 605{
614359a7 606 if (this->ike_sa == old && initiated)
d7d2a5ec
TB
607 {
608 this->ike_sa = new;
272ce5b5 609 /* re-register hook to detect initiation failures */
d7d2a5ec 610 this->public.listener.ike_updown = _ike_updown;
08d545e2
TB
611 /* if the IKE_SA got deleted by the responder we get the child_down()
612 * event on the old IKE_SA after this hook has been called, so they
613 * get ignored and thus we trigger the event here */
614 charonservice->update_status(charonservice,
615 CHARONSERVICE_CHILD_STATE_DOWN);
d7d2a5ec
TB
616 }
617 return TRUE;
618}
619
76de9646 620static void add_auth_cfg_eap(private_android_service_t *this,
8a5bffb0 621 peer_cfg_t *peer_cfg, bool byod)
76de9646
TB
622{
623 identification_t *user;
624 auth_cfg_t *auth;
625
626 auth = auth_cfg_create();
627 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
8a5bffb0
TB
628 if (byod)
629 { /* use EAP-TTLS if BYOD is enabled */
630 auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TTLS);
631 }
632
76de9646
TB
633 user = identification_create_from_string(this->username);
634 auth->add(auth, AUTH_RULE_IDENTITY, user);
635
636 this->creds->add_username_password(this->creds, this->username,
637 this->password);
638 memwipe(this->password, strlen(this->password));
639 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
640}
641
642static bool add_auth_cfg_cert(private_android_service_t *this,
643 peer_cfg_t *peer_cfg)
644{
645 certificate_t *cert;
646 identification_t *id;
647 auth_cfg_t *auth;
648
649 cert = this->creds->load_user_certificate(this->creds);
650 if (!cert)
651 {
652 return FALSE;
653 }
654
655 auth = auth_cfg_create();
656 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
657 auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
658
659 id = cert->get_subject(cert);
660 auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
661 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
662 return TRUE;
663}
664
66211196
TB
665static job_requeue_t initiate(private_android_service_t *this)
666{
76de9646 667 identification_t *gateway;
66211196
TB
668 ike_cfg_t *ike_cfg;
669 peer_cfg_t *peer_cfg;
670 child_cfg_t *child_cfg;
671 traffic_selector_t *ts;
672 ike_sa_t *ike_sa;
673 auth_cfg_t *auth;
674 lifetime_cfg_t lifetime = {
675 .time = {
f9ceb5b5
TB
676 .life = 3600, /* 1h */
677 .rekey = 3000, /* 50min */
66211196
TB
678 .jitter = 300 /* 5min */
679 }
680 };
681
3070697f 682 ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0",
66211196 683 charon->socket->get_port(charon->socket, FALSE),
3070697f 684 this->gateway, IKEV2_UDP_PORT,
306a269e 685 FRAGMENTATION_NO, 0);
66211196 686 ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
879e3d12 687 ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
66211196 688
1fdd62ff 689 peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
8658e87b 690 UNIQUE_REPLACE, 0, /* keyingtries */
66211196
TB
691 36000, 0, /* rekey 10h, reauth none */
692 600, 600, /* jitter, over 10min */
9aeaa739 693 TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
66211196 694 0, 0, /* DPD delay, timeout */
497ce2cf 695 FALSE, NULL, NULL); /* mediation */
ee66565d
TB
696 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET));
697 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET6));
66211196 698
c89cc226 699 /* local auth config */
76de9646
TB
700 if (streq("ikev2-cert", this->type) ||
701 streq("ikev2-cert-eap", this->type))
c89cc226 702 {
76de9646 703 if (!add_auth_cfg_cert(this, peer_cfg))
c89cc226
TB
704 {
705 peer_cfg->destroy(peer_cfg);
706 charonservice->update_status(charonservice,
707 CHARONSERVICE_GENERIC_ERROR);
708 return JOB_REQUEUE_NONE;
c89cc226 709 }
76de9646
TB
710 }
711 if (streq("ikev2-eap", this->type) ||
8a5bffb0
TB
712 streq("ikev2-cert-eap", this->type) ||
713 streq("ikev2-byod-eap", this->type))
76de9646 714 {
8a5bffb0 715 add_auth_cfg_eap(this, peer_cfg, strpfx(this->type, "ikev2-byod"));
c89cc226
TB
716 }
717
718 /* remote auth config */
66211196
TB
719 auth = auth_cfg_create();
720 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
721 gateway = identification_create_from_string(this->gateway);
722 auth->add(auth, AUTH_RULE_IDENTITY, gateway);
e596d0ef 723 auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE);
66211196
TB
724 peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
725
726 child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
8658e87b
TB
727 ACTION_NONE, ACTION_RESTART, ACTION_RESTART,
728 FALSE, 0, 0, NULL, NULL, 0);
1fe3b028
TB
729 /* create ESP proposals with and without DH groups, let responder decide
730 * if PFS is used */
731 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
732 "aes128gcm16-aes256gcm16-ecp256"));
733 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
734 "aes128-sha256-ecp256-modp3072"));
735 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
736 "aes256-sha384-ecp521-modp8192"));
737 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
738 "aes128-aes192-aes256-sha1-sha256-sha384-sha512-"
739 "ecp256-ecp384-ecp521-"
740 "modp2048-modp3072-modp4096-modp1024"));
740aedfe
TB
741 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
742 "aes128gcm16-aes256gcm16"));
743 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
744 "aes128-sha256"));
745 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
746 "aes256-sha384"));
e3d98f2c
TB
747 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
748 "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
ee66565d
TB
749 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
750 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
751 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
752 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
753 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
66211196 754 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
ee66565d 755 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
66211196
TB
756 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
757 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
758
759 /* get us an IKE_SA */
760 ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
761 peer_cfg);
762 if (!ike_sa)
763 {
764 peer_cfg->destroy(peer_cfg);
765 charonservice->update_status(charonservice,
766 CHARONSERVICE_GENERIC_ERROR);
767 return JOB_REQUEUE_NONE;
768 }
769 if (!ike_sa->get_peer_cfg(ike_sa))
770 {
771 ike_sa->set_peer_cfg(ike_sa, peer_cfg);
772 }
773 peer_cfg->destroy(peer_cfg);
774
775 /* store the IKE_SA so we can track its progress */
776 this->ike_sa = ike_sa;
777
778 /* get an additional reference because initiate consumes one */
779 child_cfg->get_ref(child_cfg);
780 if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
781 {
782 DBG1(DBG_CFG, "failed to initiate tunnel");
783 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
784 ike_sa);
785 return JOB_REQUEUE_NONE;
786 }
787 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
788 return JOB_REQUEUE_NONE;
789}
790
791METHOD(android_service_t, destroy, void,
792 private_android_service_t *this)
793{
794 charon->bus->remove_listener(charon->bus, &this->public.listener);
a2993d72
TB
795 /* make sure the tun device is actually closed */
796 close_tun_device(this);
cc1712a8 797 this->dns_proxy->destroy(this->dns_proxy);
a2993d72 798 this->lock->destroy(this->lock);
c89cc226 799 free(this->type);
66211196 800 free(this->gateway);
c89cc226
TB
801 free(this->username);
802 if (this->password)
803 {
804 memwipe(this->password, strlen(this->password));
805 free(this->password);
806 }
66211196
TB
807 free(this);
808}
809
810/**
811 * See header
812 */
c89cc226 813android_service_t *android_service_create(android_creds_t *creds, char *type,
38bbca58
TB
814 char *gateway, char *username,
815 char *password)
66211196
TB
816{
817 private_android_service_t *this;
818
819 INIT(this,
820 .public = {
821 .listener = {
822 .ike_rekey = _ike_rekey,
cc1712a8 823 .ike_reestablish_pre = _ike_reestablish_pre,
614359a7 824 .ike_reestablish_post = _ike_reestablish_post,
66211196 825 .ike_updown = _ike_updown,
66211196
TB
826 .child_updown = _child_updown,
827 .alert = _alert,
828 },
829 .destroy = _destroy,
830 },
a2993d72 831 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
cc1712a8 832 .dns_proxy = android_dns_proxy_create(),
66211196 833 .username = username,
c89cc226 834 .password = password,
66211196 835 .gateway = gateway,
c89cc226
TB
836 .creds = creds,
837 .type = type,
a2993d72 838 .tunfd = -1,
66211196 839 );
945832c6
TB
840 /* only allow queries for the VPN gateway */
841 this->dns_proxy->add_hostname(this->dns_proxy, gateway);
66211196
TB
842
843 charon->bus->add_listener(charon->bus, &this->public.listener);
844
845 lib->processor->queue_job(lib->processor,
846 (job_t*)callback_job_create((callback_job_cb_t)initiate, this,
847 NULL, NULL));
848 return &this->public;
849}