]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c
Merge branch 'readme-errata'
[thirdparty/strongswan.git] / src / frontends / android / app / src / main / jni / libandroidbridge / backend / android_service.c
CommitLineData
66211196 1/*
a7c43544 2 * Copyright (C) 2010-2017 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
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
35/**
36 * private data of Android service
37 */
38struct private_android_service_t {
39
40 /**
41 * public interface
42 */
43 android_service_t public;
44
c89cc226
TB
45 /**
46 * credential set
47 */
48 android_creds_t *creds;
49
66211196
TB
50 /**
51 * current IKE_SA
52 */
53 ike_sa_t *ike_sa;
54
c89cc226 55 /**
79af70c6 56 * configuration setttings
c89cc226 57 */
79af70c6 58 settings_t *settings;
c89cc226 59
a2993d72
TB
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
4d02c49e
TB
70 /**
71 * MTU of TUN device
72 */
73 int mtu;
74
cc1712a8
TB
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;
66211196
TB
84};
85
3b3cf0c8
TB
86/**
87 * Outbound callback
88 */
89static void send_esp(void *data, esp_packet_t *packet)
90{
91 charon->sender->send_no_marker(charon->sender, (packet_t*)packet);
92}
93
d9531100
TB
94/**
95 * Inbound callback
96 */
97static 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
3b3cf0c8
TB
123/**
124 * Receiver callback
125 */
126static 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
2483f6a4
TB
134/**
135 * Job handling outbound plaintext packets
136 */
137static 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;
cc1712a8 144 bool old, dns_proxy;
d7d2a5ec
TB
145 timeval_t tv = {
146 /* check every second if tunfd is still valid */
147 .tv_sec = 1,
148 };
2483f6a4
TB
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);
cc1712a8
TB
160 /* cache this while we have the lock */
161 dns_proxy = this->use_dns_proxy;
2483f6a4
TB
162 this->lock->unlock(this->lock);
163
164 old = thread_cancelability(TRUE);
d7d2a5ec 165 len = select(tunfd + 1, &set, NULL, NULL, &tv);
2483f6a4
TB
166 thread_cancelability(old);
167
168 if (len < 0)
169 {
e88b529a
TB
170 if (errno == EBADF)
171 { /* the TUN device got closed just before calling select(), retry */
172 return JOB_REQUEUE_FAIR;
173 }
2483f6a4
TB
174 DBG1(DBG_DMN, "select on TUN device failed: %s", strerror(errno));
175 return JOB_REQUEUE_NONE;
176 }
d7d2a5ec
TB
177 else if (len == 0)
178 { /* timeout, check again right away */
179 return JOB_REQUEUE_DIRECT;
180 }
2483f6a4 181
4d02c49e 182 raw = chunk_alloc(this->mtu);
2483f6a4
TB
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 {
cc1712a8
TB
195 if (!dns_proxy || !this->dns_proxy->handle(this->dns_proxy, packet))
196 {
197 ipsec->processor->queue_outbound(ipsec->processor, packet);
198 }
2483f6a4
TB
199 }
200 else
201 {
202 DBG1(DBG_DMN, "invalid IP packet read from TUN device");
203 }
204 return JOB_REQUEUE_DIRECT;
205}
206
30ba2ff7
TB
207/**
208 * Add a route to the TUN device builder
209 */
210static bool add_route(vpnservice_builder_t *builder, host_t *net,
b12c53ce 211 uint8_t prefix)
30ba2ff7
TB
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
ee66565d 215 * route. likewise for IPv6 with ::/0. */
30ba2ff7
TB
216 if (net->is_anyaddr(net) && prefix == 0)
217 {
218 bool success;
219
220 success = add_route(builder, net, 1);
ee66565d
TB
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 }
30ba2ff7
TB
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 */
239static 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;
b12c53ce 249 uint8_t prefix;
30ba2ff7
TB
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
a2993d72 259/**
2483f6a4
TB
260 * Setup a new TUN device for the supplied SAs, also queues a job that
261 * reads packets from this device.
a2993d72
TB
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 */
266static 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;
101d26ba 270 enumerator_t *enumerator;
d7d2a5ec 271 bool vip_found = FALSE, already_registered = FALSE;
62e6630b 272 host_t *vip;
a2993d72
TB
273 int tunfd;
274
275 DBG1(DBG_DMN, "setting up TUN device for CHILD_SA %s{%u}",
246c969d 276 child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa));
101d26ba
MW
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)
62e6630b
TB
295 {
296 DBG1(DBG_DMN, "setting up TUN device failed, no virtual IP found");
297 return FALSE;
298 }
101d26ba 299 if (!add_routes(builder, child_sa) ||
4d02c49e 300 !builder->set_mtu(builder, this->mtu))
a2993d72
TB
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);
d7d2a5ec
TB
312 if (this->tunfd > 0)
313 { /* close previously opened TUN device */
314 close(this->tunfd);
315 already_registered = true;
316 }
a2993d72
TB
317 this->tunfd = tunfd;
318 this->lock->unlock(this->lock);
319
320 DBG1(DBG_DMN, "successfully created TUN device");
3b3cf0c8 321
d7d2a5ec
TB
322 if (!already_registered)
323 {
324 charon->receiver->add_esp_cb(charon->receiver,
3b3cf0c8 325 (receiver_esp_cb_t)receiver_esp_cb, NULL);
d7d2a5ec 326 ipsec->processor->register_inbound(ipsec->processor,
d9531100 327 (ipsec_inbound_cb_t)deliver_plain, this);
d7d2a5ec 328 ipsec->processor->register_outbound(ipsec->processor,
3b3cf0c8 329 (ipsec_outbound_cb_t)send_esp, NULL);
cc1712a8
TB
330 this->dns_proxy->register_cb(this->dns_proxy,
331 (dns_proxy_response_cb_t)deliver_plain, this);
3b3cf0c8 332
d7d2a5ec
TB
333 lib->processor->queue_job(lib->processor,
334 (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this,
2483f6a4 335 NULL, (callback_job_cancel_t)return_false));
d7d2a5ec 336 }
a2993d72
TB
337 return TRUE;
338}
339
c66f5f84
TB
340/**
341 * Setup a new TUN device based on the existing one, but without DNS server.
342 */
343static 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
a2993d72
TB
370/**
371 * Close the current tun device
372 */
373static 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);
3b3cf0c8 386
cc1712a8
TB
387 this->dns_proxy->unregister_cb(this->dns_proxy,
388 (dns_proxy_response_cb_t)deliver_plain);
3b3cf0c8
TB
389 ipsec->processor->unregister_outbound(ipsec->processor,
390 (ipsec_outbound_cb_t)send_esp);
d9531100
TB
391 ipsec->processor->unregister_inbound(ipsec->processor,
392 (ipsec_inbound_cb_t)deliver_plain);
3b3cf0c8
TB
393 charon->receiver->del_esp_cb(charon->receiver,
394 (receiver_esp_cb_t)receiver_esp_cb);
a2993d72
TB
395 close(tunfd);
396}
397
5fd9e5fd
TB
398/**
399 * Terminate the IKE_SA with the given unique ID
400 */
401CALLBACK(terminate, job_requeue_t,
b12c53ce 402 uint32_t *id)
5fd9e5fd
TB
403{
404 charon->controller->terminate_ike(charon->controller, *id,
405 controller_cb_empty, NULL, 0);
406 return JOB_REQUEUE_NONE;
407}
408
ac1b3a6d
TB
409/**
410 * Reestablish the IKE_SA with the given unique ID
411 */
412CALLBACK(reestablish, job_requeue_t,
b12c53ce 413 uint32_t *id)
ac1b3a6d
TB
414{
415 ike_sa_t *ike_sa;
416
db80d0d2 417 ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager, *id);
ac1b3a6d
TB
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
d9c5e6d7
TB
433METHOD(listener_t, ike_updown, bool,
434 private_android_service_t *this, ike_sa_t *ike_sa, bool up)
435{
436 /* this callback is only registered during initiation, so if the IKE_SA
437 * goes down we assume some kind of authentication error, more specific
ca280574 438 * errors are caught in the alert() handler */
d9c5e6d7
TB
439 if (this->ike_sa == ike_sa && !up)
440 {
441 charonservice->update_status(charonservice,
442 CHARONSERVICE_AUTH_ERROR);
443 return FALSE;
444 }
445 return TRUE;
446}
447
448METHOD(listener_t, ike_rekey, bool,
449 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
450{
451 if (this->ike_sa == old)
452 {
453 this->ike_sa = new;
454 }
455 return TRUE;
456}
457
458METHOD(listener_t, ike_reestablish_post_redirect, bool,
459 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
460 bool initiated)
461{
462 if (this->ike_sa == old && initiated)
463 { /* if we get redirected during IKE_AUTH we just migrate to the new SA,
464 * we don't have a TUN device yet, so reinstalling it without DNS would
465 * fail (and using the DNS proxy is not required anyway) */
466 this->ike_sa = new;
467 }
468 return TRUE;
469}
470
471METHOD(listener_t, ike_reestablish_pre, bool,
472 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
473{
474 if (this->ike_sa == old)
475 {
476 /* enable DNS proxy so hosts are properly resolved while the TUN device
477 * is still active */
478 this->lock->write_lock(this->lock);
479 this->use_dns_proxy = TRUE;
480 this->lock->unlock(this->lock);
481 /* if DNS servers are installed that are only reachable through the VPN
482 * the DNS proxy doesn't help, so uninstall DNS servers */
483 if (!setup_tun_device_without_dns(this))
484 {
485 DBG1(DBG_DMN, "failed to setup TUN device without DNS");
486 charonservice->update_status(charonservice,
487 CHARONSERVICE_GENERIC_ERROR);
488 }
489 }
490 return TRUE;
491}
492
493METHOD(listener_t, ike_reestablish_post, bool,
494 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
495 bool initiated)
496{
497 if (this->ike_sa == old && initiated)
498 {
499 this->ike_sa = new;
500 /* re-register hook to detect initiation failures */
501 this->public.listener.ike_updown = _ike_updown;
502 /* if the IKE_SA got deleted by the responder we get the child_down()
503 * event on the old IKE_SA after this hook has been called, so they
504 * get ignored and thus we trigger the event here */
505 charonservice->update_status(charonservice,
506 CHARONSERVICE_CHILD_STATE_DOWN);
507 }
508 return TRUE;
509}
510
66211196
TB
511METHOD(listener_t, child_updown, bool,
512 private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
513 bool up)
514{
515 if (this->ike_sa == ike_sa)
516 {
517 if (up)
518 {
519 /* disable the hooks registered to catch initiation failures */
520 this->public.listener.ike_updown = NULL;
d9c5e6d7
TB
521 /* enable hooks to handle reauthentications */
522 this->public.listener.ike_reestablish_pre = _ike_reestablish_pre;
523 this->public.listener.ike_reestablish_post = _ike_reestablish_post;
cc1712a8
TB
524 /* CHILD_SA is up so we can disable the DNS proxy we enabled to
525 * reestablish the SA */
526 this->lock->write_lock(this->lock);
527 this->use_dns_proxy = FALSE;
528 this->lock->unlock(this->lock);
a2993d72
TB
529 if (!setup_tun_device(this, ike_sa, child_sa))
530 {
531 DBG1(DBG_DMN, "failed to setup TUN device");
532 charonservice->update_status(charonservice,
533 CHARONSERVICE_GENERIC_ERROR);
534 return FALSE;
535
536 }
66211196
TB
537 charonservice->update_status(charonservice,
538 CHARONSERVICE_CHILD_STATE_UP);
539 }
540 else
541 {
542 charonservice->update_status(charonservice,
543 CHARONSERVICE_CHILD_STATE_DOWN);
66211196
TB
544 }
545 }
546 return TRUE;
547}
548
66211196
TB
549METHOD(listener_t, alert, bool,
550 private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
551 va_list args)
552{
d6d12bab
TB
553 bool stay_registered = TRUE;
554
66211196
TB
555 if (this->ike_sa == ike_sa)
556 {
557 switch (alert)
558 {
559 case ALERT_PEER_ADDR_FAILED:
560 charonservice->update_status(charonservice,
561 CHARONSERVICE_LOOKUP_ERROR);
d6d12bab
TB
562 return FALSE;
563
66211196
TB
564 case ALERT_PEER_AUTH_FAILED:
565 charonservice->update_status(charonservice,
566 CHARONSERVICE_PEER_AUTH_ERROR);
d6d12bab
TB
567 return FALSE;
568
a39c28bb 569 case ALERT_KEEP_ON_CHILD_SA_FAILURE:
ac1b3a6d 570 {
b12c53ce 571 uint32_t *id = malloc_thing(uint32_t);
ac1b3a6d 572
a39c28bb 573 /* because close_ike_on_child_failure is set this is only
ac1b3a6d
TB
574 * triggered when CHILD_SA rekeying failed. reestablish it in
575 * the hope that the initial setup works again. */
576 *id = ike_sa->get_unique_id(ike_sa);
577 lib->processor->queue_job(lib->processor,
578 (job_t*)callback_job_create_with_prio(
579 (callback_job_cb_t)reestablish, id, free,
580 (callback_job_cancel_t)return_false, JOB_PRIO_HIGH));
a39c28bb 581 break;
ac1b3a6d 582 }
272ce5b5 583 case ALERT_PEER_INIT_UNREACHABLE:
2b6088c7
TB
584 this->lock->read_lock(this->lock);
585 if (this->tunfd < 0)
5fd9e5fd 586 {
b12c53ce 587 uint32_t *id = malloc_thing(uint32_t);
5fd9e5fd
TB
588
589 /* always fail if we are not able to initiate the IKE_SA
590 * initially */
2b6088c7
TB
591 charonservice->update_status(charonservice,
592 CHARONSERVICE_UNREACHABLE_ERROR);
5fd9e5fd
TB
593 /* terminate the IKE_SA so no further keying tries are
594 * attempted */
595 *id = ike_sa->get_unique_id(ike_sa);
596 lib->processor->queue_job(lib->processor,
597 (job_t*)callback_job_create_with_prio(
598 (callback_job_cb_t)terminate, id, free,
599 (callback_job_cancel_t)return_false, JOB_PRIO_HIGH));
d6d12bab 600 stay_registered = FALSE;
2b6088c7 601 }
ffff7219
TB
602 else
603 {
604 peer_cfg_t *peer_cfg;
b12c53ce 605 uint32_t tries, try;
ffff7219
TB
606
607 /* when reestablishing and if keyingtries is not %forever
608 * the IKE_SA is destroyed after the set number of tries,
609 * so notify the GUI */
610 peer_cfg = ike_sa->get_peer_cfg(ike_sa);
611 tries = peer_cfg->get_keyingtries(peer_cfg);
b12c53ce 612 try = va_arg(args, uint32_t);
ffff7219
TB
613 if (tries != 0 && try == tries-1)
614 {
615 charonservice->update_status(charonservice,
616 CHARONSERVICE_UNREACHABLE_ERROR);
d6d12bab 617 stay_registered = FALSE;
ffff7219
TB
618 }
619 }
2b6088c7 620 this->lock->unlock(this->lock);
272ce5b5 621 break;
66211196
TB
622 default:
623 break;
624 }
625 }
d6d12bab 626 return stay_registered;
66211196
TB
627}
628
34ca3795
TB
629static void add_auth_cfg_pw(private_android_service_t *this,
630 peer_cfg_t *peer_cfg, bool byod)
76de9646 631{
4a58ec24 632 identification_t *user, *id = NULL;
76de9646 633 auth_cfg_t *auth;
4a58ec24 634 char *username, *password, *local_id;
76de9646
TB
635
636 auth = auth_cfg_create();
637 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
8a5bffb0
TB
638 if (byod)
639 { /* use EAP-TTLS if BYOD is enabled */
640 auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TTLS);
641 }
642
79af70c6
TB
643 username = this->settings->get_str(this->settings, "connection.username",
644 NULL);
645 password = this->settings->get_str(this->settings, "connection.password",
646 NULL);
4a58ec24
TB
647 local_id = this->settings->get_str(this->settings, "connection.local_id",
648 NULL);
79af70c6 649 user = identification_create_from_string(username);
4a58ec24
TB
650 auth->add(auth, AUTH_RULE_EAP_IDENTITY, user);
651 if (local_id)
652 {
653 id = identification_create_from_string(local_id);
654 }
655 if (!id)
656 {
657 id = user->clone(user);
658 }
659 auth->add(auth, AUTH_RULE_IDENTITY, id);
76de9646 660
79af70c6 661 this->creds->add_username_password(this->creds, username, password);
76de9646
TB
662 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
663}
664
665static bool add_auth_cfg_cert(private_android_service_t *this,
666 peer_cfg_t *peer_cfg)
667{
668 certificate_t *cert;
4a58ec24 669 identification_t *id = NULL;
76de9646 670 auth_cfg_t *auth;
4a58ec24 671 char *type, *local_id;
76de9646
TB
672
673 cert = this->creds->load_user_certificate(this->creds);
674 if (!cert)
675 {
676 return FALSE;
677 }
678
79af70c6 679 type = this->settings->get_str(this->settings, "connection.type", NULL);
76de9646 680 auth = auth_cfg_create();
79af70c6 681 if (strpfx("ikev2-eap-tls", type))
34ca3795
TB
682 {
683 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
684 auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TLS);
4a58ec24
TB
685 auth->add(auth, AUTH_RULE_AAA_IDENTITY,
686 identification_create_from_string("%any"));
34ca3795
TB
687 }
688 else
689 {
690 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
691 }
76de9646
TB
692 auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
693
4a58ec24
TB
694 local_id = this->settings->get_str(this->settings, "connection.local_id",
695 NULL);
696 if (local_id)
697 {
698 id = identification_create_from_string(local_id);
699 }
700 if (!id)
701 {
702 id = cert->get_subject(cert);
703 id = id->clone(id);
704 }
705 auth->add(auth, AUTH_RULE_IDENTITY, id);
76de9646
TB
706 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
707 return TRUE;
708}
709
a7c43544
TB
710static proposal_t *parse_proposal(private_android_service_t *this,
711 protocol_id_t proto, char *opt)
712{
713 proposal_t *proposal = NULL;
714 char *prop;
715
716 prop = this->settings->get_str(this->settings, opt, NULL);
717 if (!prop || !strlen(prop))
718 {
719 return NULL;
720 }
721
722 proposal = proposal_create_from_string(proto, prop);
723 if (!proposal)
724 {
725 DBG1(DBG_CFG, "invalid %N proposal '%s', falling back to defaults",
726 protocol_id_names, proto, prop);
727 }
728 return proposal;
729}
730
66211196
TB
731static job_requeue_t initiate(private_android_service_t *this)
732{
8b3bf4a4 733 identification_t *gateway = NULL;
66211196
TB
734 ike_cfg_t *ike_cfg;
735 peer_cfg_t *peer_cfg;
736 child_cfg_t *child_cfg;
737 traffic_selector_t *ts;
a7c43544 738 proposal_t *proposal;
66211196
TB
739 ike_sa_t *ike_sa;
740 auth_cfg_t *auth;
2ba5dadb 741 peer_cfg_create_t peer = {
6bafa2d3 742 .cert_policy = CERT_ALWAYS_SEND,
2ba5dadb
TB
743 .unique = UNIQUE_REPLACE,
744 .rekey_time = 36000, /* 10h */
745 .jitter_time = 600, /* 10min */
746 .over_time = 600, /* 10min */
747 };
8a00a845
TB
748 child_cfg_create_t child = {
749 .lifetime = {
750 .time = {
751 .life = 3600, /* 1h */
752 .rekey = 3000, /* 50min */
753 .jitter = 300 /* 5min */
754 },
755 },
756 .mode = MODE_TUNNEL,
757 .dpd_action = ACTION_RESTART,
758 .close_action = ACTION_RESTART,
66211196 759 };
8b3bf4a4 760 char *type, *server, *remote_id;
cda167c8 761 int port;
3f0592d0 762 bool certreq;
66211196 763
79af70c6 764 server = this->settings->get_str(this->settings, "connection.server", NULL);
cda167c8
TB
765 port = this->settings->get_int(this->settings, "connection.port",
766 IKEV2_UDP_PORT);
3f0592d0
TB
767 certreq = this->settings->get_bool(this->settings, "connection.certreq",
768 TRUE);
769 ike_cfg = ike_cfg_create(IKEV2, certreq, TRUE, "0.0.0.0",
66211196 770 charon->socket->get_port(charon->socket, FALSE),
cda167c8 771 server, port, FRAGMENTATION_YES, 0);
a7c43544
TB
772 proposal = parse_proposal(this, PROTO_IKE, "connection.ike_proposal");
773 if (proposal)
774 {
775 ike_cfg->add_proposal(ike_cfg, proposal);
776 }
777 else
778 {
779 ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
780 ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
781 }
66211196 782
2ba5dadb 783 peer_cfg = peer_cfg_create("android", ike_cfg, &peer);
ee66565d
TB
784 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET));
785 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET6));
66211196 786
79af70c6 787 type = this->settings->get_str(this->settings, "connection.type", NULL);
c89cc226 788 /* local auth config */
79af70c6
TB
789 if (streq("ikev2-cert", type) ||
790 streq("ikev2-cert-eap", type) ||
791 streq("ikev2-eap-tls", type))
c89cc226 792 {
76de9646 793 if (!add_auth_cfg_cert(this, peer_cfg))
c89cc226
TB
794 {
795 peer_cfg->destroy(peer_cfg);
796 charonservice->update_status(charonservice,
797 CHARONSERVICE_GENERIC_ERROR);
798 return JOB_REQUEUE_NONE;
c89cc226 799 }
76de9646 800 }
79af70c6
TB
801 if (streq("ikev2-eap", type) ||
802 streq("ikev2-cert-eap", type) ||
803 streq("ikev2-byod-eap", type))
76de9646 804 {
79af70c6 805 add_auth_cfg_pw(this, peer_cfg, strpfx(type, "ikev2-byod"));
c89cc226
TB
806 }
807
808 /* remote auth config */
66211196 809 auth = auth_cfg_create();
8b3bf4a4
TB
810 remote_id = this->settings->get_str(this->settings, "connection.remote_id",
811 NULL);
812 if (remote_id)
813 {
814 gateway = identification_create_from_string(remote_id);
815 }
816 if (!gateway || gateway->get_type(gateway) == ID_ANY)
817 {
818 DESTROY_IF(gateway);
819 gateway = identification_create_from_string(server);
820 /* only use this if remote ID was not configured explicitly */
821 auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE);
822 }
66211196 823 auth->add(auth, AUTH_RULE_IDENTITY, gateway);
0e449998 824 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
66211196
TB
825 peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
826
8a00a845 827 child_cfg = child_cfg_create("android", &child);
a7c43544
TB
828 proposal = parse_proposal(this, PROTO_ESP, "connection.esp_proposal");
829 if (proposal)
830 {
831 child_cfg->add_proposal(child_cfg, proposal);
832 }
833 else
834 { /* create ESP proposals with and without DH groups, let responder decide
835 * if PFS is used */
836 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
837 "aes128gcm16-aes256gcm16-chacha20poly1305-"
838 "curve25519-ecp256-modp3072"));
839 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
840 "aes128-sha256-curve25519-ecp256-modp3072"));
841 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
842 "aes256-sha384-ecp521-modp8192"));
843 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
844 "aes128-aes192-aes256-sha1-sha256-sha384-sha512-"
845 "curve25519-ecp256-ecp384-ecp521-"
0729be1b 846 "modp2048-modp3072-modp4096"));
a7c43544
TB
847 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
848 "aes128gcm16-aes256gcm16-chacha20poly1305"));
849 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
850 "aes128-sha256"));
851 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
852 "aes256-sha384"));
853 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
854 "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
855 }
ee66565d
TB
856 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
857 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
858 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
859 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
860 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
66211196 861 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
ee66565d 862 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
66211196
TB
863 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
864 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
865
866 /* get us an IKE_SA */
867 ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
868 peer_cfg);
869 if (!ike_sa)
870 {
871 peer_cfg->destroy(peer_cfg);
872 charonservice->update_status(charonservice,
873 CHARONSERVICE_GENERIC_ERROR);
874 return JOB_REQUEUE_NONE;
875 }
876 if (!ike_sa->get_peer_cfg(ike_sa))
877 {
878 ike_sa->set_peer_cfg(ike_sa, peer_cfg);
879 }
880 peer_cfg->destroy(peer_cfg);
881
882 /* store the IKE_SA so we can track its progress */
883 this->ike_sa = ike_sa;
884
885 /* get an additional reference because initiate consumes one */
886 child_cfg->get_ref(child_cfg);
887 if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
888 {
889 DBG1(DBG_CFG, "failed to initiate tunnel");
890 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
891 ike_sa);
892 return JOB_REQUEUE_NONE;
893 }
894 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
895 return JOB_REQUEUE_NONE;
896}
897
898METHOD(android_service_t, destroy, void,
899 private_android_service_t *this)
900{
901 charon->bus->remove_listener(charon->bus, &this->public.listener);
a2993d72
TB
902 /* make sure the tun device is actually closed */
903 close_tun_device(this);
cc1712a8 904 this->dns_proxy->destroy(this->dns_proxy);
a2993d72 905 this->lock->destroy(this->lock);
79af70c6 906 this->settings->destroy(this->settings);
66211196
TB
907 free(this);
908}
909
910/**
911 * See header
912 */
79af70c6
TB
913android_service_t *android_service_create(android_creds_t *creds,
914 settings_t *settings)
66211196
TB
915{
916 private_android_service_t *this;
917
918 INIT(this,
919 .public = {
920 .listener = {
921 .ike_rekey = _ike_rekey,
d9c5e6d7 922 .ike_reestablish_post = _ike_reestablish_post_redirect,
66211196 923 .ike_updown = _ike_updown,
66211196
TB
924 .child_updown = _child_updown,
925 .alert = _alert,
926 },
927 .destroy = _destroy,
928 },
a2993d72 929 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
cc1712a8 930 .dns_proxy = android_dns_proxy_create(),
79af70c6 931 .settings = settings,
c89cc226 932 .creds = creds,
a2993d72 933 .tunfd = -1,
4d02c49e 934 .mtu = settings->get_int(settings, "global.mtu", ANDROID_DEFAULT_MTU),
66211196 935 );
945832c6 936 /* only allow queries for the VPN gateway */
79af70c6
TB
937 this->dns_proxy->add_hostname(this->dns_proxy,
938 this->settings->get_str(this->settings, "connection.server", NULL));
66211196
TB
939
940 charon->bus->add_listener(charon->bus, &this->public.listener);
941
942 lib->processor->queue_job(lib->processor,
943 (job_t*)callback_job_create((callback_job_cb_t)initiate, this,
944 NULL, NULL));
945 return &this->public;
946}