mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Generalize file/URI handling
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 Brian Pellin.
|
* Copyright 2010-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -19,11 +19,16 @@
|
|||||||
*/
|
*/
|
||||||
package com.keepassdroid.tests;
|
package com.keepassdroid.tests;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import com.keepassdroid.utils.EmptyUtils;
|
||||||
|
import com.keepassdroid.utils.UriUtil;
|
||||||
|
|
||||||
public class TestUtil {
|
public class TestUtil {
|
||||||
|
|
||||||
@@ -46,4 +51,13 @@ public class TestUtil {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static InputStream getKeyFileInputStream(Context ctx, String keyfile) throws FileNotFoundException {
|
||||||
|
InputStream keyIs = null;
|
||||||
|
if (!EmptyUtils.isNullOrEmpty(keyfile)) {
|
||||||
|
Uri uri = UriUtil.parseDefaultFile(keyfile);
|
||||||
|
keyIs = UriUtil.getUriInputStream(ctx, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyIs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 Brian Pellin.
|
* Copyright 2010-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -21,11 +21,13 @@ package com.keepassdroid.tests.database;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
import com.keepassdroid.database.load.ImporterV3;
|
import com.keepassdroid.database.load.ImporterV3;
|
||||||
import com.keepassdroid.tests.TestUtil;
|
import com.keepassdroid.tests.TestUtil;
|
||||||
|
import com.keepassdroid.utils.UriUtil;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -44,7 +46,7 @@ public class Kdb3 extends AndroidTestCase {
|
|||||||
InputStream is = am.open(dbAsset, AssetManager.ACCESS_STREAMING);
|
InputStream is = am.open(dbAsset, AssetManager.ACCESS_STREAMING);
|
||||||
|
|
||||||
ImporterV3 importer = new ImporterV3();
|
ImporterV3 importer = new ImporterV3();
|
||||||
importer.openDatabase(is, password, keyPath);
|
importer.openDatabase(is, password, TestUtil.getKeyFileInputStream(ctx, keyPath));
|
||||||
|
|
||||||
is.close();
|
is.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 Brian Pellin.
|
* Copyright 2010-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -38,7 +38,7 @@ public class Kdb3Twofish extends AndroidTestCase {
|
|||||||
|
|
||||||
ImporterV3 importer = new ImporterV3();
|
ImporterV3 importer = new ImporterV3();
|
||||||
|
|
||||||
PwDatabaseV3 db = importer.openDatabase(is, "12345", "");
|
PwDatabaseV3 db = importer.openDatabase(is, "12345", null);
|
||||||
|
|
||||||
assertTrue(db.algorithm == PwEncryptionAlgorithm.Twofish);
|
assertTrue(db.algorithm == PwEncryptionAlgorithm.Twofish);
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class Kdb4 extends AndroidTestCase {
|
|||||||
InputStream is = am.open("test.kdbx", AssetManager.ACCESS_STREAMING);
|
InputStream is = am.open("test.kdbx", AssetManager.ACCESS_STREAMING);
|
||||||
|
|
||||||
ImporterV4 importer = new ImporterV4();
|
ImporterV4 importer = new ImporterV4();
|
||||||
importer.openDatabase(is, "12345", "");
|
importer.openDatabase(is, "12345", null);
|
||||||
|
|
||||||
is.close();
|
is.close();
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ public class Kdb4 extends AndroidTestCase {
|
|||||||
InputStream is = am.open("test.kdbx", AssetManager.ACCESS_STREAMING);
|
InputStream is = am.open("test.kdbx", AssetManager.ACCESS_STREAMING);
|
||||||
|
|
||||||
ImporterV4 importer = new ImporterV4();
|
ImporterV4 importer = new ImporterV4();
|
||||||
PwDatabaseV4 db = importer.openDatabase(is, "12345", "");
|
PwDatabaseV4 db = importer.openDatabase(is, "12345", null);
|
||||||
is.close();
|
is.close();
|
||||||
|
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
@@ -91,7 +91,7 @@ public class Kdb4 extends AndroidTestCase {
|
|||||||
InputStream bis = new ByteArrayInputStream(data);
|
InputStream bis = new ByteArrayInputStream(data);
|
||||||
bis = new CopyInputStream(bis, fos);
|
bis = new CopyInputStream(bis, fos);
|
||||||
importer = new ImporterV4();
|
importer = new ImporterV4();
|
||||||
db = importer.openDatabase(bis, "12345", "");
|
db = importer.openDatabase(bis, "12345", null);
|
||||||
bis.close();
|
bis.close();
|
||||||
|
|
||||||
fos.close();
|
fos.close();
|
||||||
@@ -112,7 +112,7 @@ public class Kdb4 extends AndroidTestCase {
|
|||||||
InputStream is = am.open("keyfile.kdbx", AssetManager.ACCESS_STREAMING);
|
InputStream is = am.open("keyfile.kdbx", AssetManager.ACCESS_STREAMING);
|
||||||
|
|
||||||
ImporterV4 importer = new ImporterV4();
|
ImporterV4 importer = new ImporterV4();
|
||||||
importer.openDatabase(is, "12345", "/sdcard/key");
|
importer.openDatabase(is, "12345", TestUtil.getKeyFileInputStream(ctx,"/sdcard/key"));
|
||||||
|
|
||||||
is.close();
|
is.close();
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ public class Kdb4 extends AndroidTestCase {
|
|||||||
InputStream is = am.open("key-only.kdbx", AssetManager.ACCESS_STREAMING);
|
InputStream is = am.open("key-only.kdbx", AssetManager.ACCESS_STREAMING);
|
||||||
|
|
||||||
ImporterV4 importer = new ImporterV4();
|
ImporterV4 importer = new ImporterV4();
|
||||||
importer.openDatabase(is, "", "/sdcard/key");
|
importer.openDatabase(is, "", TestUtil.getKeyFileInputStream(ctx, "/sdcard/key"));
|
||||||
|
|
||||||
is.close();
|
is.close();
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ public class Kdb4 extends AndroidTestCase {
|
|||||||
InputStream is = am.open("no-encrypt.kdbx", AssetManager.ACCESS_STREAMING);
|
InputStream is = am.open("no-encrypt.kdbx", AssetManager.ACCESS_STREAMING);
|
||||||
|
|
||||||
ImporterV4 importer = new ImporterV4();
|
ImporterV4 importer = new ImporterV4();
|
||||||
importer.openDatabase(is, "12345", "");
|
importer.openDatabase(is, "12345", null);
|
||||||
|
|
||||||
is.close();
|
is.close();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 Brian Pellin.
|
* Copyright 2010-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -38,7 +38,7 @@ public class Kdb4Header extends AndroidTestCase {
|
|||||||
|
|
||||||
ImporterV4 importer = new ImporterV4();
|
ImporterV4 importer = new ImporterV4();
|
||||||
|
|
||||||
PwDatabaseV4 db = importer.openDatabase(is, "12345", "");
|
PwDatabaseV4 db = importer.openDatabase(is, "12345", null);
|
||||||
|
|
||||||
assertEquals(6000, db.numKeyEncRounds);
|
assertEquals(6000, db.numKeyEncRounds);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014 Brian Pellin.
|
* Copyright 2014-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -47,7 +47,7 @@ public class SprEngineTest extends AndroidTestCase {
|
|||||||
InputStream is = am.open("test.kdbx", AssetManager.ACCESS_STREAMING);
|
InputStream is = am.open("test.kdbx", AssetManager.ACCESS_STREAMING);
|
||||||
|
|
||||||
ImporterV4 importer = new ImporterV4();
|
ImporterV4 importer = new ImporterV4();
|
||||||
db = importer.openDatabase(is, "12345", "");
|
db = importer.openDatabase(is, "12345", null);
|
||||||
|
|
||||||
is.close();
|
is.close();
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ import android.net.Uri;
|
|||||||
import com.keepassdroid.Database;
|
import com.keepassdroid.Database;
|
||||||
import com.keepassdroid.database.PwDatabaseV3Debug;
|
import com.keepassdroid.database.PwDatabaseV3Debug;
|
||||||
import com.keepassdroid.database.load.Importer;
|
import com.keepassdroid.database.load.Importer;
|
||||||
|
import com.keepassdroid.tests.TestUtil;
|
||||||
|
import com.keepassdroid.utils.EmptyUtils;
|
||||||
|
import com.keepassdroid.utils.UriUtil;
|
||||||
|
|
||||||
public class TestData {
|
public class TestData {
|
||||||
private static final String TEST1_KEYFILE = "";
|
private static final String TEST1_KEYFILE = "";
|
||||||
@@ -54,7 +57,10 @@ public class TestData {
|
|||||||
InputStream is = am.open(asset, AssetManager.ACCESS_STREAMING);
|
InputStream is = am.open(asset, AssetManager.ACCESS_STREAMING);
|
||||||
|
|
||||||
Database Db = new Database();
|
Database Db = new Database();
|
||||||
Db.LoadData(ctx, is, password, keyfile, Importer.DEBUG);
|
|
||||||
|
InputStream keyIs = TestUtil.getKeyFileInputStream(ctx, keyfile);
|
||||||
|
|
||||||
|
Db.LoadData(ctx, is, password, keyIs, Importer.DEBUG);
|
||||||
Uri.Builder b = new Uri.Builder();
|
Uri.Builder b = new Uri.Builder();
|
||||||
|
|
||||||
Db.mUri = b.scheme("file").path(filename).build();
|
Db.mUri = b.scheme("file").path(filename).build();
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import java.io.SyncFailedException;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ import com.keepassdroid.database.load.ImporterFactory;
|
|||||||
import com.keepassdroid.database.save.PwDbOutput;
|
import com.keepassdroid.database.save.PwDbOutput;
|
||||||
import com.keepassdroid.icons.DrawableFactory;
|
import com.keepassdroid.icons.DrawableFactory;
|
||||||
import com.keepassdroid.search.SearchDbHelper;
|
import com.keepassdroid.search.SearchDbHelper;
|
||||||
|
import com.keepassdroid.utils.UriUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author bpellin
|
* @author bpellin
|
||||||
@@ -68,19 +70,19 @@ public class Database {
|
|||||||
loaded = true;
|
loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadData(Context ctx, InputStream is, String password, String keyfile) throws IOException, InvalidDBException {
|
public void LoadData(Context ctx, InputStream is, String password, InputStream keyInputStream) throws IOException, InvalidDBException {
|
||||||
LoadData(ctx, is, password, keyfile, new UpdateStatus(), !Importer.DEBUG);
|
LoadData(ctx, is, password, keyInputStream, new UpdateStatus(), !Importer.DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadData(Context ctx, Uri uri, String password, String keyfile) throws IOException, FileNotFoundException, InvalidDBException {
|
public void LoadData(Context ctx, Uri uri, String password, Uri keyfile) throws IOException, FileNotFoundException, InvalidDBException {
|
||||||
LoadData(ctx, uri, password, keyfile, new UpdateStatus(), !Importer.DEBUG);
|
LoadData(ctx, uri, password, keyfile, new UpdateStatus(), !Importer.DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadData(Context ctx, Uri uri, String password, String keyfile, UpdateStatus status) throws IOException, FileNotFoundException, InvalidDBException {
|
public void LoadData(Context ctx, Uri uri, String password, Uri keyfile, UpdateStatus status) throws IOException, FileNotFoundException, InvalidDBException {
|
||||||
LoadData(ctx, uri, password, keyfile, status, !Importer.DEBUG);
|
LoadData(ctx, uri, password, keyfile, status, !Importer.DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadData(Context ctx, Uri uri, String password, String keyfile, UpdateStatus status, boolean debug) throws IOException, FileNotFoundException, InvalidDBException {
|
public void LoadData(Context ctx, Uri uri, String password, Uri keyfile, UpdateStatus status, boolean debug) throws IOException, FileNotFoundException, InvalidDBException {
|
||||||
mUri = uri;
|
mUri = uri;
|
||||||
readOnly = false;
|
readOnly = false;
|
||||||
if (uri.getScheme().equals("file")) {
|
if (uri.getScheme().equals("file")) {
|
||||||
@@ -88,16 +90,17 @@ public class Database {
|
|||||||
readOnly = !file.canWrite();
|
readOnly = !file.canWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream is = ctx.getContentResolver().openInputStream(uri);
|
InputStream is = UriUtil.getUriInputStream(ctx, uri);
|
||||||
|
InputStream kfIs = UriUtil.getUriInputStream(ctx, keyfile);
|
||||||
|
|
||||||
LoadData(ctx, is, password, keyfile, status, debug);
|
LoadData(ctx, is, password, kfIs, status, debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadData(Context ctx, InputStream is, String password, String keyfile, boolean debug) throws IOException, InvalidDBException {
|
public void LoadData(Context ctx, InputStream is, String password, InputStream kfIs, boolean debug) throws IOException, InvalidDBException {
|
||||||
LoadData(ctx, is, password, keyfile, new UpdateStatus(), debug);
|
LoadData(ctx, is, password, kfIs, new UpdateStatus(), debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadData(Context ctx, InputStream is, String password, String keyfile, UpdateStatus status, boolean debug) throws IOException, InvalidDBException {
|
public void LoadData(Context ctx, InputStream is, String password, InputStream kfIs, UpdateStatus status, boolean debug) throws IOException, InvalidDBException {
|
||||||
|
|
||||||
BufferedInputStream bis = new BufferedInputStream(is);
|
BufferedInputStream bis = new BufferedInputStream(is);
|
||||||
|
|
||||||
@@ -112,19 +115,19 @@ public class Database {
|
|||||||
|
|
||||||
bis.reset(); // Return to the start
|
bis.reset(); // Return to the start
|
||||||
|
|
||||||
pm = imp.openDatabase(bis, password, keyfile, status);
|
pm = imp.openDatabase(bis, password, kfIs, status);
|
||||||
if ( pm != null ) {
|
if ( pm != null ) {
|
||||||
PwGroup root = pm.rootGroup;
|
PwGroup root = pm.rootGroup;
|
||||||
|
|
||||||
pm.populateGlobals(root);
|
pm.populateGlobals(root);
|
||||||
|
|
||||||
LoadData(ctx, pm, password, keyfile, status);
|
LoadData(ctx, pm, password, kfIs, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
loaded = true;
|
loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadData(Context ctx, PwDatabase pm, String password, String keyfile, UpdateStatus status) {
|
public void LoadData(Context ctx, PwDatabase pm, String password, InputStream keyInputStream, UpdateStatus status) {
|
||||||
if ( pm != null ) {
|
if ( pm != null ) {
|
||||||
passwordEncodingError = !pm.validatePasswordEncoding(password);
|
passwordEncodingError = !pm.validatePasswordEncoding(password);
|
||||||
}
|
}
|
||||||
@@ -148,7 +151,7 @@ public class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void SaveData(Context ctx, Uri uri) throws IOException, PwDbOutputException {
|
public void SaveData(Context ctx, Uri uri) throws IOException, PwDbOutputException {
|
||||||
if (uri.getScheme().equals("data")) {
|
if (uri.getScheme().equals("file")) {
|
||||||
String filename = uri.getPath();
|
String filename = uri.getPath();
|
||||||
File tempFile = new File(filename + ".tmp");
|
File tempFile = new File(filename + ".tmp");
|
||||||
FileOutputStream fos = new FileOutputStream(tempFile);
|
FileOutputStream fos = new FileOutputStream(tempFile);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package com.keepassdroid;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@@ -33,7 +34,6 @@ import android.net.Uri;
|
|||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@@ -61,7 +61,7 @@ import com.keepassdroid.fileselect.BrowserDialog;
|
|||||||
import com.keepassdroid.intents.Intents;
|
import com.keepassdroid.intents.Intents;
|
||||||
import com.keepassdroid.settings.AppSettingsActivity;
|
import com.keepassdroid.settings.AppSettingsActivity;
|
||||||
import com.keepassdroid.utils.Interaction;
|
import com.keepassdroid.utils.Interaction;
|
||||||
import com.keepassdroid.utils.StrUtil;
|
import com.keepassdroid.utils.UriUtil;
|
||||||
import com.keepassdroid.utils.Util;
|
import com.keepassdroid.utils.Util;
|
||||||
|
|
||||||
public class PasswordActivity extends LockingActivity {
|
public class PasswordActivity extends LockingActivity {
|
||||||
@@ -76,9 +76,10 @@ public class PasswordActivity extends LockingActivity {
|
|||||||
private static final int FILE_BROWSE = 256;
|
private static final int FILE_BROWSE = 256;
|
||||||
public static final int GET_CONTENT = 257;
|
public static final int GET_CONTENT = 257;
|
||||||
|
|
||||||
private String mFileName;
|
//private String mFileName;
|
||||||
private String mKeyFile;
|
//private String mKeyFile;
|
||||||
private Uri mUri = null;
|
private Uri mDbUri = null;
|
||||||
|
private Uri mKeyUri = null;
|
||||||
private boolean mRememberKeyfile;
|
private boolean mRememberKeyfile;
|
||||||
SharedPreferences prefs;
|
SharedPreferences prefs;
|
||||||
|
|
||||||
@@ -123,11 +124,13 @@ public class PasswordActivity extends LockingActivity {
|
|||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
String filename = data.getDataString();
|
String filename = data.getDataString();
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
|
/*
|
||||||
if (filename.startsWith("file://")) {
|
if (filename.startsWith("file://")) {
|
||||||
filename = filename.substring(7);
|
filename = filename.substring(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = URLDecoder.decode(filename);
|
filename = URLDecoder.decode(filename);
|
||||||
|
*/
|
||||||
|
|
||||||
EditText fn = (EditText) findViewById(R.id.pass_keyfile);
|
EditText fn = (EditText) findViewById(R.id.pass_keyfile);
|
||||||
fn.setText(filename);
|
fn.setText(filename);
|
||||||
@@ -182,27 +185,27 @@ public class PasswordActivity extends LockingActivity {
|
|||||||
|
|
||||||
private void retrieveSettings() {
|
private void retrieveSettings() {
|
||||||
String defaultFilename = prefs.getString(KEY_DEFAULT_FILENAME, "");
|
String defaultFilename = prefs.getString(KEY_DEFAULT_FILENAME, "");
|
||||||
if (mFileName.length() > 0 && mFileName.equals(defaultFilename)) {
|
if (mDbUri.getPath().length() > 0 && UriUtil.equalsDefaultfile(mDbUri, defaultFilename)) {
|
||||||
CheckBox checkbox = (CheckBox) findViewById(R.id.default_database);
|
CheckBox checkbox = (CheckBox) findViewById(R.id.default_database);
|
||||||
checkbox.setChecked(true);
|
checkbox.setChecked(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getKeyFile(String filename) {
|
private Uri getKeyFile(Uri dbUri) {
|
||||||
if ( mRememberKeyfile ) {
|
if ( mRememberKeyfile ) {
|
||||||
|
|
||||||
String keyfile = App.getFileHistory().getFileByName(filename);
|
return App.getFileHistory().getFileByName(dbUri);
|
||||||
|
|
||||||
return keyfile;
|
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateView() {
|
private void populateView() {
|
||||||
setEditText(R.id.filename, mFileName);
|
String db = (mDbUri == null) ? "" : mDbUri.toString();
|
||||||
|
setEditText(R.id.filename, db);
|
||||||
|
|
||||||
setEditText(R.id.pass_keyfile, mKeyFile);
|
String key = (mKeyUri == null) ? "" : mKeyUri.toString();
|
||||||
|
setEditText(R.id.pass_keyfile, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -226,7 +229,7 @@ public class PasswordActivity extends LockingActivity {
|
|||||||
String newDefaultFileName;
|
String newDefaultFileName;
|
||||||
|
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
newDefaultFileName = mFileName;
|
newDefaultFileName = mDbUri.toString();
|
||||||
} else {
|
} else {
|
||||||
newDefaultFileName = "";
|
newDefaultFileName = "";
|
||||||
}
|
}
|
||||||
@@ -251,9 +254,13 @@ public class PasswordActivity extends LockingActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadDatabase(String pass, String keyfile)
|
private void loadDatabase(String pass, String keyfile) {
|
||||||
|
loadDatabase(pass, UriUtil.parseDefaultFile(keyfile));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadDatabase(String pass, Uri keyfile)
|
||||||
{
|
{
|
||||||
if ( pass.length() == 0 && keyfile.length() == 0 ) {
|
if ( pass.length() == 0 && (keyfile == null || keyfile.toString().length() == 0)) {
|
||||||
errorMessage(R.string.error_nopass);
|
errorMessage(R.string.error_nopass);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -268,19 +275,8 @@ public class PasswordActivity extends LockingActivity {
|
|||||||
// Clear the shutdown flag
|
// Clear the shutdown flag
|
||||||
App.clearShutdown();
|
App.clearShutdown();
|
||||||
|
|
||||||
Uri uri;
|
Uri uri = UriUtil.parseDefaultFile(fileName);
|
||||||
if (mUri != null) {
|
|
||||||
uri = mUri;
|
|
||||||
} else {
|
|
||||||
uri = Uri.parse(fileName);
|
|
||||||
|
|
||||||
String scheme = uri.getScheme();
|
|
||||||
if (scheme == null || scheme.equals("")) {
|
|
||||||
Uri.Builder builder = new Uri.Builder();
|
|
||||||
builder.scheme("file").authority("").path(fileName);
|
|
||||||
uri = builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Handler handler = new Handler();
|
Handler handler = new Handler();
|
||||||
LoadDB task = new LoadDB(db, PasswordActivity.this, uri, pass, keyfile, new AfterLoad(handler, db));
|
LoadDB task = new LoadDB(db, PasswordActivity.this, uri, pass, keyfile, new AfterLoad(handler, db));
|
||||||
ProgressTask pt = new ProgressTask(PasswordActivity.this, task, R.string.loading_database);
|
ProgressTask pt = new ProgressTask(PasswordActivity.this, task, R.string.loading_database);
|
||||||
@@ -365,39 +361,38 @@ public class PasswordActivity extends LockingActivity {
|
|||||||
String action = i.getAction();;
|
String action = i.getAction();;
|
||||||
if ( action != null && action.equals(VIEW_INTENT) ) {
|
if ( action != null && action.equals(VIEW_INTENT) ) {
|
||||||
Uri incoming = i.getData();
|
Uri incoming = i.getData();
|
||||||
|
mDbUri = incoming;
|
||||||
if (incoming.getScheme().equals("file")) {
|
if (incoming.getScheme().equals("file")) {
|
||||||
mFileName = incoming.getPath();
|
String fileName = incoming.getPath();
|
||||||
|
|
||||||
if (mFileName.length() == 0) {
|
if (fileName.length() == 0) {
|
||||||
// No file name
|
// No file name
|
||||||
return R.string.FileNotFound;
|
return R.string.FileNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
File dbFile = new File(mFileName);
|
File dbFile = new File(fileName);
|
||||||
if (!dbFile.exists()) {
|
if (!dbFile.exists()) {
|
||||||
// File does not exist
|
// File does not exist
|
||||||
return R.string.FileNotFound;
|
return R.string.FileNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
mKeyFile = getKeyFile(mFileName);
|
mKeyUri = getKeyFile(mDbUri);
|
||||||
}
|
}
|
||||||
else if (incoming.getScheme().equals("content")) {
|
else if (incoming.getScheme().equals("content")) {
|
||||||
mUri = incoming;
|
mKeyUri = getKeyFile(mDbUri);
|
||||||
mFileName = mUri.toString();
|
|
||||||
mKeyFile = getKeyFile(mFileName);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return R.string.error_can_not_handle_uri;
|
return R.string.error_can_not_handle_uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mFileName = i.getStringExtra(KEY_FILENAME);
|
mDbUri = UriUtil.parseDefaultFile(i.getStringExtra(KEY_FILENAME));
|
||||||
mKeyFile = i.getStringExtra(KEY_KEYFILE);
|
mKeyUri = UriUtil.parseDefaultFile(i.getStringExtra(KEY_KEYFILE));
|
||||||
password = i.getStringExtra(KEY_PASSWORD);
|
password = i.getStringExtra(KEY_PASSWORD);
|
||||||
launch_immediately = i.getBooleanExtra(KEY_LAUNCH_IMMEDIATELY, false);
|
launch_immediately = i.getBooleanExtra(KEY_LAUNCH_IMMEDIATELY, false);
|
||||||
|
|
||||||
if ( mKeyFile == null || mKeyFile.length() == 0) {
|
if ( mKeyUri == null || mKeyUri.toString().length() == 0) {
|
||||||
mKeyFile = getKeyFile(mFileName);
|
mKeyUri = getKeyFile(mDbUri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -458,12 +453,19 @@ public class PasswordActivity extends LockingActivity {
|
|||||||
if (Interaction.isIntentAvailable(PasswordActivity.this, Intents.OPEN_INTENTS_FILE_BROWSE)) {
|
if (Interaction.isIntentAvailable(PasswordActivity.this, Intents.OPEN_INTENTS_FILE_BROWSE)) {
|
||||||
Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE);
|
Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE);
|
||||||
|
|
||||||
if (mFileName.length() > 0) {
|
// Get file path parent if possible
|
||||||
File keyfile = new File(mFileName);
|
try {
|
||||||
File parent = keyfile.getParentFile();
|
if (mDbUri != null && mDbUri.toString().length() > 0) {
|
||||||
if (parent != null) {
|
if (mDbUri.getScheme().equals("file")) {
|
||||||
i.setData(Uri.parse("file://" + parent.getAbsolutePath()));
|
File keyfile = new File(mDbUri.getPath());
|
||||||
|
File parent = keyfile.getParentFile();
|
||||||
|
if (parent != null) {
|
||||||
|
i.setData(Uri.parse("file://" + parent.getAbsolutePath()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -485,7 +487,7 @@ public class PasswordActivity extends LockingActivity {
|
|||||||
retrieveSettings();
|
retrieveSettings();
|
||||||
|
|
||||||
if (launch_immediately)
|
if (launch_immediately)
|
||||||
loadDatabase(password, mKeyFile);
|
loadDatabase(password, mDbUri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package com.keepassdroid;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -33,11 +34,13 @@ import com.keepassdroid.app.App;
|
|||||||
import com.keepassdroid.database.edit.FileOnFinish;
|
import com.keepassdroid.database.edit.FileOnFinish;
|
||||||
import com.keepassdroid.database.edit.OnFinish;
|
import com.keepassdroid.database.edit.OnFinish;
|
||||||
import com.keepassdroid.database.edit.SetPassword;
|
import com.keepassdroid.database.edit.SetPassword;
|
||||||
|
import com.keepassdroid.utils.EmptyUtils;
|
||||||
|
import com.keepassdroid.utils.UriUtil;
|
||||||
|
|
||||||
public class SetPasswordDialog extends CancelDialog {
|
public class SetPasswordDialog extends CancelDialog {
|
||||||
|
|
||||||
private byte[] masterKey;
|
private byte[] masterKey;
|
||||||
private String mKeyfile;
|
private Uri mKeyfile;
|
||||||
private FileOnFinish mFinish;
|
private FileOnFinish mFinish;
|
||||||
|
|
||||||
public SetPasswordDialog(Context context) {
|
public SetPasswordDialog(Context context) {
|
||||||
@@ -54,7 +57,7 @@ public class SetPasswordDialog extends CancelDialog {
|
|||||||
return masterKey;
|
return masterKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String keyfile() {
|
public Uri keyfile() {
|
||||||
return mKeyfile;
|
return mKeyfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,11 +86,11 @@ public class SetPasswordDialog extends CancelDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextView keyfileView = (TextView) findViewById(R.id.pass_keyfile);
|
TextView keyfileView = (TextView) findViewById(R.id.pass_keyfile);
|
||||||
String keyfile = keyfileView.getText().toString();
|
Uri keyfile = UriUtil.parseDefaultFile(keyfileView.getText().toString());
|
||||||
mKeyfile = keyfile;
|
mKeyfile = keyfile;
|
||||||
|
|
||||||
// Verify that a password or keyfile is set
|
// Verify that a password or keyfile is set
|
||||||
if ( pass.length() == 0 && keyfile.length() == 0 ) {
|
if ( pass.length() == 0 && EmptyUtils.isNullOrEmpty(keyfile)) {
|
||||||
Toast.makeText(getContext(), R.string.error_nopass, Toast.LENGTH_LONG).show();
|
Toast.makeText(getContext(), R.string.error_nopass, Toast.LENGTH_LONG).show();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009-2015 Brian Pellin.
|
* Copyright 2009-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -20,10 +20,12 @@
|
|||||||
package com.keepassdroid.database;
|
package com.keepassdroid.database;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.DigestOutputStream;
|
import java.security.DigestOutputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
@@ -40,6 +42,7 @@ import com.keepassdroid.crypto.finalkey.FinalKeyFactory;
|
|||||||
import com.keepassdroid.database.exception.InvalidKeyFileException;
|
import com.keepassdroid.database.exception.InvalidKeyFileException;
|
||||||
import com.keepassdroid.database.exception.KeyFileEmptyException;
|
import com.keepassdroid.database.exception.KeyFileEmptyException;
|
||||||
import com.keepassdroid.stream.NullOutputStream;
|
import com.keepassdroid.stream.NullOutputStream;
|
||||||
|
import com.keepassdroid.utils.Util;
|
||||||
|
|
||||||
public abstract class PwDatabase {
|
public abstract class PwDatabase {
|
||||||
|
|
||||||
@@ -100,20 +103,20 @@ public abstract class PwDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract byte[] getMasterKey(String key, String keyFileName) throws InvalidKeyFileException, IOException;
|
public abstract byte[] getMasterKey(String key, InputStream keyInputStream) throws InvalidKeyFileException, IOException;
|
||||||
|
|
||||||
public void setMasterKey(String key, String keyFileName)
|
public void setMasterKey(String key, InputStream keyInputStream)
|
||||||
throws InvalidKeyFileException, IOException {
|
throws InvalidKeyFileException, IOException {
|
||||||
assert( key != null && keyFileName != null );
|
assert(key != null);
|
||||||
|
|
||||||
masterKey = getMasterKey(key, keyFileName);
|
masterKey = getMasterKey(key, keyInputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] getCompositeKey(String key, String keyFileName)
|
protected byte[] getCompositeKey(String key, InputStream keyInputStream)
|
||||||
throws InvalidKeyFileException, IOException {
|
throws InvalidKeyFileException, IOException {
|
||||||
assert(key != null && keyFileName != null);
|
assert(key != null && keyInputStream != null);
|
||||||
|
|
||||||
byte[] fileKey = getFileKey(keyFileName);
|
byte[] fileKey = getFileKey(keyInputStream);
|
||||||
|
|
||||||
byte[] passwordKey = getPasswordKey(key);
|
byte[] passwordKey = getPasswordKey(key);
|
||||||
|
|
||||||
@@ -129,53 +132,32 @@ public abstract class PwDatabase {
|
|||||||
return md.digest(fileKey);
|
return md.digest(fileKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] getFileKey(String fileName)
|
protected byte[] getFileKey(InputStream keyInputStream)
|
||||||
throws InvalidKeyFileException, IOException {
|
throws InvalidKeyFileException, IOException {
|
||||||
assert(fileName != null);
|
assert(keyInputStream != null);
|
||||||
|
|
||||||
File keyfile = new File(fileName);
|
byte[] key = loadXmlKeyFile(keyInputStream);
|
||||||
|
|
||||||
if ( ! keyfile.exists() ) {
|
|
||||||
throw new InvalidKeyFileException();
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] key = loadXmlKeyFile(fileName);
|
|
||||||
if ( key != null ) {
|
if ( key != null ) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInputStream fis;
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
try {
|
Util.copyStream(keyInputStream, bos);
|
||||||
fis = new FileInputStream(keyfile);
|
byte[] keyData = bos.toByteArray();
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
throw new InvalidKeyFileException();
|
|
||||||
}
|
long fileSize = keyData.length;
|
||||||
|
|
||||||
BufferedInputStream bis = new BufferedInputStream(fis, 64);
|
|
||||||
|
|
||||||
long fileSize = keyfile.length();
|
|
||||||
if ( fileSize == 0 ) {
|
if ( fileSize == 0 ) {
|
||||||
throw new KeyFileEmptyException();
|
throw new KeyFileEmptyException();
|
||||||
} else if ( fileSize == 32 ) {
|
} else if ( fileSize == 32 ) {
|
||||||
byte[] outputKey = new byte[32];
|
return keyData;
|
||||||
if ( bis.read(outputKey, 0, 32) != 32 ) {
|
|
||||||
throw new IOException("Error reading key.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return outputKey;
|
|
||||||
} else if ( fileSize == 64 ) {
|
} else if ( fileSize == 64 ) {
|
||||||
byte[] hex = new byte[64];
|
byte[] hex = new byte[64];
|
||||||
|
|
||||||
bis.mark(64);
|
|
||||||
if ( bis.read(hex, 0, 64) != 64 ) {
|
|
||||||
throw new IOException("Error reading key.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return hexStringToByteArray(new String(hex));
|
return hexStringToByteArray(new String(keyData));
|
||||||
} catch (IndexOutOfBoundsException e) {
|
} catch (IndexOutOfBoundsException e) {
|
||||||
// Key is not base 64, treat it as binary data
|
// Key is not base 64, treat it as binary data
|
||||||
bis.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,14 +172,7 @@ public abstract class PwDatabase {
|
|||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (true) {
|
md.update(keyData);
|
||||||
int bytesRead = bis.read(buffer, 0, 2048);
|
|
||||||
if ( bytesRead == -1 ) break; // End of file
|
|
||||||
|
|
||||||
md.update(buffer, 0, bytesRead);
|
|
||||||
offset += bytesRead;
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println(e.toString());
|
System.out.println(e.toString());
|
||||||
}
|
}
|
||||||
@@ -205,7 +180,7 @@ public abstract class PwDatabase {
|
|||||||
return md.digest();
|
return md.digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract byte[] loadXmlKeyFile(String fileName);
|
protected abstract byte[] loadXmlKeyFile(InputStream keyInputStream);
|
||||||
|
|
||||||
public static byte[] hexStringToByteArray(String s) {
|
public static byte[] hexStringToByteArray(String s) {
|
||||||
int len = s.length();
|
int len = s.length();
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ package com.keepassdroid.database;
|
|||||||
|
|
||||||
// Java
|
// Java
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -219,16 +220,16 @@ public class PwDatabaseV3 extends PwDatabase {
|
|||||||
return newId;
|
return newId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getMasterKey(String key, String keyFileName)
|
public byte[] getMasterKey(String key, InputStream keyInputStream)
|
||||||
throws InvalidKeyFileException, IOException {
|
throws InvalidKeyFileException, IOException {
|
||||||
assert (key != null && keyFileName != null);
|
assert (key != null);
|
||||||
|
|
||||||
if (key.length() > 0 && keyFileName.length() > 0) {
|
if (key.length() > 0 && keyInputStream != null) {
|
||||||
return getCompositeKey(key, keyFileName);
|
return getCompositeKey(key, keyInputStream);
|
||||||
} else if (key.length() > 0) {
|
} else if (key.length() > 0) {
|
||||||
return getPasswordKey(key);
|
return getPasswordKey(key);
|
||||||
} else if (keyFileName.length() > 0) {
|
} else if (keyInputStream != null) {
|
||||||
return getFileKey(keyFileName);
|
return getFileKey(keyInputStream);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Key cannot be empty.");
|
throw new IllegalArgumentException("Key cannot be empty.");
|
||||||
}
|
}
|
||||||
@@ -241,7 +242,7 @@ public class PwDatabaseV3 extends PwDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected byte[] loadXmlKeyFile(String fileName) {
|
protected byte[] loadXmlKeyFile(InputStream keyInputStream) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package com.keepassdroid.database;
|
|||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -107,18 +108,18 @@ public class PwDatabaseV4 extends PwDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getMasterKey(String key, String keyFileName)
|
public byte[] getMasterKey(String key, InputStream keyInputStream)
|
||||||
throws InvalidKeyFileException, IOException {
|
throws InvalidKeyFileException, IOException {
|
||||||
assert( key != null && keyFileName != null );
|
assert(key != null);
|
||||||
|
|
||||||
byte[] fKey;
|
byte[] fKey;
|
||||||
|
|
||||||
if ( key.length() > 0 && keyFileName.length() > 0 ) {
|
if ( key.length() > 0 && keyInputStream != null) {
|
||||||
return getCompositeKey(key, keyFileName);
|
return getCompositeKey(key, keyInputStream);
|
||||||
} else if ( key.length() > 0 ) {
|
} else if ( key.length() > 0 ) {
|
||||||
fKey = getPasswordKey(key);
|
fKey = getPasswordKey(key);
|
||||||
} else if ( keyFileName.length() > 0 ) {
|
} else if ( keyInputStream != null) {
|
||||||
fKey = getFileKey(keyFileName);
|
fKey = getFileKey(keyInputStream);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException( "Key cannot be empty." );
|
throw new IllegalArgumentException( "Key cannot be empty." );
|
||||||
}
|
}
|
||||||
@@ -145,12 +146,11 @@ public class PwDatabaseV4 extends PwDatabase {
|
|||||||
private static final String KeyDataElementName = "Data";
|
private static final String KeyDataElementName = "Data";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected byte[] loadXmlKeyFile(String fileName) {
|
protected byte[] loadXmlKeyFile(InputStream keyInputStream) {
|
||||||
try {
|
try {
|
||||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||||
FileInputStream fis = new FileInputStream(fileName);
|
Document doc = db.parse(keyInputStream);
|
||||||
Document doc = db.parse(fis);
|
|
||||||
|
|
||||||
Element el = doc.getDocumentElement();
|
Element el = doc.getDocumentElement();
|
||||||
if (el == null || ! el.getNodeName().equalsIgnoreCase(RootElementName)) {
|
if (el == null || ! el.getNodeName().equalsIgnoreCase(RootElementName)) {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import com.keepassdroid.app.App;
|
|||||||
import com.keepassdroid.database.PwDatabase;
|
import com.keepassdroid.database.PwDatabase;
|
||||||
import com.keepassdroid.database.PwDatabaseV3;
|
import com.keepassdroid.database.PwDatabaseV3;
|
||||||
import com.keepassdroid.database.PwEncryptionAlgorithm;
|
import com.keepassdroid.database.PwEncryptionAlgorithm;
|
||||||
|
import com.keepassdroid.utils.UriUtil;
|
||||||
|
|
||||||
public class CreateDB extends RunnableOnFinish {
|
public class CreateDB extends RunnableOnFinish {
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ public class CreateDB extends RunnableOnFinish {
|
|||||||
// Set Database state
|
// Set Database state
|
||||||
db.pm = pm;
|
db.pm = pm;
|
||||||
Uri.Builder b = new Uri.Builder();
|
Uri.Builder b = new Uri.Builder();
|
||||||
db.mUri = b.scheme("path").path(mFilename).build();
|
db.mUri = UriUtil.parseDefaultFile(mFilename);
|
||||||
db.setLoaded();
|
db.setLoaded();
|
||||||
|
|
||||||
// Commit changes
|
// Commit changes
|
||||||
|
|||||||
@@ -1,7 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Brian Pellin.
|
||||||
|
*
|
||||||
|
* This file is part of KeePassDroid.
|
||||||
|
*
|
||||||
|
* KeePassDroid is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* KeePassDroid is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with KeePassDroid. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
package com.keepassdroid.database.edit;
|
package com.keepassdroid.database.edit;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
public class FileOnFinish extends OnFinish {
|
public class FileOnFinish extends OnFinish {
|
||||||
private String mFilename = "";
|
private Uri mFilename = null;
|
||||||
protected FileOnFinish mOnFinish;
|
protected FileOnFinish mOnFinish;
|
||||||
|
|
||||||
public FileOnFinish(FileOnFinish finish) {
|
public FileOnFinish(FileOnFinish finish) {
|
||||||
@@ -10,11 +31,11 @@ public class FileOnFinish extends OnFinish {
|
|||||||
mOnFinish = finish;
|
mOnFinish = finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFilename(String filename) {
|
public void setFilename(Uri filename) {
|
||||||
mFilename = filename;
|
mFilename = filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFilename() {
|
public Uri getFilename() {
|
||||||
return mFilename;
|
return mFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,12 +42,12 @@ import com.keepassdroid.database.exception.KeyFileEmptyException;
|
|||||||
public class LoadDB extends RunnableOnFinish {
|
public class LoadDB extends RunnableOnFinish {
|
||||||
private Uri mUri;
|
private Uri mUri;
|
||||||
private String mPass;
|
private String mPass;
|
||||||
private String mKey;
|
private Uri mKey;
|
||||||
private Database mDb;
|
private Database mDb;
|
||||||
private Context mCtx;
|
private Context mCtx;
|
||||||
private boolean mRememberKeyfile;
|
private boolean mRememberKeyfile;
|
||||||
|
|
||||||
public LoadDB(Database db, Context ctx, Uri uri, String pass, String key, OnFinish finish) {
|
public LoadDB(Database db, Context ctx, Uri uri, String pass, Uri key, OnFinish finish) {
|
||||||
super(finish);
|
super(finish);
|
||||||
|
|
||||||
mDb = db;
|
mDb = db;
|
||||||
@@ -105,9 +105,9 @@ public class LoadDB extends RunnableOnFinish {
|
|||||||
finish(true);
|
finish(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveFileData(Uri uri, String key) {
|
private void saveFileData(Uri uri, Uri key) {
|
||||||
if ( ! mRememberKeyfile ) {
|
if ( ! mRememberKeyfile ) {
|
||||||
key = "";
|
key = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
App.getFileHistory().createFile(uri, key);
|
App.getFileHistory().createFile(uri, key);
|
||||||
|
|||||||
@@ -20,29 +20,32 @@
|
|||||||
package com.keepassdroid.database.edit;
|
package com.keepassdroid.database.edit;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
import com.keepassdroid.Database;
|
import com.keepassdroid.Database;
|
||||||
import com.keepassdroid.database.PwDatabase;
|
import com.keepassdroid.database.PwDatabase;
|
||||||
import com.keepassdroid.database.exception.InvalidKeyFileException;
|
import com.keepassdroid.database.exception.InvalidKeyFileException;
|
||||||
import com.keepassdroid.dialog.PasswordEncodingDialogHelper;
|
import com.keepassdroid.dialog.PasswordEncodingDialogHelper;
|
||||||
|
import com.keepassdroid.utils.UriUtil;
|
||||||
|
|
||||||
public class SetPassword extends RunnableOnFinish {
|
public class SetPassword extends RunnableOnFinish {
|
||||||
|
|
||||||
private String mPassword;
|
private String mPassword;
|
||||||
private String mKeyfile;
|
private Uri mKeyfile;
|
||||||
private Database mDb;
|
private Database mDb;
|
||||||
private boolean mDontSave;
|
private boolean mDontSave;
|
||||||
private Context ctx;
|
private Context ctx;
|
||||||
|
|
||||||
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish) {
|
public SetPassword(Context ctx, Database db, String password, Uri keyfile, OnFinish finish) {
|
||||||
this(ctx, db, password, keyfile, finish, false);
|
this(ctx, db, password, keyfile, finish, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish, boolean dontSave) {
|
public SetPassword(Context ctx, Database db, String password, Uri keyfile, OnFinish finish, boolean dontSave) {
|
||||||
super(finish);
|
super(finish);
|
||||||
|
|
||||||
mDb = db;
|
mDb = db;
|
||||||
@@ -71,7 +74,8 @@ public class SetPassword extends RunnableOnFinish {
|
|||||||
|
|
||||||
// Set key
|
// Set key
|
||||||
try {
|
try {
|
||||||
pm.setMasterKey(mPassword, mKeyfile);
|
InputStream is = UriUtil.getUriInputStream(ctx, mKeyfile);
|
||||||
|
pm.setMasterKey(mPassword, is);
|
||||||
} catch (InvalidKeyFileException e) {
|
} catch (InvalidKeyFileException e) {
|
||||||
erase(backupKey);
|
erase(backupKey);
|
||||||
finish(false, e.getMessage());
|
finish(false, e.getMessage());
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009 Brian Pellin.
|
* Copyright 2009-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -30,10 +30,10 @@ public abstract class Importer {
|
|||||||
|
|
||||||
public static final boolean DEBUG = true;
|
public static final boolean DEBUG = true;
|
||||||
|
|
||||||
public abstract PwDatabase openDatabase( InputStream inStream, String password, String keyfile )
|
public abstract PwDatabase openDatabase( InputStream inStream, String password, InputStream keyInputStream)
|
||||||
throws IOException, InvalidDBException;
|
throws IOException, InvalidDBException;
|
||||||
|
|
||||||
public abstract PwDatabase openDatabase( InputStream inStream, String password, String keyfile, UpdateStatus status )
|
public abstract PwDatabase openDatabase( InputStream inStream, String password, InputStream keyInputStream, UpdateStatus status )
|
||||||
throws IOException, InvalidDBException;
|
throws IOException, InvalidDBException;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009-2012 Brian Pellin.
|
* Copyright 2009-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -105,9 +105,8 @@ public class ImporterV3 extends Importer {
|
|||||||
/**
|
/**
|
||||||
* Load a v3 database file, return contents in a new PwDatabaseV3.
|
* Load a v3 database file, return contents in a new PwDatabaseV3.
|
||||||
*
|
*
|
||||||
* @param infile Existing file to load.
|
* @param inStream Existing file to load.
|
||||||
* @param password Pass phrase for infile.
|
* @param password Pass phrase for infile.
|
||||||
* @param pRepair (unused)
|
|
||||||
* @return new PwDatabaseV3 container.
|
* @return new PwDatabaseV3 container.
|
||||||
*
|
*
|
||||||
* @throws IOException on any file error.
|
* @throws IOException on any file error.
|
||||||
@@ -123,13 +122,13 @@ public class ImporterV3 extends Importer {
|
|||||||
* @throws InvalidAlgorithmParameterException if error decrypting main file body.
|
* @throws InvalidAlgorithmParameterException if error decrypting main file body.
|
||||||
* @throws ShortBufferException if error decrypting main file body.
|
* @throws ShortBufferException if error decrypting main file body.
|
||||||
*/
|
*/
|
||||||
public PwDatabaseV3 openDatabase( InputStream inStream, String password, String keyfile )
|
public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream kfIs)
|
||||||
throws IOException, InvalidDBException
|
throws IOException, InvalidDBException
|
||||||
{
|
{
|
||||||
return openDatabase(inStream, password, keyfile, new UpdateStatus());
|
return openDatabase(inStream, password, kfIs, new UpdateStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
public PwDatabaseV3 openDatabase( InputStream inStream, String password, String keyfile, UpdateStatus status )
|
public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream kfIs, UpdateStatus status )
|
||||||
throws IOException, InvalidDBException
|
throws IOException, InvalidDBException
|
||||||
{
|
{
|
||||||
PwDatabaseV3 newManager;
|
PwDatabaseV3 newManager;
|
||||||
@@ -157,7 +156,7 @@ public class ImporterV3 extends Importer {
|
|||||||
|
|
||||||
status.updateMessage(R.string.creating_db_key);
|
status.updateMessage(R.string.creating_db_key);
|
||||||
newManager = createDB();
|
newManager = createDB();
|
||||||
newManager.setMasterKey( password, keyfile );
|
newManager.setMasterKey(password, kfIs);
|
||||||
|
|
||||||
// Select algorithm
|
// Select algorithm
|
||||||
if( (hdr.flags & PwDbHeaderV3.FLAG_RIJNDAEL) != 0 ) {
|
if( (hdr.flags & PwDbHeaderV3.FLAG_RIJNDAEL) != 0 ) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011 Brian Pellin.
|
* Copyright 2011-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -35,9 +35,9 @@ public class ImporterV3Debug extends ImporterV3 {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PwDatabaseV3Debug openDatabase(InputStream inStream, String password,
|
public PwDatabaseV3Debug openDatabase(InputStream inStream, String password,
|
||||||
String keyfile, UpdateStatus status) throws IOException,
|
InputStream keyInputStream, UpdateStatus status) throws IOException,
|
||||||
InvalidDBException {
|
InvalidDBException {
|
||||||
return (PwDatabaseV3Debug) super.openDatabase(inStream, password, keyfile, status);
|
return (PwDatabaseV3Debug) super.openDatabase(inStream, password, keyInputStream, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -84,14 +84,14 @@ public class ImporterV4 extends Importer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PwDatabaseV4 openDatabase(InputStream inStream, String password,
|
public PwDatabaseV4 openDatabase(InputStream inStream, String password,
|
||||||
String keyfile) throws IOException, InvalidDBException {
|
InputStream keyInputStream) throws IOException, InvalidDBException {
|
||||||
|
|
||||||
return openDatabase(inStream, password, keyfile, new UpdateStatus());
|
return openDatabase(inStream, password, keyInputStream, new UpdateStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PwDatabaseV4 openDatabase(InputStream inStream, String password,
|
public PwDatabaseV4 openDatabase(InputStream inStream, String password,
|
||||||
String keyfile, UpdateStatus status) throws IOException,
|
InputStream keyInputStream, UpdateStatus status) throws IOException,
|
||||||
InvalidDBException {
|
InvalidDBException {
|
||||||
|
|
||||||
db = createDB();
|
db = createDB();
|
||||||
@@ -100,7 +100,7 @@ public class ImporterV4 extends Importer {
|
|||||||
|
|
||||||
hashOfHeader = header.loadFromFile(inStream);
|
hashOfHeader = header.loadFromFile(inStream);
|
||||||
|
|
||||||
db.setMasterKey(password, keyfile);
|
db.setMasterKey(password, keyInputStream);
|
||||||
db.makeFinalKey(header.masterSeed, header.transformSeed, (int)db.numKeyEncRounds);
|
db.makeFinalKey(header.masterSeed, header.transformSeed, (int)db.numKeyEncRounds);
|
||||||
|
|
||||||
// Attach decryptor
|
// Attach decryptor
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011 Brian Pellin.
|
* Copyright 2011-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -35,9 +35,9 @@ public class ImporterV4Debug extends ImporterV4 {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PwDatabaseV4Debug openDatabase(InputStream inStream, String password,
|
public PwDatabaseV4Debug openDatabase(InputStream inStream, String password,
|
||||||
String keyfile, UpdateStatus status) throws IOException,
|
InputStream keyInputFile, UpdateStatus status) throws IOException,
|
||||||
InvalidDBException {
|
InvalidDBException {
|
||||||
return (PwDatabaseV4Debug) super.openDatabase(inStream, password, keyfile, status);
|
return (PwDatabaseV4Debug) super.openDatabase(inStream, password, keyInputFile, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.android.keepass.R;
|
import com.android.keepass.R;
|
||||||
import com.keepassdroid.compat.EditorCompat;
|
import com.keepassdroid.compat.EditorCompat;
|
||||||
|
import com.keepassdroid.utils.UriUtil;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
@@ -125,8 +126,8 @@ public class RecentFileHistory {
|
|||||||
return db.exists();
|
return db.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createFile(Uri uri, String keyFile) {
|
public void createFile(Uri uri, Uri keyUri) {
|
||||||
if (!enabled) return;
|
if (!enabled || uri == null || keyUri == null) return;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
@@ -134,7 +135,7 @@ public class RecentFileHistory {
|
|||||||
deleteFile(uri, false);
|
deleteFile(uri, false);
|
||||||
|
|
||||||
databases.add(0, uri.toString());
|
databases.add(0, uri.toString());
|
||||||
keyfiles.add(0, keyFile);
|
keyfiles.add(0, keyUri.toString());
|
||||||
|
|
||||||
trimLists();
|
trimLists();
|
||||||
savePrefs();
|
savePrefs();
|
||||||
@@ -220,19 +221,19 @@ public class RecentFileHistory {
|
|||||||
return databases;
|
return databases;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileByName(String database) {
|
public Uri getFileByName(Uri database) {
|
||||||
if (!enabled) return "";
|
if (!enabled) return null;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
int size = databases.size();
|
int size = databases.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
if (database.equals(databases.get(i))) {
|
if (UriUtil.equalsDefaultfile(database,databases.get(i))) {
|
||||||
return keyfiles.get(i);
|
return UriUtil.parseDefaultFile(keyfiles.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAll() {
|
public void deleteAll() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012 Brian Pellin.
|
* Copyright 2012-2016 Brian Pellin.
|
||||||
*
|
*
|
||||||
* This file is part of KeePassDroid.
|
* This file is part of KeePassDroid.
|
||||||
*
|
*
|
||||||
@@ -19,6 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.keepassdroid.utils;
|
package com.keepassdroid.utils;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
import com.keepassdroid.database.PwDate;
|
import com.keepassdroid.database.PwDate;
|
||||||
import com.keepassdroid.database.PwEntryV3;
|
import com.keepassdroid.database.PwEntryV3;
|
||||||
|
|
||||||
@@ -34,4 +36,8 @@ public class EmptyUtils {
|
|||||||
public static boolean isNullOrEmpty(PwDate date) {
|
public static boolean isNullOrEmpty(PwDate date) {
|
||||||
return (date == null) || date.equals(PwEntryV3.DEFAULT_PWDATE);
|
return (date == null) || date.equals(PwEntryV3.DEFAULT_PWDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isNullOrEmpty(Uri uri) {
|
||||||
|
return (uri==null) || (uri.toString().length() == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
74
app/src/main/java/com/keepassdroid/utils/UriUtil.java
Normal file
74
app/src/main/java/com/keepassdroid/utils/UriUtil.java
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Brian Pellin.
|
||||||
|
*
|
||||||
|
* This file is part of KeePassDroid.
|
||||||
|
*
|
||||||
|
* KeePassDroid is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* KeePassDroid is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with KeePassDroid. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.keepassdroid.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by bpellin on 3/5/16.
|
||||||
|
*/
|
||||||
|
public class UriUtil {
|
||||||
|
public static Uri parseDefaultFile(String text) {
|
||||||
|
if (EmptyUtils.isNullOrEmpty(text)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri uri = Uri.parse(text);
|
||||||
|
if (EmptyUtils.isNullOrEmpty(uri.getScheme())) {
|
||||||
|
uri = uri.buildUpon().scheme("file").authority("").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
public static Uri parseDefaultFile(Uri uri) {
|
||||||
|
if (EmptyUtils.isNullOrEmpty(uri.getScheme())) {
|
||||||
|
uri = uri.buildUpon().scheme("file").authority("").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean equalsDefaultfile(Uri left, String right) {
|
||||||
|
left = parseDefaultFile(left);
|
||||||
|
Uri uriRight = parseDefaultFile(right);
|
||||||
|
|
||||||
|
return left.equals(uriRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputStream getUriInputStream(Context ctx, Uri uri) throws FileNotFoundException {
|
||||||
|
if (uri == null) return null;
|
||||||
|
|
||||||
|
String scheme = uri.getScheme();
|
||||||
|
if (scheme.equals("file")) {
|
||||||
|
return new FileInputStream(uri.getPath());
|
||||||
|
}
|
||||||
|
else if (scheme.equals("content")) {
|
||||||
|
return ctx.getContentResolver().openInputStream(uri);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user