]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Only allow access to log file via explicitly created URIs
authorTobias Brunner <tobias@strongswan.org>
Fri, 10 Aug 2012 14:42:49 +0000 (16:42 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 13 Aug 2012 09:27:55 +0000 (11:27 +0200)
Since ContentProviders are public and permissions don't seem to work any
other application could access the log file.  With this token system
only URIs we explicitly created can be accessed.

src/frontends/android/AndroidManifest.xml
src/frontends/android/src/org/strongswan/android/data/LogContentProvider.java

index 1b1aabac471f6df327312e54f4ad4dd6b0511168..1aa2d8502cca7f8eff464a8c19c14ef7344cd086 100644 (file)
@@ -62,6 +62,9 @@
         <provider
             android:name=".data.LogContentProvider"
             android:authorities="org.strongswan.android.content.log" >
+            <!-- android:grantUriPermissions="true" combined with a custom permission does
+                 not work (probably too many indirections with ACTION_SEND) so we secure
+                 this provider with a custom ticketing system -->
         </provider>
     </application>
 
index 7225ca4ef2aa515b631652bae71ea2d68a5feef6..370a8d5e47bb3c53f23c962df8a2c07c88b9581a 100644 (file)
@@ -17,6 +17,9 @@ package org.strongswan.android.data;
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.strongswan.android.logic.CharonVpnService;
 
@@ -26,11 +29,15 @@ import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
 import android.provider.OpenableColumns;
 
 public class LogContentProvider extends ContentProvider
 {
        private static final String AUTHORITY = "org.strongswan.android.content.log";
+       /* an Uri is valid for 30 minutes */
+       private static final long URI_VALIDITY = 30 * 60 * 1000;
+       private static ConcurrentHashMap<Uri, Long> mUris = new ConcurrentHashMap<Uri, Long>();
        private File mLogFile;
 
        public LogContentProvider()
@@ -50,7 +57,17 @@ public class LogContentProvider extends ContentProvider
         */
        public static Uri createContentUri()
        {
-               Uri uri = Uri.parse("content://"+ AUTHORITY + "/" + CharonVpnService.LOG_FILE);
+               SecureRandom random;
+               try
+               {
+                       random = SecureRandom.getInstance("SHA1PRNG");
+               }
+               catch (NoSuchAlgorithmException e)
+               {
+                       return null;
+               }
+               Uri uri = Uri.parse("content://" + AUTHORITY + "/" + random.nextLong());
+               mUris.put(uri, SystemClock.uptimeMillis());
                return uri;
        }
 
@@ -71,6 +88,11 @@ public class LogContentProvider extends ContentProvider
                {
                        return null;
                }
+               Long timestamp = mUris.get(uri);
+               if (timestamp == null)
+               {       /* don't check the validity as this information is not really private */
+                       return null;
+               }
                MatrixCursor cursor = new MatrixCursor(projection, 1);
                if (OpenableColumns.DISPLAY_NAME.equals(cursor.getColumnName(0)))
                {
@@ -90,7 +112,17 @@ public class LogContentProvider extends ContentProvider
        @Override
        public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
        {
-               return ParcelFileDescriptor.open(mLogFile, ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_ONLY);
+               Long timestamp = mUris.get(uri);
+               if (timestamp != null)
+               {
+                       long elapsed = SystemClock.uptimeMillis() - timestamp;
+                       if (elapsed > 0 && elapsed < URI_VALIDITY)
+                       {       /* we fail if clock wrapped, should happen rarely though */
+                               return ParcelFileDescriptor.open(mLogFile, ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_ONLY);
+                       }
+                       mUris.remove(uri);
+               }
+               return super.openFile(uri, mode);
        }
 
        @Override