From b8240d482fd31066232e59f5bd391262b9bbc891 Mon Sep 17 00:00:00 2001 From: Geoffroy BONNEVILLE Date: Mon, 16 Mar 2020 15:28:05 +0100 Subject: [PATCH] Update Lib to version 2.44 Update nuget packages --- .../ModernKeePassLib.Test.csproj | 9 +- .../Collections/AutoTypeConfig.cs | 2 +- .../Collections/ProtectedBinaryDictionary.cs | 2 +- .../Collections/ProtectedBinarySet.cs | 2 +- .../Collections/ProtectedStringDictionary.cs | 2 +- ModernKeePassLib/Collections/PwObjectList.cs | 2 +- ModernKeePassLib/Collections/PwObjectPool.cs | 2 +- .../Collections/StringDictionaryEx.cs | 2 +- .../Collections/VariantDictionary.cs | 2 +- .../Cryptography/Cipher/ChaCha20Cipher.cs | 2 +- .../Cryptography/Cipher/ChaCha20Engine.cs | 26 +- .../Cryptography/Cipher/CipherPool.cs | 2 +- .../Cryptography/Cipher/CtrBlockCipher.cs | 2 +- .../Cryptography/Cipher/ICipherEngine.cs | 2 +- .../Cryptography/Cipher/Salsa20Cipher.cs | 2 +- .../Cryptography/Cipher/StandardAesEngine.cs | 2 +- ModernKeePassLib/Cryptography/CryptoRandom.cs | 2 +- .../Cryptography/CryptoRandomStream.cs | 2 +- .../Cryptography/CryptoStreamEx.cs | 2 +- ModernKeePassLib/Cryptography/CryptoUtil.cs | 2 +- ModernKeePassLib/Cryptography/Hash/Blake2b.cs | 2 +- .../Cryptography/HashingStreamEx.cs | 2 +- ModernKeePassLib/Cryptography/HmacOtp.cs | 2 +- .../KeyDerivation/AesKdf.GCrypt.cs | 2 +- .../Cryptography/KeyDerivation/AesKdf.cs | 2 +- .../KeyDerivation/Argon2Kdf.Core.cs | 2 +- .../Cryptography/KeyDerivation/Argon2Kdf.cs | 2 +- .../Cryptography/KeyDerivation/KdfEngine.cs | 2 +- .../KeyDerivation/KdfParameters.cs | 2 +- .../Cryptography/KeyDerivation/KdfPool.cs | 2 +- .../CharSetBasedGenerator.cs | 2 +- .../PasswordGenerator/CustomPwGenerator.cs | 2 +- .../CustomPwGeneratorPool.cs | 2 +- .../PatternBasedGenerator.cs | 2 +- .../PasswordGenerator/PwCharSet.cs | 130 ++++------ .../PasswordGenerator/PwGenerator.cs | 4 +- .../PasswordGenerator/PwProfile.cs | 10 +- .../Cryptography/PopularPasswords.cs | 2 +- .../Cryptography/QualityEstimation.cs | 12 +- ModernKeePassLib/Cryptography/SelfTest.cs | 234 +++++++++++------- ModernKeePassLib/Delegates/Handlers.cs | 2 +- ModernKeePassLib/Interfaces/IDeepCloneable.cs | 2 +- ModernKeePassLib/Interfaces/IStatusLogger.cs | 2 +- ModernKeePassLib/Interfaces/IStructureItem.cs | 2 +- ModernKeePassLib/Interfaces/ITimeLogger.cs | 2 +- ModernKeePassLib/Interfaces/IUIOperations.cs | 2 +- .../Interfaces/IXmlSerializerEx.cs | 2 +- ModernKeePassLib/Keys/CompositeKey.cs | 2 +- ModernKeePassLib/Keys/IUserKey.cs | 2 +- ModernKeePassLib/Keys/KcpCustomKey.cs | 2 +- ModernKeePassLib/Keys/KcpKeyFile.cs | 26 +- ModernKeePassLib/Keys/KcpPassword.cs | 2 +- ModernKeePassLib/Keys/KcpUserAccount.cs | 2 +- ModernKeePassLib/Keys/KeyProvider.cs | 2 +- ModernKeePassLib/Keys/KeyProviderPool.cs | 2 +- ModernKeePassLib/Keys/KeyValidator.cs | 2 +- ModernKeePassLib/Keys/KeyValidatorPool.cs | 2 +- ModernKeePassLib/Keys/UserKeyType.cs | 2 +- ModernKeePassLib/ModernKeePassLib.csproj | 12 +- ModernKeePassLib/Native/ClipboardU.cs | 2 +- ModernKeePassLib/Native/Native.PCL.cs | 10 + ModernKeePassLib/Native/NativeLib.cs | 193 ++++++++++++--- ModernKeePassLib/Native/NativeMethods.Unix.cs | 2 +- ModernKeePassLib/Native/NativeMethods.cs | 2 +- ModernKeePassLib/Native/SimpleStat.cs | 150 +++++++++++ ModernKeePassLib/PwCustomIcon.cs | 2 +- ModernKeePassLib/PwDatabase.cs | 97 ++++---- ModernKeePassLib/PwDefs.cs | 26 +- ModernKeePassLib/PwDeletedObject.cs | 2 +- ModernKeePassLib/PwEntry.cs | 18 +- ModernKeePassLib/PwEnums.cs | 2 +- ModernKeePassLib/PwGroup.cs | 16 +- ModernKeePassLib/PwUuid.cs | 2 +- ModernKeePassLib/Resources/KLRes.Generated.cs | 91 +++++++ ModernKeePassLib/Security/ProtectedBinary.cs | 2 +- ModernKeePassLib/Security/ProtectedString.cs | 2 +- ModernKeePassLib/Security/XorredBuffer.cs | 2 +- .../Serialization/BinaryReaderEx.cs | 2 +- ModernKeePassLib/Serialization/FileLock.cs | 2 +- .../Serialization/FileTransactionEx.cs | 82 +++--- .../Serialization/HashedBlockStream.cs | 135 +++++----- .../Serialization/HmacBlockStream.cs | 19 +- .../Serialization/IOConnection.cs | 48 ++-- .../Serialization/IOConnectionInfo.cs | 10 +- .../Serialization/IocProperties.cs | 2 +- .../Serialization/IocPropertyInfo.cs | 2 +- .../Serialization/IocPropertyInfoPool.cs | 2 +- .../Serialization/KdbxFile.Read.Streamed.cs | 2 +- .../Serialization/KdbxFile.Read.cs | 16 +- .../Serialization/KdbxFile.Write.cs | 7 +- ModernKeePassLib/Serialization/KdbxFile.cs | 15 +- .../Serialization/OldFormatException.cs | 2 +- .../Translation/KPControlCustomization.cs | 2 +- .../Translation/KPFormCustomization.cs | 2 +- ModernKeePassLib/Translation/KPStringTable.cs | 2 +- .../Translation/KPStringTableItem.cs | 2 +- ModernKeePassLib/Translation/KPTranslation.cs | 2 +- .../Translation/KPTranslationProperties.cs | 2 +- ModernKeePassLib/Utility/AppLogEx.cs | 2 +- ModernKeePassLib/Utility/GfxUtil.cs | 2 +- ModernKeePassLib/Utility/MemUtil.cs | 26 +- ModernKeePassLib/Utility/MessageService.cs | 2 +- ModernKeePassLib/Utility/MonoWorkarounds.cs | 8 +- ModernKeePassLib/Utility/StrUtil.cs | 24 +- ModernKeePassLib/Utility/TimeUtil.cs | 2 +- ModernKeePassLib/Utility/TypeOverridePool.cs | 2 +- ModernKeePassLib/Utility/UrlUtil.cs | 69 ++++-- ModernKeePassLib/Utility/XmlUtilEx.cs | 18 +- 108 files changed, 1102 insertions(+), 595 deletions(-) create mode 100644 ModernKeePassLib/Native/SimpleStat.cs diff --git a/ModernKeePassLib.Test/ModernKeePassLib.Test.csproj b/ModernKeePassLib.Test/ModernKeePassLib.Test.csproj index 794924d..71eb005 100644 --- a/ModernKeePassLib.Test/ModernKeePassLib.Test.csproj +++ b/ModernKeePassLib.Test/ModernKeePassLib.Test.csproj @@ -7,10 +7,13 @@ - + - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/ModernKeePassLib/Collections/AutoTypeConfig.cs b/ModernKeePassLib/Collections/AutoTypeConfig.cs index 390fccd..c536051 100644 --- a/ModernKeePassLib/Collections/AutoTypeConfig.cs +++ b/ModernKeePassLib/Collections/AutoTypeConfig.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Collections/ProtectedBinaryDictionary.cs b/ModernKeePassLib/Collections/ProtectedBinaryDictionary.cs index 8d51964..9676c2f 100644 --- a/ModernKeePassLib/Collections/ProtectedBinaryDictionary.cs +++ b/ModernKeePassLib/Collections/ProtectedBinaryDictionary.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Collections/ProtectedBinarySet.cs b/ModernKeePassLib/Collections/ProtectedBinarySet.cs index 1d95c71..c64718e 100644 --- a/ModernKeePassLib/Collections/ProtectedBinarySet.cs +++ b/ModernKeePassLib/Collections/ProtectedBinarySet.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Collections/ProtectedStringDictionary.cs b/ModernKeePassLib/Collections/ProtectedStringDictionary.cs index d02e5bc..cea9db3 100644 --- a/ModernKeePassLib/Collections/ProtectedStringDictionary.cs +++ b/ModernKeePassLib/Collections/ProtectedStringDictionary.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Collections/PwObjectList.cs b/ModernKeePassLib/Collections/PwObjectList.cs index 814b1cb..8d53834 100644 --- a/ModernKeePassLib/Collections/PwObjectList.cs +++ b/ModernKeePassLib/Collections/PwObjectList.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Collections/PwObjectPool.cs b/ModernKeePassLib/Collections/PwObjectPool.cs index 6178279..0a18f01 100644 --- a/ModernKeePassLib/Collections/PwObjectPool.cs +++ b/ModernKeePassLib/Collections/PwObjectPool.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Collections/StringDictionaryEx.cs b/ModernKeePassLib/Collections/StringDictionaryEx.cs index a14a24b..226b55e 100644 --- a/ModernKeePassLib/Collections/StringDictionaryEx.cs +++ b/ModernKeePassLib/Collections/StringDictionaryEx.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Collections/VariantDictionary.cs b/ModernKeePassLib/Collections/VariantDictionary.cs index c3b7dc9..e45e61d 100644 --- a/ModernKeePassLib/Collections/VariantDictionary.cs +++ b/ModernKeePassLib/Collections/VariantDictionary.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/Cipher/ChaCha20Cipher.cs b/ModernKeePassLib/Cryptography/Cipher/ChaCha20Cipher.cs index ce6bc20..a235027 100644 --- a/ModernKeePassLib/Cryptography/Cipher/ChaCha20Cipher.cs +++ b/ModernKeePassLib/Cryptography/Cipher/ChaCha20Cipher.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/Cipher/ChaCha20Engine.cs b/ModernKeePassLib/Cryptography/Cipher/ChaCha20Engine.cs index 369911d..e3d0080 100644 --- a/ModernKeePassLib/Cryptography/Cipher/ChaCha20Engine.cs +++ b/ModernKeePassLib/Cryptography/Cipher/ChaCha20Engine.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,13 +29,27 @@ namespace ModernKeePassLib.Cryptography.Cipher { public sealed class ChaCha20Engine : ICipherEngine2 { - private PwUuid m_uuid = new PwUuid(new byte[] { - 0xD6, 0x03, 0x8A, 0x2B, 0x8B, 0x6F, 0x4C, 0xB5, - 0xA5, 0x24, 0x33, 0x9A, 0x31, 0xDB, 0xB5, 0x9A - }); + private static PwUuid g_uuid = null; + internal static PwUuid ChaCha20Uuid + { + get + { + PwUuid pu = g_uuid; + if(pu == null) + { + pu = new PwUuid(new byte[] { + 0xD6, 0x03, 0x8A, 0x2B, 0x8B, 0x6F, 0x4C, 0xB5, + 0xA5, 0x24, 0x33, 0x9A, 0x31, 0xDB, 0xB5, 0x9A }); + g_uuid = pu; + } + + return pu; + } + } + public PwUuid CipherUuid { - get { return m_uuid; } + get { return ChaCha20Engine.ChaCha20Uuid; } } public string DisplayName diff --git a/ModernKeePassLib/Cryptography/Cipher/CipherPool.cs b/ModernKeePassLib/Cryptography/Cipher/CipherPool.cs index c38aabd..70ca446 100644 --- a/ModernKeePassLib/Cryptography/Cipher/CipherPool.cs +++ b/ModernKeePassLib/Cryptography/Cipher/CipherPool.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/Cipher/CtrBlockCipher.cs b/ModernKeePassLib/Cryptography/Cipher/CtrBlockCipher.cs index 3fb83a4..ad4fd79 100644 --- a/ModernKeePassLib/Cryptography/Cipher/CtrBlockCipher.cs +++ b/ModernKeePassLib/Cryptography/Cipher/CtrBlockCipher.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/Cipher/ICipherEngine.cs b/ModernKeePassLib/Cryptography/Cipher/ICipherEngine.cs index 5dc2c93..fc3acb3 100644 --- a/ModernKeePassLib/Cryptography/Cipher/ICipherEngine.cs +++ b/ModernKeePassLib/Cryptography/Cipher/ICipherEngine.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/Cipher/Salsa20Cipher.cs b/ModernKeePassLib/Cryptography/Cipher/Salsa20Cipher.cs index 2052a72..5a8ae21 100644 --- a/ModernKeePassLib/Cryptography/Cipher/Salsa20Cipher.cs +++ b/ModernKeePassLib/Cryptography/Cipher/Salsa20Cipher.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/Cipher/StandardAesEngine.cs b/ModernKeePassLib/Cryptography/Cipher/StandardAesEngine.cs index 80fcf32..866374b 100644 --- a/ModernKeePassLib/Cryptography/Cipher/StandardAesEngine.cs +++ b/ModernKeePassLib/Cryptography/Cipher/StandardAesEngine.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/CryptoRandom.cs b/ModernKeePassLib/Cryptography/CryptoRandom.cs index 534c626..0696b2d 100644 --- a/ModernKeePassLib/Cryptography/CryptoRandom.cs +++ b/ModernKeePassLib/Cryptography/CryptoRandom.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/CryptoRandomStream.cs b/ModernKeePassLib/Cryptography/CryptoRandomStream.cs index e17fc83..25d5202 100644 --- a/ModernKeePassLib/Cryptography/CryptoRandomStream.cs +++ b/ModernKeePassLib/Cryptography/CryptoRandomStream.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/CryptoStreamEx.cs b/ModernKeePassLib/Cryptography/CryptoStreamEx.cs index a7beb03..26bb873 100644 --- a/ModernKeePassLib/Cryptography/CryptoStreamEx.cs +++ b/ModernKeePassLib/Cryptography/CryptoStreamEx.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/CryptoUtil.cs b/ModernKeePassLib/Cryptography/CryptoUtil.cs index 1c94a88..8f0da22 100644 --- a/ModernKeePassLib/Cryptography/CryptoUtil.cs +++ b/ModernKeePassLib/Cryptography/CryptoUtil.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/Hash/Blake2b.cs b/ModernKeePassLib/Cryptography/Hash/Blake2b.cs index d4658be..3c42fbd 100644 --- a/ModernKeePassLib/Cryptography/Hash/Blake2b.cs +++ b/ModernKeePassLib/Cryptography/Hash/Blake2b.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/HashingStreamEx.cs b/ModernKeePassLib/Cryptography/HashingStreamEx.cs index 0288753..9010225 100644 --- a/ModernKeePassLib/Cryptography/HashingStreamEx.cs +++ b/ModernKeePassLib/Cryptography/HashingStreamEx.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/HmacOtp.cs b/ModernKeePassLib/Cryptography/HmacOtp.cs index 1b06119..d0aa2b1 100644 --- a/ModernKeePassLib/Cryptography/HmacOtp.cs +++ b/ModernKeePassLib/Cryptography/HmacOtp.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/KeyDerivation/AesKdf.GCrypt.cs b/ModernKeePassLib/Cryptography/KeyDerivation/AesKdf.GCrypt.cs index 45de516..2fe7bbb 100644 --- a/ModernKeePassLib/Cryptography/KeyDerivation/AesKdf.GCrypt.cs +++ b/ModernKeePassLib/Cryptography/KeyDerivation/AesKdf.GCrypt.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/KeyDerivation/AesKdf.cs b/ModernKeePassLib/Cryptography/KeyDerivation/AesKdf.cs index 112660f..e323311 100644 --- a/ModernKeePassLib/Cryptography/KeyDerivation/AesKdf.cs +++ b/ModernKeePassLib/Cryptography/KeyDerivation/AesKdf.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/KeyDerivation/Argon2Kdf.Core.cs b/ModernKeePassLib/Cryptography/KeyDerivation/Argon2Kdf.Core.cs index eff035f..35c5521 100644 --- a/ModernKeePassLib/Cryptography/KeyDerivation/Argon2Kdf.Core.cs +++ b/ModernKeePassLib/Cryptography/KeyDerivation/Argon2Kdf.Core.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/KeyDerivation/Argon2Kdf.cs b/ModernKeePassLib/Cryptography/KeyDerivation/Argon2Kdf.cs index ec78e39..fceee43 100644 --- a/ModernKeePassLib/Cryptography/KeyDerivation/Argon2Kdf.cs +++ b/ModernKeePassLib/Cryptography/KeyDerivation/Argon2Kdf.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/KeyDerivation/KdfEngine.cs b/ModernKeePassLib/Cryptography/KeyDerivation/KdfEngine.cs index 56b5291..41e1160 100644 --- a/ModernKeePassLib/Cryptography/KeyDerivation/KdfEngine.cs +++ b/ModernKeePassLib/Cryptography/KeyDerivation/KdfEngine.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/KeyDerivation/KdfParameters.cs b/ModernKeePassLib/Cryptography/KeyDerivation/KdfParameters.cs index 31d374f..91019f3 100644 --- a/ModernKeePassLib/Cryptography/KeyDerivation/KdfParameters.cs +++ b/ModernKeePassLib/Cryptography/KeyDerivation/KdfParameters.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/KeyDerivation/KdfPool.cs b/ModernKeePassLib/Cryptography/KeyDerivation/KdfPool.cs index cd14869..541b96c 100644 --- a/ModernKeePassLib/Cryptography/KeyDerivation/KdfPool.cs +++ b/ModernKeePassLib/Cryptography/KeyDerivation/KdfPool.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/PasswordGenerator/CharSetBasedGenerator.cs b/ModernKeePassLib/Cryptography/PasswordGenerator/CharSetBasedGenerator.cs index 763a0a3..edb0b3c 100644 --- a/ModernKeePassLib/Cryptography/PasswordGenerator/CharSetBasedGenerator.cs +++ b/ModernKeePassLib/Cryptography/PasswordGenerator/CharSetBasedGenerator.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/PasswordGenerator/CustomPwGenerator.cs b/ModernKeePassLib/Cryptography/PasswordGenerator/CustomPwGenerator.cs index 15b5860..286e653 100644 --- a/ModernKeePassLib/Cryptography/PasswordGenerator/CustomPwGenerator.cs +++ b/ModernKeePassLib/Cryptography/PasswordGenerator/CustomPwGenerator.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/PasswordGenerator/CustomPwGeneratorPool.cs b/ModernKeePassLib/Cryptography/PasswordGenerator/CustomPwGeneratorPool.cs index 967e224..1a1fb9c 100644 --- a/ModernKeePassLib/Cryptography/PasswordGenerator/CustomPwGeneratorPool.cs +++ b/ModernKeePassLib/Cryptography/PasswordGenerator/CustomPwGeneratorPool.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/PasswordGenerator/PatternBasedGenerator.cs b/ModernKeePassLib/Cryptography/PasswordGenerator/PatternBasedGenerator.cs index b06ac42..13ad680 100644 --- a/ModernKeePassLib/Cryptography/PasswordGenerator/PatternBasedGenerator.cs +++ b/ModernKeePassLib/Cryptography/PasswordGenerator/PatternBasedGenerator.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/PasswordGenerator/PwCharSet.cs b/ModernKeePassLib/Cryptography/PasswordGenerator/PwCharSet.cs index 463de3f..9f13b8a 100644 --- a/ModernKeePassLib/Cryptography/PasswordGenerator/PwCharSet.cs +++ b/ModernKeePassLib/Cryptography/PasswordGenerator/PwCharSet.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,6 +38,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator public static readonly string Punctuation = @",.;:"; public static readonly string Brackets = @"[]{}()<>"; + public static readonly string Special = "!\"#$%&'*+,./:;=?@\\^`|~"; public static readonly string PrintableAsciiSpecial = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; public static readonly string UpperHex = "0123456789ABCDEF"; @@ -45,95 +46,54 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator public static readonly string LookAlike = @"O0l1I|"; + /// + /// Latin-1 Supplement except U+00A0 (NBSP) and U+00AD (SHY). + /// + public static readonly string Latin1S = + "\u00A1\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7" + + "\u00A8\u00A9\u00AA\u00AB\u00AC\u00AE\u00AF" + + "\u00B0\u00B1\u00B2\u00B3\u00B4\u00B5\u00B6\u00B7" + + "\u00B8\u00B9\u00BA\u00BB\u00BC\u00BD\u00BE\u00BF" + + "\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7" + + "\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF" + + "\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D7" + + "\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF" + + "\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7" + + "\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF" + + "\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7" + + "\u00F8\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF"; + internal static readonly string MenuAccels = PwCharSet.LowerCase + PwCharSet.Digits; + [Obsolete] + public static string SpecialChars { get { return PwCharSet.Special; } } + [Obsolete] + public static string HighAnsiChars { get { return PwCharSet.Latin1S; } } + private const int CharTabSize = 0x10000 / 8; - private List m_vChars = new List(); + private List m_lChars = new List(); private byte[] m_vTab = new byte[CharTabSize]; - private static string m_strHighAnsi = null; - public static string HighAnsiChars - { - get - { - if(m_strHighAnsi == null) { new PwCharSet(); } // Create string - Debug.Assert(m_strHighAnsi != null); - return m_strHighAnsi; - } - } - - private static string m_strSpecial = null; - public static string SpecialChars - { - get - { - if(m_strSpecial == null) { new PwCharSet(); } // Create string - Debug.Assert(m_strSpecial != null); - return m_strSpecial; - } - } - /// - /// Create a new, empty character set collection object. + /// Create a new, empty character set. /// public PwCharSet() { - Initialize(true); + Debug.Assert(PwCharSet.Latin1S.Length == (16 * 6 - 2)); } public PwCharSet(string strCharSet) { - Initialize(true); Add(strCharSet); } - private PwCharSet(bool bFullInitialize) - { - Initialize(bFullInitialize); - } - - private void Initialize(bool bFullInitialize) - { - Clear(); - - if(!bFullInitialize) return; - - if(m_strHighAnsi == null) - { - StringBuilder sbHighAnsi = new StringBuilder(); - // [U+0080, U+009F] are C1 control characters, - // U+00A0 is non-breaking space - for(char ch = '\u00A1'; ch <= '\u00AC'; ++ch) - sbHighAnsi.Append(ch); - // U+00AD is soft hyphen (format character) - for(char ch = '\u00AE'; ch < '\u00FF'; ++ch) - sbHighAnsi.Append(ch); - sbHighAnsi.Append('\u00FF'); - - m_strHighAnsi = sbHighAnsi.ToString(); - } - - if(m_strSpecial == null) - { - PwCharSet pcs = new PwCharSet(false); - pcs.AddRange('!', '/'); - pcs.AddRange(':', '@'); - pcs.AddRange('[', '`'); - pcs.Add(@"|~"); - pcs.Remove(@"-_ "); - pcs.Remove(PwCharSet.Brackets); - - m_strSpecial = pcs.ToString(); - } - } - /// /// Number of characters in this set. /// public uint Size { - get { return (uint)m_vChars.Count; } + get { return (uint)m_lChars.Count; } } /// @@ -146,10 +106,10 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator { get { - if(uPos >= (uint)m_vChars.Count) + if(uPos >= (uint)m_lChars.Count) throw new ArgumentOutOfRangeException("uPos"); - return m_vChars[(int)uPos]; + return m_lChars[(int)uPos]; } } @@ -158,7 +118,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator /// public void Clear() { - m_vChars.Clear(); + m_lChars.Clear(); Array.Clear(m_vTab, 0, m_vTab.Length); } @@ -190,7 +150,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator if(!Contains(ch)) { - m_vChars.Add(ch); + m_lChars.Add(ch); m_vTab[ch / 8] |= (byte)(1 << (ch % 8)); } } @@ -204,8 +164,6 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator Debug.Assert(strCharSet != null); if(strCharSet == null) throw new ArgumentNullException("strCharSet"); - m_vChars.Capacity = m_vChars.Count + strCharSet.Length; - foreach(char ch in strCharSet) Add(ch); } @@ -225,8 +183,6 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator public void AddRange(char chMin, char chMax) { - m_vChars.Capacity = m_vChars.Count + (chMax - chMin) + 1; - for(char ch = chMin; ch < chMax; ++ch) Add(ch); @@ -261,7 +217,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator case 'v': Add(PwCharSet.LowerVowels); break; case 'V': Add(PwCharSet.LowerVowels, PwCharSet.UpperVowels); break; case 'Z': Add(PwCharSet.UpperVowels); break; - case 'x': Add(m_strHighAnsi); break; + case 'x': Add(PwCharSet.Latin1S); break; default: bResult = false; break; } @@ -271,7 +227,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator public bool Remove(char ch) { m_vTab[ch / 8] &= (byte)(~(1 << (ch % 8))); - return m_vChars.Remove(ch); + return m_lChars.Remove(ch); } public bool Remove(string strCharacters) @@ -305,8 +261,8 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator /// String containing all character set characters. public override string ToString() { - StringBuilder sb = new StringBuilder(); - foreach(char ch in m_vChars) + StringBuilder sb = new StringBuilder(m_lChars.Count); + foreach(char ch in m_lChars) sb.Append(ch); return sb.ToString(); @@ -319,13 +275,13 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator sb.Append(RemoveIfAllExist(PwCharSet.UpperCase) ? 'U' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.LowerCase) ? 'L' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Digits) ? 'D' : '_'); - sb.Append(RemoveIfAllExist(m_strSpecial) ? 'S' : '_'); + sb.Append(RemoveIfAllExist(PwCharSet.Special) ? 'S' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Punctuation) ? 'P' : '_'); - sb.Append(RemoveIfAllExist(@"-") ? 'm' : '_'); - sb.Append(RemoveIfAllExist(@"_") ? 'u' : '_'); - sb.Append(RemoveIfAllExist(@" ") ? 's' : '_'); + sb.Append(RemoveIfAllExist("-") ? 'm' : '_'); + sb.Append(RemoveIfAllExist("_") ? 'u' : '_'); + sb.Append(RemoveIfAllExist(" ") ? 's' : '_'); sb.Append(RemoveIfAllExist(PwCharSet.Brackets) ? 'B' : '_'); - sb.Append(RemoveIfAllExist(m_strHighAnsi) ? 'H' : '_'); + sb.Append(RemoveIfAllExist(PwCharSet.Latin1S) ? 'H' : '_'); return sb.ToString(); } @@ -338,13 +294,13 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator if(strRanges[0] != '_') Add(PwCharSet.UpperCase); if(strRanges[1] != '_') Add(PwCharSet.LowerCase); if(strRanges[2] != '_') Add(PwCharSet.Digits); - if(strRanges[3] != '_') Add(m_strSpecial); + if(strRanges[3] != '_') Add(PwCharSet.Special); if(strRanges[4] != '_') Add(PwCharSet.Punctuation); if(strRanges[5] != '_') Add('-'); if(strRanges[6] != '_') Add('_'); if(strRanges[7] != '_') Add(' '); if(strRanges[8] != '_') Add(PwCharSet.Brackets); - if(strRanges[9] != '_') Add(m_strHighAnsi); + if(strRanges[9] != '_') Add(PwCharSet.Latin1S); } } } diff --git a/ModernKeePassLib/Cryptography/PasswordGenerator/PwGenerator.cs b/ModernKeePassLib/Cryptography/PasswordGenerator/PwGenerator.cs index b2f33f7..f10d331 100644 --- a/ModernKeePassLib/Cryptography/PasswordGenerator/PwGenerator.cs +++ b/ModernKeePassLib/Cryptography/PasswordGenerator/PwGenerator.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -42,7 +42,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator } /// - /// Utility functions for generating random passwords. + /// Password generator. /// public static class PwGenerator { diff --git a/ModernKeePassLib/Cryptography/PasswordGenerator/PwProfile.cs b/ModernKeePassLib/Cryptography/PasswordGenerator/PwProfile.cs index 3122d49..985fff9 100644 --- a/ModernKeePassLib/Cryptography/PasswordGenerator/PwProfile.cs +++ b/ModernKeePassLib/Cryptography/PasswordGenerator/PwProfile.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -252,15 +252,15 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator if((ch >= 'A') && (ch <= 'Z')) pcs.Add(PwCharSet.UpperCase); else if((ch >= 'a') && (ch <= 'z')) pcs.Add(PwCharSet.LowerCase); else if((ch >= '0') && (ch <= '9')) pcs.Add(PwCharSet.Digits); - else if(PwCharSet.SpecialChars.IndexOf(ch) >= 0) - pcs.Add(PwCharSet.SpecialChars); + else if(PwCharSet.Special.IndexOf(ch) >= 0) + pcs.Add(PwCharSet.Special); else if(ch == ' ') pcs.Add(' '); else if(ch == '-') pcs.Add('-'); else if(ch == '_') pcs.Add('_'); else if(PwCharSet.Brackets.IndexOf(ch) >= 0) pcs.Add(PwCharSet.Brackets); - else if(PwCharSet.HighAnsiChars.IndexOf(ch) >= 0) - pcs.Add(PwCharSet.HighAnsiChars); + else if(PwCharSet.Latin1S.IndexOf(ch) >= 0) + pcs.Add(PwCharSet.Latin1S); else pcs.Add(ch); } diff --git a/ModernKeePassLib/Cryptography/PopularPasswords.cs b/ModernKeePassLib/Cryptography/PopularPasswords.cs index 48b38a4..0a43d1b 100644 --- a/ModernKeePassLib/Cryptography/PopularPasswords.cs +++ b/ModernKeePassLib/Cryptography/PopularPasswords.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Cryptography/QualityEstimation.cs b/ModernKeePassLib/Cryptography/QualityEstimation.cs index 5aa89b9..94ac8e5 100644 --- a/ModernKeePassLib/Cryptography/QualityEstimation.cs +++ b/ModernKeePassLib/Cryptography/QualityEstimation.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,7 +39,7 @@ namespace ModernKeePassLib.Cryptography internal const char UpperAlpha = 'U'; internal const char Digit = 'D'; internal const char Special = 'S'; - internal const char High = 'H'; + internal const char Latin1S = 'H'; internal const char Other = 'X'; internal const char Dictionary = 'W'; @@ -295,7 +295,7 @@ namespace ModernKeePassLib.Cryptography else strSpecial = strSpecial + " "; int nSp = strSpecial.Length; - int nHi = PwCharSet.HighAnsiChars.Length; + int nL1S = PwCharSet.Latin1S.Length; m_lCharTypes = new List(); @@ -307,10 +307,10 @@ namespace ModernKeePassLib.Cryptography PwCharSet.Digits, true)); m_lCharTypes.Add(new QeCharType(PatternID.Special, strSpecial, false)); - m_lCharTypes.Add(new QeCharType(PatternID.High, - PwCharSet.HighAnsiChars, false)); + m_lCharTypes.Add(new QeCharType(PatternID.Latin1S, + PwCharSet.Latin1S, false)); m_lCharTypes.Add(new QeCharType(PatternID.Other, - 0x10000 - (2 * 26) - 10 - nSp - nHi)); + 0x10000 - (2 * 26) - 10 - nSp - nL1S)); } } } diff --git a/ModernKeePassLib/Cryptography/SelfTest.cs b/ModernKeePassLib/Cryptography/SelfTest.cs index c9631ea..36480c3 100644 --- a/ModernKeePassLib/Cryptography/SelfTest.cs +++ b/ModernKeePassLib/Cryptography/SelfTest.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -92,6 +92,8 @@ namespace ModernKeePassLib.Cryptography TestHmacOtp(); TestProtectedObjects(r); + TestNativeLib(); + TestMemUtil(r); TestStrUtil(); TestUrlUtil(); @@ -796,94 +798,6 @@ namespace ModernKeePassLib.Cryptography #endif } - private static void TestMemUtil(Random r) - { -#if DEBUG - byte[] pb = CryptoRandom.Instance.GetRandomBytes((uint)r.Next( - 0, 0x2FFFF)); - - byte[] pbCompressed = MemUtil.Compress(pb); - if(!MemUtil.ArraysEqual(MemUtil.Decompress(pbCompressed), pb)) - throw new InvalidOperationException("GZip"); - - Encoding enc = StrUtil.Utf8; - pb = enc.GetBytes("012345678901234567890a"); - byte[] pbN = enc.GetBytes("9012"); - if(MemUtil.IndexOf(pb, pbN) != 9) - throw new InvalidOperationException("MemUtil-1"); - pbN = enc.GetBytes("01234567890123"); - if(MemUtil.IndexOf(pb, pbN) != 0) - throw new InvalidOperationException("MemUtil-2"); - pbN = enc.GetBytes("a"); - if(MemUtil.IndexOf(pb, pbN) != 21) - throw new InvalidOperationException("MemUtil-3"); - pbN = enc.GetBytes("0a"); - if(MemUtil.IndexOf(pb, pbN) != 20) - throw new InvalidOperationException("MemUtil-4"); - pbN = enc.GetBytes("1"); - if(MemUtil.IndexOf(pb, pbN) != 1) - throw new InvalidOperationException("MemUtil-5"); - pbN = enc.GetBytes("b"); - if(MemUtil.IndexOf(pb, pbN) >= 0) - throw new InvalidOperationException("MemUtil-6"); - pbN = enc.GetBytes("012b"); - if(MemUtil.IndexOf(pb, pbN) >= 0) - throw new InvalidOperationException("MemUtil-7"); - - byte[] pbRes = MemUtil.ParseBase32("MY======"); - byte[] pbExp = Encoding.UTF8.GetBytes("f"); - if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-1"); - - pbRes = MemUtil.ParseBase32("MZXQ===="); - pbExp = Encoding.UTF8.GetBytes("fo"); - if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-2"); - - pbRes = MemUtil.ParseBase32("MZXW6==="); - pbExp = Encoding.UTF8.GetBytes("foo"); - if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-3"); - - pbRes = MemUtil.ParseBase32("MZXW6YQ="); - pbExp = Encoding.UTF8.GetBytes("foob"); - if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-4"); - - pbRes = MemUtil.ParseBase32("MZXW6YTB"); - pbExp = Encoding.UTF8.GetBytes("fooba"); - if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-5"); - - pbRes = MemUtil.ParseBase32("MZXW6YTBOI======"); - pbExp = Encoding.UTF8.GetBytes("foobar"); - if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-6"); - - pbRes = MemUtil.ParseBase32("JNSXSIDQOJXXM2LEMVZCAYTBONSWIIDPNYQG63TFFV2GS3LFEBYGC43TO5XXEZDTFY======"); - pbExp = Encoding.UTF8.GetBytes("Key provider based on one-time passwords."); - if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-7"); - - int i = 0 - 0x10203040; - pbRes = MemUtil.Int32ToBytes(i); - if(MemUtil.ByteArrayToHexString(pbRes) != "C0CFDFEF") - throw new Exception("MemUtil-8"); // Must be little-endian - if(MemUtil.BytesToUInt32(pbRes) != (uint)i) - throw new Exception("MemUtil-9"); - if(MemUtil.BytesToInt32(pbRes) != i) - throw new Exception("MemUtil-10"); - - ArrayHelperEx ah = MemUtil.ArrayHelperExOfChar; - for(int j = 0; j < 30; ++j) - { - string strA = r.Next(30).ToString(); - string strB = r.Next(30).ToString(); - char[] vA = strA.ToCharArray(); - char[] vB = strB.ToCharArray(); - - if(ah.Equals(vA, vB) != string.Equals(strA, strB)) - throw new Exception("MemUtil-11"); - if((vA.Length == vB.Length) && (Math.Sign(ah.Compare(vA, vB)) != - Math.Sign(string.CompareOrdinal(strA, strB)))) - throw new Exception("MemUtil-12"); - } -#endif - } - private static void TestHmacOtp() { #if (DEBUG && !KeePassLibSD) @@ -999,6 +913,119 @@ namespace ModernKeePassLib.Cryptography #endif } + private static void TestNativeLib() + { +#if DEBUG && !ModernKeePassLib + if(NativeLib.IsUnix()) + { + if(NativeLib.EncodeDataToArgs("A\"B C\\D") != + "A\\\"B C\\\\D") + throw new Exception("NativeLib-Args-U"); + } + else // Windows + { + if(NativeLib.EncodeDataToArgs("A\"B C\\D \\\\ \\\" \\\\\" \\\\\\\" \\\\\\") != + "A\\\"B C\\D \\\\ \\\\\\\" \\\\\\\\\\\" \\\\\\\\\\\\\\\" \\\\\\") + throw new Exception("NativeLib-Args-W"); + } + + string strOrg = "A\\B\\\\C\\\\\\D E\"F\"\"G\"\"\"H I\'J\'\'K\'\'\'L " + + "M\\\"N\\\\\"O\\\\\\\"P\\\\\\\\\\\"Q R\\\'S T\\\\\'U \\\\\\"; + string strArgs = NativeLib.EncodeDataToArgs(strOrg); + string strDec = NativeLib.DecodeArgsToData(strArgs); + if(strDec != strOrg) + throw new Exception("NativeLib-Args-EncDec"); +#endif + } + + private static void TestMemUtil(Random r) + { +#if DEBUG + byte[] pb = CryptoRandom.Instance.GetRandomBytes((uint)r.Next( + 0, 0x2FFFF)); + + byte[] pbCompressed = MemUtil.Compress(pb); + if(!MemUtil.ArraysEqual(MemUtil.Decompress(pbCompressed), pb)) + throw new InvalidOperationException("GZip"); + + Encoding enc = StrUtil.Utf8; + pb = enc.GetBytes("012345678901234567890a"); + byte[] pbN = enc.GetBytes("9012"); + if(MemUtil.IndexOf(pb, pbN) != 9) + throw new InvalidOperationException("MemUtil-1"); + pbN = enc.GetBytes("01234567890123"); + if(MemUtil.IndexOf(pb, pbN) != 0) + throw new InvalidOperationException("MemUtil-2"); + pbN = enc.GetBytes("a"); + if(MemUtil.IndexOf(pb, pbN) != 21) + throw new InvalidOperationException("MemUtil-3"); + pbN = enc.GetBytes("0a"); + if(MemUtil.IndexOf(pb, pbN) != 20) + throw new InvalidOperationException("MemUtil-4"); + pbN = enc.GetBytes("1"); + if(MemUtil.IndexOf(pb, pbN) != 1) + throw new InvalidOperationException("MemUtil-5"); + pbN = enc.GetBytes("b"); + if(MemUtil.IndexOf(pb, pbN) >= 0) + throw new InvalidOperationException("MemUtil-6"); + pbN = enc.GetBytes("012b"); + if(MemUtil.IndexOf(pb, pbN) >= 0) + throw new InvalidOperationException("MemUtil-7"); + + byte[] pbRes = MemUtil.ParseBase32("MY======"); + byte[] pbExp = Encoding.ASCII.GetBytes("f"); + if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-1"); + + pbRes = MemUtil.ParseBase32("MZXQ===="); + pbExp = Encoding.ASCII.GetBytes("fo"); + if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-2"); + + pbRes = MemUtil.ParseBase32("MZXW6==="); + pbExp = Encoding.ASCII.GetBytes("foo"); + if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-3"); + + pbRes = MemUtil.ParseBase32("MZXW6YQ="); + pbExp = Encoding.ASCII.GetBytes("foob"); + if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-4"); + + pbRes = MemUtil.ParseBase32("MZXW6YTB"); + pbExp = Encoding.ASCII.GetBytes("fooba"); + if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-5"); + + pbRes = MemUtil.ParseBase32("MZXW6YTBOI======"); + pbExp = Encoding.ASCII.GetBytes("foobar"); + if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-6"); + + pbRes = MemUtil.ParseBase32("JNSXSIDQOJXXM2LEMVZCAYTBONSWIIDPNYQG63TFFV2GS3LFEBYGC43TO5XXEZDTFY======"); + pbExp = Encoding.ASCII.GetBytes("Key provider based on one-time passwords."); + if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-7"); + + int i = 0 - 0x10203040; + pbRes = MemUtil.Int32ToBytes(i); + if(MemUtil.ByteArrayToHexString(pbRes) != "C0CFDFEF") + throw new Exception("MemUtil-8"); // Must be little-endian + if(MemUtil.BytesToUInt32(pbRes) != (uint)i) + throw new Exception("MemUtil-9"); + if(MemUtil.BytesToInt32(pbRes) != i) + throw new Exception("MemUtil-10"); + + ArrayHelperEx ah = MemUtil.ArrayHelperExOfChar; + for(int j = 0; j < 30; ++j) + { + string strA = r.Next(30).ToString(); + string strB = r.Next(30).ToString(); + char[] vA = strA.ToCharArray(); + char[] vB = strB.ToCharArray(); + + if(ah.Equals(vA, vB) != string.Equals(strA, strB)) + throw new Exception("MemUtil-11"); + if((vA.Length == vB.Length) && (Math.Sign(ah.Compare(vA, vB)) != + Math.Sign(string.CompareOrdinal(strA, strB)))) + throw new Exception("MemUtil-12"); + } +#endif + } + private static void TestStrUtil() { #if DEBUG @@ -1128,6 +1155,21 @@ namespace ModernKeePassLib.Cryptography Debug.Assert(Uri.UriSchemeHttps.Equals("https", StrUtil.CaseIgnoreCmp)); #endif + string str = UrlUtil.FilterFileName(" A \"*:?/\\|<>B.txt . "); + if(!str.StartsWith(" A ")) throw new Exception("UrlUtil-FFN1"); + if(!str.EndsWith("B.txt")) throw new Exception("UrlUtil-FFN2"); + if(str.IndexOfAny(new char[] { '\"', '*', ':', '?', '/', '\\', '|', '<', '>' }) >= 0) + throw new Exception("UrlUtil-FFN3"); + + if(UrlUtil.GetScheme("cmdG://\"Test.txt\"") != "cmdG") + throw new Exception("UrlUtil-GS"); + if(UrlUtil.RemoveScheme("cmdX://\"T\":A") != "\"T\":A") + throw new Exception("UrlUtil-RS1"); + if(UrlUtil.RemoveScheme("cmdY:/\"T\":A") != "/\"T\":A") + throw new Exception("UrlUtil-RS2"); + if(UrlUtil.RemoveScheme("cmdZ:\"T\":A") != "\"T\":A") + throw new Exception("UrlUtil-RS3"); + if(UrlUtil.GetHost(@"scheme://domain:port/path?query_string#fragment_id") != "domain") throw new InvalidOperationException("UrlUtil-H1"); @@ -1145,13 +1187,25 @@ namespace ModernKeePassLib.Cryptography if(UrlUtil.GetHost(@"s://u:p@d.tld:p/p?q#f") != "d.tld") throw new InvalidOperationException("UrlUtil-H7"); + if(!NativeLib.IsUnix()) // Windows + { + if(UrlUtil.FileUrlToPath("file:///C:/Windows/Win.ini") != + "C:\\Windows\\Win.ini") + throw new Exception("UrlUtil-FUTP-W"); + } + else // Unix + { + if(UrlUtil.FileUrlToPath("file:///etc/fstab") != "/etc/fstab") + throw new Exception("UrlUtil-FUTP-U"); + } + if(NativeLib.IsUnix()) return; string strBase = "\\\\HOMESERVER\\Apps\\KeePass\\KeePass.exe"; string strDoc = "\\\\HOMESERVER\\Documents\\KeePass\\NewDatabase.kdbx"; string strRel = "..\\..\\Documents\\KeePass\\NewDatabase.kdbx"; - string str = UrlUtil.MakeRelativePath(strBase, strDoc); + str = UrlUtil.MakeRelativePath(strBase, strDoc); if(!str.Equals(strRel)) throw new InvalidOperationException("UrlUtil-R1"); str = UrlUtil.MakeAbsolutePath(strBase, strRel); diff --git a/ModernKeePassLib/Delegates/Handlers.cs b/ModernKeePassLib/Delegates/Handlers.cs index 949821c..351a0b3 100644 --- a/ModernKeePassLib/Delegates/Handlers.cs +++ b/ModernKeePassLib/Delegates/Handlers.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Interfaces/IDeepCloneable.cs b/ModernKeePassLib/Interfaces/IDeepCloneable.cs index 7d7647c..ebd7670 100644 --- a/ModernKeePassLib/Interfaces/IDeepCloneable.cs +++ b/ModernKeePassLib/Interfaces/IDeepCloneable.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Interfaces/IStatusLogger.cs b/ModernKeePassLib/Interfaces/IStatusLogger.cs index 3675210..859cec9 100644 --- a/ModernKeePassLib/Interfaces/IStatusLogger.cs +++ b/ModernKeePassLib/Interfaces/IStatusLogger.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Interfaces/IStructureItem.cs b/ModernKeePassLib/Interfaces/IStructureItem.cs index 93e017b..a509cb6 100644 --- a/ModernKeePassLib/Interfaces/IStructureItem.cs +++ b/ModernKeePassLib/Interfaces/IStructureItem.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Interfaces/ITimeLogger.cs b/ModernKeePassLib/Interfaces/ITimeLogger.cs index 4c6fd73..92e8cf4 100644 --- a/ModernKeePassLib/Interfaces/ITimeLogger.cs +++ b/ModernKeePassLib/Interfaces/ITimeLogger.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Interfaces/IUIOperations.cs b/ModernKeePassLib/Interfaces/IUIOperations.cs index b8e9a1a..1415a9a 100644 --- a/ModernKeePassLib/Interfaces/IUIOperations.cs +++ b/ModernKeePassLib/Interfaces/IUIOperations.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Interfaces/IXmlSerializerEx.cs b/ModernKeePassLib/Interfaces/IXmlSerializerEx.cs index 04df73f..8d71c49 100644 --- a/ModernKeePassLib/Interfaces/IXmlSerializerEx.cs +++ b/ModernKeePassLib/Interfaces/IXmlSerializerEx.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/CompositeKey.cs b/ModernKeePassLib/Keys/CompositeKey.cs index cdcce64..f35991b 100644 --- a/ModernKeePassLib/Keys/CompositeKey.cs +++ b/ModernKeePassLib/Keys/CompositeKey.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/IUserKey.cs b/ModernKeePassLib/Keys/IUserKey.cs index 09cc4c7..cd0172f 100644 --- a/ModernKeePassLib/Keys/IUserKey.cs +++ b/ModernKeePassLib/Keys/IUserKey.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/KcpCustomKey.cs b/ModernKeePassLib/Keys/KcpCustomKey.cs index 5e6cca7..fcc500f 100644 --- a/ModernKeePassLib/Keys/KcpCustomKey.cs +++ b/ModernKeePassLib/Keys/KcpCustomKey.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/KcpKeyFile.cs b/ModernKeePassLib/Keys/KcpKeyFile.cs index dc85ad8..fb5ae22 100644 --- a/ModernKeePassLib/Keys/KcpKeyFile.cs +++ b/ModernKeePassLib/Keys/KcpKeyFile.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -179,15 +179,15 @@ namespace ModernKeePassLib.Keys return null; } - /// - /// Create a new, random key-file. - /// - /// Path where the key-file should be saved to. - /// If the file exists already, it will be overwritten. - /// Additional entropy used to generate - /// the random key. May be null (in this case only the KeePass-internal - /// random number generator is used). - /// Returns a FileSaveResult error code. + /// + /// Create a new, random key-file. + /// + /// Path where the key-file should be saved to. + /// If the file exists already, it will be overwritten. + /// Additional entropy used to generate + /// the random key. May be null (in this case only the KeePass-internal + /// random number generator is used). + /// Returns a FileSaveResult error code. #if ModernKeePassLib public static byte[] Create(byte[] pbAdditionalEntropy) #else @@ -281,7 +281,7 @@ namespace ModernKeePassLib.Keys private static byte[] CreateXmlKeyFile(byte[] pbKeyData) { #else - private static void CreateXmlKeyFile(string strFile, byte[] pbKeyData) + private static void CreateXmlKeyFile(string strFile, byte[] pbKeyData) { Debug.Assert(strFile != null); if(strFile == null) throw new ArgumentNullException("strFile"); @@ -323,6 +323,6 @@ namespace ModernKeePassLib.Keys return ((MemoryStream) s).ToArray(); #endif } - } - } + } + } } diff --git a/ModernKeePassLib/Keys/KcpPassword.cs b/ModernKeePassLib/Keys/KcpPassword.cs index 0eb10ea..38f6e63 100644 --- a/ModernKeePassLib/Keys/KcpPassword.cs +++ b/ModernKeePassLib/Keys/KcpPassword.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/KcpUserAccount.cs b/ModernKeePassLib/Keys/KcpUserAccount.cs index d6d53fc..baae05a 100644 --- a/ModernKeePassLib/Keys/KcpUserAccount.cs +++ b/ModernKeePassLib/Keys/KcpUserAccount.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/KeyProvider.cs b/ModernKeePassLib/Keys/KeyProvider.cs index 87b04ef..d1e8d97 100644 --- a/ModernKeePassLib/Keys/KeyProvider.cs +++ b/ModernKeePassLib/Keys/KeyProvider.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/KeyProviderPool.cs b/ModernKeePassLib/Keys/KeyProviderPool.cs index 26183d9..a4fdab8 100644 --- a/ModernKeePassLib/Keys/KeyProviderPool.cs +++ b/ModernKeePassLib/Keys/KeyProviderPool.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/KeyValidator.cs b/ModernKeePassLib/Keys/KeyValidator.cs index cb9a40a..84cb39b 100644 --- a/ModernKeePassLib/Keys/KeyValidator.cs +++ b/ModernKeePassLib/Keys/KeyValidator.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/KeyValidatorPool.cs b/ModernKeePassLib/Keys/KeyValidatorPool.cs index 2b0a98e..e603864 100644 --- a/ModernKeePassLib/Keys/KeyValidatorPool.cs +++ b/ModernKeePassLib/Keys/KeyValidatorPool.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Keys/UserKeyType.cs b/ModernKeePassLib/Keys/UserKeyType.cs index 3b7528f..fe9e34a 100644 --- a/ModernKeePassLib/Keys/UserKeyType.cs +++ b/ModernKeePassLib/Keys/UserKeyType.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/ModernKeePassLib.csproj b/ModernKeePassLib/ModernKeePassLib.csproj index a59bcdb..4f9b027 100644 --- a/ModernKeePassLib/ModernKeePassLib.csproj +++ b/ModernKeePassLib/ModernKeePassLib.csproj @@ -1,9 +1,9 @@  - netstandard2.0 + netstandard2.1 true - 2.42.1.3 + 2.44.0 Geoffroy Bonneville https://www.gnu.org/licenses/gpl-3.0.en.html https://github.com/wismna/ModernKeePassLib @@ -12,7 +12,7 @@ ModernKeePassLib Save corrections KeePass KeePassLib Portable PCL NetStandard ModernKeePass - Copyright © 2019 Geoffroy Bonneville + Copyright © 2020 Geoffroy Bonneville @@ -54,9 +54,9 @@ - - - + + + diff --git a/ModernKeePassLib/Native/ClipboardU.cs b/ModernKeePassLib/Native/ClipboardU.cs index ccfc1b6..f284236 100644 --- a/ModernKeePassLib/Native/ClipboardU.cs +++ b/ModernKeePassLib/Native/ClipboardU.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Native/Native.PCL.cs b/ModernKeePassLib/Native/Native.PCL.cs index 815f49d..b08cf18 100644 --- a/ModernKeePassLib/Native/Native.PCL.cs +++ b/ModernKeePassLib/Native/Native.PCL.cs @@ -27,6 +27,16 @@ namespace ModernKeePassLib.Native { if (!string.IsNullOrEmpty(strApp)) return strApp; return string.Empty; + } + + internal static string EncodeDataToArgs(string v) + { + throw new NotImplementedException(); + } + + public static string DecodeArgsToData(string strApp) + { + throw new NotImplementedException(); } } diff --git a/ModernKeePassLib/Native/NativeLib.cs b/ModernKeePassLib/Native/NativeLib.cs index c3fbe15..02b631f 100644 --- a/ModernKeePassLib/Native/NativeLib.cs +++ b/ModernKeePassLib/Native/NativeLib.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -234,7 +234,7 @@ namespace ModernKeePassLib.Native { ProcessStartInfo psi = new ProcessStartInfo(); - psi.FileName = EncodePath(strAppPath); + psi.FileName = strAppPath; if(!string.IsNullOrEmpty(strParams)) psi.Arguments = strParams; psi.CreateNoWindow = true; @@ -244,7 +244,7 @@ namespace ModernKeePassLib.Native psi.RedirectStandardOutput = bStdOut; if(strStdInput != null) psi.RedirectStandardInput = true; - Process p = Process.Start(psi); + Process p = StartProcessEx(psi); pToDispose = p; if(strStdInput != null) @@ -449,19 +449,18 @@ namespace ModernKeePassLib.Native Marshal.FreeHGlobal(kvpPointers.Value); } - internal static Type GetUwpType(string strType) - { - if(string.IsNullOrEmpty(strType)) { Debug.Assert(false); return null; } - - // https://referencesource.microsoft.com/#mscorlib/system/runtime/interopservices/windowsruntime/winrtclassactivator.cs - return Type.GetType(strType + ", Windows, ContentType=WindowsRuntime", false); - } + // internal static Type GetUwpType(string strType) + // { + // if(string.IsNullOrEmpty(strType)) { Debug.Assert(false); return null; } + // // https://referencesource.microsoft.com/#mscorlib/system/runtime/interopservices/windowsruntime/winrtclassactivator.cs + // return Type.GetType(strType + ", Windows, ContentType=WindowsRuntime", false); + // } + // Cf. DecodeArgsToData internal static string EncodeDataToArgs(string strData) { if(strData == null) { Debug.Assert(false); return string.Empty; } - // Cf. EncodePath and DecodeArgsToPath if(MonoWorkarounds.IsRequired(3471228285U) && IsUnix()) { string str = strData; @@ -479,53 +478,165 @@ namespace ModernKeePassLib.Native return str; } - // See SHELLEXECUTEINFO structure documentation - return strData.Replace("\"", "\"\"\""); + // SHELLEXECUTEINFOW structure documentation: + // https://docs.microsoft.com/en-us/windows/desktop/api/shellapi/ns-shellapi-shellexecuteinfow + // return strData.Replace("\"", "\"\"\""); + + // Microsoft C/C++ startup code: + // https://docs.microsoft.com/en-us/cpp/cpp/parsing-cpp-command-line-arguments + // CommandLineToArgvW function: + // https://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-commandlinetoargvw + + StringBuilder sb = new StringBuilder(); + int i = 0; + while(i < strData.Length) + { + char ch = strData[i++]; + + if(ch == '\\') + { + int cBackslashes = 1; + while((i < strData.Length) && (strData[i] == '\\')) + { + ++cBackslashes; + ++i; + } + + if(i == strData.Length) + sb.Append('\\', cBackslashes); // Assume no quote follows + else if(strData[i] == '\"') + { + sb.Append('\\', (cBackslashes * 2) + 1); + sb.Append('\"'); + ++i; + } + else sb.Append('\\', cBackslashes); + } + else if(ch == '\"') sb.Append("\\\""); + else sb.Append(ch); + } + + return sb.ToString(); } - /// - /// Encode a path for Process.Start. - /// - internal static string EncodePath(string strPath) + // Cf. EncodeDataToArgs + internal static string DecodeArgsToData(string strArgs) { - if(strPath == null) { Debug.Assert(false); return string.Empty; } + if(strArgs == null) { Debug.Assert(false); return string.Empty; } + + Debug.Assert(StrUtil.Count(strArgs, "\"") == StrUtil.Count(strArgs, "\\\"")); - // Cf. EncodeDataToArgs and DecodeArgsToPath if(MonoWorkarounds.IsRequired(3471228285U) && IsUnix()) { - string str = strPath; + string str = strArgs; - str = str.Replace("\\", "\\\\"); - str = str.Replace("\"", "\\\""); - - // '\'' must not be encoded in paths (only in args) - // str = str.Replace("\'", "\\\'"); + str = str.Replace("\\\"", "\""); + str = str.Replace("\\\\", "\\"); return str; } - return strPath; // '\"' is not allowed in paths on Windows + StringBuilder sb = new StringBuilder(); + int i = 0; + while(i < strArgs.Length) + { + char ch = strArgs[i++]; + + if(ch == '\\') + { + int cBackslashes = 1; + while((i < strArgs.Length) && (strArgs[i] == '\\')) + { + ++cBackslashes; + ++i; + } + + if(i == strArgs.Length) + sb.Append('\\', cBackslashes); // Assume no quote follows + else if(strArgs[i] == '\"') + { + Debug.Assert((cBackslashes & 1) == 1); + sb.Append('\\', (cBackslashes - 1) / 2); + sb.Append('\"'); + ++i; + } + else sb.Append('\\', cBackslashes); + } + else sb.Append(ch); + } + + return sb.ToString(); } - /// - /// Decode command line arguments to a path for Process.Start. - /// - internal static string DecodeArgsToPath(string strArgs) + internal static void StartProcess(string strFile) { - if(strArgs == null) { Debug.Assert(false); return string.Empty; } + StartProcess(strFile, null); + } - string str = strArgs; + internal static void StartProcess(string strFile, string strArgs) + { + ProcessStartInfo psi = new ProcessStartInfo(); + if(!string.IsNullOrEmpty(strFile)) psi.FileName = strFile; + if(!string.IsNullOrEmpty(strArgs)) psi.Arguments = strArgs; - // Cf. EncodeDataToArgs and EncodePath - // if(MonoWorkarounds.IsRequired(3471228285U) && IsUnix()) - // { - // string strPlh = Guid.NewGuid().ToString(); - // str = str.Replace("\\\\", strPlh); - // str = str.Replace("\\\'", "\'"); - // str = str.Replace(strPlh, "\\\\"); // Restore - // } + StartProcess(psi); + } - return str; // '\"' is not allowed in paths on Windows + internal static void StartProcess(ProcessStartInfo psi) + { + Process p = StartProcessEx(psi); + + try { if(p != null) p.Dispose(); } + catch(Exception) { Debug.Assert(false); } + } + + internal static Process StartProcessEx(ProcessStartInfo psi) + { + if(psi == null) { Debug.Assert(false); return null; } + + string strFileOrg = psi.FileName; + if(string.IsNullOrEmpty(strFileOrg)) { Debug.Assert(false); return null; } + + Process p; + try + { + string strFile = strFileOrg; + + string[] vUrlEncSchemes = new string[] { + "file:", "ftp:", "ftps:", "http:", "https:", + "mailto:", "scp:", "sftp:" + }; + foreach(string strPfx in vUrlEncSchemes) + { + if(strFile.StartsWith(strPfx, StrUtil.CaseIgnoreCmp)) + { + Debug.Assert(string.IsNullOrEmpty(psi.Arguments)); + + strFile = strFile.Replace("\"", "%22"); + strFile = strFile.Replace("\'", "%27"); + strFile = strFile.Replace("\\", "%5C"); + break; + } + } + + if(IsUnix()) + { + // Mono's Process.Start method replaces '\\' by '/', + // which may cause a different file to be executed; + // therefore, we refuse to start such files + if(strFile.Contains("\\") && MonoWorkarounds.IsRequired(190417)) + throw new ArgumentException(KLRes.PathBackslash); + + strFile = strFile.Replace("\\", "\\\\"); // If WA not required + strFile = strFile.Replace("\"", "\\\""); + } + + psi.FileName = strFile; + p = Process.Start(psi); + } + finally { psi.FileName = strFileOrg; } + + return p; } } } diff --git a/ModernKeePassLib/Native/NativeMethods.Unix.cs b/ModernKeePassLib/Native/NativeMethods.Unix.cs index 2b3f2de..4f55b76 100644 --- a/ModernKeePassLib/Native/NativeMethods.Unix.cs +++ b/ModernKeePassLib/Native/NativeMethods.Unix.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Native/NativeMethods.cs b/ModernKeePassLib/Native/NativeMethods.cs index 69d21fd..4efb499 100644 --- a/ModernKeePassLib/Native/NativeMethods.cs +++ b/ModernKeePassLib/Native/NativeMethods.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Native/SimpleStat.cs b/ModernKeePassLib/Native/SimpleStat.cs new file mode 100644 index 0000000..d3816cf --- /dev/null +++ b/ModernKeePassLib/Native/SimpleStat.cs @@ -0,0 +1,150 @@ +/* + KeePass Password Safe - The Open-Source Password Manager + Copyright (C) 2003-2020 Dominik Reichl + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Text; +using System.Xml; + +namespace ModernKeePassLib.Native +{ + internal sealed class SimpleStat + { + private readonly object m_oPermissions; + private readonly long m_nUserId; + private readonly long m_nGroupId; + + private SimpleStat(object oPermissions, long nUserId, long nGroupId) + { + if(oPermissions == null) throw new ArgumentNullException("oPermissions"); + + m_oPermissions = oPermissions; + m_nUserId = nUserId; + m_nGroupId = nGroupId; + } + + public static SimpleStat Get(string strFilePath) + { + try + { + Type tUfsi, tUfi; + object oUfi = GetUnixFileInfo(strFilePath, out tUfsi, out tUfi); + if(oUfi == null) return null; + + PropertyInfo piPerm = tUfsi.GetProperty("FileAccessPermissions", + BindingFlags.Public | BindingFlags.Instance); + if(piPerm == null) { Debug.Assert(false); return null; } + Debug.Assert(piPerm.PropertyType.IsEnum); + + PropertyInfo piUser = tUfsi.GetProperty("OwnerUserId", + BindingFlags.Public | BindingFlags.Instance); + if(piUser == null) { Debug.Assert(false); return null; } + Debug.Assert(piUser.PropertyType == typeof(long)); + + PropertyInfo piGroup = tUfsi.GetProperty("OwnerGroupId", + BindingFlags.Public | BindingFlags.Instance); + if(piGroup == null) { Debug.Assert(false); return null; } + Debug.Assert(piGroup.PropertyType == typeof(long)); + + return new SimpleStat(piPerm.GetValue(oUfi, null), + (long)piUser.GetValue(oUfi, null), + (long)piGroup.GetValue(oUfi, null)); + } + catch(Exception) { Debug.Assert(false); } + + return null; + } + + public static void Set(string strFilePath, SimpleStat s) + { + if(s == null) { Debug.Assert(false); return; } + + try + { + Type tUfsi, tUfi; + object oUfi = GetUnixFileInfo(strFilePath, out tUfsi, out tUfi); + if(oUfi == null) return; + + PropertyInfo piPerm = tUfsi.GetProperty("FileAccessPermissions", + BindingFlags.Public | BindingFlags.Instance); + if(piPerm == null) { Debug.Assert(false); return; } + + piPerm.SetValue(oUfi, s.m_oPermissions, null); + + MethodInfo miOwner = tUfsi.GetMethod("SetOwner", + new Type[] { typeof(long), typeof(long) }); + if(miOwner == null) { Debug.Assert(false); return; } + + miOwner.Invoke(oUfi, new object[] { s.m_nUserId, s.m_nGroupId }); + } + catch(Exception) { Debug.Assert(false); } + } + + private static bool GetTypes(out Type tUfsi, out Type tUfi) + { + tUfsi = null; + tUfi = null; + + try + { + if(!NativeLib.IsUnix()) return false; + + string strVer = typeof(XmlNode).Assembly.GetName().Version.ToString(); + string strPosix = "Mono.Posix, Version=" + strVer; + Assembly asmPosix = Assembly.Load(strPosix); + if(asmPosix == null) { Debug.Assert(false); return false; } + + tUfsi = asmPosix.GetType("Mono.Unix.UnixFileSystemInfo", false); + tUfi = asmPosix.GetType("Mono.Unix.UnixFileInfo", false); + + bool b = ((tUfsi != null) && (tUfi != null)); + Debug.Assert(b); + return b; + } + catch(Exception) { Debug.Assert(false); } + + return false; + } + + private static object GetUnixFileInfo(string strFilePath, Type tUfi) + { + if(string.IsNullOrEmpty(strFilePath)) { Debug.Assert(false); return null; } + + try + { + if(!File.Exists(strFilePath)) { Debug.Assert(false); return null; } + + return Activator.CreateInstance(tUfi, strFilePath); + } + catch(Exception) { Debug.Assert(false); } + + return null; + } + + private static object GetUnixFileInfo(string strFilePath, + out Type tUfsi, out Type tUfi) + { + if(!GetTypes(out tUfsi, out tUfi)) return null; + return GetUnixFileInfo(strFilePath, tUfi); + } + } +} diff --git a/ModernKeePassLib/PwCustomIcon.cs b/ModernKeePassLib/PwCustomIcon.cs index 670a2fc..4c1d7c8 100644 --- a/ModernKeePassLib/PwCustomIcon.cs +++ b/ModernKeePassLib/PwCustomIcon.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/PwDatabase.cs b/ModernKeePassLib/PwDatabase.cs index c688af3..671d166 100644 --- a/ModernKeePassLib/PwDatabase.cs +++ b/ModernKeePassLib/PwDatabase.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -108,7 +108,7 @@ namespace ModernKeePassLib private IStatusLogger m_slStatus = null; - private static string m_strLocalizedAppName = string.Empty; + private static string g_strLocalizedAppName = string.Empty; // private const string StrBackupExtension = ".bak"; @@ -116,16 +116,14 @@ namespace ModernKeePassLib /// Get the root group that contains all groups and entries stored in the /// database. /// - /// Root group. The return value is null, if no database - /// has been opened. + /// Root group. The return value is null, if the database + /// is not open. public PwGroup RootGroup { get { return m_pgRootGroup; } set { - Debug.Assert(value != null); - if(value == null) throw new ArgumentNullException("value"); - + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_pgRootGroup = value; } } @@ -167,8 +165,7 @@ namespace ModernKeePassLib get { return m_pwUserKey; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); - + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_pwUserKey = value; } } @@ -187,8 +184,8 @@ namespace ModernKeePassLib get { return m_strName; } set { - Debug.Assert(value != null); - if(value != null) m_strName = value; + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } + m_strName = value; } } @@ -206,8 +203,8 @@ namespace ModernKeePassLib get { return m_strDesc; } set { - Debug.Assert(value != null); - if(value != null) m_strDesc = value; + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } + m_strDesc = value; } } @@ -225,8 +222,8 @@ namespace ModernKeePassLib get { return m_strDefaultUserName; } set { - Debug.Assert(value != null); - if(value != null) m_strDefaultUserName = value; + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } + m_strDefaultUserName = value; } } @@ -284,8 +281,8 @@ namespace ModernKeePassLib get { return m_uuidDataCipher; } set { - Debug.Assert(value != null); - if(value != null) m_uuidDataCipher = value; + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } + m_uuidDataCipher = value; } } @@ -312,7 +309,7 @@ namespace ModernKeePassLib get { return m_kdfParams; } set { - if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_kdfParams = value; } } @@ -325,8 +322,7 @@ namespace ModernKeePassLib get { return m_memProtConfig; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); - + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_memProtConfig = value; } } @@ -362,7 +358,7 @@ namespace ModernKeePassLib get { return m_pwLastSelectedGroup; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_pwLastSelectedGroup = value; } } @@ -372,7 +368,7 @@ namespace ModernKeePassLib get { return m_pwLastTopVisibleGroup; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_pwLastTopVisibleGroup = value; } } @@ -388,7 +384,7 @@ namespace ModernKeePassLib get { return m_pwRecycleBin; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_pwRecycleBin = value; } } @@ -408,7 +404,7 @@ namespace ModernKeePassLib get { return m_pwEntryTemplatesGroup; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_pwEntryTemplatesGroup = value; } } @@ -512,8 +508,12 @@ namespace ModernKeePassLib /// public static string LocalizedAppName { - get { return m_strLocalizedAppName; } - set { Debug.Assert(value != null); m_strLocalizedAppName = value; } + get { return g_strLocalizedAppName; } + set + { + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } + g_strLocalizedAppName = value; + } } /// @@ -521,8 +521,6 @@ namespace ModernKeePassLib /// public PwDatabase() { - if(m_bPrimaryCreated == false) m_bPrimaryCreated = true; - Clear(); } @@ -682,7 +680,7 @@ namespace ModernKeePassLib #if ModernKeePassLib IOConnectionInfo.Bytes = ((MemoryStream)s).ToArray(); #endif - } + } ft.CommitWrite(); } @@ -908,19 +906,18 @@ namespace ModernKeePassLib MergeInLocationChanged(m_pgRootGroup, ppOrg, ppSrc); ppOrg = null; // Pools are now invalid, because the location ppSrc = null; // changed times have been merged in - - // Delete *after* relocating, because relocating might - // empty some groups that are marked for deletion (and - // objects that weren't relocated yet might prevent the - // deletion) - Dictionary dOrgDel = CreateDeletedObjectsPool(); - MergeInDeletionInfo(pdSource.m_vDeletedObjects, dOrgDel); - ApplyDeletions(m_pgRootGroup, dOrgDel); - - // The list and the dictionary should be kept in sync - Debug.Assert(m_vDeletedObjects.UCount == (uint)dOrgDel.Count); } + // Delete *after* relocating, because relocating might empty + // some groups that are marked for deletion (and objects + // that weren't relocated yet might prevent the deletion) + Dictionary dOrgDel = CreateDeletedObjectsPool(); + if(mm == PwMergeMethod.Synchronize) + MergeInDeletionInfo(pdSource.m_vDeletedObjects, dOrgDel); + ApplyDeletions(m_pgRootGroup, dOrgDel); + // The list and the dictionary should be kept in sync + Debug.Assert(m_vDeletedObjects.UCount == (uint)dOrgDel.Count); + // Must be called *after* merging groups, because group UUIDs // are required for recycle bin and entry template UUIDs MergeInDbProperties(pdSource, mm); @@ -1957,16 +1954,22 @@ namespace ModernKeePassLib return uDeleted; } - private static List m_lStdFields = null; + private static List g_lDupStdFields = null; private static bool DupEntriesEqual(PwEntry a, PwEntry b) { - if(m_lStdFields == null) m_lStdFields = PwDefs.GetStandardFields(); - - foreach(string strStdKey in m_lStdFields) + if(g_lDupStdFields == null) { - string strA = a.Strings.ReadSafe(strStdKey); - string strB = b.Strings.ReadSafe(strStdKey); - if(!strA.Equals(strB)) return false; + g_lDupStdFields = PwDefs.GetStandardFields(); + if(g_lDupStdFields.Remove(PwDefs.PasswordField)) + g_lDupStdFields.Add(PwDefs.PasswordField); // Move to end (perf. opt.) + else { Debug.Assert(false); } + } + + foreach(string strStdKey in g_lDupStdFields) + { + ProtectedString psA = a.Strings.GetSafe(strStdKey); + ProtectedString psB = b.Strings.GetSafe(strStdKey); + if(!psA.Equals(psB, false)) return false; } foreach(KeyValuePair kvpA in a.Strings) diff --git a/ModernKeePassLib/PwDefs.cs b/ModernKeePassLib/PwDefs.cs index 4683691..58b4f67 100644 --- a/ModernKeePassLib/PwDefs.cs +++ b/ModernKeePassLib/PwDefs.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -234,9 +234,33 @@ namespace ModernKeePassLib if(strFileVersion == null) { Debug.Assert(false); return string.Empty; } if(strFileVersion == "2.39") return "2.39 / 2.39.1"; + if(strFileVersion == "2.42") return "2.42 / 2.42.1"; return strFileVersion; } + + internal static PwIcon GroupIconToEntryIcon(PwIcon i) + { + PwIcon r = i; // Inherit by default + + switch(i) + { + case PwIcon.Folder: + case PwIcon.FolderOpen: + case PwIcon.FolderPackage: + Debug.Assert((new PwEntry(false, false)).IconId == PwIcon.Key); + r = PwIcon.Key; + break; + + case PwIcon.EMailBox: + r = PwIcon.EMail; + break; + + default: break; + } + + return r; + } } // #pragma warning disable 1591 // Missing XML comments warning diff --git a/ModernKeePassLib/PwDeletedObject.cs b/ModernKeePassLib/PwDeletedObject.cs index 474fe6a..55c3f59 100644 --- a/ModernKeePassLib/PwDeletedObject.cs +++ b/ModernKeePassLib/PwDeletedObject.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/PwEntry.cs b/ModernKeePassLib/PwEntry.cs index 46259ab..8b5b19c 100644 --- a/ModernKeePassLib/PwEntry.cs +++ b/ModernKeePassLib/PwEntry.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -73,7 +73,7 @@ namespace ModernKeePassLib get { return m_uuid; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_uuid = value; } } @@ -106,7 +106,7 @@ namespace ModernKeePassLib get { return m_listStrings; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_listStrings = value; } } @@ -119,7 +119,7 @@ namespace ModernKeePassLib get { return m_listBinaries; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_listBinaries = value; } } @@ -132,7 +132,7 @@ namespace ModernKeePassLib get { return m_listAutoType; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_listAutoType = value; } } @@ -145,7 +145,7 @@ namespace ModernKeePassLib get { return m_listHistory; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_listHistory = value; } } @@ -169,7 +169,7 @@ namespace ModernKeePassLib get { return m_pwCustomIconID; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_pwCustomIconID = value; } } @@ -256,7 +256,7 @@ namespace ModernKeePassLib get { return m_strOverrideUrl; } set { - if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_strOverrideUrl = value; } } @@ -269,7 +269,7 @@ namespace ModernKeePassLib get { return m_vTags; } set { - if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_vTags = value; } } diff --git a/ModernKeePassLib/PwEnums.cs b/ModernKeePassLib/PwEnums.cs index 0dab7c5..5e95704 100644 --- a/ModernKeePassLib/PwEnums.cs +++ b/ModernKeePassLib/PwEnums.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/PwGroup.cs b/ModernKeePassLib/PwGroup.cs index 6b089ef..2779c93 100644 --- a/ModernKeePassLib/PwGroup.cs +++ b/ModernKeePassLib/PwGroup.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -82,7 +82,7 @@ namespace ModernKeePassLib get { return m_uuid; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_uuid = value; } } @@ -95,7 +95,7 @@ namespace ModernKeePassLib get { return m_strName; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_strName = value; } } @@ -108,7 +108,7 @@ namespace ModernKeePassLib get { return m_strNotes; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_strNotes = value; } } @@ -132,7 +132,7 @@ namespace ModernKeePassLib get { return m_pwCustomIconID; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_pwCustomIconID = value; } } @@ -262,7 +262,7 @@ namespace ModernKeePassLib get { return m_strDefaultAutoTypeSequence; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_strDefaultAutoTypeSequence = value; } } @@ -284,7 +284,7 @@ namespace ModernKeePassLib get { return m_pwLastTopVisibleEntry; } set { - Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value"); + if(value == null) { Debug.Assert(false); throw new ArgumentNullException("value"); } m_pwLastTopVisibleEntry = value; } } @@ -900,7 +900,7 @@ namespace ModernKeePassLib { RegexOptions ro = RegexOptions.None; // RegexOptions.Compiled if((sp.ComparisonMode == StringComparison.CurrentCultureIgnoreCase) || -#if !ModernKeePassLib && !KeePassRT +#if !ModernKeePassLib (sp.ComparisonMode == StringComparison.InvariantCultureIgnoreCase) || #endif (sp.ComparisonMode == StringComparison.OrdinalIgnoreCase)) diff --git a/ModernKeePassLib/PwUuid.cs b/ModernKeePassLib/PwUuid.cs index 5e020d3..4873037 100644 --- a/ModernKeePassLib/PwUuid.cs +++ b/ModernKeePassLib/PwUuid.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Resources/KLRes.Generated.cs b/ModernKeePassLib/Resources/KLRes.Generated.cs index 3e4a6c2..c87b503 100644 --- a/ModernKeePassLib/Resources/KLRes.Generated.cs +++ b/ModernKeePassLib/Resources/KLRes.Generated.cs @@ -26,6 +26,9 @@ namespace ModernKeePassLib.Resources { if(dictNew == null) throw new ArgumentNullException("dictNew"); + m_strAlgorithmUnknown = TryGetEx(dictNew, "AlgorithmUnknown", m_strAlgorithmUnknown); + m_strCharSetInvalid = TryGetEx(dictNew, "CharSetInvalid", m_strCharSetInvalid); + m_strCharSetTooFewChars = TryGetEx(dictNew, "CharSetTooFewChars", m_strCharSetTooFewChars); m_strCryptoStreamFailed = TryGetEx(dictNew, "CryptoStreamFailed", m_strCryptoStreamFailed); m_strEncDataTooLarge = TryGetEx(dictNew, "EncDataTooLarge", m_strEncDataTooLarge); m_strErrorInClipboard = TryGetEx(dictNew, "ErrorInClipboard", m_strErrorInClipboard); @@ -58,10 +61,14 @@ namespace ModernKeePassLib.Resources m_strMasterSeedLengthInvalid = TryGetEx(dictNew, "MasterSeedLengthInvalid", m_strMasterSeedLengthInvalid); m_strOldFormat = TryGetEx(dictNew, "OldFormat", m_strOldFormat); m_strPassive = TryGetEx(dictNew, "Passive", m_strPassive); + m_strPathBackslash = TryGetEx(dictNew, "PathBackslash", m_strPathBackslash); + m_strPatternInvalid = TryGetEx(dictNew, "PatternInvalid", m_strPatternInvalid); m_strPreAuth = TryGetEx(dictNew, "PreAuth", m_strPreAuth); + m_strPwGenFailed = TryGetEx(dictNew, "PwGenFailed", m_strPwGenFailed); m_strStructsTooDeep = TryGetEx(dictNew, "StructsTooDeep", m_strStructsTooDeep); m_strTimeout = TryGetEx(dictNew, "Timeout", m_strTimeout); m_strTryAgainSecs = TryGetEx(dictNew, "TryAgainSecs", m_strTryAgainSecs); + m_strUnknownError = TryGetEx(dictNew, "UnknownError", m_strUnknownError); m_strUnknownHeaderId = TryGetEx(dictNew, "UnknownHeaderId", m_strUnknownHeaderId); m_strUnknownKdf = TryGetEx(dictNew, "UnknownKdf", m_strUnknownKdf); m_strUserAccountKeyError = TryGetEx(dictNew, "UserAccountKeyError", m_strUserAccountKeyError); @@ -69,6 +76,9 @@ namespace ModernKeePassLib.Resources } private static readonly string[] m_vKeyNames = { + "AlgorithmUnknown", + "CharSetInvalid", + "CharSetTooFewChars", "CryptoStreamFailed", "EncDataTooLarge", "ErrorInClipboard", @@ -101,10 +111,14 @@ namespace ModernKeePassLib.Resources "MasterSeedLengthInvalid", "OldFormat", "Passive", + "PathBackslash", + "PatternInvalid", "PreAuth", + "PwGenFailed", "StructsTooDeep", "Timeout", "TryAgainSecs", + "UnknownError", "UnknownHeaderId", "UnknownKdf", "UserAccountKeyError", @@ -116,6 +130,39 @@ namespace ModernKeePassLib.Resources return m_vKeyNames; } + private static string m_strAlgorithmUnknown = + @"The algorithm is unknown."; + /// + /// Look up a localized string similar to + /// 'The algorithm is unknown.'. + /// + public static string AlgorithmUnknown + { + get { return m_strAlgorithmUnknown; } + } + + private static string m_strCharSetInvalid = + @"The character set is invalid."; + /// + /// Look up a localized string similar to + /// 'The character set is invalid.'. + /// + public static string CharSetInvalid + { + get { return m_strCharSetInvalid; } + } + + private static string m_strCharSetTooFewChars = + @"There are too few characters in the character set."; + /// + /// Look up a localized string similar to + /// 'There are too few characters in the character set.'. + /// + public static string CharSetTooFewChars + { + get { return m_strCharSetTooFewChars; } + } + private static string m_strCryptoStreamFailed = @"Failed to initialize encryption/decryption stream!"; /// @@ -468,6 +515,28 @@ namespace ModernKeePassLib.Resources get { return m_strPassive; } } + private static string m_strPathBackslash = + @"The path contains a backslash. Such paths are not supported (for security reasons)."; + /// + /// Look up a localized string similar to + /// 'The path contains a backslash. Such paths are not supported (for security reasons).'. + /// + public static string PathBackslash + { + get { return m_strPathBackslash; } + } + + private static string m_strPatternInvalid = + @"The pattern is invalid."; + /// + /// Look up a localized string similar to + /// 'The pattern is invalid.'. + /// + public static string PatternInvalid + { + get { return m_strPatternInvalid; } + } + private static string m_strPreAuth = @"Pre-authenticate"; /// @@ -479,6 +548,17 @@ namespace ModernKeePassLib.Resources get { return m_strPreAuth; } } + private static string m_strPwGenFailed = + @"Failed to generate a password."; + /// + /// Look up a localized string similar to + /// 'Failed to generate a password.'. + /// + public static string PwGenFailed + { + get { return m_strPwGenFailed; } + } + private static string m_strStructsTooDeep = @"Structures are nested too deeply."; /// @@ -512,6 +592,17 @@ namespace ModernKeePassLib.Resources get { return m_strTryAgainSecs; } } + private static string m_strUnknownError = + @"An unknown error occurred."; + /// + /// Look up a localized string similar to + /// 'An unknown error occurred.'. + /// + public static string UnknownError + { + get { return m_strUnknownError; } + } + private static string m_strUnknownHeaderId = @"Unknown header ID!"; /// diff --git a/ModernKeePassLib/Security/ProtectedBinary.cs b/ModernKeePassLib/Security/ProtectedBinary.cs index 7a25eb0..8ec5841 100644 --- a/ModernKeePassLib/Security/ProtectedBinary.cs +++ b/ModernKeePassLib/Security/ProtectedBinary.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Security/ProtectedString.cs b/ModernKeePassLib/Security/ProtectedString.cs index 23572b1..01dd879 100644 --- a/ModernKeePassLib/Security/ProtectedString.cs +++ b/ModernKeePassLib/Security/ProtectedString.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Security/XorredBuffer.cs b/ModernKeePassLib/Security/XorredBuffer.cs index 3a7768f..2a00cf2 100644 --- a/ModernKeePassLib/Security/XorredBuffer.cs +++ b/ModernKeePassLib/Security/XorredBuffer.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Serialization/BinaryReaderEx.cs b/ModernKeePassLib/Serialization/BinaryReaderEx.cs index d851705..9d8ffc4 100644 --- a/ModernKeePassLib/Serialization/BinaryReaderEx.cs +++ b/ModernKeePassLib/Serialization/BinaryReaderEx.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Serialization/FileLock.cs b/ModernKeePassLib/Serialization/FileLock.cs index eb5af4a..1981225 100644 --- a/ModernKeePassLib/Serialization/FileLock.cs +++ b/ModernKeePassLib/Serialization/FileLock.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Serialization/FileTransactionEx.cs b/ModernKeePassLib/Serialization/FileTransactionEx.cs index 9865e61..c40822b 100644 --- a/ModernKeePassLib/Serialization/FileTransactionEx.cs +++ b/ModernKeePassLib/Serialization/FileTransactionEx.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,7 +23,7 @@ using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Text; -#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT) +#if (!ModernKeePassLib && !KeePassUAP) using System.Security.AccessControl; #endif @@ -45,9 +45,9 @@ namespace ModernKeePassLib.Serialization private bool m_bMadeUnhidden = false; private List m_lToDelete = new List(); - private const string StrTempSuffix = ".tmp"; + internal const string StrTempSuffix = ".tmp"; private static readonly string StrTxfTempPrefix = PwDefs.ShortProductName + "_TxF_"; - private const string StrTxfTempSuffix = ".tmp"; + internal const string StrTxfTempSuffix = ".tmp"; private static Dictionary g_dEnabled = new Dictionary(StrUtil.CaseIgnoreComparer); @@ -212,6 +212,7 @@ namespace ModernKeePassLib.Serialization byte[] pbSec = null; DateTime? otCreation = null; + SimpleStat sStat = null; bool bBaseExists = IOConnection.FileExists(m_iocBase); if(bBaseExists && m_iocBase.IsLocalFile()) @@ -226,6 +227,7 @@ namespace ModernKeePassLib.Serialization catch(Exception) { Debug.Assert(false); } #endif otCreation = File.GetCreationTimeUtc(m_iocBase.Path); + sStat = SimpleStat.Get(m_iocBase.Path); #if !ModernKeePassLib // May throw with Mono FileSecurity sec = File.GetAccessControl(m_iocBase.Path, acs); @@ -255,6 +257,8 @@ namespace ModernKeePassLib.Serialization if(otCreation.HasValue && (otCreation.Value.Year >= 1971)) File.SetCreationTimeUtc(m_iocBase.Path, otCreation.Value); + if(sStat != null) SimpleStat.Set(m_iocBase.Path, sStat); + if(bEfsEncrypted) { try { File.Encrypt(m_iocBase.Path); } @@ -328,7 +332,7 @@ namespace ModernKeePassLib.Serialization { if(NativeLib.IsUnix()) return; if(!m_iocBase.IsLocalFile()) return; - if(IsOneDriveWorkaroundRequired()) return; + if(TxfIsUnusable()) return; string strID = StrUtil.AlphaNumericOnly(Convert.ToBase64String( CryptoRandom.Instance.GetRandomBytes(16))); @@ -420,46 +424,35 @@ namespace ModernKeePassLib.Serialization } } #endif + return false; } - internal static void ClearOld() - { - try - { - // See also TxfPrepare method - DirectoryInfo di = new DirectoryInfo(UrlUtil.GetTempPath()); - List l = UrlUtil.GetFileInfos(di, StrTxfTempPrefix + - "*" + StrTxfTempSuffix, SearchOption.TopDirectoryOnly); - - foreach(FileInfo fi in l) - { - if(fi == null) { Debug.Assert(false); continue; } - if(!fi.Name.StartsWith(StrTxfTempPrefix, StrUtil.CaseIgnoreCmp) || - !fi.Name.EndsWith(StrTxfTempSuffix, StrUtil.CaseIgnoreCmp)) - continue; - - if((DateTime.UtcNow - fi.LastWriteTimeUtc).TotalDays > 1.0) - fi.Delete(); - } - } - catch(Exception) { Debug.Assert(false); } - } - - // https://sourceforge.net/p/keepass/discussion/329220/thread/672ffecc65/ - // https://sourceforge.net/p/keepass/discussion/329221/thread/514786c23a/ - private bool IsOneDriveWorkaroundRequired() + private bool TxfIsUnusable() { #if !ModernKeePassLib - if(NativeLib.IsUnix()) return false; - try { string strReleaseId = (Registry.GetValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ReleaseId", string.Empty) as string); + + // Due to a bug in Microsoft's 'cldflt.sys' driver, a TxF transaction + // results in a Blue Screen of Death on Windows 10 1903/1909; + // https://www.windowslatest.com/2019/10/20/windows-10-update-issues-bsod-broken-apps-and-defender-atp/ + // https://sourceforge.net/p/keepass/discussion/329221/thread/924b94ea48/ + // This bug is fixed by the Windows update 4530684; + // https://support.microsoft.com/en-us/help/4530684/windows-10-update-kb4530684 + // if(strReleaseId == "1903") return true; + // if(strReleaseId == "1909") return true; + if(strReleaseId != "1809") return false; + // On Windows 10 1809, OneDrive crashes if the file is + // in a OneDrive folder; + // https://sourceforge.net/p/keepass/discussion/329220/thread/672ffecc65/ + // https://sourceforge.net/p/keepass/discussion/329221/thread/514786c23a/ + string strFile = m_iocBase.Path; GFunc fMatch = delegate(string strRoot, string strSfx) @@ -529,5 +522,28 @@ namespace ModernKeePassLib.Serialization #endif return false; } + + internal static void ClearOld() + { + try + { + // See also TxfPrepare method + DirectoryInfo di = new DirectoryInfo(UrlUtil.GetTempPath()); + List l = UrlUtil.GetFileInfos(di, StrTxfTempPrefix + + "*" + StrTxfTempSuffix, SearchOption.TopDirectoryOnly); + + foreach(FileInfo fi in l) + { + if(fi == null) { Debug.Assert(false); continue; } + if(!fi.Name.StartsWith(StrTxfTempPrefix, StrUtil.CaseIgnoreCmp) || + !fi.Name.EndsWith(StrTxfTempSuffix, StrUtil.CaseIgnoreCmp)) + continue; + + if((DateTime.UtcNow - fi.LastWriteTimeUtc).TotalDays > 1.0) + fi.Delete(); + } + } + catch(Exception) { Debug.Assert(false); } + } } } diff --git a/ModernKeePassLib/Serialization/HashedBlockStream.cs b/ModernKeePassLib/Serialization/HashedBlockStream.cs index e856f40..6c7071a 100644 --- a/ModernKeePassLib/Serialization/HashedBlockStream.cs +++ b/ModernKeePassLib/Serialization/HashedBlockStream.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ */ using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; @@ -36,16 +37,16 @@ namespace ModernKeePassLib.Serialization { private const int NbDefaultBufferSize = 1024 * 1024; // 1 MB - private Stream m_sBaseStream; - private bool m_bWriting; - private bool m_bVerify; + private Stream m_sBase; + private readonly bool m_bWriting; + private readonly bool m_bVerify; + + private BinaryReader m_brInput = null; + private BinaryWriter m_bwOutput = null; + private bool m_bEos = false; - - private BinaryReader m_brInput; - private BinaryWriter m_bwOutput; - private byte[] m_pbBuffer; - private int m_nBufferPos = 0; + private int m_iBufferPos = 0; private uint m_uBlockIndex = 0; @@ -75,50 +76,42 @@ namespace ModernKeePassLib.Serialization set { Debug.Assert(false); throw new NotSupportedException(); } } - public HashedBlockStream(Stream sBaseStream, bool bWriting) + public HashedBlockStream(Stream sBase, bool bWriting) : + this(sBase, bWriting, 0, true) { - Initialize(sBaseStream, bWriting, 0, true); } - public HashedBlockStream(Stream sBaseStream, bool bWriting, int nBufferSize) + public HashedBlockStream(Stream sBase, bool bWriting, int nBufferSize) : + this(sBase, bWriting, nBufferSize, true) { - Initialize(sBaseStream, bWriting, nBufferSize, true); } - public HashedBlockStream(Stream sBaseStream, bool bWriting, int nBufferSize, + public HashedBlockStream(Stream sBase, bool bWriting, int nBufferSize, bool bVerify) { - Initialize(sBaseStream, bWriting, nBufferSize, bVerify); - } - - private void Initialize(Stream sBaseStream, bool bWriting, int nBufferSize, - bool bVerify) - { - if(sBaseStream == null) throw new ArgumentNullException("sBaseStream"); + if(sBase == null) throw new ArgumentNullException("sBase"); if(nBufferSize < 0) throw new ArgumentOutOfRangeException("nBufferSize"); if(nBufferSize == 0) nBufferSize = NbDefaultBufferSize; - m_sBaseStream = sBaseStream; + m_sBase = sBase; m_bWriting = bWriting; m_bVerify = bVerify; UTF8Encoding utf8 = StrUtil.Utf8; if(!m_bWriting) // Reading mode { - if(!m_sBaseStream.CanRead) - throw new InvalidOperationException(); + if(!m_sBase.CanRead) throw new InvalidOperationException(); - m_brInput = new BinaryReader(sBaseStream, utf8); + m_brInput = new BinaryReader(m_sBase, utf8); m_pbBuffer = MemUtil.EmptyByteArray; } else // Writing mode { - if(!m_sBaseStream.CanWrite) - throw new InvalidOperationException(); + if(!m_sBase.CanWrite) throw new InvalidOperationException(); - m_bwOutput = new BinaryWriter(sBaseStream, utf8); + m_bwOutput = new BinaryWriter(m_sBase, utf8); m_pbBuffer = new byte[nBufferSize]; } @@ -126,7 +119,7 @@ namespace ModernKeePassLib.Serialization protected override void Dispose(bool disposing) { - if(disposing && (m_sBaseStream != null)) + if(disposing && (m_sBase != null)) { if(!m_bWriting) // Reading mode { @@ -135,12 +128,12 @@ namespace ModernKeePassLib.Serialization } else // Writing mode { - if(m_nBufferPos == 0) // No data left in buffer - WriteHashedBlock(); // Write terminating block + if(m_iBufferPos == 0) // No data left in buffer + WriteSafeBlock(); // Write terminating block else { - WriteHashedBlock(); // Write remaining buffered data - WriteHashedBlock(); // Write terminating block + WriteSafeBlock(); // Write remaining buffered data + WriteSafeBlock(); // Write terminating block } Flush(); @@ -148,47 +141,60 @@ namespace ModernKeePassLib.Serialization m_bwOutput = null; } - m_sBaseStream.Dispose(); - m_sBaseStream = null; + m_sBase.Dispose(); + m_sBase = null; } + SetBuffer(MemUtil.EmptyByteArray); + base.Dispose(disposing); } + private void SetBuffer(byte[] pb) + { + MemUtil.ZeroByteArray(m_pbBuffer); // Erase previous buffer + + m_pbBuffer = pb; + } + public override void Flush() { - if(m_bWriting) m_bwOutput.Flush(); + Debug.Assert(m_sBase != null); // Object should not be disposed + if(m_bWriting && (m_bwOutput != null)) m_bwOutput.Flush(); } public override long Seek(long lOffset, SeekOrigin soOrigin) { + Debug.Assert(false); throw new NotSupportedException(); } public override void SetLength(long lValue) { + Debug.Assert(false); throw new NotSupportedException(); } - public override int Read(byte[] pbBuffer, int nOffset, int nCount) + public override int Read(byte[] pbBuffer, int iOffset, int nCount) { if(m_bWriting) throw new InvalidOperationException(); int nRemaining = nCount; while(nRemaining > 0) { - if(m_nBufferPos == m_pbBuffer.Length) + if(m_iBufferPos == m_pbBuffer.Length) { - if(ReadHashedBlock() == false) + if(!ReadSafeBlock()) return (nCount - nRemaining); // Bytes actually read } - int nCopy = Math.Min(m_pbBuffer.Length - m_nBufferPos, nRemaining); + int nCopy = Math.Min(m_pbBuffer.Length - m_iBufferPos, nRemaining); + Debug.Assert(nCopy > 0); - Array.Copy(m_pbBuffer, m_nBufferPos, pbBuffer, nOffset, nCopy); + Array.Copy(m_pbBuffer, m_iBufferPos, pbBuffer, iOffset, nCopy); - nOffset += nCopy; - m_nBufferPos += nCopy; + iOffset += nCopy; + m_iBufferPos += nCopy; nRemaining -= nCopy; } @@ -196,11 +202,11 @@ namespace ModernKeePassLib.Serialization return nCount; } - private bool ReadHashedBlock() + private bool ReadSafeBlock() { if(m_bEos) return false; // End of stream reached already - m_nBufferPos = 0; + m_iBufferPos = 0; if(m_brInput.ReadUInt32() != m_uBlockIndex) throw new InvalidDataException(); @@ -229,11 +235,11 @@ namespace ModernKeePassLib.Serialization } m_bEos = true; - m_pbBuffer = MemUtil.EmptyByteArray; + SetBuffer(MemUtil.EmptyByteArray); return false; } - m_pbBuffer = m_brInput.ReadBytes(nBufferSize); + SetBuffer(m_brInput.ReadBytes(nBufferSize)); if((m_pbBuffer == null) || ((m_pbBuffer.Length != nBufferSize) && m_bVerify)) throw new InvalidDataException(); @@ -250,44 +256,45 @@ namespace ModernKeePassLib.Serialization return true; } - public override void Write(byte[] pbBuffer, int nOffset, int nCount) + public override void Write(byte[] pbBuffer, int iOffset, int nCount) { if(!m_bWriting) throw new InvalidOperationException(); while(nCount > 0) { - if(m_nBufferPos == m_pbBuffer.Length) - WriteHashedBlock(); + if(m_iBufferPos == m_pbBuffer.Length) + WriteSafeBlock(); - int nCopy = Math.Min(m_pbBuffer.Length - m_nBufferPos, nCount); + int nCopy = Math.Min(m_pbBuffer.Length - m_iBufferPos, nCount); + Debug.Assert(nCopy > 0); - Array.Copy(pbBuffer, nOffset, m_pbBuffer, m_nBufferPos, nCopy); + Array.Copy(pbBuffer, iOffset, m_pbBuffer, m_iBufferPos, nCopy); - nOffset += nCopy; - m_nBufferPos += nCopy; + iOffset += nCopy; + m_iBufferPos += nCopy; nCount -= nCopy; } } - private void WriteHashedBlock() + private void WriteSafeBlock() { m_bwOutput.Write(m_uBlockIndex); ++m_uBlockIndex; - if(m_nBufferPos > 0) + if(m_iBufferPos != 0) { - byte[] pbHash = CryptoUtil.HashSha256(m_pbBuffer, 0, m_nBufferPos); + byte[] pbHash = CryptoUtil.HashSha256(m_pbBuffer, 0, m_iBufferPos); // For KeePassLibSD: // SHA256Managed sha256 = new SHA256Managed(); // byte[] pbHash; - // if(m_nBufferPos == m_pbBuffer.Length) + // if(m_iBufferPos == m_pbBuffer.Length) // pbHash = sha256.ComputeHash(m_pbBuffer); // else // { - // byte[] pbData = new byte[m_nBufferPos]; - // Array.Copy(m_pbBuffer, 0, pbData, 0, m_nBufferPos); + // byte[] pbData = new byte[m_iBufferPos]; + // Array.Copy(m_pbBuffer, 0, pbData, 0, m_iBufferPos); // pbHash = sha256.ComputeHash(pbData); // } @@ -301,12 +308,12 @@ namespace ModernKeePassLib.Serialization m_bwOutput.Write((ulong)0); } - m_bwOutput.Write(m_nBufferPos); + m_bwOutput.Write(m_iBufferPos); - if(m_nBufferPos > 0) - m_bwOutput.Write(m_pbBuffer, 0, m_nBufferPos); + if(m_iBufferPos != 0) + m_bwOutput.Write(m_pbBuffer, 0, m_iBufferPos); - m_nBufferPos = 0; + m_iBufferPos = 0; } } } diff --git a/ModernKeePassLib/Serialization/HmacBlockStream.cs b/ModernKeePassLib/Serialization/HmacBlockStream.cs index b95378f..329e6ec 100644 --- a/ModernKeePassLib/Serialization/HmacBlockStream.cs +++ b/ModernKeePassLib/Serialization/HmacBlockStream.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -119,9 +119,18 @@ namespace ModernKeePassLib.Serialization m_sBase = null; } + SetBuffer(MemUtil.EmptyByteArray); + base.Dispose(disposing); } + private void SetBuffer(byte[] pb) + { + MemUtil.ZeroByteArray(m_pbBuffer); // Erase previous buffer + + m_pbBuffer = pb; + } + public override void Flush() { Debug.Assert(m_sBase != null); // Object should not be disposed @@ -225,7 +234,7 @@ namespace ModernKeePassLib.Serialization m_iBufferPos = 0; - m_pbBuffer = MemUtil.Read(m_sBase, nBlockSize); + SetBuffer(MemUtil.Read(m_sBase, nBlockSize)); if((m_pbBuffer == null) || ((m_pbBuffer.Length != nBlockSize) && m_bVerify)) throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncompleteExpc); @@ -241,7 +250,7 @@ namespace ModernKeePassLib.Serialization h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length, pbBlockSize, 0); - if(m_pbBuffer.Length > 0) + if(m_pbBuffer.Length != 0) h.TransformBlock(m_pbBuffer, 0, m_pbBuffer.Length, m_pbBuffer, 0); @@ -302,7 +311,7 @@ namespace ModernKeePassLib.Serialization h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length, pbBlockSize, 0); - if(cbBlockSize > 0) + if(cbBlockSize != 0) h.TransformBlock(m_pbBuffer, 0, cbBlockSize, m_pbBuffer, 0); h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); @@ -314,7 +323,7 @@ namespace ModernKeePassLib.Serialization MemUtil.Write(m_sBase, pbBlockHmac); // MemUtil.Write(m_sBase, pbBlockIndex); // Implicit MemUtil.Write(m_sBase, pbBlockSize); - if(cbBlockSize > 0) + if(cbBlockSize != 0) m_sBase.Write(m_pbBuffer, 0, cbBlockSize); ++m_uBlockIndex; diff --git a/ModernKeePassLib/Serialization/IOConnection.cs b/ModernKeePassLib/Serialization/IOConnection.cs index a540c73..57dac75 100644 --- a/ModernKeePassLib/Serialization/IOConnection.cs +++ b/ModernKeePassLib/Serialization/IOConnection.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,7 +38,7 @@ using ModernKeePassLib.Utility; namespace ModernKeePassLib.Serialization { -#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT) +#if (!ModernKeePassLib && !KeePassLibSD) internal sealed class IOWebClient : WebClient { private IOConnectionInfo m_ioc; @@ -240,7 +240,7 @@ namespace ModernKeePassLib.Serialization public static class IOConnection { -#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT) +#if (!ModernKeePassLib && !KeePassLibSD) private static ProxyServerType m_pstProxyType = ProxyServerType.System; private static string m_strProxyAddr = string.Empty; private static string m_strProxyPort = string.Empty; @@ -269,7 +269,7 @@ namespace ModernKeePassLib.Serialization public static event EventHandler IOAccessPre; -#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT) +#if (!ModernKeePassLib && !KeePassLibSD) // Allow self-signed certificates, expired certificates, etc. private static bool AcceptCertificate(object sender, X509Certificate certificate, X509Chain chain, @@ -598,12 +598,12 @@ namespace ModernKeePassLib.Serialization #if ModernKeePassLib return new MemoryStream(ioc.Bytes); #else - return new FileStream(ioc.Path, FileMode.Open, FileAccess.Read, + return new FileStream(ioc.Path, FileMode.Open, FileAccess.Read, FileShare.Read); #endif } -#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT) +#if (!ModernKeePassLib && !KeePassLibSD) public static Stream OpenWrite(IOConnectionInfo ioc) { if(ioc == null) { Debug.Assert(false); return null; } @@ -640,7 +640,7 @@ namespace ModernKeePassLib.Serialization return new FileStream(ioc.Path, FileMode.Create, FileAccess.Write, FileShare.None); #endif - } + } public static bool FileExists(IOConnectionInfo ioc) { @@ -718,7 +718,7 @@ namespace ModernKeePassLib.Serialization } #endif #endif - } + } /// /// Rename/move a file. For local file system and WebDAV, the @@ -740,13 +740,15 @@ namespace ModernKeePassLib.Serialization WebRequest req = CreateWebRequest(iocFrom); if(req != null) { + string strToCnc = UrlUtil.GetCanonicalUri(iocTo.Path); + if(IsHttpWebRequest(req)) { #if KeePassUAP throw new NotSupportedException(); #else req.Method = "MOVE"; - req.Headers.Set("Destination", iocTo.Path); // Full URL supported + req.Headers.Set("Destination", strToCnc); // Full URL supported #endif } else if(IsFtpWebRequest(req)) @@ -755,13 +757,13 @@ namespace ModernKeePassLib.Serialization throw new NotSupportedException(); #else req.Method = WebRequestMethods.Ftp.Rename; - string strTo = UrlUtil.GetFileName(iocTo.Path); + string strToName = UrlUtil.GetFileName(strToCnc); // We're affected by .NET bug 621450: // https://connect.microsoft.com/VisualStudio/feedback/details/621450/problem-renaming-file-on-ftp-server-using-ftpwebrequest-in-net-framework-4-0-vs2010-only // Prepending "./", "%2E/" or "Dummy/../" doesn't work. - ((FtpWebRequest)req).RenameTo = strTo; + ((FtpWebRequest)req).RenameTo = strToName; #endif } else if(IsFileWebRequest(req)) @@ -776,7 +778,7 @@ namespace ModernKeePassLib.Serialization throw new NotSupportedException(); #else req.Method = WrmMoveFile; - req.Headers.Set(WrhMoveFileTo, iocTo.Path); + req.Headers.Set(WrhMoveFileTo, strToCnc); #endif } @@ -800,7 +802,7 @@ namespace ModernKeePassLib.Serialization #endif } -#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT) +#if (!ModernKeePassLib && !KeePassLibSD) private static bool SendCommand(IOConnectionInfo ioc, string strMethod) { try @@ -835,24 +837,14 @@ namespace ModernKeePassLib.Serialization #endif public static byte[] ReadFile(IOConnectionInfo ioc) { - Stream sIn = null; - MemoryStream ms = null; try { - sIn = IOConnection.OpenRead(ioc); - if(sIn == null) return null; - - ms = new MemoryStream(); - MemUtil.CopyStream(sIn, ms); - - return ms.ToArray(); - } - catch(Exception) { } - finally - { - if(sIn != null) sIn.Dispose(); - if(ms != null) ms.Dispose(); + using(Stream s = IOConnection.OpenRead(ioc)) + { + return MemUtil.Read(s); + } } + catch(Exception) { Debug.Assert(false); } return null; } diff --git a/ModernKeePassLib/Serialization/IOConnectionInfo.cs b/ModernKeePassLib/Serialization/IOConnectionInfo.cs index 27416d8..a2cec31 100644 --- a/ModernKeePassLib/Serialization/IOConnectionInfo.cs +++ b/ModernKeePassLib/Serialization/IOConnectionInfo.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -63,10 +63,9 @@ namespace ModernKeePassLib.Serialization public sealed class IOConnectionInfo : IDeepCloneable { // private IOFileFormatHint m_ioHint = IOFileFormatHint.None; - public byte[] Bytes { get; set; } - private string m_strUrl = string.Empty; + private string m_strUrl = string.Empty; public string Path { get { return m_strUrl; } @@ -115,8 +114,7 @@ namespace ModernKeePassLib.Serialization } private IOCredSaveMode m_ioCredSaveMode = IOCredSaveMode.NoSave; - - public IOCredSaveMode CredSaveMode + public IOCredSaveMode CredSaveMode { get { return m_ioCredSaveMode; } set { m_ioCredSaveMode = value; } @@ -333,7 +331,7 @@ namespace ModernKeePassLib.Serialization return ioc; } - public bool CanProbablyAccess() + public bool CanProbablyAccess() { #if ModernKeePassLib if (IsLocalFile()) return Bytes != null; diff --git a/ModernKeePassLib/Serialization/IocProperties.cs b/ModernKeePassLib/Serialization/IocProperties.cs index 9bbb556..ec651b8 100644 --- a/ModernKeePassLib/Serialization/IocProperties.cs +++ b/ModernKeePassLib/Serialization/IocProperties.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Serialization/IocPropertyInfo.cs b/ModernKeePassLib/Serialization/IocPropertyInfo.cs index 00d2e9a..de17566 100644 --- a/ModernKeePassLib/Serialization/IocPropertyInfo.cs +++ b/ModernKeePassLib/Serialization/IocPropertyInfo.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Serialization/IocPropertyInfoPool.cs b/ModernKeePassLib/Serialization/IocPropertyInfoPool.cs index 968f26a..dd45458 100644 --- a/ModernKeePassLib/Serialization/IocPropertyInfoPool.cs +++ b/ModernKeePassLib/Serialization/IocPropertyInfoPool.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Serialization/KdbxFile.Read.Streamed.cs b/ModernKeePassLib/Serialization/KdbxFile.Read.Streamed.cs index f0ffd31..668b965 100644 --- a/ModernKeePassLib/Serialization/KdbxFile.Read.Streamed.cs +++ b/ModernKeePassLib/Serialization/KdbxFile.Read.Streamed.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Serialization/KdbxFile.Read.cs b/ModernKeePassLib/Serialization/KdbxFile.Read.cs index b924d5a..c80fc36 100644 --- a/ModernKeePassLib/Serialization/KdbxFile.Read.cs +++ b/ModernKeePassLib/Serialization/KdbxFile.Read.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -53,18 +53,18 @@ namespace ModernKeePassLib.Serialization /// public sealed partial class KdbxFile { - /// - /// Load a KDBX file. - /// - /// File to load. - /// Format. - /// Status logger (optional). + /// + /// Load a KDBX file. + /// + /// File to load. + /// Format. + /// Status logger (optional). #if ModernKeePassLib public void Load(byte[] fileContents, KdbxFormat fmt, IStatusLogger slLogger) { IOConnectionInfo ioc = IOConnectionInfo.FromByteArray(fileContents); #else - public void Load(string strFilePath, KdbxFormat fmt, IStatusLogger slLogger) + public void Load(string strFilePath, KdbxFormat fmt, IStatusLogger slLogger) { IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath); #endif diff --git a/ModernKeePassLib/Serialization/KdbxFile.Write.cs b/ModernKeePassLib/Serialization/KdbxFile.Write.cs index d4a6226..59de6c4 100644 --- a/ModernKeePassLib/Serialization/KdbxFile.Write.cs +++ b/ModernKeePassLib/Serialization/KdbxFile.Write.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -842,7 +842,7 @@ namespace ModernKeePassLib.Serialization // string transformation here. By default, language-dependent conversions // should be applied, otherwise characters could be rendered incorrectly // (code page problems). - if(m_bLocalizedNames) + if(g_bLocalizedNames) { StringBuilder sb = new StringBuilder(); foreach(char ch in strValue) @@ -853,8 +853,7 @@ namespace ModernKeePassLib.Serialization // page area if(char.IsSymbol(ch) || char.IsSurrogate(ch)) { - System.Globalization.UnicodeCategory cat = - CharUnicodeInfo.GetUnicodeCategory(ch); + UnicodeCategory cat = CharUnicodeInfo.GetUnicodeCategory(ch); // Map character to correct position in code page chMapped = (char)((int)cat * 32 + ch); } diff --git a/ModernKeePassLib/Serialization/KdbxFile.cs b/ModernKeePassLib/Serialization/KdbxFile.cs index 3fb6faf..5ac3ad0 100644 --- a/ModernKeePassLib/Serialization/KdbxFile.cs +++ b/ModernKeePassLib/Serialization/KdbxFile.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -227,7 +227,7 @@ namespace ModernKeePassLib.Serialization private const uint NeutralLanguageOffset = 0x100000; // 2^20, see 32-bit Unicode specs private const uint NeutralLanguageIDSec = 0x7DC5C; // See 32-bit Unicode specs private const uint NeutralLanguageID = NeutralLanguageOffset + NeutralLanguageIDSec; - private static bool m_bLocalizedNames = false; + private static bool g_bLocalizedNames = false; private enum KdbxHeaderFieldID : byte { @@ -312,8 +312,8 @@ namespace ModernKeePassLib.Serialization public static void DetermineLanguageId() { // Test if localized names should be used. If localized names are used, - // the m_bLocalizedNames value must be set to true. By default, localized - // names should be used! (Otherwise characters could be corrupted + // the g_bLocalizedNames value must be set to true. By default, localized + // names should be used (otherwise characters could be corrupted // because of different code pages). unchecked { @@ -321,7 +321,7 @@ namespace ModernKeePassLib.Serialization foreach(char ch in PwDatabase.LocalizedAppName) uTest = uTest * 5 + ch; - m_bLocalizedNames = (uTest != NeutralLanguageID); + g_bLocalizedNames = (uTest != NeutralLanguageID); } } @@ -331,8 +331,11 @@ namespace ModernKeePassLib.Serialization // See also KeePassKdb2x3.Export (KDBX 3.1 export module) + if(m_pwDatabase.DataCipherUuid.Equals(ChaCha20Engine.ChaCha20Uuid)) + return FileVersion32; + AesKdf kdfAes = new AesKdf(); - if(!kdfAes.Uuid.Equals(m_pwDatabase.KdfParameters.KdfUuid)) + if(!m_pwDatabase.KdfParameters.KdfUuid.Equals(kdfAes.Uuid)) return FileVersion32; if(m_pwDatabase.PublicCustomData.Count > 0) diff --git a/ModernKeePassLib/Serialization/OldFormatException.cs b/ModernKeePassLib/Serialization/OldFormatException.cs index a66ab85..39c4b2e 100644 --- a/ModernKeePassLib/Serialization/OldFormatException.cs +++ b/ModernKeePassLib/Serialization/OldFormatException.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Translation/KPControlCustomization.cs b/ModernKeePassLib/Translation/KPControlCustomization.cs index 1f98346..4aea1c9 100644 --- a/ModernKeePassLib/Translation/KPControlCustomization.cs +++ b/ModernKeePassLib/Translation/KPControlCustomization.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Translation/KPFormCustomization.cs b/ModernKeePassLib/Translation/KPFormCustomization.cs index 78a23c6..3df75bb 100644 --- a/ModernKeePassLib/Translation/KPFormCustomization.cs +++ b/ModernKeePassLib/Translation/KPFormCustomization.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Translation/KPStringTable.cs b/ModernKeePassLib/Translation/KPStringTable.cs index 649d654..8344e1d 100644 --- a/ModernKeePassLib/Translation/KPStringTable.cs +++ b/ModernKeePassLib/Translation/KPStringTable.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Translation/KPStringTableItem.cs b/ModernKeePassLib/Translation/KPStringTableItem.cs index a32119c..028c726 100644 --- a/ModernKeePassLib/Translation/KPStringTableItem.cs +++ b/ModernKeePassLib/Translation/KPStringTableItem.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Translation/KPTranslation.cs b/ModernKeePassLib/Translation/KPTranslation.cs index 8aee9f1..072b43b 100644 --- a/ModernKeePassLib/Translation/KPTranslation.cs +++ b/ModernKeePassLib/Translation/KPTranslation.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Translation/KPTranslationProperties.cs b/ModernKeePassLib/Translation/KPTranslationProperties.cs index 904fe03..cee1a8a 100644 --- a/ModernKeePassLib/Translation/KPTranslationProperties.cs +++ b/ModernKeePassLib/Translation/KPTranslationProperties.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Utility/AppLogEx.cs b/ModernKeePassLib/Utility/AppLogEx.cs index 8208c79..1d0b79c 100644 --- a/ModernKeePassLib/Utility/AppLogEx.cs +++ b/ModernKeePassLib/Utility/AppLogEx.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Utility/GfxUtil.cs b/ModernKeePassLib/Utility/GfxUtil.cs index 9056a5a..503eafc 100644 --- a/ModernKeePassLib/Utility/GfxUtil.cs +++ b/ModernKeePassLib/Utility/GfxUtil.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Utility/MemUtil.cs b/ModernKeePassLib/Utility/MemUtil.cs index 995373b..d44e423 100644 --- a/ModernKeePassLib/Utility/MemUtil.cs +++ b/ModernKeePassLib/Utility/MemUtil.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -597,20 +597,34 @@ namespace ModernKeePassLib.Utility if(sSource == null) throw new ArgumentNullException("sSource"); if(sTarget == null) throw new ArgumentNullException("sTarget"); - const int nBufSize = 4096; - byte[] pbBuf = new byte[nBufSize]; + const int cbBuf = 4096; + byte[] pbBuf = new byte[cbBuf]; while(true) { - int nRead = sSource.Read(pbBuf, 0, nBufSize); - if(nRead == 0) break; + int cbRead = sSource.Read(pbBuf, 0, cbBuf); + if(cbRead == 0) break; - sTarget.Write(pbBuf, 0, nRead); + sTarget.Write(pbBuf, 0, cbRead); } // Do not close any of the streams } + public static byte[] Read(Stream s) + { + if(s == null) throw new ArgumentNullException("s"); + + byte[] pb; + using(MemoryStream ms = new MemoryStream()) + { + MemUtil.CopyStream(s, ms); + pb = ms.ToArray(); + } + + return pb; + } + public static byte[] Read(Stream s, int nCount) { if(s == null) throw new ArgumentNullException("s"); diff --git a/ModernKeePassLib/Utility/MessageService.cs b/ModernKeePassLib/Utility/MessageService.cs index 3f09a28..88596eb 100644 --- a/ModernKeePassLib/Utility/MessageService.cs +++ b/ModernKeePassLib/Utility/MessageService.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Utility/MonoWorkarounds.cs b/ModernKeePassLib/Utility/MonoWorkarounds.cs index a960d05..72ac395 100644 --- a/ModernKeePassLib/Utility/MonoWorkarounds.cs +++ b/ModernKeePassLib/Utility/MonoWorkarounds.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -141,6 +141,12 @@ namespace ModernKeePassLib.Utility // 100001: // Control locations/sizes are invalid/unexpected. // [NoRef] + // 100002: + // TextChanged event isn't raised when the formatting changes. + // [NoRef] + // 190417: + // Mono's Process.Start method replaces '\\' by '/'. + // https://github.com/mono/mono/blob/master/mono/metadata/w32process-unix.c // 373134: // Control.InvokeRequired doesn't always return the correct value. // https://bugzilla.novell.com/show_bug.cgi?id=373134 diff --git a/ModernKeePassLib/Utility/StrUtil.cs b/ModernKeePassLib/Utility/StrUtil.cs index 4cfc02f..c4d52fe 100644 --- a/ModernKeePassLib/Utility/StrUtil.cs +++ b/ModernKeePassLib/Utility/StrUtil.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -398,12 +398,6 @@ namespace ModernKeePassLib.Utility public static void SplitCommandLine(string strCmdLine, out string strApp, out string strArgs) - { - SplitCommandLine(strCmdLine, out strApp, out strArgs, true); - } - - internal static void SplitCommandLine(string strCmdLine, out string strApp, - out string strArgs, bool bDecodeAppToPath) { if(strCmdLine == null) { Debug.Assert(false); throw new ArgumentNullException("strCmdLine"); } @@ -435,7 +429,7 @@ namespace ModernKeePassLib.Utility if(strApp == null) { Debug.Assert(false); strApp = string.Empty; } if(strArgs == null) strArgs = string.Empty; - if(bDecodeAppToPath) strApp = NativeLib.DecodeArgsToPath(strApp); + strApp = NativeLib.DecodeArgsToData(strApp); } // /// @@ -538,7 +532,7 @@ namespace ModernKeePassLib.Utility if(!string.IsNullOrEmpty(excp.StackTrace)) strText += excp.StackTrace + MessageService.NewLine; #if !KeePassLibSD -#if !ModernKeePassLib && !KeePassRT +#if !ModernKeePassLib if(excp.TargetSite != null) strText += excp.TargetSite.ToString() + MessageService.NewLine; #endif @@ -564,7 +558,7 @@ namespace ModernKeePassLib.Utility if(!string.IsNullOrEmpty(excp.InnerException.StackTrace)) strText += excp.InnerException.StackTrace + MessageService.NewLine; #if !KeePassLibSD -#if !ModernKeePassLib && !KeePassRT +#if !ModernKeePassLib if(excp.InnerException.TargetSite != null) strText += excp.InnerException.TargetSite.ToString(); #endif @@ -966,10 +960,10 @@ namespace ModernKeePassLib.Utility for(char ch = 'A'; ch <= 'Z'; ++ch) { - string strEnhAcc = @"(&" + ch.ToString() + @")"; + string strEnhAcc = @"(&" + ch.ToString() + ")"; if(str.IndexOf(strEnhAcc) >= 0) { - str = str.Replace(@" " + strEnhAcc, string.Empty); + str = str.Replace(" " + strEnhAcc, string.Empty); str = str.Replace(strEnhAcc, string.Empty); } } @@ -1382,7 +1376,7 @@ namespace ModernKeePassLib.Utility byte[] pbEnc = CryptoUtil.ProtectData(pbPlain, m_pbOptEnt, DataProtectionScope.CurrentUser); -#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT) +#if (!ModernKeePassLib && !KeePassLibSD) return Convert.ToBase64String(pbEnc, Base64FormattingOptions.None); #else return Convert.ToBase64String(pbEnc); @@ -1495,7 +1489,7 @@ namespace ModernKeePassLib.Utility Array.Reverse(pb); for(int i = 0; i < pb.Length; ++i) pb[i] = (byte)(pb[i] ^ 0x65); -#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT) +#if (!ModernKeePassLib && !KeePassLibSD) return Convert.ToBase64String(pb, Base64FormattingOptions.None); #else return Convert.ToBase64String(pb); @@ -1655,7 +1649,7 @@ namespace ModernKeePassLib.Utility if(strMediaType == null) strMediaType = "application/octet-stream"; -#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT) +#if (!ModernKeePassLib && !KeePassLibSD) return ("data:" + strMediaType + ";base64," + Convert.ToBase64String( pbData, Base64FormattingOptions.None)); #else diff --git a/ModernKeePassLib/Utility/TimeUtil.cs b/ModernKeePassLib/Utility/TimeUtil.cs index 60ae625..74ef241 100644 --- a/ModernKeePassLib/Utility/TimeUtil.cs +++ b/ModernKeePassLib/Utility/TimeUtil.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Utility/TypeOverridePool.cs b/ModernKeePassLib/Utility/TypeOverridePool.cs index 4038bbc..fa351c8 100644 --- a/ModernKeePassLib/Utility/TypeOverridePool.cs +++ b/ModernKeePassLib/Utility/TypeOverridePool.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/ModernKeePassLib/Utility/UrlUtil.cs b/ModernKeePassLib/Utility/UrlUtil.cs index daa9ecd..9f5d0e5 100644 --- a/ModernKeePassLib/Utility/UrlUtil.cs +++ b/ModernKeePassLib/Utility/UrlUtil.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -275,21 +275,30 @@ namespace ModernKeePassLib.Utility public static string FileUrlToPath(string strUrl) { - Debug.Assert(strUrl != null); - if(strUrl == null) throw new ArgumentNullException("strUrl"); + if(strUrl == null) { Debug.Assert(false); throw new ArgumentNullException("strUrl"); } + if(strUrl.Length == 0) { Debug.Assert(false); return string.Empty; } - string str = strUrl; - if(str.StartsWith("file:///", StrUtil.CaseIgnoreCmp)) - str = str.Substring(8, str.Length - 8); + if(!strUrl.StartsWith(Uri.UriSchemeFile + ":", StrUtil.CaseIgnoreCmp)) + { + Debug.Assert(false); + return strUrl; + } - str = str.Replace('/', UrlUtil.LocalDirSepChar); + try + { + Uri uri = new Uri(strUrl); + string str = uri.LocalPath; + if(!string.IsNullOrEmpty(str)) return str; + } + catch(Exception) { Debug.Assert(false); } - return str; + Debug.Assert(false); + return strUrl; } public static bool UnhideFile(string strFile) { -#if (ModernKeePassLib || KeePassLibSD || KeePassRT) +#if (ModernKeePassLib || KeePassLibSD) return false; #else if(strFile == null) throw new ArgumentNullException("strFile"); @@ -309,7 +318,7 @@ namespace ModernKeePassLib.Utility public static bool HideFile(string strFile, bool bHide) { -#if (ModernKeePassLib || KeePassLibSD || KeePassRT) +#if (ModernKeePassLib || KeePassLibSD) return false; #else if(strFile == null) throw new ArgumentNullException("strFile"); @@ -606,7 +615,7 @@ namespace ModernKeePassLib.Utility } /// - /// Get the host component of an URL. + /// Get the host component of a URL. /// This method is faster and more fault-tolerant than creating /// an Uri object and querying its Host /// property. @@ -776,21 +785,32 @@ namespace ModernKeePassLib.Utility /// Expand shell variables in a string. /// [0] is the value of %1, etc. /// - public static string ExpandShellVariables(string strText, string[] vParams) + internal static string ExpandShellVariables(string strText, string[] vParams, + bool bEncParamsToArgs) { if(strText == null) { Debug.Assert(false); return string.Empty; } - if(vParams == null) { Debug.Assert(false); vParams = new string[0]; } + + string[] v = vParams; + if(v == null) { Debug.Assert(false); v = new string[0]; } + if(bEncParamsToArgs) + { + for(int i = 0; i < v.Length; ++i) + v[i] = NativeLib.EncodeDataToArgs(v[i] ?? string.Empty); + } string str = strText; NumberFormatInfo nfi = NumberFormatInfo.InvariantInfo; + string strPctPlh = Guid.NewGuid().ToString(); + str = str.Replace("%%", strPctPlh); + for(int i = 0; i <= 9; ++i) { string strPlh = "%" + i.ToString(nfi); string strValue = string.Empty; - if((i > 0) && ((i - 1) < vParams.Length)) - strValue = (vParams[i - 1] ?? string.Empty); + if((i > 0) && ((i - 1) < v.Length)) + strValue = (v[i - 1] ?? string.Empty); str = str.Replace(strPlh, strValue); @@ -806,7 +826,7 @@ namespace ModernKeePassLib.Utility if(str.IndexOf("%*") >= 0) { StringBuilder sb = new StringBuilder(); - foreach(string strValue in vParams) + foreach(string strValue in v) { if(!string.IsNullOrEmpty(strValue)) { @@ -818,6 +838,7 @@ namespace ModernKeePassLib.Utility str = str.Replace("%*", sb.ToString()); } + str = str.Replace(strPctPlh, "%"); return str; } @@ -846,5 +867,21 @@ namespace ModernKeePassLib.Utility } return str; } + + internal static string GetCanonicalUri(string strUri) + { + if(string.IsNullOrEmpty(strUri)) { Debug.Assert(false); return strUri; } + + try + { + Uri uri = new Uri(strUri); + + if(uri.IsAbsoluteUri) return uri.AbsoluteUri; + else { Debug.Assert(false); } + } + catch(Exception) { Debug.Assert(false); } + + return strUri; + } } } diff --git a/ModernKeePassLib/Utility/XmlUtilEx.cs b/ModernKeePassLib/Utility/XmlUtilEx.cs index a755070..6c36c4e 100644 --- a/ModernKeePassLib/Utility/XmlUtilEx.cs +++ b/ModernKeePassLib/Utility/XmlUtilEx.cs @@ -1,6 +1,6 @@ /* KeePass Password Safe - The Open-Source Password Manager - Copyright (C) 2003-2019 Dominik Reichl + Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -116,5 +116,21 @@ namespace ModernKeePassLib.Utility return t; } + +#if DEBUG + internal static void ValidateXml(string strXml, bool bReplaceStdEntities) + { + if(strXml == null) throw new ArgumentNullException("strXml"); + if(strXml.Length == 0) { Debug.Assert(false); return; } + + string str = strXml; + + if(bReplaceStdEntities) + str = str.Replace(" ", " "); + + XmlDocument d = new XmlDocument(); + d.LoadXml(str); + } +#endif } }