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
}
}