]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/frontends/android/jni/libandroidbridge/backend/android_service.c
Added an option that allows to force IKEv1 fragmentation
[thirdparty/strongswan.git] / src / frontends / android / jni / libandroidbridge / backend / android_service.c
1 /*
2 * Copyright (C) 2010-2012 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 DBG1(DBG_DMN, "select on TUN device failed: %s", strerror(errno));
171 return JOB_REQUEUE_NONE;
172 }
173 else if (len == 0)
174 { /* timeout, check again right away */
175 return JOB_REQUEUE_DIRECT;
176 }
177
178 raw = chunk_alloc(TUN_DEFAULT_MTU);
179 len = read(tunfd, raw.ptr, raw.len);
180 if (len < 0)
181 {
182 DBG1(DBG_DMN, "reading from TUN device failed: %s", strerror(errno));
183 chunk_free(&raw);
184 return JOB_REQUEUE_FAIR;
185 }
186 raw.len = len;
187
188 packet = ip_packet_create(raw);
189 if (packet)
190 {
191 ipsec->processor->queue_outbound(ipsec->processor, packet);
192 }
193 else
194 {
195 DBG1(DBG_DMN, "invalid IP packet read from TUN device");
196 }
197 return JOB_REQUEUE_DIRECT;
198 }
199
200 /**
201 * Add a route to the TUN device builder
202 */
203 static bool add_route(vpnservice_builder_t *builder, host_t *net,
204 u_int8_t prefix)
205 {
206 /* if route is 0.0.0.0/0, split it into two routes 0.0.0.0/1 and
207 * 128.0.0.0/1 because otherwise it would conflict with the current default
208 * route */
209 if (net->is_anyaddr(net) && prefix == 0)
210 {
211 bool success;
212
213 success = add_route(builder, net, 1);
214 net = host_create_from_string("128.0.0.0", 0);
215 success = success && add_route(builder, net, 1);
216 net->destroy(net);
217 return success;
218 }
219 return builder->add_route(builder, net, prefix);
220 }
221
222 /**
223 * Generate and set routes from installed IPsec policies
224 */
225 static bool add_routes(vpnservice_builder_t *builder, child_sa_t *child_sa)
226 {
227 traffic_selector_t *src_ts, *dst_ts;
228 enumerator_t *enumerator;
229 bool success = TRUE;
230
231 enumerator = child_sa->create_policy_enumerator(child_sa);
232 while (success && enumerator->enumerate(enumerator, &src_ts, &dst_ts))
233 {
234 host_t *net;
235 u_int8_t prefix;
236
237 dst_ts->to_subnet(dst_ts, &net, &prefix);
238 success = add_route(builder, net, prefix);
239 net->destroy(net);
240 }
241 enumerator->destroy(enumerator);
242 return success;
243 }
244
245 /**
246 * Setup a new TUN device for the supplied SAs, also queues a job that
247 * reads packets from this device.
248 * Additional information such as DNS servers are gathered in appropriate
249 * listeners asynchronously. To be sure every required bit of information is
250 * available this should be called after the CHILD_SA has been established.
251 */
252 static bool setup_tun_device(private_android_service_t *this,
253 ike_sa_t *ike_sa, child_sa_t *child_sa)
254 {
255 vpnservice_builder_t *builder;
256 enumerator_t *enumerator;
257 bool vip_found = FALSE, already_registered = FALSE;
258 host_t *vip;
259 int tunfd;
260
261 DBG1(DBG_DMN, "setting up TUN device for CHILD_SA %s{%u}",
262 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa));
263
264 builder = charonservice->get_vpnservice_builder(charonservice);
265
266 enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
267 while (enumerator->enumerate(enumerator, &vip))
268 {
269 if (!vip->is_anyaddr(vip))
270 {
271 if (!builder->add_address(builder, vip))
272 {
273 break;
274 }
275 vip_found = TRUE;
276 }
277 }
278 enumerator->destroy(enumerator);
279
280 if (!vip_found)
281 {
282 DBG1(DBG_DMN, "setting up TUN device failed, no virtual IP found");
283 return FALSE;
284 }
285 if (!add_routes(builder, child_sa) ||
286 !builder->set_mtu(builder, TUN_DEFAULT_MTU))
287 {
288 return FALSE;
289 }
290
291 tunfd = builder->establish(builder);
292 if (tunfd == -1)
293 {
294 return FALSE;
295 }
296
297 this->lock->write_lock(this->lock);
298 if (this->tunfd > 0)
299 { /* close previously opened TUN device */
300 close(this->tunfd);
301 already_registered = true;
302 }
303 this->tunfd = tunfd;
304 this->lock->unlock(this->lock);
305
306 DBG1(DBG_DMN, "successfully created TUN device");
307
308 if (!already_registered)
309 {
310 charon->receiver->add_esp_cb(charon->receiver,
311 (receiver_esp_cb_t)receiver_esp_cb, NULL);
312 ipsec->processor->register_inbound(ipsec->processor,
313 (ipsec_inbound_cb_t)deliver_plain, this);
314 ipsec->processor->register_outbound(ipsec->processor,
315 (ipsec_outbound_cb_t)send_esp, NULL);
316
317 lib->processor->queue_job(lib->processor,
318 (job_t*)callback_job_create((callback_job_cb_t)handle_plain, this,
319 NULL, (callback_job_cancel_t)return_false));
320 }
321 return TRUE;
322 }
323
324 /**
325 * Close the current tun device
326 */
327 static void close_tun_device(private_android_service_t *this)
328 {
329 int tunfd;
330
331 this->lock->write_lock(this->lock);
332 if (this->tunfd < 0)
333 { /* already closed (or never created) */
334 this->lock->unlock(this->lock);
335 return;
336 }
337 tunfd = this->tunfd;
338 this->tunfd = -1;
339 this->lock->unlock(this->lock);
340
341 ipsec->processor->unregister_outbound(ipsec->processor,
342 (ipsec_outbound_cb_t)send_esp);
343 ipsec->processor->unregister_inbound(ipsec->processor,
344 (ipsec_inbound_cb_t)deliver_plain);
345 charon->receiver->del_esp_cb(charon->receiver,
346 (receiver_esp_cb_t)receiver_esp_cb);
347 close(tunfd);
348 }
349
350 METHOD(listener_t, child_updown, bool,
351 private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
352 bool up)
353 {
354 if (this->ike_sa == ike_sa)
355 {
356 if (up)
357 {
358 /* disable the hooks registered to catch initiation failures */
359 this->public.listener.ike_updown = NULL;
360 if (!setup_tun_device(this, ike_sa, child_sa))
361 {
362 DBG1(DBG_DMN, "failed to setup TUN device");
363 charonservice->update_status(charonservice,
364 CHARONSERVICE_GENERIC_ERROR);
365 return FALSE;
366
367 }
368 charonservice->update_status(charonservice,
369 CHARONSERVICE_CHILD_STATE_UP);
370 }
371 else
372 {
373 if (ike_sa->has_condition(ike_sa, COND_REAUTHENTICATING))
374 { /* we ignore this during reauthentication */
375 return TRUE;
376 }
377 close_tun_device(this);
378 charonservice->update_status(charonservice,
379 CHARONSERVICE_CHILD_STATE_DOWN);
380 return FALSE;
381 }
382 }
383 return TRUE;
384 }
385
386 METHOD(listener_t, ike_updown, bool,
387 private_android_service_t *this, ike_sa_t *ike_sa, bool up)
388 {
389 /* this callback is only registered during initiation, so if the IKE_SA
390 * goes down we assume an authentication error */
391 if (this->ike_sa == ike_sa && !up)
392 {
393 charonservice->update_status(charonservice,
394 CHARONSERVICE_AUTH_ERROR);
395 return FALSE;
396 }
397 return TRUE;
398 }
399
400 METHOD(listener_t, alert, bool,
401 private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
402 va_list args)
403 {
404 if (this->ike_sa == ike_sa)
405 {
406 switch (alert)
407 {
408 case ALERT_PEER_ADDR_FAILED:
409 charonservice->update_status(charonservice,
410 CHARONSERVICE_LOOKUP_ERROR);
411 break;
412 case ALERT_PEER_AUTH_FAILED:
413 charonservice->update_status(charonservice,
414 CHARONSERVICE_PEER_AUTH_ERROR);
415 break;
416 case ALERT_PEER_INIT_UNREACHABLE:
417 this->lock->read_lock(this->lock);
418 if (this->tunfd < 0)
419 { /* only handle this if we are not reestablishing the SA */
420 charonservice->update_status(charonservice,
421 CHARONSERVICE_UNREACHABLE_ERROR);
422 }
423 this->lock->unlock(this->lock);
424 break;
425 default:
426 break;
427 }
428 }
429 return TRUE;
430 }
431
432 METHOD(listener_t, ike_rekey, bool,
433 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
434 {
435 if (this->ike_sa == old)
436 {
437 this->ike_sa = new;
438 }
439 return TRUE;
440 }
441
442 METHOD(listener_t, ike_reestablish, bool,
443 private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
444 {
445 if (this->ike_sa == old)
446 {
447 this->ike_sa = new;
448 /* re-register hook to detect initiation failures */
449 this->public.listener.ike_updown = _ike_updown;
450 /* the TUN device will be closed when the new CHILD_SA is established */
451 }
452 return TRUE;
453 }
454
455 static job_requeue_t initiate(private_android_service_t *this)
456 {
457 identification_t *gateway, *user;
458 ike_cfg_t *ike_cfg;
459 peer_cfg_t *peer_cfg;
460 child_cfg_t *child_cfg;
461 traffic_selector_t *ts;
462 ike_sa_t *ike_sa;
463 auth_cfg_t *auth;
464 lifetime_cfg_t lifetime = {
465 .time = {
466 .life = 10800, /* 3h */
467 .rekey = 10200, /* 2h50min */
468 .jitter = 300 /* 5min */
469 }
470 };
471
472 ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0", FALSE,
473 charon->socket->get_port(charon->socket, FALSE),
474 this->gateway, FALSE, IKEV2_UDP_PORT,
475 FRAGMENTATION_NO);
476 ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
477
478 peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
479 UNIQUE_REPLACE, 0, /* keyingtries */
480 36000, 0, /* rekey 10h, reauth none */
481 600, 600, /* jitter, over 10min */
482 TRUE, FALSE, /* mobike, aggressive */
483 0, 0, /* DPD delay, timeout */
484 FALSE, NULL, NULL); /* mediation */
485 peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
486
487 /* local auth config */
488 if (streq("ikev2-eap", this->type))
489 {
490 auth = auth_cfg_create();
491 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
492 user = identification_create_from_string(this->username);
493 auth->add(auth, AUTH_RULE_IDENTITY, user);
494
495 this->creds->add_username_password(this->creds, this->username,
496 this->password);
497 memwipe(this->password, strlen(this->password));
498 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
499 }
500 else if (streq("ikev2-cert", this->type))
501 {
502 certificate_t *cert;
503 identification_t *id;
504
505 cert = this->creds->load_user_certificate(this->creds);
506 if (!cert)
507 {
508 peer_cfg->destroy(peer_cfg);
509 charonservice->update_status(charonservice,
510 CHARONSERVICE_GENERIC_ERROR);
511 return JOB_REQUEUE_NONE;
512
513 }
514 auth = auth_cfg_create();
515 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
516 auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert);
517 id = cert->get_subject(cert);
518 auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
519 peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
520 }
521
522 /* remote auth config */
523 auth = auth_cfg_create();
524 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
525 gateway = identification_create_from_string(this->gateway);
526 auth->add(auth, AUTH_RULE_IDENTITY, gateway);
527 auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE);
528 peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
529
530 child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
531 ACTION_NONE, ACTION_RESTART, ACTION_RESTART,
532 FALSE, 0, 0, NULL, NULL, 0);
533 /* create an ESP proposal with the algorithms currently supported by
534 * libipsec, no PFS for now */
535 child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP,
536 "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
537 ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "0.0.0.0",
538 0, "255.255.255.255", 65535);
539 child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
540 ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "0.0.0.0",
541 0, "255.255.255.255", 65535);
542 child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
543 peer_cfg->add_child_cfg(peer_cfg, child_cfg);
544
545 /* get us an IKE_SA */
546 ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
547 peer_cfg);
548 if (!ike_sa)
549 {
550 peer_cfg->destroy(peer_cfg);
551 charonservice->update_status(charonservice,
552 CHARONSERVICE_GENERIC_ERROR);
553 return JOB_REQUEUE_NONE;
554 }
555 if (!ike_sa->get_peer_cfg(ike_sa))
556 {
557 ike_sa->set_peer_cfg(ike_sa, peer_cfg);
558 }
559 peer_cfg->destroy(peer_cfg);
560
561 /* store the IKE_SA so we can track its progress */
562 this->ike_sa = ike_sa;
563
564 /* get an additional reference because initiate consumes one */
565 child_cfg->get_ref(child_cfg);
566 if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
567 {
568 DBG1(DBG_CFG, "failed to initiate tunnel");
569 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
570 ike_sa);
571 return JOB_REQUEUE_NONE;
572 }
573 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
574 return JOB_REQUEUE_NONE;
575 }
576
577 METHOD(android_service_t, destroy, void,
578 private_android_service_t *this)
579 {
580 charon->bus->remove_listener(charon->bus, &this->public.listener);
581 /* make sure the tun device is actually closed */
582 close_tun_device(this);
583 this->lock->destroy(this->lock);
584 free(this->type);
585 free(this->gateway);
586 free(this->username);
587 if (this->password)
588 {
589 memwipe(this->password, strlen(this->password));
590 free(this->password);
591 }
592 free(this);
593 }
594
595 /**
596 * See header
597 */
598 android_service_t *android_service_create(android_creds_t *creds, char *type,
599 char *gateway, char *username,
600 char *password)
601 {
602 private_android_service_t *this;
603
604 INIT(this,
605 .public = {
606 .listener = {
607 .ike_rekey = _ike_rekey,
608 .ike_reestablish = _ike_reestablish,
609 .ike_updown = _ike_updown,
610 .child_updown = _child_updown,
611 .alert = _alert,
612 },
613 .destroy = _destroy,
614 },
615 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
616 .username = username,
617 .password = password,
618 .gateway = gateway,
619 .creds = creds,
620 .type = type,
621 .tunfd = -1,
622 );
623
624 charon->bus->add_listener(charon->bus, &this->public.listener);
625
626 lib->processor->queue_job(lib->processor,
627 (job_t*)callback_job_create((callback_job_cb_t)initiate, this,
628 NULL, NULL));
629 return &this->public;
630 }