diff --git a/.gitignore b/.gitignore
index ec4e4d19..15afed1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -282,3 +282,5 @@ Thumbs.db
/src/java/MasterKee
/src/PluginSdkBinding/obj/ReleaseNoNet
+/src/MasterKeeWinPlugin/bin/Release
+/src/SamplePlugin
diff --git a/src/KeePassLib2Android/KeePassLib2Android.csproj b/src/KeePassLib2Android/KeePassLib2Android.csproj
index d6516bda..9f86c555 100644
--- a/src/KeePassLib2Android/KeePassLib2Android.csproj
+++ b/src/KeePassLib2Android/KeePassLib2Android.csproj
@@ -20,7 +20,7 @@
full
False
bin\Debug
- DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE;EXCLUDE_KEYTRANSFORM
+ DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE;INCLUDE_KEYTRANSFORM
prompt
4
False
diff --git a/src/KeePassLib2Android/Keys/KcpKeyFile.cs b/src/KeePassLib2Android/Keys/KcpKeyFile.cs
index edbc949d..39810ff3 100644
--- a/src/KeePassLib2Android/Keys/KcpKeyFile.cs
+++ b/src/KeePassLib2Android/Keys/KcpKeyFile.cs
@@ -41,7 +41,7 @@ namespace KeePassLib.Keys
///
public sealed class KcpKeyFile : IUserKey
{
- private string m_strPath;
+ private IOConnectionInfo m_ioc;
private ProtectedBinary m_pbKeyData;
///
@@ -49,7 +49,7 @@ namespace KeePassLib.Keys
///
public string Path
{
- get { return m_strPath; }
+ get { return m_ioc.Path; }
}
///
@@ -62,6 +62,11 @@ namespace KeePassLib.Keys
get { return m_pbKeyData; }
}
+ public IOConnectionInfo Ioc
+ {
+ get { return m_ioc; }
+ }
+
public KcpKeyFile(string strKeyFile)
{
Construct(IOConnectionInfo.FromPath(strKeyFile), false);
@@ -82,17 +87,21 @@ namespace KeePassLib.Keys
Construct(iocKeyFile, bThrowIfDbFile);
}
- private void Construct(IOConnectionInfo iocFile, bool bThrowIfDbFile)
+ public KcpKeyFile(byte[] keyFileContents, IOConnectionInfo iocKeyFile, bool bThrowIfDbFile)
{
- byte[] pbFileData = IOConnection.ReadFile(iocFile);
- if(pbFileData == null) throw new Java.IO.FileNotFoundException();
+ Construct(keyFileContents, iocKeyFile, bThrowIfDbFile);
+ }
- if(bThrowIfDbFile && (pbFileData.Length >= 8))
+ private void Construct(byte[] pbFileData, IOConnectionInfo iocKeyFile, bool bThrowIfDbFile)
+ {
+ if (pbFileData == null) throw new Java.IO.FileNotFoundException();
+
+ if (bThrowIfDbFile && (pbFileData.Length >= 8))
{
uint uSig1 = MemUtil.BytesToUInt32(MemUtil.Mid(pbFileData, 0, 4));
uint uSig2 = MemUtil.BytesToUInt32(MemUtil.Mid(pbFileData, 4, 4));
- if(((uSig1 == KdbxFile.FileSignature1) &&
+ if (((uSig1 == KdbxFile.FileSignature1) &&
(uSig2 == KdbxFile.FileSignature2)) ||
((uSig1 == KdbxFile.FileSignaturePreRelease1) &&
(uSig2 == KdbxFile.FileSignaturePreRelease2)) ||
@@ -106,16 +115,22 @@ namespace KeePassLib.Keys
}
byte[] pbKey = LoadXmlKeyFile(pbFileData);
- if(pbKey == null) pbKey = LoadKeyFile(pbFileData);
+ if (pbKey == null) pbKey = LoadKeyFile(pbFileData);
- if(pbKey == null) throw new InvalidOperationException();
+ if (pbKey == null) throw new InvalidOperationException();
- m_strPath = iocFile.Path;
+ m_ioc = iocKeyFile;
m_pbKeyData = new ProtectedBinary(true, pbKey);
MemUtil.ZeroByteArray(pbKey);
}
+ private void Construct(IOConnectionInfo iocFile, bool bThrowIfDbFile)
+ {
+ byte[] pbFileData = IOConnection.ReadFile(iocFile);
+ Construct(pbFileData, iocFile, bThrowIfDbFile);
+ }
+
// public void Clear()
// {
// m_strPath = string.Empty;
diff --git a/src/Kp2aBusinessLogic/Io/AndroidContentStorage.cs b/src/Kp2aBusinessLogic/Io/AndroidContentStorage.cs
new file mode 100644
index 00000000..d840b096
--- /dev/null
+++ b/src/Kp2aBusinessLogic/Io/AndroidContentStorage.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+using KeePassLib.Serialization;
+
+namespace keepass2android.Io
+{
+ //TODOC,TOTEST, TODO: unimplemented methods?
+ public class AndroidContentStorage: IFileStorage
+ {
+ private readonly Context _ctx;
+
+ public AndroidContentStorage(Context ctx)
+ {
+ _ctx = ctx;
+ }
+
+ public IEnumerable SupportedProtocols
+ {
+ get { yield return "content"; }
+ }
+
+ public void Delete(IOConnectionInfo ioc)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool CheckForFileChangeFast(IOConnectionInfo ioc, string previousFileVersion)
+ {
+ return false;
+ }
+
+ public string GetCurrentFileVersionFast(IOConnectionInfo ioc)
+ {
+ return null;
+ }
+
+ public Stream OpenFileForRead(IOConnectionInfo ioc)
+ {
+ return _ctx.ContentResolver.OpenInputStream(Android.Net.Uri.Parse(ioc.Path));
+ }
+
+ public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)
+ {
+ return new AndroidContentWriteTransaction(ioc.Path, _ctx);
+ }
+
+ public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc)
+ {
+ return "";
+ }
+
+ public bool RequiresCredentials(IOConnectionInfo ioc)
+ {
+ return false;
+ }
+
+ public void CreateDirectory(IOConnectionInfo ioc, string newDirName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable ListContents(IOConnectionInfo ioc)
+ {
+ throw new NotImplementedException();
+ }
+
+ public FileDescription GetFileDescription(IOConnectionInfo ioc)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool RequiresSetup(IOConnectionInfo ioConnection)
+ {
+ return false;
+ }
+
+ public string IocToPath(IOConnectionInfo ioc)
+ {
+ return ioc.Path;
+ }
+
+ public void StartSelectFile(IFileStorageSetupInitiatorActivity activity, bool isForSave, int requestCode, string protocolId)
+ {
+ Intent intent = new Intent();
+ activity.IocToIntent(intent, new IOConnectionInfo() { Path = protocolId + "://" });
+ activity.OnImmediateResult(requestCode, (int)FileStorageResults.FileChooserPrepared, intent);
+ }
+
+ public void PrepareFileUsage(IFileStorageSetupInitiatorActivity activity, IOConnectionInfo ioc, int requestCode,
+ bool alwaysReturnSuccess)
+ {
+ Intent intent = new Intent();
+ activity.IocToIntent(intent, ioc);
+ activity.OnImmediateResult(requestCode, (int)FileStorageResults.FileUsagePrepared, intent);
+ }
+
+ public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnResume(IFileStorageSetupActivity activity)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnStart(IFileStorageSetupActivity activity)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnActivityResult(IFileStorageSetupActivity activity, int requestCode, int resultCode, Intent data)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string GetDisplayName(IOConnectionInfo ioc)
+ {
+ return ioc.Path;
+ }
+
+ public string CreateFilePath(string parent, string newFilename)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ class AndroidContentWriteTransaction : IWriteTransaction
+ {
+ private readonly string _path;
+ private readonly Context _ctx;
+ private MemoryStream _memoryStream;
+
+ public AndroidContentWriteTransaction(string path, Context ctx)
+ {
+ _path = path;
+ _ctx = ctx;
+ }
+
+ public void Dispose()
+ {
+ _memoryStream.Dispose();
+ }
+
+ public Stream OpenFile()
+ {
+ _memoryStream = new MemoryStream();
+ return _memoryStream;
+ }
+
+ public void CommitWrite()
+ {
+ using (Stream outputStream = _ctx.ContentResolver.OpenOutputStream(Android.Net.Uri.Parse(_path)))
+ {
+ outputStream.Write(_memoryStream.ToArray(), 0, (int)_memoryStream.Length);
+ }
+
+
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj b/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj
index 198d4208..6c7ad4b7 100644
--- a/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj
+++ b/src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj
@@ -20,7 +20,7 @@
full
false
bin\Debug\
- TRACE;DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE;EXCLUDE_KEYTRANSFORM
+ TRACE;DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE;INCLUDE_KEYTRANSFORM
prompt
4
@@ -64,6 +64,7 @@
+
diff --git a/src/java/InputStickAPI/project.properties b/src/java/InputStickAPI/project.properties
index 7e2ca64f..91d2b024 100644
--- a/src/java/InputStickAPI/project.properties
+++ b/src/java/InputStickAPI/project.properties
@@ -11,5 +11,5 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
-target=android-20
+target=android-19
android.library=true
diff --git a/src/java/KP2AKdbLibrary/bin/kp2akdblibrary.jar b/src/java/KP2AKdbLibrary/bin/kp2akdblibrary.jar
index 0461a369..35d084ab 100644
Binary files a/src/java/KP2AKdbLibrary/bin/kp2akdblibrary.jar and b/src/java/KP2AKdbLibrary/bin/kp2akdblibrary.jar differ
diff --git a/src/java/KP2AKdbLibrary/src/com/keepassdroid/database/PwDatabaseV3.java b/src/java/KP2AKdbLibrary/src/com/keepassdroid/database/PwDatabaseV3.java
index a6f924fd..9164352e 100644
--- a/src/java/KP2AKdbLibrary/src/com/keepassdroid/database/PwDatabaseV3.java
+++ b/src/java/KP2AKdbLibrary/src/com/keepassdroid/database/PwDatabaseV3.java
@@ -47,10 +47,14 @@ package com.keepassdroid.database;
// Java
import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
import java.io.UnsupportedEncodingException;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
@@ -125,18 +129,18 @@ public class PwDatabaseV3 {
- public void setMasterKey(String key, String keyFileName)
+ public void setMasterKey(String key, InputStream keyfileStream)
throws InvalidKeyFileException, IOException {
- assert( key != null && keyFileName != null );
+ assert( key != null && keyfileStream != null );
- masterKey = getMasterKey(key, keyFileName);
+ masterKey = getMasterKey(key, keyfileStream);
}
- protected byte[] getCompositeKey(String key, String keyFileName)
+ protected byte[] getCompositeKey(String key, InputStream keyfileStream)
throws InvalidKeyFileException, IOException {
- assert(key != null && keyFileName != null);
+ assert(key != null && keyfileStream != null);
- byte[] fileKey = getFileKey(keyFileName);
+ byte[] fileKey = getFileKey(keyfileStream);
byte[] passwordKey = getPasswordKey(key);
@@ -151,46 +155,40 @@ public class PwDatabaseV3 {
return md.digest(fileKey);
}
-
- protected byte[] getFileKey(String fileName)
+
+ protected byte[] getFileKey(InputStream keyfileStream)
throws InvalidKeyFileException, IOException {
- assert(fileName != null);
+ assert(keyfileStream != null);
- File keyfile = new File(fileName);
- if ( ! keyfile.exists() ) {
- throw new InvalidKeyFileException();
+ byte[] buff = new byte[8000];
+
+ int bytesRead = 0;
+
+ ByteArrayOutputStream bao = new ByteArrayOutputStream();
+
+ while ((bytesRead = keyfileStream.read(buff)) != -1) {
+ bao.write(buff, 0, bytesRead);
}
+
+ byte[] keyFileData = bao.toByteArray();
+
+ ByteArrayInputStream bin = new ByteArrayInputStream(keyFileData);
- byte[] key = loadXmlKeyFile(fileName);
- if ( key != null ) {
- return key;
- }
-
- FileInputStream fis;
- try {
- fis = new FileInputStream(keyfile);
- } catch (FileNotFoundException e) {
- throw new InvalidKeyFileException();
- }
- BufferedInputStream bis = new BufferedInputStream(fis, 64);
- long fileSize = keyfile.length();
- if ( fileSize == 0 ) {
- throw new KeyFileEmptyException();
- } else if ( fileSize == 32 ) {
+ if ( keyFileData.length == 32 ) {
byte[] outputKey = new byte[32];
- if ( bis.read(outputKey, 0, 32) != 32 ) {
+ if ( bin.read(outputKey, 0, 32) != 32 ) {
throw new IOException("Error reading key.");
}
return outputKey;
- } else if ( fileSize == 64 ) {
+ } else if ( keyFileData.length == 64 ) {
byte[] hex = new byte[64];
- bis.mark(64);
- if ( bis.read(hex, 0, 64) != 64 ) {
+ bin.mark(64);
+ if ( bin.read(hex, 0, 64) != 64 ) {
throw new IOException("Error reading key.");
}
@@ -198,7 +196,7 @@ public class PwDatabaseV3 {
return hexStringToByteArray(new String(hex));
} catch (IndexOutOfBoundsException e) {
// Key is not base 64, treat it as binary data
- bis.reset();
+ bin.reset();
}
}
@@ -214,7 +212,7 @@ public class PwDatabaseV3 {
try {
while (true) {
- int bytesRead = bis.read(buffer, 0, 2048);
+ bytesRead = bin.read(buffer, 0, 2048);
if ( bytesRead == -1 ) break; // End of file
md.update(buffer, 0, bytesRead);
@@ -495,16 +493,16 @@ public class PwDatabaseV3 {
return newId;
}
- public byte[] getMasterKey(String key, String keyFileName)
+ public byte[] getMasterKey(String key, InputStream keyfileStream)
throws InvalidKeyFileException, IOException {
- assert (key != null && keyFileName != null);
+ assert (key != null && keyfileStream != null);
- if (key.length() > 0 && keyFileName.length() > 0) {
- return getCompositeKey(key, keyFileName);
+ if (key.length() > 0 && keyfileStream != null) {
+ return getCompositeKey(key, keyfileStream);
} else if (key.length() > 0) {
return getPasswordKey(key);
- } else if (keyFileName.length() > 0) {
- return getFileKey(keyFileName);
+ } else if (keyfileStream != null) {
+ return getFileKey(keyfileStream);
} else {
throw new IllegalArgumentException("Key cannot be empty.");
}
@@ -514,11 +512,6 @@ public class PwDatabaseV3 {
public byte[] getPasswordKey(String key) throws IOException {
return getPasswordKey(key, "ISO-8859-1");
}
-
- protected byte[] loadXmlKeyFile(String fileName) {
- return null;
- }
-
public long getNumRounds() {
diff --git a/src/java/KP2AKdbLibrary/src/com/keepassdroid/database/load/ImporterV3.java b/src/java/KP2AKdbLibrary/src/com/keepassdroid/database/load/ImporterV3.java
index 57d9f734..bc319b7d 100644
--- a/src/java/KP2AKdbLibrary/src/com/keepassdroid/database/load/ImporterV3.java
+++ b/src/java/KP2AKdbLibrary/src/com/keepassdroid/database/load/ImporterV3.java
@@ -123,13 +123,13 @@ public class ImporterV3 {
* @throws InvalidAlgorithmParameterException 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 keyfileStream )
throws IOException, InvalidDBException
{
- return openDatabase(inStream, password, keyfile, new UpdateStatus());
+ return openDatabase(inStream, password, keyfileStream, new UpdateStatus());
}
- public PwDatabaseV3 openDatabase( InputStream inStream, String password, String keyfile, UpdateStatus status )
+ public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream keyfileStream, UpdateStatus status )
throws IOException, InvalidDBException
{
PwDatabaseV3 newManager;
@@ -175,7 +175,7 @@ public class ImporterV3 {
}
newManager = createDB();
- newManager.setMasterKey( password, keyfile );
+ newManager.setMasterKey( password, keyfileStream );
// Select algorithm
if( (hdr.flags & PwDbHeaderV3.FLAG_RIJNDAEL) != 0 ) {
diff --git a/src/java/Keepass2AndroidPluginSDK/bin/keepass2androidpluginsdk.jar b/src/java/Keepass2AndroidPluginSDK/bin/keepass2androidpluginsdk.jar
index e01d050a..e6e33352 100644
Binary files a/src/java/Keepass2AndroidPluginSDK/bin/keepass2androidpluginsdk.jar and b/src/java/Keepass2AndroidPluginSDK/bin/keepass2androidpluginsdk.jar differ
diff --git a/src/keepass2android/CreateDatabaseActivity.cs b/src/keepass2android/CreateDatabaseActivity.cs
index 8383d044..1a7eee87 100644
--- a/src/keepass2android/CreateDatabaseActivity.cs
+++ b/src/keepass2android/CreateDatabaseActivity.cs
@@ -327,9 +327,9 @@ namespace keepass2android
defaultPath =>
{
if (defaultPath.StartsWith("sftp://"))
- Util.ShowSftpDialog(this, OnReceiveSftpData);
+ Util.ShowSftpDialog(this, OnReceiveSftpData, () => { });
else
- Util.ShowFilenameDialog(this, OnCreateButton, null, false, defaultPath, GetString(Resource.String.enter_filename_details_url),
+ Util.ShowFilenameDialog(this, OnCreateButton, null, null, false, defaultPath, GetString(Resource.String.enter_filename_details_url),
Intents.RequestCodeFileBrowseForOpen);
}
), true, RequestCodeDbFilename, protocolId);
diff --git a/src/keepass2android/EntryEditActivity.cs b/src/keepass2android/EntryEditActivity.cs
index 52dc8bcb..a0a57357 100644
--- a/src/keepass2android/EntryEditActivity.cs
+++ b/src/keepass2android/EntryEditActivity.cs
@@ -1,4 +1,4 @@
-/*
+/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
@@ -682,7 +682,7 @@ namespace keepass2android
addBinaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuAdd) , null, null, null);
addBinaryButton.Click += (sender, e) =>
{
- Util.ShowBrowseDialog("/mnt/sdcard", this, Intents.RequestCodeFileBrowseForBinary, false);
+ Util.ShowBrowseDialog(this, Intents.RequestCodeFileBrowseForBinary, false);
};
binariesGroup.AddView(addBinaryButton,layoutParams);
diff --git a/src/keepass2android/ExportDatabaseActivity.cs b/src/keepass2android/ExportDatabaseActivity.cs
index bca5cf63..ad942c5b 100644
--- a/src/keepass2android/ExportDatabaseActivity.cs
+++ b/src/keepass2android/ExportDatabaseActivity.cs
@@ -61,9 +61,9 @@ namespace keepass2android
defaultPath =>
{
if (defaultPath.StartsWith("sftp://"))
- Util.ShowSftpDialog(this, OnReceiveSftpData);
+ Util.ShowSftpDialog(this, OnReceiveSftpData, () => { });
else
- Util.ShowFilenameDialog(this, OnCreateButton, null, false, defaultPath, GetString(Resource.String.enter_filename_details_url),
+ Util.ShowFilenameDialog(this, OnCreateButton, null, null, false, defaultPath, GetString(Resource.String.enter_filename_details_url),
Intents.RequestCodeFileBrowseForOpen);
}
), true, RequestCodeDbFilename, protocolId);
diff --git a/src/keepass2android/FileStorageSelectionActivity.cs b/src/keepass2android/FileStorageSelectionActivity.cs
index 9f5d3e95..1dc83353 100644
--- a/src/keepass2android/FileStorageSelectionActivity.cs
+++ b/src/keepass2android/FileStorageSelectionActivity.cs
@@ -14,7 +14,7 @@ namespace keepass2android
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden , Theme="@style/NoTitleBar")]
public class FileStorageSelectionActivity : ListActivity
{
- private ActivityDesign _design;
+ private readonly ActivityDesign _design;
private FileStorageAdapter _fileStorageAdapter;
@@ -42,6 +42,9 @@ namespace keepass2android
//put file:// to the top
_protocolIds.Remove("file");
_protocolIds.Insert(0, "file");
+ //remove "content" (covered by androidget)
+ _protocolIds.Remove("content");
+
if (context.Intent.GetBooleanExtra(AllowThirdPartyAppGet, false))
_protocolIds.Add("androidget");
if (context.Intent.GetBooleanExtra(AllowThirdPartyAppSend, false))
diff --git a/src/keepass2android/PasswordActivity.cs b/src/keepass2android/PasswordActivity.cs
index f963be24..2dca2922 100644
--- a/src/keepass2android/PasswordActivity.cs
+++ b/src/keepass2android/PasswordActivity.cs
@@ -24,6 +24,7 @@ using System.Xml.Serialization;
using Android.App;
using Android.Content;
using Android.Database;
+using Android.Graphics.Drawables;
using Android.OS;
using Android.Runtime;
using Android.Views;
@@ -86,7 +87,7 @@ namespace keepass2android
private const int RequestCodePrepareDbFile = 1000;
private const int RequestCodePrepareOtpAuxFile = 1001;
private const int RequestCodeChallengeYubikey = 1002;
-
+ private const int RequestCodeSelectKeyfile = 1003;
private Task _loadDbTask;
private IOConnectionInfo _ioConnection;
@@ -136,6 +137,7 @@ namespace keepass2android
private ActivityDesign _design;
private bool _performingLoad;
+
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
@@ -258,26 +260,20 @@ namespace keepass2android
KcpKeyFile kcpKeyfile = (KcpKeyFile)App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof(KcpKeyFile));
- SetEditText(Resource.Id.pass_keyfile, kcpKeyfile.Path);
-
+ FindViewById(Resource.Id.label_keyfilename).Text =
+ App.Kp2a.GetFileStorage(kcpKeyfile.Ioc).GetDisplayName(kcpKeyfile.Ioc);
+
}
}
App.Kp2a.LockDatabase(false);
break;
- case Result.Ok: // Key file browse dialog OK'ed.
- if (requestCode == Intents.RequestCodeFileBrowseForKeyfile) {
- string filename = Util.IntentToFilename(data, this);
- if (filename != null) {
- if (filename.StartsWith("file://")) {
- filename = filename.Substring(7);
- }
-
- filename = URLDecoder.Decode(filename);
-
- EditText fn = (EditText) FindViewById(Resource.Id.pass_keyfile);
- fn.Text = filename;
-
- }
+ case Result.Ok:
+ if (requestCode == RequestCodeSelectKeyfile)
+ {
+ IOConnectionInfo ioc = new IOConnectionInfo();
+ SetIoConnectionFromIntent(ioc, data);
+ _keyFileOrProvider = IOConnectionInfo.SerializeToString(ioc);
+ UpdateKeyfileIocView();
}
break;
case (Result)FileStorageResults.FileUsagePrepared:
@@ -354,6 +350,39 @@ namespace keepass2android
}
+ private void UpdateKeyfileIocView()
+ {
+ //store keyfile in the view so that we can show the selected keyfile again if the user switches to another key provider and back to key file
+ FindViewById(Resource.Id.label_keyfilename).Tag = _keyFileOrProvider;
+ if (string.IsNullOrEmpty(_keyFileOrProvider))
+ {
+ FindViewById(Resource.Id.filestorage_label).Visibility = ViewStates.Gone;
+ FindViewById(Resource.Id.filestorage_logo).Visibility = ViewStates.Gone;
+ FindViewById(Resource.Id.label_keyfilename).Text = Resources.GetString(Resource.String.no_keyfile_selected);
+
+ return;
+ }
+ var ioc = IOConnectionInfo.UnserializeFromString(_keyFileOrProvider);
+ string displayPath = App.Kp2a.GetFileStorage(ioc).GetDisplayName(ioc);
+ int protocolSeparatorPos = displayPath.IndexOf("://", StringComparison.Ordinal);
+ string protocolId = protocolSeparatorPos < 0 ?
+ "file" : displayPath.Substring(0, protocolSeparatorPos);
+ Drawable drawable = App.Kp2a.GetResourceDrawable("ic_storage_" + protocolId);
+ FindViewById(Resource.Id.filestorage_logo).SetImageDrawable(drawable);
+ FindViewById(Resource.Id.filestorage_logo).Visibility = ViewStates.Visible;
+
+
+ String title = App.Kp2a.GetResourceString("filestoragename_" + protocolId);
+ FindViewById(Resource.Id.filestorage_label).Text = title;
+ FindViewById(Resource.Id.filestorage_label).Visibility = ViewStates.Visible;
+
+ FindViewById(Resource.Id.label_keyfilename).Text = protocolSeparatorPos < 0 ?
+ displayPath :
+ displayPath.Substring(protocolSeparatorPos + 3);
+
+ }
+
+
private void LoadOtpFile()
{
new LoadingDialog