diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/frontends/android/AndroidManifest.xml | 3 | ||||
-rw-r--r-- | src/frontends/android/src/org/strongswan/android/data/LogContentProvider.java | 36 |
2 files changed, 37 insertions, 2 deletions
diff --git a/src/frontends/android/AndroidManifest.xml b/src/frontends/android/AndroidManifest.xml index 1b1aabac4..1aa2d8502 100644 --- a/src/frontends/android/AndroidManifest.xml +++ b/src/frontends/android/AndroidManifest.xml @@ -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> diff --git a/src/frontends/android/src/org/strongswan/android/data/LogContentProvider.java b/src/frontends/android/src/org/strongswan/android/data/LogContentProvider.java index 7225ca4ef..370a8d5e4 100644 --- a/src/frontends/android/src/org/strongswan/android/data/LogContentProvider.java +++ b/src/frontends/android/src/org/strongswan/android/data/LogContentProvider.java @@ -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 |