fix delete file securely method and use for delete original file
This commit is contained in:
@@ -18,23 +18,15 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.pgp;
|
package org.sufficientlysecure.keychain.pgp;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.pm.PackageInfo;
|
import java.util.regex.Matcher;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Preferences;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.RandomAccessFile;
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class PgpHelper {
|
public class PgpHelper {
|
||||||
|
|
||||||
@@ -50,35 +42,6 @@ public class PgpHelper {
|
|||||||
".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*",
|
".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*",
|
||||||
Pattern.DOTALL);
|
Pattern.DOTALL);
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes file securely by overwriting it with random data before deleting it.
|
|
||||||
* <p/>
|
|
||||||
* TODO: Does this really help on flash storage?
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static void deleteFileSecurely(Context context, Progressable progressable, File file)
|
|
||||||
throws IOException {
|
|
||||||
long length = file.length();
|
|
||||||
SecureRandom random = new SecureRandom();
|
|
||||||
RandomAccessFile raf = new RandomAccessFile(file, "rws");
|
|
||||||
raf.seek(0);
|
|
||||||
raf.getFilePointer();
|
|
||||||
byte[] data = new byte[1 << 16];
|
|
||||||
int pos = 0;
|
|
||||||
String msg = context.getString(R.string.progress_deleting_securely, file.getName());
|
|
||||||
while (pos < length) {
|
|
||||||
if (progressable != null) {
|
|
||||||
progressable.setProgress(msg, (int) (100 * pos / length), 100);
|
|
||||||
}
|
|
||||||
random.nextBytes(data);
|
|
||||||
raf.write(data);
|
|
||||||
pos += data.length;
|
|
||||||
}
|
|
||||||
raf.close();
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fixing broken PGP MESSAGE Strings coming from GMail/AOSP Mail
|
* Fixing broken PGP MESSAGE Strings coming from GMail/AOSP Mail
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -800,33 +800,18 @@ public class DecryptListFragment
|
|||||||
// we can only ever delete a file once, if we got this far either it's gone or it will never work
|
// we can only ever delete a file once, if we got this far either it's gone or it will never work
|
||||||
mCanDelete = false;
|
mCanDelete = false;
|
||||||
|
|
||||||
if ("file".equals(uri.getScheme())) {
|
try {
|
||||||
File file = new File(uri.getPath());
|
int deleted = FileHelper.deleteFileSecurely(activity, uri);
|
||||||
if (file.delete()) {
|
if (deleted > 0) {
|
||||||
Notify.create(activity, R.string.file_delete_ok, Style.OK).show();
|
Notify.create(activity, R.string.file_delete_ok, Style.OK).show();
|
||||||
} else {
|
} else {
|
||||||
Notify.create(activity, R.string.file_delete_none, Style.WARN).show();
|
Notify.create(activity, R.string.file_delete_none, Style.WARN).show();
|
||||||
}
|
}
|
||||||
return;
|
} catch (Exception e) {
|
||||||
|
Log.e(Constants.TAG, "exception deleting file", e);
|
||||||
|
Notify.create(activity, R.string.file_delete_exception, Style.ERROR).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("content".equals(uri.getScheme())) {
|
|
||||||
try {
|
|
||||||
int deleted = activity.getContentResolver().delete(uri, null, null);
|
|
||||||
if (deleted > 0) {
|
|
||||||
Notify.create(activity, R.string.file_delete_ok, Style.OK).show();
|
|
||||||
} else {
|
|
||||||
Notify.create(activity, R.string.file_delete_none, Style.WARN).show();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(Constants.TAG, "exception deleting file", e);
|
|
||||||
Notify.create(activity, R.string.file_delete_exception, Style.ERROR).show();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Notify.create(activity, R.string.file_delete_exception, Style.ERROR).show();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DecryptFilesAdapter extends RecyclerView.Adapter<ViewHolder> {
|
public class DecryptFilesAdapter extends RecyclerView.Adapter<ViewHolder> {
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ import java.io.File;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
@@ -33,7 +35,6 @@ import android.content.ActivityNotFoundException;
|
|||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.AssetFileDescriptor;
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
@@ -41,20 +42,13 @@ import android.net.Uri;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.provider.DocumentsContract;
|
import android.provider.DocumentsContract;
|
||||||
import android.provider.OpenableColumns;
|
import android.provider.OpenableColumns;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.system.ErrnoException;
|
|
||||||
import android.system.Os;
|
|
||||||
import android.system.StructStat;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
|
||||||
import static android.system.OsConstants.S_IROTH;
|
|
||||||
|
|
||||||
/** This class offers a number of helper functions for saving documents.
|
/** This class offers a number of helper functions for saving documents.
|
||||||
*
|
*
|
||||||
* There are three entry points here: openDocument, saveDocument and
|
* There are three entry points here: openDocument, saveDocument and
|
||||||
@@ -167,6 +161,14 @@ public class FileHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static long getFileSize(Context context, Uri uri, long def) {
|
public static long getFileSize(Context context, Uri uri, long def) {
|
||||||
|
if ("file".equals(uri.getScheme())) {
|
||||||
|
long size = new File(uri.getPath()).length();
|
||||||
|
if (size == 0) {
|
||||||
|
size = def;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
long size = def;
|
long size = def;
|
||||||
try {
|
try {
|
||||||
Cursor cursor = context.getContentResolver().query(uri, new String[]{OpenableColumns.SIZE}, null, null, null);
|
Cursor cursor = context.getContentResolver().query(uri, new String[]{OpenableColumns.SIZE}, null, null, null);
|
||||||
@@ -261,6 +263,44 @@ public class FileHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes data at a URI securely by overwriting it with random data
|
||||||
|
* before deleting it. This method is fail-fast - if we can't securely
|
||||||
|
* delete the file, we don't delete it at all.
|
||||||
|
*/
|
||||||
|
public static int deleteFileSecurely(Context context, Uri uri)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
ContentResolver resolver = context.getContentResolver();
|
||||||
|
long lengthLeft = FileHelper.getFileSize(context, uri);
|
||||||
|
|
||||||
|
if (lengthLeft == -1) {
|
||||||
|
throw new IOException("Error opening file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
byte[] randomData = new byte[1024];
|
||||||
|
|
||||||
|
OutputStream out = resolver.openOutputStream(uri, "w");
|
||||||
|
if (out == null) {
|
||||||
|
throw new IOException("Error opening file!");
|
||||||
|
}
|
||||||
|
out = new BufferedOutputStream(out);
|
||||||
|
while (lengthLeft > 0) {
|
||||||
|
random.nextBytes(randomData);
|
||||||
|
out.write(randomData, 0, lengthLeft > randomData.length ? randomData.length : (int) lengthLeft);
|
||||||
|
lengthLeft -= randomData.length;
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
if ("file".equals(uri.getScheme())) {
|
||||||
|
return new File(uri.getPath()).delete() ? 1 : 0;
|
||||||
|
} else {
|
||||||
|
return resolver.delete(uri, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/** Checks if external storage is mounted if file is located on external storage. */
|
/** Checks if external storage is mounted if file is located on external storage. */
|
||||||
public static boolean isStorageMounted(String file) {
|
public static boolean isStorageMounted(String file) {
|
||||||
if (file.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
|
if (file.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
|
||||||
|
|||||||
Reference in New Issue
Block a user