mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-28 09:38:09 +00:00
Merge pull request #474 from alexbakker/fix-sql-import
Fix the flakiness of importing from SQLite databases
This commit is contained in:
commit
25b359a136
15 changed files with 193 additions and 174 deletions
|
@ -4,17 +4,20 @@ import android.content.Context;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.encoding.EncodingException;
|
import com.beemdevelopment.aegis.encoding.EncodingException;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||||
|
import com.beemdevelopment.aegis.util.IOUtils;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
import com.beemdevelopment.aegis.vault.VaultFile;
|
import com.beemdevelopment.aegis.vault.VaultFile;
|
||||||
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
|
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
|
||||||
import com.beemdevelopment.aegis.vault.VaultFileException;
|
import com.beemdevelopment.aegis.vault.VaultFileException;
|
||||||
import com.beemdevelopment.aegis.vault.slots.SlotList;
|
import com.beemdevelopment.aegis.vault.slots.SlotList;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class AegisImporter extends DatabaseImporter {
|
public class AegisImporter extends DatabaseImporter {
|
||||||
|
|
||||||
|
@ -23,19 +26,14 @@ public class AegisImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
try {
|
try {
|
||||||
byte[] bytes = reader.readAll();
|
byte[] bytes = IOUtils.readAll(stream);
|
||||||
VaultFile file = VaultFile.fromBytes(bytes);
|
VaultFile file = VaultFile.fromBytes(bytes);
|
||||||
if (file.isEncrypted()) {
|
if (file.isEncrypted()) {
|
||||||
return new EncryptedState(file);
|
return new EncryptedState(file);
|
||||||
|
|
|
@ -17,13 +17,16 @@ import com.beemdevelopment.aegis.otp.SteamInfo;
|
||||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||||
import com.beemdevelopment.aegis.ui.Dialogs;
|
import com.beemdevelopment.aegis.ui.Dialogs;
|
||||||
import com.beemdevelopment.aegis.ui.tasks.ProgressDialogTask;
|
import com.beemdevelopment.aegis.ui.tasks.ProgressDialogTask;
|
||||||
|
import com.beemdevelopment.aegis.util.IOUtils;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
@ -55,20 +58,15 @@ public class AndOtpImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
try {
|
try {
|
||||||
bytes = reader.readAll();
|
bytes = IOUtils.readAll(stream);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new DatabaseImporterException(e);
|
throw new DatabaseImporterException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.beemdevelopment.aegis.importers;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.ui.Dialogs;
|
import com.beemdevelopment.aegis.ui.Dialogs;
|
||||||
|
import com.beemdevelopment.aegis.util.IOUtils;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import net.lingala.zip4j.io.inputstream.ZipInputStream;
|
import net.lingala.zip4j.io.inputstream.ZipInputStream;
|
||||||
import net.lingala.zip4j.model.LocalFileHeader;
|
import net.lingala.zip4j.model.LocalFileHeader;
|
||||||
|
@ -11,6 +13,7 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class AuthenticatorPlusImporter extends DatabaseImporter {
|
public class AuthenticatorPlusImporter extends DatabaseImporter {
|
||||||
private static final String FILENAME = "Accounts.txt";
|
private static final String FILENAME = "Accounts.txt";
|
||||||
|
@ -20,19 +23,14 @@ public class AuthenticatorPlusImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
try {
|
try {
|
||||||
return new EncryptedState(reader.readAll());
|
return new EncryptedState(IOUtils.readAll(stream));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new DatabaseImporterException(e);
|
throw new DatabaseImporterException(e);
|
||||||
}
|
}
|
||||||
|
@ -55,9 +53,8 @@ public class AuthenticatorPlusImporter extends DatabaseImporter {
|
||||||
while ((header = zipStream.getNextEntry()) != null) {
|
while ((header = zipStream.getNextEntry()) != null) {
|
||||||
File file = new File(header.getFileName());
|
File file = new File(header.getFileName());
|
||||||
if (file.getName().equals(FILENAME)) {
|
if (file.getName().equals(FILENAME)) {
|
||||||
FileReader reader = new FileReader(zipStream);
|
|
||||||
GoogleAuthUriImporter importer = new GoogleAuthUriImporter(context);
|
GoogleAuthUriImporter importer = new GoogleAuthUriImporter(context);
|
||||||
GoogleAuthUriImporter.State state = importer.read(reader);
|
DatabaseImporter.State state = importer.read(zipStream);
|
||||||
listener.onStateDecrypted(state);
|
listener.onStateDecrypted(state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.beemdevelopment.aegis.importers;
|
package com.beemdevelopment.aegis.importers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.R;
|
import com.beemdevelopment.aegis.R;
|
||||||
|
@ -13,6 +14,7 @@ import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||||
import com.beemdevelopment.aegis.ui.Dialogs;
|
import com.beemdevelopment.aegis.ui.Dialogs;
|
||||||
import com.beemdevelopment.aegis.util.PreferenceParser;
|
import com.beemdevelopment.aegis.util.PreferenceParser;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
@ -21,6 +23,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
|
@ -53,21 +56,16 @@ public class AuthyImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() throws PackageManager.NameNotFoundException {
|
||||||
return _pkgName;
|
return getAppPath(_pkgName, _subPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
return _subPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
try {
|
try {
|
||||||
XmlPullParser parser = Xml.newPullParser();
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
||||||
parser.setInput(reader.getStream(), null);
|
parser.setInput(stream, null);
|
||||||
parser.nextTag();
|
parser.nextTag();
|
||||||
|
|
||||||
JSONArray array = new JSONArray();
|
JSONArray array = new JSONArray();
|
||||||
|
|
|
@ -3,10 +3,10 @@ package com.beemdevelopment.aegis.importers;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
|
||||||
import com.beemdevelopment.aegis.util.IOUtils;
|
|
||||||
import com.beemdevelopment.aegis.util.UUIDMap;
|
import com.beemdevelopment.aegis.util.UUIDMap;
|
||||||
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
import com.topjohnwu.superuser.io.SuFile;
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
import com.topjohnwu.superuser.io.SuFileInputStream;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -57,20 +57,27 @@ public abstract class DatabaseImporter {
|
||||||
return _context;
|
return _context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SuFile getAppPath() throws DatabaseImporterException, PackageManager.NameNotFoundException {
|
protected abstract SuFile getAppPath() throws DatabaseImporterException, PackageManager.NameNotFoundException;
|
||||||
return getAppPath(getAppPkgName(), getAppSubPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SuFile getAppPath(String pkgName, String subPath) throws PackageManager.NameNotFoundException {
|
protected SuFile getAppPath(String pkgName, String subPath) throws PackageManager.NameNotFoundException {
|
||||||
PackageManager man = getContext().getPackageManager();
|
PackageManager man = getContext().getPackageManager();
|
||||||
return new SuFile(man.getApplicationInfo(pkgName, 0).dataDir, subPath);
|
return new SuFile(man.getApplicationInfo(pkgName, 0).dataDir, subPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String getAppPkgName();
|
protected abstract State read(InputStream stream, boolean isInternal) throws DatabaseImporterException;
|
||||||
|
|
||||||
protected abstract String getAppSubPath() throws DatabaseImporterException, PackageManager.NameNotFoundException;
|
public State read(InputStream stream) throws DatabaseImporterException {
|
||||||
|
return read(stream, false);
|
||||||
|
}
|
||||||
|
|
||||||
public abstract State read(FileReader reader) throws DatabaseImporterException;
|
public State readFromApp() throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||||
|
SuFile file = getAppPath();
|
||||||
|
try (SuFileInputStream stream = new SuFileInputStream(file)) {
|
||||||
|
return read(stream, true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new DatabaseImporterException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static DatabaseImporter create(Context context, Class<? extends DatabaseImporter> type) {
|
public static DatabaseImporter create(Context context, Class<? extends DatabaseImporter> type) {
|
||||||
try {
|
try {
|
||||||
|
@ -138,36 +145,6 @@ public abstract class DatabaseImporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FileReader {
|
|
||||||
private InputStream _stream;
|
|
||||||
private boolean _internal;
|
|
||||||
|
|
||||||
public FileReader(InputStream stream) {
|
|
||||||
this(stream, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileReader(InputStream stream, boolean internal) {
|
|
||||||
_stream = stream;
|
|
||||||
_internal = internal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] readAll() throws IOException {
|
|
||||||
return IOUtils.readAll(_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputStream getStream() {
|
|
||||||
return _stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reports whether this reader reads the internal state of an app.
|
|
||||||
* @return true if reading from internal file, false if reading from external file
|
|
||||||
*/
|
|
||||||
public boolean isInternal() {
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface DecryptListener {
|
public interface DecryptListener {
|
||||||
void onStateDecrypted(State state);
|
void onStateDecrypted(State state);
|
||||||
void onError(Exception e);
|
void onError(Exception e);
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
package com.beemdevelopment.aegis.importers;
|
package com.beemdevelopment.aegis.importers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
|
||||||
import com.beemdevelopment.aegis.otp.HotpInfo;
|
import com.beemdevelopment.aegis.otp.HotpInfo;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfo;
|
import com.beemdevelopment.aegis.otp.OtpInfo;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||||
import com.beemdevelopment.aegis.otp.SteamInfo;
|
import com.beemdevelopment.aegis.otp.SteamInfo;
|
||||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||||
import com.beemdevelopment.aegis.util.PreferenceParser;
|
import com.beemdevelopment.aegis.util.PreferenceParser;
|
||||||
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
@ -18,6 +20,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -30,21 +33,16 @@ public class FreeOtpImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() throws PackageManager.NameNotFoundException {
|
||||||
return _pkgName;
|
return getAppPath(_pkgName, _subPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
return _subPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
try {
|
try {
|
||||||
XmlPullParser parser = Xml.newPullParser();
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
||||||
parser.setInput(reader.getStream(), null);
|
parser.setInput(stream, null);
|
||||||
parser.nextTag();
|
parser.nextTag();
|
||||||
|
|
||||||
List<JSONObject> entries = new ArrayList<>();
|
List<JSONObject> entries = new ArrayList<>();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
package com.beemdevelopment.aegis.importers;
|
package com.beemdevelopment.aegis.importers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
|
import com.beemdevelopment.aegis.util.IOUtils;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -20,24 +25,19 @@ public class FreeOtpPlusImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() throws PackageManager.NameNotFoundException {
|
||||||
return _pkgName;
|
return getAppPath(_pkgName, _subPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
return _subPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
State state;
|
State state;
|
||||||
|
|
||||||
if (reader.isInternal()) {
|
if (isInternal) {
|
||||||
state = new FreeOtpImporter(getContext()).read(reader);
|
state = new FreeOtpImporter(getContext()).read(stream);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
String json = new String(reader.readAll(), StandardCharsets.UTF_8);
|
String json = new String(IOUtils.readAll(stream), StandardCharsets.UTF_8);
|
||||||
JSONObject obj = new JSONObject(json);
|
JSONObject obj = new JSONObject(json);
|
||||||
JSONArray array = obj.getJSONArray("tokens");
|
JSONArray array = obj.getJSONArray("tokens");
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.beemdevelopment.aegis.importers;
|
package com.beemdevelopment.aegis.importers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.encoding.Base32;
|
import com.beemdevelopment.aegis.encoding.Base32;
|
||||||
|
@ -10,7 +11,9 @@ import com.beemdevelopment.aegis.otp.OtpInfo;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class GoogleAuthImporter extends DatabaseImporter {
|
public class GoogleAuthImporter extends DatabaseImporter {
|
||||||
|
@ -25,19 +28,22 @@ public class GoogleAuthImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() throws PackageManager.NameNotFoundException {
|
||||||
return _pkgName;
|
return getAppPath(_pkgName, _subPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
return _subPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
SqlImporterHelper helper = new SqlImporterHelper(getContext());
|
SqlImporterHelper helper = new SqlImporterHelper(getContext());
|
||||||
List<Entry> entries = helper.read(Entry.class, reader.getStream(), "accounts");
|
List<Entry> entries = helper.read(Entry.class, stream, "accounts");
|
||||||
|
return new State(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DatabaseImporter.State readFromApp() throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||||
|
SuFile path = getAppPath();
|
||||||
|
SqlImporterHelper helper = new SqlImporterHelper(getContext());
|
||||||
|
List<Entry> entries = helper.read(Entry.class, path, "accounts");
|
||||||
return new State(entries);
|
return new State(entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,11 @@ import android.content.Context;
|
||||||
import com.beemdevelopment.aegis.otp.GoogleAuthInfo;
|
import com.beemdevelopment.aegis.otp.GoogleAuthInfo;
|
||||||
import com.beemdevelopment.aegis.otp.GoogleAuthInfoException;
|
import com.beemdevelopment.aegis.otp.GoogleAuthInfoException;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@ -17,20 +19,15 @@ public class GoogleAuthUriImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() {
|
||||||
return null;
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public GoogleAuthUriImporter.State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GoogleAuthUriImporter.State read(DatabaseImporter.FileReader reader) throws DatabaseImporterException {
|
|
||||||
ArrayList<String> lines = new ArrayList<>();
|
ArrayList<String> lines = new ArrayList<>();
|
||||||
|
|
||||||
try (InputStreamReader streamReader = new InputStreamReader(reader.getStream());
|
try (InputStreamReader streamReader = new InputStreamReader(stream);
|
||||||
BufferedReader bufferedReader = new BufferedReader(streamReader)) {
|
BufferedReader bufferedReader = new BufferedReader(streamReader)) {
|
||||||
String line;
|
String line;
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.beemdevelopment.aegis.importers;
|
package com.beemdevelopment.aegis.importers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.encoding.Base32;
|
import com.beemdevelopment.aegis.encoding.Base32;
|
||||||
|
@ -10,7 +11,9 @@ import com.beemdevelopment.aegis.otp.OtpInfo;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MicrosoftAuthImporter extends DatabaseImporter {
|
public class MicrosoftAuthImporter extends DatabaseImporter {
|
||||||
|
@ -25,19 +28,22 @@ public class MicrosoftAuthImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() throws PackageManager.NameNotFoundException {
|
||||||
return _pkgName;
|
return getAppPath(_pkgName, _subPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
return _subPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
SqlImporterHelper helper = new SqlImporterHelper(getContext());
|
SqlImporterHelper helper = new SqlImporterHelper(getContext());
|
||||||
List<Entry> entries = helper.read(Entry.class, reader.getStream(), "accounts");
|
List<Entry> entries = helper.read(Entry.class, stream, "accounts");
|
||||||
|
return new State(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DatabaseImporter.State readFromApp() throws PackageManager.NameNotFoundException, DatabaseImporterException {
|
||||||
|
SuFile path = getAppPath();
|
||||||
|
SqlImporterHelper helper = new SqlImporterHelper(getContext());
|
||||||
|
List<Entry> entries = helper.read(Entry.class, path, "accounts");
|
||||||
return new State(entries);
|
return new State(entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,10 @@ import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteException;
|
import android.database.sqlite.SQLiteException;
|
||||||
|
|
||||||
import com.topjohnwu.superuser.ShellUtils;
|
import com.beemdevelopment.aegis.util.IOUtils;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
import com.topjohnwu.superuser.io.SuFileInputStream;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
@ -24,19 +27,75 @@ public class SqlImporterHelper {
|
||||||
_context = context;
|
_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Entry> List<T> read(Class<T> type, InputStream inStream, String table) throws DatabaseImporterException {
|
public <T extends Entry> List<T> read(Class<T> type, SuFile path, String table) throws DatabaseImporterException {
|
||||||
File file;
|
File dir = Files.createTempDir();
|
||||||
|
File mainFile = new File(dir, path.getName());
|
||||||
|
|
||||||
|
List<File> fileCopies = new ArrayList<>();
|
||||||
|
for (SuFile file : SqlImporterHelper.findDatabaseFiles(path)) {
|
||||||
|
// create temporary copies of the database files so that SQLiteDatabase can open them
|
||||||
|
File fileCopy = null;
|
||||||
|
try (SuFileInputStream inStream = new SuFileInputStream(file)) {
|
||||||
|
fileCopy = new File(dir, file.getName());
|
||||||
|
try (FileOutputStream out = new FileOutputStream(fileCopy)) {
|
||||||
|
IOUtils.copy(inStream, out);
|
||||||
|
}
|
||||||
|
fileCopies.add(fileCopy);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (fileCopy != null) {
|
||||||
|
fileCopy.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (File fileCopy2 : fileCopies) {
|
||||||
|
fileCopy2.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new DatabaseImporterException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return read(type, mainFile, table);
|
||||||
|
} finally {
|
||||||
|
for (File fileCopy : fileCopies) {
|
||||||
|
fileCopy.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SuFile[] findDatabaseFiles(SuFile path) throws DatabaseImporterException {
|
||||||
|
SuFile[] files = path.getParentFile().listFiles((d, name) -> name.startsWith(path.getName()));
|
||||||
|
if (files == null || files.length == 0) {
|
||||||
|
throw new DatabaseImporterException(String.format("File does not exist: %s", path.getAbsolutePath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Entry> List<T> read(Class<T> type, InputStream inStream, String table) throws DatabaseImporterException {
|
||||||
|
File file = null;
|
||||||
try {
|
try {
|
||||||
// create a temporary copy of the database so that SQLiteDatabase can open it
|
// create a temporary copy of the database so that SQLiteDatabase can open it
|
||||||
file = File.createTempFile("db-import-", "", _context.getCacheDir());
|
file = File.createTempFile("db-import-", "", _context.getCacheDir());
|
||||||
try (FileOutputStream out = new FileOutputStream(file)) {
|
try (FileOutputStream out = new FileOutputStream(file)) {
|
||||||
ShellUtils.pump(inStream, out);
|
IOUtils.copy(inStream, out);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
if (file != null) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
throw new DatabaseImporterException(e);
|
throw new DatabaseImporterException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return read(type, file, table);
|
||||||
|
} finally {
|
||||||
|
// always delete the temporary file
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Entry> List<T> read(Class<T> type, File file, String table) throws DatabaseImporterException {
|
||||||
try (SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, OPEN_READONLY)) {
|
try (SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, OPEN_READONLY)) {
|
||||||
try (Cursor cursor = db.rawQuery(String.format("SELECT * FROM %s", table), null)) {
|
try (Cursor cursor = db.rawQuery(String.format("SELECT * FROM %s", table), null)) {
|
||||||
List<T> entries = new ArrayList<>();
|
List<T> entries = new ArrayList<>();
|
||||||
|
@ -55,9 +114,6 @@ public class SqlImporterHelper {
|
||||||
}
|
}
|
||||||
} catch (SQLiteException e) {
|
} catch (SQLiteException e) {
|
||||||
throw new DatabaseImporterException(e);
|
throw new DatabaseImporterException(e);
|
||||||
} finally {
|
|
||||||
// always delete the temporary file
|
|
||||||
file.delete();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.beemdevelopment.aegis.encoding.Base64;
|
||||||
import com.beemdevelopment.aegis.encoding.EncodingException;
|
import com.beemdevelopment.aegis.encoding.EncodingException;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||||
import com.beemdevelopment.aegis.otp.SteamInfo;
|
import com.beemdevelopment.aegis.otp.SteamInfo;
|
||||||
|
import com.beemdevelopment.aegis.util.IOUtils;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
import com.topjohnwu.superuser.io.SuFile;
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class SteamImporter extends DatabaseImporter {
|
public class SteamImporter extends DatabaseImporter {
|
||||||
|
@ -25,27 +27,22 @@ public class SteamImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() throws DatabaseImporterException, PackageManager.NameNotFoundException {
|
||||||
return _pkgName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getAppSubPath() throws DatabaseImporterException, PackageManager.NameNotFoundException {
|
|
||||||
// NOTE: this assumes that a global root shell has already been obtained by the caller
|
// NOTE: this assumes that a global root shell has already been obtained by the caller
|
||||||
SuFile path = getAppPath(getAppPkgName(), _subDir);
|
SuFile path = getAppPath(_pkgName, _subDir);
|
||||||
SuFile[] files = path.listFiles((d, name) -> name.startsWith("Steamguard-"));
|
SuFile[] files = path.listFiles((d, name) -> name.startsWith("Steamguard-"));
|
||||||
if (files == null || files.length == 0) {
|
if (files == null || files.length == 0) {
|
||||||
throw new DatabaseImporterException(String.format("Empty directory: %s", path.getAbsolutePath()));
|
throw new DatabaseImporterException(String.format("Empty directory: %s", path.getAbsolutePath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle multiple files (can this even occur?)
|
// TODO: handle multiple files (can this even occur?)
|
||||||
return new SuFile(_subDir, files[0].getName()).getPath();
|
return files[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
try {
|
try {
|
||||||
byte[] bytes = reader.readAll();
|
byte[] bytes = IOUtils.readAll(stream);
|
||||||
JSONObject obj = new JSONObject(new String(bytes, StandardCharsets.UTF_8));
|
JSONObject obj = new JSONObject(new String(bytes, StandardCharsets.UTF_8));
|
||||||
return new State(obj);
|
return new State(obj);
|
||||||
} catch (IOException | JSONException e) {
|
} catch (IOException | JSONException e) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.beemdevelopment.aegis.importers;
|
package com.beemdevelopment.aegis.importers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
@ -14,8 +15,10 @@ import com.beemdevelopment.aegis.encoding.Hex;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||||
import com.beemdevelopment.aegis.ui.Dialogs;
|
import com.beemdevelopment.aegis.ui.Dialogs;
|
||||||
|
import com.beemdevelopment.aegis.util.IOUtils;
|
||||||
import com.beemdevelopment.aegis.util.PreferenceParser;
|
import com.beemdevelopment.aegis.util.PreferenceParser;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
@ -24,6 +27,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
|
@ -59,22 +63,17 @@ public class TotpAuthenticatorImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() throws PackageManager.NameNotFoundException {
|
||||||
return _pkgName;
|
return getAppPath(_pkgName, _subPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
return _subPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
try {
|
try {
|
||||||
if (reader.isInternal()) {
|
if (isInternal) {
|
||||||
XmlPullParser parser = Xml.newPullParser();
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
||||||
parser.setInput(reader.getStream(), null);
|
parser.setInput(stream, null);
|
||||||
parser.nextTag();
|
parser.nextTag();
|
||||||
|
|
||||||
String data = null;
|
String data = null;
|
||||||
|
@ -91,7 +90,7 @@ public class TotpAuthenticatorImporter extends DatabaseImporter {
|
||||||
List<JSONObject> entries = parse(data);
|
List<JSONObject> entries = parse(data);
|
||||||
return new DecryptedState(entries);
|
return new DecryptedState(entries);
|
||||||
} else {
|
} else {
|
||||||
byte[] base64 = reader.readAll();
|
byte[] base64 = IOUtils.readAll(stream);
|
||||||
byte[] cipherText = Base64.decode(base64);
|
byte[] cipherText = Base64.decode(base64);
|
||||||
return new EncryptedState(cipherText);
|
return new EncryptedState(cipherText);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@ package com.beemdevelopment.aegis.importers;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class WinAuthImporter extends DatabaseImporter {
|
public class WinAuthImporter extends DatabaseImporter {
|
||||||
public WinAuthImporter(Context context) {
|
public WinAuthImporter(Context context) {
|
||||||
|
@ -10,32 +13,27 @@ public class WinAuthImporter extends DatabaseImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppPkgName() {
|
protected SuFile getAppPath() {
|
||||||
return null;
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getAppSubPath() {
|
public WinAuthImporter.State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WinAuthImporter.State read(FileReader reader) throws DatabaseImporterException {
|
|
||||||
GoogleAuthUriImporter importer = new GoogleAuthUriImporter(getContext());
|
GoogleAuthUriImporter importer = new GoogleAuthUriImporter(getContext());
|
||||||
GoogleAuthUriImporter.State state = importer.read(reader);
|
DatabaseImporter.State state = importer.read(stream);
|
||||||
return new State(state);
|
return new State(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class State extends DatabaseImporter.State {
|
public static class State extends DatabaseImporter.State {
|
||||||
private GoogleAuthUriImporter.State _state;
|
private DatabaseImporter.State _state;
|
||||||
|
|
||||||
private State(GoogleAuthUriImporter.State state) {
|
private State(DatabaseImporter.State state) {
|
||||||
super(false);
|
super(false);
|
||||||
_state = state;
|
_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result convert() {
|
public Result convert() throws DatabaseImporterException {
|
||||||
Result result = _state.convert();
|
Result result = _state.convert();
|
||||||
|
|
||||||
for (VaultEntry entry : result.getEntries()) {
|
for (VaultEntry entry : result.getEntries()) {
|
||||||
|
|
|
@ -49,8 +49,6 @@ import com.beemdevelopment.aegis.vault.slots.Slot;
|
||||||
import com.beemdevelopment.aegis.vault.slots.SlotException;
|
import com.beemdevelopment.aegis.vault.slots.SlotException;
|
||||||
import com.beemdevelopment.aegis.vault.slots.SlotList;
|
import com.beemdevelopment.aegis.vault.slots.SlotList;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
import com.topjohnwu.superuser.io.SuFile;
|
|
||||||
import com.topjohnwu.superuser.io.SuFileInputStream;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -527,11 +525,8 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SuFile file = importer.getAppPath();
|
DatabaseImporter.State state = importer.readFromApp();
|
||||||
try (SuFileInputStream stream = new SuFileInputStream(file)) {
|
processImporterState(state);
|
||||||
DatabaseImporter.FileReader reader = new DatabaseImporter.FileReader(stream, true);
|
|
||||||
importDatabase(importer, reader);
|
|
||||||
}
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Toast.makeText(getActivity(), R.string.app_lookup_error, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity(), R.string.app_lookup_error, Toast.LENGTH_SHORT).show();
|
||||||
|
@ -541,9 +536,8 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importDatabase(DatabaseImporter importer, DatabaseImporter.FileReader reader) {
|
private void processImporterState(DatabaseImporter.State state) {
|
||||||
try {
|
try {
|
||||||
DatabaseImporter.State state = importer.read(reader);
|
|
||||||
if (state.isEncrypted()) {
|
if (state.isEncrypted()) {
|
||||||
// temporary special case for encrypted Aegis vaults
|
// temporary special case for encrypted Aegis vaults
|
||||||
if (state instanceof AegisImporter.EncryptedState) {
|
if (state instanceof AegisImporter.EncryptedState) {
|
||||||
|
@ -604,11 +598,11 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
||||||
|
|
||||||
try (InputStream stream = getContext().getContentResolver().openInputStream(uri)) {
|
try (InputStream stream = getContext().getContentResolver().openInputStream(uri)) {
|
||||||
DatabaseImporter importer = DatabaseImporter.create(getContext(), _importerType);
|
DatabaseImporter importer = DatabaseImporter.create(getContext(), _importerType);
|
||||||
DatabaseImporter.FileReader reader = new DatabaseImporter.FileReader(stream);
|
DatabaseImporter.State state = importer.read(stream);
|
||||||
importDatabase(importer, reader);
|
processImporterState(state);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Toast.makeText(getActivity(), R.string.file_not_found, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity(), R.string.file_not_found, Toast.LENGTH_SHORT).show();
|
||||||
} catch (IOException e) {
|
} catch (DatabaseImporterException | IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Dialogs.showErrorDialog(getContext(), R.string.reading_file_error, e);
|
Dialogs.showErrorDialog(getContext(), R.string.reading_file_error, e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue