2 Commits

Author SHA1 Message Date
Geoffroy BONNEVILLE
2e1cc97738 Update to KeePassLib version 2.45 2020-05-12 12:46:25 +02:00
Geoffroy BONNEVILLE
107e009807 Updated Readme 2020-05-02 13:46:26 +02:00
22 changed files with 177 additions and 67 deletions

View File

@@ -234,7 +234,7 @@ namespace ModernKeePassLib.Cryptography
try
{
#if KeePassUAP
f(DiagnosticsExt.GetProcessEntropy(), true);
f(DiagnosticsExt.GetProcessEntropy(), true);
#elif !KeePassLibSD && !ModernKeePassLib
using(Process p = Process.GetCurrentProcess())
{
@@ -282,7 +282,6 @@ namespace ModernKeePassLib.Cryptography
{
byte[] pb = new byte[32];
try { m_rng.GetBytes(pb); }
catch(Exception)
{

View File

@@ -108,7 +108,7 @@ namespace ModernKeePassLib.Cryptography
}
#if !ModernKeePassLib
internal static byte[] HashSha256(string strFilePath)
internal static byte[] HashSha256(string strFilePath)
{
byte[] pbHash = null;

View File

@@ -151,6 +151,8 @@ namespace ModernKeePassLib.Cryptography.KeyDerivation
aes.ProcessBlock(pbNewKey32, 0, pbNewKey32, 0);
aes.ProcessBlock(pbNewKey32, 16, pbNewKey32, 16);
}
aes.Reset();
#else
byte[] pbIV = new byte[16];

View File

@@ -468,7 +468,6 @@ namespace ModernKeePassLib.Cryptography.KeyDerivation
#if ModernKeePassLib
Task.Factory.StartNew(FillSegmentThr, ti);
//ThreadPool.RunAsync(a => FillSegmentThr(ti));
#else
if(!ThreadPool.QueueUserWorkItem(FillSegmentThr, ti))
{

View File

@@ -281,8 +281,9 @@ namespace ModernKeePassLib.Keys
#if ModernKeePassLib
return GenerateKey32(p);
#else
if (sl == null) return GenerateKey32(p);
CkGkTaskInfo ti = new CkGkTaskInfo();
if(sl == null) return GenerateKey32(p);
CkGkTaskInfo ti = new CkGkTaskInfo();
ThreadStart f = delegate()
{

View File

@@ -70,7 +70,7 @@ namespace ModernKeePassLib.Keys
Construct(IOConnectionInfo.FromByteArray(keyFile), false);
}
#else
public KcpKeyFile(string strKeyFile)
public KcpKeyFile(string strKeyFile)
{
Construct(IOConnectionInfo.FromPath(strKeyFile), false);
}
@@ -191,7 +191,7 @@ namespace ModernKeePassLib.Keys
#if ModernKeePassLib
public static byte[] Create(byte[] pbAdditionalEntropy)
#else
public static void Create(string strFilePath, byte[] pbAdditionalEntropy)
public static void Create(string strFilePath, byte[] pbAdditionalEntropy)
#endif
{
byte[] pbKey32 = CryptoRandom.Instance.GetRandomBytes(32);
@@ -214,7 +214,7 @@ namespace ModernKeePassLib.Keys
#if ModernKeePassLib
return CreateXmlKeyFile(pbFinalKey32);
#else
CreateXmlKeyFile(strFilePath, pbFinalKey32);
CreateXmlKeyFile(strFilePath, pbFinalKey32);
#endif
}

View File

@@ -3,11 +3,11 @@
<PropertyGroup>
<TargetFramework>netstandard1.2</TargetFramework>
<Description>Portable KeePass Password Management Library that targets .Net Standard and WinRT. Allows reading, editing and writing to KeePass 2.x databases.</Description>
<Version>2.44.3</Version>
<Version>2.45.1</Version>
<Authors>Geoffroy Bonneville</Authors>
<Company>wismna</Company>
<PackageProjectUrl>https://github.com/wismna/ModernKeePass</PackageProjectUrl>
<PackageReleaseNotes>Implementation of KeePass library version 2.44</PackageReleaseNotes>
<PackageReleaseNotes>Implementation of KeePass library version 2.45</PackageReleaseNotes>
<Copyright>Copyright © 2018 Geoffroy Bonneville</Copyright>
<PackageTags>KeePass KeePassLib Portable PCL NetStandard</PackageTags>
<PackageLicenseExpression></PackageLicenseExpression>

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2020 Dominik Reichl <dominik.reichl@t-online.de>
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
@@ -27,7 +27,7 @@ namespace ModernKeePassLib.Native
{
internal static class ClipboardU
{
private const string XSel = "xsel";
internal const string XSel = "xsel";
private const string XSelV = "--version";
private const string XSelR = "--output --clipboard";
private const string XSelC = "--clear --clipboard";

View File

@@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
@@ -273,7 +274,13 @@ namespace ModernKeePassLib.Native
return strOutput;
}
#if DEBUG
catch(Exception ex) { Debug.Assert(ex is ThreadAbortException); }
catch(ThreadAbortException) { }
catch(Win32Exception exW)
{
Debug.Assert((strAppPath == ClipboardU.XSel) &&
(exW.NativeErrorCode == 2)); // XSel not found
}
catch(Exception) { Debug.Assert(false); }
#else
catch(Exception) { }
#endif

View File

@@ -21,6 +21,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Xml.Serialization;
using ModernKeePassLib.Delegates;
@@ -55,18 +56,18 @@ namespace ModernKeePassLib
/// e.g. 2.19 = 0x02130000.
/// It is highly recommended to use <c>FileVersion64</c> instead.
/// </summary>
public static readonly uint Version32 = 0x022C0000;
public static readonly uint Version32 = 0x022D0000;
/// <summary>
/// Version, encoded as 64-bit unsigned integer
/// (component-wise, 16 bits per component).
/// </summary>
public static readonly ulong FileVersion64 = 0x0002002C00000000UL;
public static readonly ulong FileVersion64 = 0x0002002D00000000UL;
/// <summary>
/// Version, encoded as string.
/// </summary>
public static readonly string VersionString = "2.44";
public static readonly string VersionString = "2.45";
public static readonly string Copyright = @"Copyright © 2003-2020 Dominik Reichl";
@@ -187,6 +188,8 @@ namespace ModernKeePassLib
/// </summary>
internal const int UIUpdateDelay = 50;
internal const uint QualityBitsWeak = 79;
/// <summary>
/// Check if a name is a standard field name.
/// </summary>
@@ -507,13 +510,13 @@ namespace ModernKeePassLib
public sealed class ObjectTouchedEventArgs : EventArgs
{
private object m_o;
private readonly object m_o;
public object Object { get { return m_o; } }
private bool m_bModified;
private readonly bool m_bModified;
public bool Modified { get { return m_bModified; } }
private bool m_bParentsTouched;
private readonly bool m_bParentsTouched;
public bool ParentsTouched { get { return m_bParentsTouched; } }
public ObjectTouchedEventArgs(object o, bool bModified,
@@ -527,13 +530,13 @@ namespace ModernKeePassLib
public sealed class IOAccessEventArgs : EventArgs
{
private IOConnectionInfo m_ioc;
private readonly IOConnectionInfo m_ioc;
public IOConnectionInfo IOConnectionInfo { get { return m_ioc; } }
private IOConnectionInfo m_ioc2;
private readonly IOConnectionInfo m_ioc2;
public IOConnectionInfo IOConnectionInfo2 { get { return m_ioc2; } }
private IOAccessType m_t;
private readonly IOAccessType m_t;
public IOAccessType Type { get { return m_t; } }
public IOAccessEventArgs(IOConnectionInfo ioc, IOConnectionInfo ioc2,
@@ -544,4 +547,21 @@ namespace ModernKeePassLib
m_t = t;
}
}
public sealed class IOWebRequestEventArgs : EventArgs
{
#if !ModernKeePassLib
private readonly WebRequest m_wr;
public WebRequest Request { get { return m_wr; } }
private readonly IOConnectionInfo m_ioc;
public IOConnectionInfo IOConnectionInfo { get { return m_ioc; } }
public IOWebRequestEventArgs(WebRequest r, IOConnectionInfo ioc)
{
m_wr = r;
m_ioc = ioc;
}
#endif
}
}

View File

@@ -235,28 +235,28 @@ namespace ModernKeePassLib
None = 0,
/// <summary>
/// The IO connection is being opened for reading.
/// The I/O connection is being opened for reading.
/// </summary>
Read = 1,
/// <summary>
/// The IO connection is being opened for writing.
/// The I/O connection is being opened for writing.
/// </summary>
Write = 2,
/// <summary>
/// The IO connection is being opened for testing
/// The I/O connection is being opened for testing
/// whether a file/object exists.
/// </summary>
Exists = 3,
/// <summary>
/// The IO connection is being opened for deleting a file/object.
/// The I/O connection is being opened for deleting a file/object.
/// </summary>
Delete = 4,
/// <summary>
/// The IO connection is being opened for renaming/moving a file/object.
/// The I/O connection is being opened for renaming/moving a file/object.
/// </summary>
Move = 5
}

View File

@@ -1725,7 +1725,7 @@ namespace ModernKeePassLib
{
Dictionary<string, bool> d = new Dictionary<string, bool>();
GAction<string> fAdd = delegate(string str)
Action<string> fAdd = delegate(string str)
{
if(!string.IsNullOrEmpty(str)) d[str] = true;
};

View File

@@ -9,7 +9,7 @@ namespace ModernKeePassLib.Resources
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
public static class KLRes
public static partial class KLRes
{
private static string TryGetEx(Dictionary<string, string> dictNew,
string strName, string strDefault)

View File

@@ -524,7 +524,7 @@ namespace ModernKeePassLib.Serialization
return false;
}
#if !ModernKeePassLib
internal static void ClearOld()
internal static void ClearOld()
{
try
{

View File

@@ -273,6 +273,7 @@ namespace ModernKeePassLib.Serialization
public static readonly string WrhMoveFileTo = "MoveFileTo";
public static event EventHandler<IOAccessEventArgs> IOAccessPre;
public static event EventHandler<IOWebRequestEventArgs> IOWebRequestPre;
#if !ModernKeePassLib && !KeePassLibSD
// Allow self-signed certificates, expired certificates, etc.
@@ -369,6 +370,13 @@ namespace ModernKeePassLib.Serialization
bool? ob = p.GetBool(IocKnownProperties.PreAuth);
if(ob.HasValue) request.PreAuthenticate = ob.Value;
#endif
if(IOConnection.IOWebRequestPre != null)
{
IOWebRequestEventArgs e = new IOWebRequestEventArgs(request,
((ioc != null) ? ioc.CloneDeep() : null));
IOConnection.IOWebRequestPre(null, e);
}
}
internal static void ConfigureWebClient(WebClient wc)
@@ -549,13 +557,13 @@ namespace ModernKeePassLib.Serialization
PrepareWebAccess(ioc);
IOWebClient wc = new IOWebClient(ioc);
ConfigureWebClient(wc);
if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
wc.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
else if(NativeLib.IsUnix()) // Mono requires credentials
else if(MonoWorkarounds.IsRequired(688007))
wc.Credentials = new NetworkCredential("anonymous", string.Empty);
ConfigureWebClient(wc);
return wc;
}
@@ -564,13 +572,13 @@ namespace ModernKeePassLib.Serialization
PrepareWebAccess(ioc);
WebRequest req = WebRequest.Create(ioc.Path);
ConfigureWebRequest(req, ioc);
if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
req.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
else if(NativeLib.IsUnix()) // Mono requires credentials
else if(MonoWorkarounds.IsRequired(688007))
req.Credentials = new NetworkCredential("anonymous", string.Empty);
ConfigureWebRequest(req, ioc);
return req;
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2020 Dominik Reichl <dominik.reichl@t-online.de>
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
@@ -336,7 +336,7 @@ namespace ModernKeePassLib.Serialization
#if ModernKeePassLib
if (IsLocalFile()) return Bytes != null;
#else
if(IsLocalFile()) return File.Exists(m_strUrl);
return IOConnection.FileExists(this, false); // Raises event
#endif
return true;

View File

@@ -22,6 +22,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
#if KeePassLibSD
@@ -820,6 +821,52 @@ namespace ModernKeePassLib.Utility
IDisposable d = (o as IDisposable);
if(d != null) d.Dispose();
}
internal static T BytesToStruct<T>(byte[] pb, int iOffset)
where T : struct
{
if(pb == null) throw new ArgumentNullException("pb");
if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset");
int cb = Marshal.SizeOf(typeof(T));
if(cb <= 0) { Debug.Assert(false); return default(T); }
if(iOffset > (pb.Length - cb)) throw new ArgumentOutOfRangeException("iOffset");
IntPtr p = Marshal.AllocCoTaskMem(cb);
if(p == IntPtr.Zero) throw new OutOfMemoryException();
object o;
try
{
Marshal.Copy(pb, iOffset, p, cb);
o = Marshal.PtrToStructure(p, typeof(T));
}
finally { Marshal.FreeCoTaskMem(p); }
return (T)o;
}
internal static byte[] StructToBytes<T>(ref T t)
where T : struct
{
int cb = Marshal.SizeOf(typeof(T));
if(cb <= 0) { Debug.Assert(false); return MemUtil.EmptyByteArray; }
byte[] pb = new byte[cb];
IntPtr p = Marshal.AllocCoTaskMem(cb);
if(p == IntPtr.Zero) throw new OutOfMemoryException();
try
{
Marshal.StructureToPtr(t, p, false);
Marshal.Copy(p, pb, 0, cb);
}
finally { Marshal.FreeCoTaskMem(p); }
return pb;
}
}
internal sealed class ArrayHelperEx<T> : IEqualityComparer<T[]>, IComparer<T[]>

View File

@@ -180,6 +180,8 @@ namespace ModernKeePassLib.Utility
internal static DialogResult SafeShowMessageBox(string strText, string strTitle,
MessageBoxButtons mb, MessageBoxIcon mi, MessageBoxDefaultButton mdb)
{
// strText += MessageService.NewParagraph + (new StackTrace(true)).ToString();
#if KeePassLibSD
return MessageBox.Show(strText, strTitle, mb, mi, mdb);
#else

View File

@@ -119,10 +119,12 @@ namespace ModernKeePassLib.Utility
// 2140:
// Explicit control focusing is ignored.
// https://sourceforge.net/p/keepass/feature-requests/2140/
// 5795:
// 5795: [Fixed]
// Text in input field is incomplete.
// https://bugzilla.xamarin.com/show_bug.cgi?id=5795
// https://sourceforge.net/p/keepass/discussion/329220/thread/d23dc88b/
// https://github.com/mono/mono/commit/1a79065f8cd9f128e6e527e5d573111f794ce288
// https://github.com/mono/mono/pull/5947
// 9604:
// Trying to resolve a non-existing metadata token crashes Mono.
// https://github.com/mono/mono/issues/9604
@@ -162,6 +164,10 @@ namespace ModernKeePassLib.Utility
// 686017:
// Minimum sizes must be enforced.
// https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=686017
// 688007: [Fixed]
// Credentials are required for anonymous web requests.
// https://bugzilla.novell.com/show_bug.cgi?id=688007
// https://sourceforge.net/p/keepass/bugs/1950/
// 801414:
// Mono recreates the main window incorrectly.
// https://bugs.launchpad.net/ubuntu/+source/keepass2/+bug/801414
@@ -192,13 +198,21 @@ namespace ModernKeePassLib.Utility
if(g_dForceReq.TryGetValue(uBugID, out bForce)) return bForce;
ulong v = NativeLib.MonoVersion;
if(v != 0)
if(v == 0) return true;
bool b = true;
switch(uBugID)
{
if(uBugID == 10163)
return (v >= 0x0002000B00000000UL); // >= 2.11
case 5795:
b = (v < 0x0005000A00000000UL); break;
case 10163:
b = (v >= 0x0002000B00000000UL); break;
case 688007:
b = (v < 0x0006000000000000UL); break;
default: break;
}
return true;
return b;
}
internal static void SetEnabled(string strIDs, bool bEnabled)

View File

@@ -320,6 +320,18 @@ namespace ModernKeePassLib.Utility
return str;
}
internal static string RtfFilterText(string strText)
{
if(strText == null) { Debug.Assert(false); return string.Empty; }
// A U+FFFC character causes the rest of the text to be lost.
// With '?', the string length, substring indices and
// character visibility remain the same.
// More special characters (unproblematic) in rich text boxes:
// https://docs.microsoft.com/en-us/windows/win32/api/richedit/ns-richedit-gettextex
return strText.Replace('\uFFFC', '?');
}
internal static bool ContainsHighChar(string str)
{
if(str == null) { Debug.Assert(false); return false; }
@@ -975,35 +987,25 @@ namespace ModernKeePassLib.Utility
public static string AddAccelerator(string strMenuText,
List<char> lAvailKeys)
{
if(strMenuText == null) { Debug.Assert(false); return null; }
if(strMenuText == null) { Debug.Assert(false); return string.Empty; }
if(lAvailKeys == null) { Debug.Assert(false); return strMenuText; }
int xa = -1, xs = 0;
for(int i = 0; i < strMenuText.Length; ++i)
{
char ch = strMenuText[i];
char ch = char.ToLowerInvariant(strMenuText[i]);
#if KeePassLibSD
char chUpper = char.ToUpper(ch);
#else
char chUpper = char.ToUpperInvariant(ch);
#endif
xa = lAvailKeys.IndexOf(chUpper);
if(xa >= 0) { xs = i; break; }
#if KeePassLibSD
char chLower = char.ToLower(ch);
#else
char chLower = char.ToLowerInvariant(ch);
#endif
xa = lAvailKeys.IndexOf(chLower);
if(xa >= 0) { xs = i; break; }
for(int j = 0; j < lAvailKeys.Count; ++j)
{
if(char.ToLowerInvariant(lAvailKeys[j]) == ch)
{
lAvailKeys.RemoveAt(j);
return strMenuText.Insert(i, @"&");
}
}
}
if(xa < 0) return strMenuText;
lAvailKeys.RemoveAt(xa);
return strMenuText.Insert(xs, @"&");
return strMenuText;
}
public static string EncodeMenuText(string strText)

View File

@@ -287,13 +287,13 @@ namespace ModernKeePassLib.Utility
if(strUrl.Length == 0) { Debug.Assert(false); return string.Empty; }
#if !ModernKeePassLib
if(!strUrl.StartsWith(Uri.UriSchemeFile + ":", StrUtil.CaseIgnoreCmp))
if(!strUrl.StartsWith(Uri.UriSchemeFile + ":", StrUtil.CaseIgnoreCmp))
{
Debug.Assert(false);
return strUrl;
}
#endif
try
try
{
Uri uri = new Uri(strUrl);
string str = uri.LocalPath;

View File

@@ -5,12 +5,16 @@
# What is this ?
ModernKeePassLib is a port of KeePassLib to .netstandard 1.2, distributed as a nuget package.
The aim was to change as little as possible the original library. However, some workarounds have to be made as .netstandard misses quite a few features of the full .net framework.
The aim was to change as little as possible the original library. However, some workarounds have to be made as .netstandard 1.2 misses quite a few features of the full .net framework.
Main changes:
- Removed the dependency on the filesystem
- Added a dependency on Windows (I'm working on tring to find a way to remove it altogether)
- Some features are handled by external nuget packages (cryptography, colors, etc.), so it may introduce small differences
# Installation
From [nuget.org](https://www.nuget.org/packages/ModernKeePassLib/)
# Usage
1. Create a IOConnectionInfo from a byte array:
@@ -29,4 +33,9 @@ compositeKey.AddUserKey(new KcpKeyFile(IOConnectionInfo.FromByteArray(KeyFileCon
`PwDatabase.Save(new NullStatusLogger());`
6. At this point, nothing is commited to disk, so you need to retrieve the byte array:
`var contents = PwDatabase.IOConnectionInfo.Bytes;`
7. Write the byte array to a file, to a stream, whatever !
7. Write the byte array to a file, to a stream, whatever !
# Todo
- Remove Windows dependencies entirely
- Find a way to use Color class (handled by Splat at the moment, but I'm not satisfied)