diff --git a/app/build.gradle b/app/build.gradle index 48b1234e7..67c9602ea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -103,6 +103,7 @@ dependencies { annotationProcessor "com.github.hotchemi:permissionsdispatcher-processor:$permissionDispatcherVersion" // Apache Commons Collections implementation 'commons-collections:commons-collections:3.2.1' + implementation 'org.apache.commons:commons-io:1.3.2' // Base64 implementation 'biz.source_code:base64coder:2010-12-19' // IO-Extras diff --git a/app/src/main/java/com/kunzisoft/keepass/app/App.java b/app/src/main/java/com/kunzisoft/keepass/app/App.java index 6a861dcde..346fdd1e4 100644 --- a/app/src/main/java/com/kunzisoft/keepass/app/App.java +++ b/app/src/main/java/com/kunzisoft/keepass/app/App.java @@ -92,7 +92,7 @@ public class App extends MultiDexApplication { @Override public void onTerminate() { if ( db != null ) { - db.clear(); + db.clear(getApplicationContext()); } super.onTerminate(); } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/BinaryPool.java b/app/src/main/java/com/kunzisoft/keepass/database/BinaryPool.java index 5acfd27c9..c256d5fd9 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/BinaryPool.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/BinaryPool.java @@ -51,6 +51,8 @@ public class BinaryPool { } public void clear() { + for (Entry entry: pool.entrySet()) + entry.getValue().clear(); pool.clear(); } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/Database.java b/app/src/main/java/com/kunzisoft/keepass/database/Database.java index fc822cc6e..ce5c4ce50 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/Database.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/Database.java @@ -39,6 +39,8 @@ import com.kunzisoft.keepass.icons.IconDrawableFactory; import com.kunzisoft.keepass.tasks.ProgressTaskUpdater; import com.kunzisoft.keepass.utils.UriUtil; +import org.apache.commons.io.FileUtils; + import java.io.BufferedInputStream; import java.io.File; import java.io.FileNotFoundException; @@ -58,7 +60,7 @@ public class Database { private static final String TAG = Database.class.getName(); - private PwDatabase pm; + private PwDatabase pwDatabase; private Uri mUri; private SearchDbHelper searchHelper; private boolean readOnly = false; @@ -69,11 +71,11 @@ public class Database { private boolean loaded = false; public PwDatabase getPwDatabase() { - return pm; + return pwDatabase; } public void setPwDatabase(PwDatabase pm) { - this.pm = pm; + this.pwDatabase = pm; } public void setUri(Uri mUri) { @@ -156,20 +158,20 @@ public class Database { bis.reset(); // Return to the start - pm = databaseImporter.openDatabase(bis, password, keyFileInputStream, progressTaskUpdater); - if ( pm != null ) { + pwDatabase = databaseImporter.openDatabase(bis, password, keyFileInputStream, progressTaskUpdater); + if ( pwDatabase != null ) { try { - switch (pm.getVersion()) { + switch (pwDatabase.getVersion()) { case V3: - PwGroupV3 rootV3 = ((PwDatabaseV3) pm).getRootGroup(); - ((PwDatabaseV3) pm).populateGlobals(rootV3); - passwordEncodingError = !pm.validatePasswordEncoding(password); + PwGroupV3 rootV3 = ((PwDatabaseV3) pwDatabase).getRootGroup(); + ((PwDatabaseV3) pwDatabase).populateGlobals(rootV3); + passwordEncodingError = !pwDatabase.validatePasswordEncoding(password); searchHelper = new SearchDbHelper.SearchDbHelperV3(ctx); break; case V4: - PwGroupV4 rootV4 = ((PwDatabaseV4) pm).getRootGroup(); - ((PwDatabaseV4) pm).populateGlobals(rootV4); - passwordEncodingError = !pm.validatePasswordEncoding(password); + PwGroupV4 rootV4 = ((PwDatabaseV4) pwDatabase).getRootGroup(); + ((PwDatabaseV4) pwDatabase).populateGlobals(rootV4); + passwordEncodingError = !pwDatabase.validatePasswordEncoding(password); searchHelper = new SearchDbHelper.SearchDbHelperV4(ctx); break; } @@ -188,11 +190,11 @@ public class Database { public PwGroup search(String str, int max) { if (searchHelper == null) { return null; } try { - switch (pm.getVersion()) { + switch (pwDatabase.getVersion()) { case V3: - return ((SearchDbHelper.SearchDbHelperV3) searchHelper).search(((PwDatabaseV3) pm), str, max); + return ((SearchDbHelper.SearchDbHelperV3) searchHelper).search(((PwDatabaseV3) pwDatabase), str, max); case V4: - return ((SearchDbHelper.SearchDbHelperV4) searchHelper).search(((PwDatabaseV4) pm), str, max); + return ((SearchDbHelper.SearchDbHelperV4) searchHelper).search(((PwDatabaseV4) pwDatabase), str, max); } } catch (Exception e) { Log.e(TAG, "Search can't be performed with this SearchHelper", e); @@ -262,7 +264,7 @@ public class Database { FileOutputStream fos = null; try { fos = new FileOutputStream(tempFile); - PwDbOutput pmo = PwDbOutput.getInstance(pm, fos); + PwDbOutput pmo = PwDbOutput.getInstance(pwDatabase, fos); if (pmo != null) pmo.output(); } catch (Exception e) { @@ -290,7 +292,7 @@ public class Database { OutputStream os = null; try { os = ctx.getContentResolver().openOutputStream(uri); - PwDbOutput pmo = PwDbOutput.getInstance(pm, os); + PwDbOutput pmo = PwDbOutput.getInstance(pwDatabase, os); if (pmo != null) pmo.output(); } catch (Exception e) { @@ -305,10 +307,19 @@ public class Database { } // TODO Clear database when lock broadcast is receive in backstage - public void clear() { + public void clear(Context context) { drawFactory.clearCache(); + // Delete the cache of the database if present + if (pwDatabase != null) + pwDatabase.clearCache(); + // In all cases, delete all the files in the temp dir + try { + FileUtils.cleanDirectory(context.getFilesDir()); + } catch (IOException e) { + Log.e(TAG, "Unable to clear the directory cache.", e); + } - pm = null; + pwDatabase = null; mUri = null; loaded = false; passwordEncodingError = false; @@ -546,7 +557,7 @@ public class Database { case V4: newPwGroup = new PwGroupV4((PwGroupV4) parent); } - newPwGroup.setId(pm.newGroupId()); + newPwGroup.setId(pwDatabase.newGroupId()); } catch (Exception e) { Log.e(TAG, "This version of PwGroup can't be created", e); } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabase.java b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabase.java index cd2a797ae..3dda73adf 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabase.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabase.java @@ -430,4 +430,6 @@ public abstract class PwDatabase */ public abstract void initNew(String dbPath); + public void clearCache() {} + } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV4.java b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV4.java index 512a8e644..a20ad5a0a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV4.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV4.java @@ -754,4 +754,9 @@ public class PwDatabaseV4 extends PwDatabase { return filename.substring(0, lastExtDot); } + @Override + public void clearCache() { + super.clearCache(); + binPool.clear(); + } } \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java b/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java index 5263b3d3f..355af8eff 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java @@ -21,6 +21,7 @@ package com.kunzisoft.keepass.database.security; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; import java.io.ByteArrayInputStream; import java.io.File; @@ -31,7 +32,8 @@ import java.util.Arrays; import java.util.Objects; public class ProtectedBinary implements Parcelable { - + + private static final String TAG = ProtectedBinary.class.getName(); public final static ProtectedBinary EMPTY = new ProtectedBinary(); private boolean protect; @@ -84,6 +86,12 @@ public class ProtectedBinary implements Parcelable { return null; } + public void clear() { + data = null; + if (dataFile != null && !dataFile.delete()) + Log.e(TAG, "Unable to delete temp file " + dataFile.getAbsolutePath()); + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -92,13 +100,13 @@ public class ProtectedBinary implements Parcelable { return protect == that.protect && size == that.size && Arrays.equals(data, that.data) && - Objects.equals(dataFile, that.dataFile); + Objects.equals(dataFile, that.dataFile); // TODO old equals } @Override public int hashCode() { - int result = Objects.hash(protect, dataFile, size); + int result = Objects.hash(protect, dataFile, size); // TODO old hash result = 31 * result + Arrays.hashCode(data); return result; } diff --git a/app/src/main/java/com/kunzisoft/keepass/password/PasswordActivity.java b/app/src/main/java/com/kunzisoft/keepass/password/PasswordActivity.java index 1db624afb..71c246737 100644 --- a/app/src/main/java/com/kunzisoft/keepass/password/PasswordActivity.java +++ b/app/src/main/java/com/kunzisoft/keepass/password/PasswordActivity.java @@ -252,7 +252,7 @@ public class PasswordActivity extends StylishActivity case LockingActivity.RESULT_EXIT_LOCK: case Activity.RESULT_CANCELED: setEmptyViews(); - App.getDB().clear(); + App.getDB().clear(getApplicationContext()); break; } } @@ -938,7 +938,7 @@ public class PasswordActivity extends StylishActivity private void loadDatabase(String password, Uri keyfile) { // Clear before we load Database database = App.getDB(); - database.clear(); + database.clear(getApplicationContext()); // Clear the shutdown flag App.clearShutdown();