diff --git a/src/KeePassLib2Android/Keys/KcpUserAccount.cs b/src/KeePassLib2Android/Keys/KcpUserAccount.cs index 529af0aa..67bc9dc1 100644 --- a/src/KeePassLib2Android/Keys/KcpUserAccount.cs +++ b/src/KeePassLib2Android/Keys/KcpUserAccount.cs @@ -21,7 +21,6 @@ using System; using System.Diagnostics; -using System.IO; using System.Security; #if !KeePassUAP @@ -78,26 +77,7 @@ namespace KeePassLib.Keys // m_pbKeyData = null; // } - private static string GetUserKeyFilePath(bool bCreate) - { -#if KeePassRT - string strUserDir = Windows.Storage.ApplicationData.Current.RoamingFolder.Path; -#else - string strUserDir = Environment.GetFolderPath( - Environment.SpecialFolder.ApplicationData); -#endif - - strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false); - strUserDir += PwDefs.ShortProductName; - - if (bCreate && !Directory.Exists(strUserDir)) - Directory.CreateDirectory(strUserDir); - - strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false); - return strUserDir + UserKeyFileName; - } - - private static byte[] LoadUserKey(bool bShowWarning) + private static byte[] LoadUserKey(bool bShowWarning) { byte[] pbKey = null; diff --git a/src/KeePassLib2Android/PwDatabase.cs b/src/KeePassLib2Android/PwDatabase.cs index 19158f15..d67225fb 100644 --- a/src/KeePassLib2Android/PwDatabase.cs +++ b/src/KeePassLib2Android/PwDatabase.cs @@ -587,7 +587,7 @@ namespace KeePassLib /// /// IO connection of the new database. /// Key to open the database. - public void New(IOConnectionInfo ioConnection, CompositeKey pwKey) + public void New(IOConnectionInfo ioConnection, CompositeKey pwKey, string filenameWithoutPathAndExt) { Debug.Assert(ioConnection != null); if(ioConnection == null) throw new ArgumentNullException("ioConnection"); @@ -602,26 +602,11 @@ namespace KeePassLib m_bDatabaseOpened = true; m_bModified = true; - m_pgRootGroup = new PwGroup(true, true, - UrlUtil.StripExtension(UrlUtil.GetFileName(ioConnection.Path)), + m_pgRootGroup = new PwGroup(true, true, filenameWithoutPathAndExt, PwIcon.FolderOpen); m_pgRootGroup.IsExpanded = true; } - /// - /// Open a database. The URL may point to any supported data source. - /// - /// IO connection to load the database from. - /// Key used to open the specified database. - /// Logger, which gets all status messages. - public void Open(IOConnectionInfo ioSource, CompositeKey pwKey, - IStatusLogger slLogger, IDatabaseFormat format) - - { - Open(IOConnection.OpenRead(ioSource), UrlUtil.StripExtension( - UrlUtil.GetFileName(ioSource.Path)), ioSource, pwKey, slLogger, format); - - } /// /// Open a database. The URL may point to any supported data source. @@ -669,37 +654,7 @@ namespace KeePassLib throw; } } - - /// - /// Save the currently opened database. The file is written to the location - /// it has been opened from. - /// - /// Logger that recieves status information. - public void Save(IStatusLogger slLogger) - { - Debug.Assert(!HasDuplicateUuids()); - - FileLock fl = null; - if(m_bUseFileLocks) fl = new FileLock(m_ioSource); - try - { - FileTransactionEx ft = new FileTransactionEx(m_ioSource, - m_bUseFileTransactions); - Stream s = ft.OpenWrite(); - - KdbxFile kdb = new KdbxFile(this); - kdb.Save(s, null, KdbpFile.GetFormatToUse(m_ioSource), slLogger); - - ft.CommitWrite(); - - m_pbHashOfLastIO = kdb.HashOfFileOnDisk; - m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk; - Debug.Assert(m_pbHashOfFileOnDisk != null); - } - finally { if(fl != null) fl.Dispose(); } - - m_bModified = false; - } + /// /// Save the currently opened database. The file is written to the given stream which is expected to be the original location. @@ -717,46 +672,6 @@ namespace KeePassLib m_bModified = false; } - /// - /// Save the currently opened database to a different location. If - /// is true, the specified - /// location is made the default location for future saves - /// using SaveDatabase. - /// - /// New location to serialize the database to. - /// If true, the new location is made the - /// standard location for the database. If false, a copy of the currently - /// opened database is saved to the specified location, but it isn't - /// made the default location (i.e. no lock files will be moved for - /// example). - /// Logger that recieves status information. - public void SaveAs(IOConnectionInfo ioConnection, bool bIsPrimaryNow, - IStatusLogger slLogger) - { - Debug.Assert(ioConnection != null); - if(ioConnection == null) throw new ArgumentNullException("ioConnection"); - - IOConnectionInfo ioCurrent = m_ioSource; // Remember current - m_ioSource = ioConnection; - - byte[] pbHashCopy = m_pbHashOfFileOnDisk; - - try { this.Save(slLogger); } - catch(Exception) - { - m_ioSource = ioCurrent; // Restore - m_pbHashOfFileOnDisk = pbHashCopy; - - m_pbHashOfLastIO = null; - throw; - } - - if(!bIsPrimaryNow) - { - m_ioSource = ioCurrent; // Restore - m_pbHashOfFileOnDisk = pbHashCopy; - } - } /// /// Closes the currently opened database. No confirmation message is shown diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs index 5f70eaae..85e22e3c 100644 --- a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs +++ b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs @@ -581,7 +581,7 @@ namespace KeePassLib.Serialization return vEntries; */ PwDatabase pd = new PwDatabase(); - pd.New(new IOConnectionInfo(), new CompositeKey()); + pd.New(new IOConnectionInfo(), new CompositeKey(), ""); KdbxFile f = new KdbxFile(pd); f.Load(msData, KdbxFormat.PlainXml, null); diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs index c01cf5c5..fd65cf5a 100644 --- a/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs +++ b/src/KeePassLib2Android/Serialization/KdbxFile.Write.cs @@ -1048,7 +1048,7 @@ namespace KeePassLib.Serialization return true; */ PwDatabase pd = new PwDatabase(); - pd.New(new IOConnectionInfo(), new CompositeKey()); + pd.New(new IOConnectionInfo(), new CompositeKey(), ""); PwGroup pg = pd.RootGroup; if (pg == null) { Debug.Assert(false); return false; } diff --git a/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs b/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs index ade8a8f5..3b47bffb 100644 --- a/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs +++ b/src/KeePassLib2Android/Serialization/ProtoBuf/KdbpFile.cs @@ -26,10 +26,10 @@ namespace KeePassLib.Serialization /// /// Determines whether the database pointed to by the specified ioc should be (de)serialised in default (xml) or protocol buffers format. /// - public static KdbxFormat GetFormatToUse(IOConnectionInfo ioc) + public static KdbxFormat GetFormatToUse(string fileExt) { // If the filename ends in .kdbp, use ProtocolBuffers format. - return UrlUtil.GetExtension(UrlUtil.GetFileName(ioc.Path)).Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers : KdbxFormat.Default; + return fileExt.Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers : KdbxFormat.Default; } public static void WriteDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] hashOfHeader) diff --git a/src/Kp2aBusinessLogic/Io/AndroidContentStorage.cs b/src/Kp2aBusinessLogic/Io/AndroidContentStorage.cs index 7a296bc6..32f79a8d 100644 --- a/src/Kp2aBusinessLogic/Io/AndroidContentStorage.cs +++ b/src/Kp2aBusinessLogic/Io/AndroidContentStorage.cs @@ -82,7 +82,12 @@ namespace keepass2android.Io UrlUtil.GetFileName(ioc.Path)); } - public bool RequiresCredentials(IOConnectionInfo ioc) + public string GetFileExtension(IOConnectionInfo ioc) + { + return UrlUtil.GetExtension(ioc.Path); + } + + public bool RequiresCredentials(IOConnectionInfo ioc) { return false; } diff --git a/src/Kp2aBusinessLogic/Io/BuiltInFileStorage.cs b/src/Kp2aBusinessLogic/Io/BuiltInFileStorage.cs index b8e8c1da..64df475e 100644 --- a/src/Kp2aBusinessLogic/Io/BuiltInFileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/BuiltInFileStorage.cs @@ -201,7 +201,12 @@ namespace keepass2android.Io } - public bool RequiresCredentials(IOConnectionInfo ioc) + public string GetFileExtension(IOConnectionInfo ioc) + { + return UrlUtil.GetExtension(ioc.Path); + } + + public bool RequiresCredentials(IOConnectionInfo ioc) { return (!ioc.IsLocalFile()) && (ioc.CredSaveMode != IOCredSaveMode.SaveCred); } diff --git a/src/Kp2aBusinessLogic/Io/CachingFileStorage.cs b/src/Kp2aBusinessLogic/Io/CachingFileStorage.cs index 4b291e23..a3d29556 100644 --- a/src/Kp2aBusinessLogic/Io/CachingFileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/CachingFileStorage.cs @@ -448,7 +448,12 @@ namespace keepass2android.Io return _cachedStorage.GetFilenameWithoutPathAndExt(ioc); } - public bool RequiresCredentials(IOConnectionInfo ioc) + public string GetFileExtension(IOConnectionInfo ioc) + { + return _cachedStorage.GetFileExtension(ioc); + } + + public bool RequiresCredentials(IOConnectionInfo ioc) { return _cachedStorage.RequiresCredentials(ioc); } diff --git a/src/Kp2aBusinessLogic/Io/IFileStorage.cs b/src/Kp2aBusinessLogic/Io/IFileStorage.cs index 33793ce5..b02aa7ee 100644 --- a/src/Kp2aBusinessLogic/Io/IFileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/IFileStorage.cs @@ -88,11 +88,13 @@ namespace keepass2android.Io IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction); string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc); - - /// - /// Returns true if the the given ioc must be filled with username/password - /// - bool RequiresCredentials(IOConnectionInfo ioc); + + string GetFileExtension(IOConnectionInfo ioc); + + /// + /// Returns true if the the given ioc must be filled with username/password + /// + bool RequiresCredentials(IOConnectionInfo ioc); /// /// Creates the directory described by ioc diff --git a/src/Kp2aBusinessLogic/Io/IoUtil.cs b/src/Kp2aBusinessLogic/Io/IoUtil.cs index eeb8ba56..6956635e 100644 --- a/src/Kp2aBusinessLogic/Io/IoUtil.cs +++ b/src/Kp2aBusinessLogic/Io/IoUtil.cs @@ -128,10 +128,12 @@ namespace keepass2android.Io } //creates a local ioc where the sourceIoc can be stored to - public static IOConnectionInfo GetInternalIoc(IOConnectionInfo sourceIoc, Context ctx) + public static IOConnectionInfo GetInternalIoc(IOConnectionInfo sourceIoc, Context ctx, IKp2aApp app) { Java.IO.File internalDirectory = IoUtil.GetInternalDirectory(ctx); - string targetPath = UrlUtil.GetFileName(sourceIoc.Path); + var filestorage = app.GetFileStorage(sourceIoc); + + string targetPath = filestorage.GetFilenameWithoutPathAndExt(sourceIoc); targetPath = targetPath.Trim("|\\?*<\":>+[]/'".ToCharArray()); if (targetPath == "") targetPath = "internal"; @@ -153,7 +155,7 @@ namespace keepass2android.Io public static IOConnectionInfo ImportFileToInternalDirectory(IOConnectionInfo sourceIoc, Context ctx, IKp2aApp app) { - var targetIoc = GetInternalIoc(sourceIoc, ctx); + var targetIoc = GetInternalIoc(sourceIoc, ctx, app); IoUtil.Copy(targetIoc, sourceIoc, app); diff --git a/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs b/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs index 443d5f83..38211960 100644 --- a/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs @@ -177,7 +177,12 @@ namespace keepass2android.Io _jfs.GetFilename(IocToPath(ioc))); } - public bool RequiresCredentials(IOConnectionInfo ioc) + public string GetFileExtension(IOConnectionInfo ioc) + { + return UrlUtil.GetExtension(ioc.Path); + } + + public bool RequiresCredentials(IOConnectionInfo ioc) { return false; } diff --git a/src/Kp2aBusinessLogic/Io/NetFtpFileStorage.cs b/src/Kp2aBusinessLogic/Io/NetFtpFileStorage.cs index f975ac16..0dd18038 100644 --- a/src/Kp2aBusinessLogic/Io/NetFtpFileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/NetFtpFileStorage.cs @@ -314,7 +314,12 @@ namespace keepass2android.Io UrlUtil.GetFileName(ioc.Path)); } - public bool RequiresCredentials(IOConnectionInfo ioc) + public string GetFileExtension(IOConnectionInfo ioc) + { + return UrlUtil.GetExtension(ioc.Path); + } + + public bool RequiresCredentials(IOConnectionInfo ioc) { return false; } diff --git a/src/Kp2aBusinessLogic/Io/OfflineSwitchableFileStorage.cs b/src/Kp2aBusinessLogic/Io/OfflineSwitchableFileStorage.cs index 725b7f31..4d82ad26 100644 --- a/src/Kp2aBusinessLogic/Io/OfflineSwitchableFileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/OfflineSwitchableFileStorage.cs @@ -78,7 +78,12 @@ namespace keepass2android.Io return _baseStorage.GetFilenameWithoutPathAndExt(ioc); } - public bool RequiresCredentials(IOConnectionInfo ioc) + public string GetFileExtension(IOConnectionInfo ioc) + { + return _baseStorage.GetFileExtension(ioc); + } + + public bool RequiresCredentials(IOConnectionInfo ioc) { return _baseStorage.RequiresCredentials(ioc); } diff --git a/src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs b/src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs index a0849abe..4defbea9 100644 --- a/src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/OneDrive2FileStorage.cs @@ -491,6 +491,11 @@ namespace keepass2android.Io GetFilename(IocToPath(ioc))); } + public string GetFileExtension(IOConnectionInfo ioc) + { + return UrlUtil.GetExtension(OneDrive2ItemLocation.FromString(ioc.Path).LocalPathString); + } + private string GetFilename(string path) { string localPath = "/"+OneDrive2ItemLocation.FromString(path).LocalPath; diff --git a/src/Kp2aBusinessLogic/Utils/EntryUtil.cs b/src/Kp2aBusinessLogic/Utils/EntryUtil.cs index ee0aa9d6..068821a0 100644 --- a/src/Kp2aBusinessLogic/Utils/EntryUtil.cs +++ b/src/Kp2aBusinessLogic/Utils/EntryUtil.cs @@ -25,9 +25,7 @@ using KeePass.Util.Spr; using KeePassLib; using KeePassLib.Collections; -using KeePassLib.Cryptography; using KeePassLib.Delegates; -using KeePassLib.Security; using KeePassLib.Utility; namespace KeePass.Util @@ -89,41 +87,8 @@ namespace KeePass.Util return str; } */ - private static string ReplaceHmacOtpPlaceholder(string strText, - SprContext ctx) - { - PwEntry pe = ctx.Entry; - PwDatabase pd = ctx.Database; - if((pe == null) || (pd == null)) return strText; - string str = strText; - - const string strHmacOtpPlh = @"{HMACOTP}"; - if(str.IndexOf(strHmacOtpPlh, StrUtil.CaseIgnoreCmp) >= 0) - { - const string strKeyField = "HmacOtp-Secret"; - const string strCounterField = "HmacOtp-Counter"; - - byte[] pbSecret = StrUtil.Utf8.GetBytes(pe.Strings.ReadSafe( - strKeyField)); - - string strCounter = pe.Strings.ReadSafe(strCounterField); - ulong uCounter; - ulong.TryParse(strCounter, out uCounter); - - string strValue = HmacOtp.Generate(pbSecret, uCounter, 6, false, -1); - - pe.Strings.Set(strCounterField, new ProtectedString(false, - (uCounter + 1).ToString())); - pd.Modified = true; - - str = StrUtil.ReplaceCaseInsensitive(str, strHmacOtpPlh, strValue); - } - - return str; - } - - public static bool EntriesHaveSameParent(PwObjectList v) + public static bool EntriesHaveSameParent(PwObjectList v) { if(v == null) { Debug.Assert(false); return true; } if(v.UCount == 0) return true; diff --git a/src/Kp2aBusinessLogic/database/edit/CreateDB.cs b/src/Kp2aBusinessLogic/database/edit/CreateDB.cs index b7094dc9..c007d8d7 100644 --- a/src/Kp2aBusinessLogic/database/edit/CreateDB.cs +++ b/src/Kp2aBusinessLogic/database/edit/CreateDB.cs @@ -65,7 +65,7 @@ namespace keepass2android _key = new CompositeKey(); //use a temporary key which should be changed after creation } - db.KpDatabase.New(_ioc, _key); + db.KpDatabase.New(_ioc, _key, _app.GetFileStorage(_ioc).GetFilenameWithoutPathAndExt(_ioc)); db.KpDatabase.KdfParameters = (new AesKdf()).GetDefaultParameters(); db.KpDatabase.Name = "Keepass2Android Password Database"; diff --git a/src/Kp2aBusinessLogic/database/edit/LoadDB.cs b/src/Kp2aBusinessLogic/database/edit/LoadDB.cs index 8d571921..a5c33513 100644 --- a/src/Kp2aBusinessLogic/database/edit/LoadDB.cs +++ b/src/Kp2aBusinessLogic/database/edit/LoadDB.cs @@ -82,7 +82,7 @@ namespace keepass2android } //ok, try to load the database. Let's start with Kdbx format and retry later if that is the wrong guess: - _format = new KdbxDatabaseFormat(KdbpFile.GetFormatToUse(_ioc)); + _format = new KdbxDatabaseFormat(KdbpFile.GetFormatToUse(_app.GetFileStorage(_ioc).GetFileExtension(_ioc))); TryLoad(databaseStream); diff --git a/src/Kp2aBusinessLogic/database/edit/SaveDB.cs b/src/Kp2aBusinessLogic/database/edit/SaveDB.cs index 3f65d053..6bcbb11a 100644 --- a/src/Kp2aBusinessLogic/database/edit/SaveDB.cs +++ b/src/Kp2aBusinessLogic/database/edit/SaveDB.cs @@ -230,7 +230,7 @@ namespace keepass2android PwDatabase pwImp = new PwDatabase(); PwDatabase pwDatabase = _db.KpDatabase; - pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey); + pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey, _app.GetFileStorage(ioc).GetFilenameWithoutPathAndExt(ioc)); pwImp.MemoryProtection = pwDatabase.MemoryProtection.CloneDeep(); pwImp.MasterKey = pwDatabase.MasterKey; var stream = GetStreamForBaseFile(fileStorage, ioc); diff --git a/src/keepass2android/PasswordActivity.cs b/src/keepass2android/PasswordActivity.cs index ca1ce9b8..3311eafe 100644 --- a/src/keepass2android/PasswordActivity.cs +++ b/src/keepass2android/PasswordActivity.cs @@ -1552,7 +1552,7 @@ namespace keepass2android private MemoryStream PreloadDbFile() { - if (KdbpFile.GetFormatToUse(_ioConnection) == KdbxFormat.ProtocolBuffers) + if (KdbpFile.GetFormatToUse(App.Kp2a.GetFileStorage(_ioConnection).GetFileExtension(_ioConnection)) == KdbxFormat.ProtocolBuffers) { Kp2aLog.Log("Preparing kdbp serializer"); KdbpFile.PrepareSerializer();