android: Fix handling of redirects during IKE_AUTH
authorTobias Brunner <tobias@strongswan.org>
Wed, 27 Apr 2016 12:55:43 +0000 (14:55 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 2 May 2016 14:41:25 +0000 (16:41 +0200)
src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c

index b3e91d8..3db0f74 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (C) 2010-2015 Tobias Brunner
+ * Copyright (C) 2010-2016 Tobias Brunner
  * Copyright (C) 2012 Giuliano Grassi
  * Copyright (C) 2012 Ralf Sager
- * Hochschule fuer Technik Rapperswil
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -430,6 +430,84 @@ CALLBACK(reestablish, job_requeue_t,
        return JOB_REQUEUE_NONE;
 }
 
+METHOD(listener_t, ike_updown, bool,
+       private_android_service_t *this, ike_sa_t *ike_sa, bool up)
+{
+       /* this callback is only registered during initiation, so if the IKE_SA
+        * goes down we assume some kind of authentication error, more specific
+        * errors are catched in the alert() handler */
+       if (this->ike_sa == ike_sa && !up)
+       {
+               charonservice->update_status(charonservice,
+                                                                        CHARONSERVICE_AUTH_ERROR);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+METHOD(listener_t, ike_rekey, bool,
+       private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
+{
+       if (this->ike_sa == old)
+       {
+               this->ike_sa = new;
+       }
+       return TRUE;
+}
+
+METHOD(listener_t, ike_reestablish_post_redirect, bool,
+       private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
+       bool initiated)
+{
+       if (this->ike_sa == old && initiated)
+       {       /* if we get redirected during IKE_AUTH we just migrate to the new SA,
+                * we don't have a TUN device yet, so reinstalling it without DNS would
+                * fail (and using the DNS proxy is not required anyway) */
+               this->ike_sa = new;
+       }
+       return TRUE;
+}
+
+METHOD(listener_t, ike_reestablish_pre, bool,
+       private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
+{
+       if (this->ike_sa == old)
+       {
+               /* enable DNS proxy so hosts are properly resolved while the TUN device
+                * is still active */
+               this->lock->write_lock(this->lock);
+               this->use_dns_proxy = TRUE;
+               this->lock->unlock(this->lock);
+               /* if DNS servers are installed that are only reachable through the VPN
+                * the DNS proxy doesn't help, so uninstall DNS servers */
+               if (!setup_tun_device_without_dns(this))
+               {
+                       DBG1(DBG_DMN, "failed to setup TUN device without DNS");
+                       charonservice->update_status(charonservice,
+                                                                                CHARONSERVICE_GENERIC_ERROR);
+               }
+       }
+       return TRUE;
+}
+
+METHOD(listener_t, ike_reestablish_post, bool,
+       private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
+       bool initiated)
+{
+       if (this->ike_sa == old && initiated)
+       {
+               this->ike_sa = new;
+               /* re-register hook to detect initiation failures */
+               this->public.listener.ike_updown = _ike_updown;
+               /* if the IKE_SA got deleted by the responder we get the child_down()
+                * event on the old IKE_SA after this hook has been called, so they
+                * get ignored and thus we trigger the event here */
+               charonservice->update_status(charonservice,
+                                                                        CHARONSERVICE_CHILD_STATE_DOWN);
+       }
+       return TRUE;
+}
+
 METHOD(listener_t, child_updown, bool,
        private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
        bool up)
@@ -440,6 +518,9 @@ METHOD(listener_t, child_updown, bool,
                {
                        /* disable the hooks registered to catch initiation failures */
                        this->public.listener.ike_updown = NULL;
+                       /* enable hooks to handle reauthentications */
+                       this->public.listener.ike_reestablish_pre = _ike_reestablish_pre;
+                       this->public.listener.ike_reestablish_post = _ike_reestablish_post;
                        /* CHILD_SA is up so we can disable the DNS proxy we enabled to
                         * reestablish the SA */
                        this->lock->write_lock(this->lock);
@@ -465,21 +546,6 @@ METHOD(listener_t, child_updown, bool,
        return TRUE;
 }
 
-METHOD(listener_t, ike_updown, bool,
-       private_android_service_t *this, ike_sa_t *ike_sa, bool up)
-{
-       /* this callback is only registered during initiation, so if the IKE_SA
-        * goes down we assume some kind of authentication error, more specific
-        * errors are catched in the alert() handler */
-       if (this->ike_sa == ike_sa && !up)
-       {
-               charonservice->update_status(charonservice,
-                                                                        CHARONSERVICE_AUTH_ERROR);
-               return FALSE;
-       }
-       return TRUE;
-}
-
 METHOD(listener_t, alert, bool,
        private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
        va_list args)
@@ -554,56 +620,6 @@ METHOD(listener_t, alert, bool,
        return TRUE;
 }
 
-METHOD(listener_t, ike_rekey, bool,
-       private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
-{
-       if (this->ike_sa == old)
-       {
-               this->ike_sa = new;
-       }
-       return TRUE;
-}
-
-METHOD(listener_t, ike_reestablish_pre, bool,
-       private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
-{
-       if (this->ike_sa == old)
-       {
-               /* enable DNS proxy so hosts are properly resolved while the TUN device
-                * is still active */
-               this->lock->write_lock(this->lock);
-               this->use_dns_proxy = TRUE;
-               this->lock->unlock(this->lock);
-               /* if DNS servers are installed that are only reachable through the VPN
-                * the DNS proxy doesn't help, so uninstall DNS servers */
-               if (!setup_tun_device_without_dns(this))
-               {
-                       DBG1(DBG_DMN, "failed to setup TUN device without DNS");
-                       charonservice->update_status(charonservice,
-                                                                                CHARONSERVICE_GENERIC_ERROR);
-               }
-       }
-       return TRUE;
-}
-
-METHOD(listener_t, ike_reestablish_post, bool,
-       private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
-       bool initiated)
-{
-       if (this->ike_sa == old && initiated)
-       {
-               this->ike_sa = new;
-               /* re-register hook to detect initiation failures */
-               this->public.listener.ike_updown = _ike_updown;
-               /* if the IKE_SA got deleted by the responder we get the child_down()
-                * event on the old IKE_SA after this hook has been called, so they
-                * get ignored and thus we trigger the event here */
-               charonservice->update_status(charonservice,
-                                                                        CHARONSERVICE_CHILD_STATE_DOWN);
-       }
-       return TRUE;
-}
-
 static void add_auth_cfg_pw(private_android_service_t *this,
                                                        peer_cfg_t *peer_cfg, bool byod)
 {
@@ -824,8 +840,7 @@ android_service_t *android_service_create(android_creds_t *creds,
                .public = {
                        .listener = {
                                .ike_rekey = _ike_rekey,
-                               .ike_reestablish_pre = _ike_reestablish_pre,
-                               .ike_reestablish_post = _ike_reestablish_post,
+                               .ike_reestablish_post = _ike_reestablish_post_redirect,
                                .ike_updown = _ike_updown,
                                .child_updown = _child_updown,
                                .alert = _alert,