ike: Add an additional but separate AEAD proposal to IKE config, if supported
[strongswan.git] / src / frontends / android / jni / libandroidbridge / backend / android_service.c
1 /*
2 * Copyright (C) 2010-2013 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 "../charonservice.h"
23 #include "../vpnservice_builder.h"
24
25 #include <daemon.h>
26 #include <library.h>
27 #include <ipsec.h>
28 #include <processing/jobs/callback_job.h>
29 #include <threading/rwlock.h>
30 #include <threading/thread.h>
31
32 typedef struct private_android_service_t private_android_service_t;
33
34 #define TUN_DEFAULT_MTU 1400
35
36 /**
37 * private data of Android service
38 */
39 struct private_android_service_t {
40
41 /**
42 * public interface
43 */
44 android_service_t public;
45
46 /**
47 * credential set
48 */
49 android_creds_t *creds;
50
51 /**
52 * current IKE_SA
53 */
54 ike_sa_t *ike_sa;
55
56 /**
57 * the type of VPN
58 */
59 char *type;
60
61 /**
62 * gateway
63 */
64 char *gateway;
65
66 /**
67 * username
68 */
69 char *username;
70
71 /**
72 * password
73 */
74 char *password;
75
76 /**
77 * lock to safely access the TUN device fd
78 */
79 rwlock_t *lock;
80
81 /**
82 * TUN device file descriptor
83 */
84 int tunfd;
85
86 };
87
88 /**
89 * Outbound callback
90 */
91 static void send_esp(void *data, esp_packet_t *packet)
92 {
93 charon->sender->send_no_marker(charon->sender, (packet_t*)packet);
94 }
95
96 /**
97 * Inbound callback
98 */
99 static void deliver_plain(private_android_service_t *this,
100 ip_packet_t *packet)
101 {
102 chunk_t encoding;
103 ssize_t len;
104
105 encoding = packet->get_encoding(packet);
106
107 this->lock->read_lock(this->lock);
108 if (this->tunfd < 0)
109 { /* the TUN device is already closed */
110 this->lock->unlock(this->lock);
111 packet->destroy(packet);
112 return;
113 }
114 len = write(this->tunfd, encoding.ptr, encoding.len);
115 this->lock->unlock(this->lock);
116
117 if (len < 0 || len != encoding.len)
118 {
119 DBG1(DBG_DMN, "failed to write packet to TUN device: %s",
120 strerror(errno));
121 }
122 packet->destroy(packet);
123 }
124
125 /**
126 * Receiver callback
127 */
128 static void receiver_esp_cb(void *data, packet_t *packet)
129 {
130 esp_packet_t *esp_packet;
131
132 esp_packet = esp_packet_create_from_packet(packet);
133 ipsec->processor->queue_inbound(ipsec->processor, esp_packet);
134 }
135
136 /**
137 * Job handling outbound plaintext packets
138 */
139 static job_requeue_t handle_plain(private_android_service_t *this)
140 {
141 ip_packet_t *packet;
142 chunk_t raw;
143 fd_set set;
144 ssize_t len;
145 int tunfd;
146 bool old;
147 timeval_t tv = {
148 /* check every second if tunfd is still valid */
149 .tv_sec = 1,
150 };
151
152 FD_ZERO(&set);
153
154 this->lock->read_lock(this->lock);
155 if (this->tunfd < 0)
156 { /* the TUN device is already closed */
157 this->lock->unlock(this->lock);
158 return JOB_REQUEUE_NONE;
159 }
160 tunfd = this->tunfd;
161 FD_SET(tunfd, &set);
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(TUN_DEFAULT_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 ipsec->processor->queue_outbound(ipsec->processor, packet);
196 }
197 else
198 {
199 DBG1(DBG_DMN, "invalid IP packet read from TUN device");
200 }
201 return JOB_REQUEUE_DIRECT;
202 }
203
204 /**
205 * Add a route to the TUN device builder
206 */
207 static bool add_route(vpnservice_builder_t *builder, host_t *net,
208 u_int8_t prefix)
209 {
210 /* if route is 0.0.0.0/0, split it into two routes 0.0.0.0/1 and
211 * 128.0.0.0/1 because otherwise it would conflict with the current default
212 * route. likewise for IPv6 with ::/0. */
213 if (net->is_anyaddr(net) && prefix == 0)
214 {
215 bool success;
216
217 success = add_route(builder, net, 1);
218 if (net->get_family(net) == AF_INET)
219 {
220 net = host_create_from_string("128.0.0.0", 0);
221 }
222 else
223 {
224 net = host_create_from_string("8000::", 0);
225 }
226 success = success && add_route(builder, net, 1);
227 net->destroy(net);
228 return success;
229 }
230 return builder->add_route(builder, net, prefix);
231 }
232
233 /**
234 * Generate and set routes from installed IPsec policies
235 */
236 static bool add_routes(vpnservice_builder_t *builder, child_sa_t *child_sa)
237 {
238 traffic_selector_t *src_ts, *dst_ts;
239 enumerator_t *enumerator;
240 bool success = TRUE;
241
242 enumerator = child_sa->create_policy_enumerator(child_sa);
243 while (success && enumerator->enumerate(enumerator, &src_ts, &dst_ts))
244 {
245 host_t *net;
246 u_int8_t prefix;
247
248 dst_ts->to_subnet(dst_ts, &net, &prefix);
249 success = add_route(builder, net, prefix);
250 net->destroy(net);
251 }
252 enumerator->destroy(enumerator);
253 return success;
254 }
255
256 /**
257 * Setup a new TUN device for the supplied SAs, also queues a job that
258 * reads packets from this device.
259 * Additional information such as DNS servers are gathered in appropriate
260 * listeners asynchronously. To be sure every required bit of information is
261 * available this should be called after the CHILD_SA has been established.
262 */
263 static bool setup_tun_device(private_android_service_t *this,
264 ike_sa_t *ike_sa, child_sa_t *child_sa)
265 {
266 vpnservice_builder_t *builder;
267 enumerator_t *enumerator;
268 bool vip_found = FALSE, already_registered = FALSE;
269 host_t *vip;
270 int tunfd;
271
272 DBG1(DBG_DMN, "setting up TUN device for CHILD_SA %s{%u}",
273 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa));
274
275 builder = charonservice->get_vpnservice_builder(charonservice);
276
277 enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
278 while (enumerator->enumerate(enumerator, &vip))
279 {
280 if (!vip->is_anyaddr(vip))
281 {
282 if (!builder->add_address(builder, vip))
283 {
284 break;
285 }
286 vip_found = TRUE;
287 }
288 }
289 enumerator->destroy(enumerator);
290
291 if (!vip_found)
292 {
293 DBG1(DBG_DMN, "setting up TUN device failed, no virtual IP found");
294 return FALSE;
295 }
296 if (!add_routes(builder, child_sa) ||
297 !builder->set_mtu(builder, TUN_DEFAULT_MTU))
298 {
299 return FALSE;
300 }
301
302 tunfd = builder->establish(builder);
303 if (tunfd == -1)
304 {
305 return FALSE;
306 }
307
308 this->lock->write_lock(this->lock);
309 if (this->tunfd > 0)
310 { /* close previously opened TUN device */
311 close(this->tunfd);
312 already_registered = true;
313 }
314 this->tunfd = tunfd;
315 this->lock->unlock(this->lock);
316
317 DBG1(DBG_DMN, "successfully created TUN device");
318
319 if (!already_registered)
320 {
321 charon->receiver->add_esp_cb(charon->receiver,
322 (receiver_esp_cb_t)receiver_esp_cb, NULL);
323 ipsec->processor->register_inbound(ipsec->processor,
324 (ipsec_inbound_cb_t)deliver_plain, this);
325 ipsec->processor->register_outbound(ipsec->processor,
326 (ipsec_outbound_cb_t)send_esp, NULL);
327
328 lib->processor->queue_job(lib->processor,
329 (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this,
330 NULL, (callback_job_cancel_t)return_false));
331 }
332 return TRUE;
333 }
334
335 /**
336 * Close the current tun device
337 */
338 static void close_tun_device(private_android_service_t *this)
339 {
340 int tunfd;
341
342 this->lock->write_lock(this->lock);
343 if (this->tunfd < 0)
344 { /* already closed (or never created) */
345 this->lock->unlock(this->lock);
346 return;
347 }
348 tunfd = this->tunfd;
349 this->tunfd = -1;
350 this->lock->unlock(this->lock);
351
352 ipsec->processor->unregister_outbound(ipsec->processor,
353 (ipsec_outbound_cb_t)send_esp);
354 ipsec->processor->unregister_inbound(ipsec->processor,
355 (ipsec_inbound_cb_t)deliver_plain);
356 charon->receiver->del_esp_cb(charon->receiver,
357 (receiver_esp_cb_t)receiver_esp_cb);
358 close(tunfd);
359 }
360
361 METHOD(listener_t, child_updown, bool,
362 private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
363 bool up)
364 {
365 if (this->ike_sa == ike_sa)
366 {
367 if (up)
368 {
369 /* disable the hooks registered to catch initiation failures */
370 this->public.listener.ike_updown = NULL;
371 if (!setup_tun_device(this, ike_sa, child_sa))
372 {
373 DBG1(DBG_DMN, "failed to setup TUN device");
374 charonservice->update_status(charonservice,
375 CHARONSERVICE_GENERIC_ERROR);
376 return FALSE;
377
378 }
379 charonservice->update_status(charonservice,
380 CHARONSERVICE_CHILD_STATE_UP);
381 }
382 else
383 {
384 if (ike_sa->has_condition(ike_sa, COND_REAUTHENTICATING))
385 { /* we ignore this during reauthentication */
386 return TRUE;
387 }
388 close_tun_device(this);
389 charonservice->update_status(charonservice,
390 CHARONSERVICE_CHILD_STATE_DOWN);
391 return FALSE;
392 }
393 }
394 return TRUE;
395 }
396
397 METHOD(listener_t, ike_updown, bool,
398 private_android_service_t *this, ike_sa_t *ike_sa, bool up)
399 {
400 /* this callback is only registered during initiation, so if the IKE_SA
401 * goes down we assume an authentication error */
402 if (this->ike_sa == ike_sa && !up)
403 {
404 charonservice->update_status(charonservice,
405 CHARONSERVICE_AUTH_ERROR);
406 return FALSE;
407 }
408 return TRUE;
409 }
410
411 METHOD(listener_t, alert, bool,
412 private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
413 va_list args)
414 {
415 if (this->ike_sa == ike_sa)
416 {
417 switch (alert)
418 {
419 case ALERT_PEER_ADDR_FAILED:
420 charonservice->update_status(charonservice,
421 CHARONSERVICE_LOOKUP_ERROR);
422 break;
423 case ALERT_PEER_AUTH_FAILED:
424 charonservice->update_status(charonservice,
425 CHARONSERVICE_PEER_AUTH_ERROR);
426 break;
427 case ALERT_PEER_INIT_UNREACHABLE:
428 this->lock->read_lock(this->lock);
429 if (this->tunfd < 0)
430 { /* only handle this if we are not reestablishing the SA */
431 charonservice->update_status(charonservice,
432 CHARONSERVICE_UNREACHABLE_ERROR);
433 }
434 this->lock->unlock(this->lock);
435 break;
436 default:
437 break;
438 }
439 }
440 return TRUE;
441 }
442
443 METHOD(listener_t, ike_rekey, bool,
444 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
445 {
446 if (this->ike_sa == old)
447 {
448 this->ike_sa = new;
449 }
450 return TRUE;
451 }
452
453 METHOD(listener_t, ike_reestablish, bool,
454 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
455 {
456 if (this->ike_sa == old)
457 {
458 this->ike_sa = new;
459 /* re-register hook to detect initiation failures */
460 this->public.listener.ike_updown = _ike_updown;
461 /* the TUN device will be closed when the new CHILD_SA is established */
462 }
463 return TRUE;
464 }
465
466 static void add_auth_cfg_eap(private_android_service_t *this,
467 peer_cfg_t *peer_cfg, bool byod)
468 {
469 identification_t *user;
470 auth_cfg_t *auth;
471
472 auth = auth_cfg_create();
473 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
474 if (byod)
475 { /* use EAP-TTLS if BYOD is enabled */
476 auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TTLS);
477 }
478
479 user = identification_create_from_string(this->username);
480 auth->add(auth, AUTH_RULE_IDENTITY, user);
481
482 this->creds->add_username_password(this->creds, this->username,
483 this->password);
484 memwipe(this->password, strlen(this->password));
485 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
486 }
487
488 static bool add_auth_cfg_cert(private_android_service_t *this,
489 peer_cfg_t *peer_cfg)
490 {
491 certificate_t *cert;
492 identification_t *id;
493 auth_cfg_t *auth;
494
495 cert = this->creds->load_user_certificate(this->creds);
496 if (!cert)
497 {
498 return FALSE;
499 }
500
501 auth = auth_cfg_create();
502 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
503 auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
504
505 id = cert->get_subject(cert);
506 auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
507 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
508 return TRUE;
509 }
510
511 static job_requeue_t initiate(private_android_service_t *this)
512 {
513 identification_t *gateway;
514 ike_cfg_t *ike_cfg;
515 peer_cfg_t *peer_cfg;
516 child_cfg_t *child_cfg;
517 traffic_selector_t *ts;
518 ike_sa_t *ike_sa;
519 auth_cfg_t *auth;
520 lifetime_cfg_t lifetime = {
521 .time = {
522 .life = 10800, /* 3h */
523 .rekey = 10200, /* 2h50min */
524 .jitter = 300 /* 5min */
525 }
526 };
527
528 ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0",
529 charon->socket->get_port(charon->socket, FALSE),
530 this->gateway, IKEV2_UDP_PORT,
531 FRAGMENTATION_NO, 0);
532 ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
533 ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
534
535 peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
536 UNIQUE_REPLACE, 0, /* keyingtries */
537 36000, 0, /* rekey 10h, reauth none */
538 600, 600, /* jitter, over 10min */
539 TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
540 0, 0, /* DPD delay, timeout */
541 FALSE, NULL, NULL); /* mediation */
542 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET));
543 peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET6));
544
545 /* local auth config */
546 if (streq("ikev2-cert", this->type) ||
547 streq("ikev2-cert-eap", this->type))
548 {
549 if (!add_auth_cfg_cert(this, peer_cfg))
550 {
551 peer_cfg->destroy(peer_cfg);
552 charonservice->update_status(charonservice,
553 CHARONSERVICE_GENERIC_ERROR);
554 return JOB_REQUEUE_NONE;
555 }
556 }
557 if (streq("ikev2-eap", this->type) ||
558 streq("ikev2-cert-eap", this->type) ||
559 streq("ikev2-byod-eap", this->type))
560 {
561 add_auth_cfg_eap(this, peer_cfg, strpfx(this->type, "ikev2-byod"));
562 }
563
564 /* remote auth config */
565 auth = auth_cfg_create();
566 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
567 gateway = identification_create_from_string(this->gateway);
568 auth->add(auth, AUTH_RULE_IDENTITY, gateway);
569 auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE);
570 peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
571
572 child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
573 ACTION_NONE, ACTION_RESTART, ACTION_RESTART,
574 FALSE, 0, 0, NULL, NULL, 0);
575 /* create an ESP proposal with the algorithms currently supported by
576 * libipsec, no PFS for now */
577 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
578 "aes128gcm16-aes256gcm16"));
579 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
580 "aes128-sha256"));
581 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
582 "aes256-sha384"));
583 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
584 "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
585 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
586 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
587 ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
588 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
589 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
590 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
591 ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
592 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
593 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
594
595 /* get us an IKE_SA */
596 ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
597 peer_cfg);
598 if (!ike_sa)
599 {
600 peer_cfg->destroy(peer_cfg);
601 charonservice->update_status(charonservice,
602 CHARONSERVICE_GENERIC_ERROR);
603 return JOB_REQUEUE_NONE;
604 }
605 if (!ike_sa->get_peer_cfg(ike_sa))
606 {
607 ike_sa->set_peer_cfg(ike_sa, peer_cfg);
608 }
609 peer_cfg->destroy(peer_cfg);
610
611 /* store the IKE_SA so we can track its progress */
612 this->ike_sa = ike_sa;
613
614 /* get an additional reference because initiate consumes one */
615 child_cfg->get_ref(child_cfg);
616 if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
617 {
618 DBG1(DBG_CFG, "failed to initiate tunnel");
619 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
620 ike_sa);
621 return JOB_REQUEUE_NONE;
622 }
623 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
624 return JOB_REQUEUE_NONE;
625 }
626
627 METHOD(android_service_t, destroy, void,
628 private_android_service_t *this)
629 {
630 charon->bus->remove_listener(charon->bus, &this->public.listener);
631 /* make sure the tun device is actually closed */
632 close_tun_device(this);
633 this->lock->destroy(this->lock);
634 free(this->type);
635 free(this->gateway);
636 free(this->username);
637 if (this->password)
638 {
639 memwipe(this->password, strlen(this->password));
640 free(this->password);
641 }
642 free(this);
643 }
644
645 /**
646 * See header
647 */
648 android_service_t *android_service_create(android_creds_t *creds, char *type,
649 char *gateway, char *username,
650 char *password)
651 {
652 private_android_service_t *this;
653
654 INIT(this,
655 .public = {
656 .listener = {
657 .ike_rekey = _ike_rekey,
658 .ike_reestablish = _ike_reestablish,
659 .ike_updown = _ike_updown,
660 .child_updown = _child_updown,
661 .alert = _alert,
662 },
663 .destroy = _destroy,
664 },
665 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
666 .username = username,
667 .password = password,
668 .gateway = gateway,
669 .creds = creds,
670 .type = type,
671 .tunfd = -1,
672 );
673
674 charon->bus->add_listener(charon->bus, &this->public.listener);
675
676 lib->processor->queue_job(lib->processor,
677 (job_t*)callback_job_create((callback_job_cb_t)initiate, this,
678 NULL, NULL));
679 return &this->public;
680 }