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