Use a separate (volatile) variable for certificate alias
authorTobias Brunner <tobias@strongswan.org>
Wed, 8 Aug 2012 17:10:33 +0000 (19:10 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 13 Aug 2012 09:18:23 +0000 (11:18 +0200)
If a connection is started while certificates are still loading and the
initiation is then canceled a deadlock could result if the daemon is
trying to enumerate the certificates just then.

src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java

index 1d9881c..58730c0 100644 (file)
@@ -46,6 +46,7 @@ public class CharonVpnService extends VpnService implements Runnable
        private VpnProfileDataSource mDataSource;
        private Thread mConnectionHandler;
        private VpnProfile mCurrentProfile;
+       private volatile String mCurrentCertificateAlias;
        private VpnProfile mNextProfile;
        private volatile boolean mProfileUpdated;
        private volatile boolean mTerminate;
@@ -189,6 +190,10 @@ public class CharonVpnService extends VpnService implements Runnable
                                                mCurrentProfile = mNextProfile;
                                                mNextProfile = null;
 
+                                               /* store this in a separate (volatile) variable to avoid
+                                                * a possible deadlock during deinitialization */
+                                               mCurrentCertificateAlias = mCurrentProfile.getCertificateAlias();
+
                                                setProfile(mCurrentProfile);
                                                setError(ErrorState.NO_ERROR);
                                                setState(State.CONNECTING);
@@ -350,7 +355,7 @@ public class CharonVpnService extends VpnService implements Runnable
         * @param hash optional alias (only hash part), if given matching certificates are returned
         * @return a list of DER encoded CA certificates
         */
-       private synchronized byte[][] getTrustedCertificates(String hash)
+       private byte[][] getTrustedCertificates(String hash)
        {
                ArrayList<byte[]> certs = new ArrayList<byte[]>();
                TrustedCertificateManager certman = TrustedCertificateManager.getInstance();
@@ -373,7 +378,7 @@ public class CharonVpnService extends VpnService implements Runnable
                        }
                        else
                        {
-                               String alias = this.mCurrentProfile.getCertificateAlias();
+                               String alias = this.mCurrentCertificateAlias;
                                if (alias != null)
                                {
                                        X509Certificate cert = certman.getCACertificateFromAlias(alias);