mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-12-06 08:12:39 -05:00
ModernKeePassLib custom PCL version
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
using ModernKeePassLib;
|
using ModernKeePassLib;
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
@@ -23,13 +22,14 @@ namespace ModernKeePass.Common
|
|||||||
{
|
{
|
||||||
this.databaseFile = databaseFile;
|
this.databaseFile = databaseFile;
|
||||||
}
|
}
|
||||||
public async Task<string> Open(string password)
|
public string Open(string password)
|
||||||
{
|
{
|
||||||
var key = new CompositeKey();
|
var key = new CompositeKey();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
key.AddUserKey(new KcpPassword(password));
|
key.AddUserKey(new KcpPassword(password));
|
||||||
await _pwDatabase.Open(IOConnectionInfo.FromFile(databaseFile), key, new NullStatusLogger());
|
_pwDatabase.Open(IOConnectionInfo.FromFile(databaseFile), key, new NullStatusLogger());
|
||||||
|
//_pwDatabase.Open(IOConnectionInfo.FromPath(databaseFile.Path), key, new NullStatusLogger());
|
||||||
IsOpen = _pwDatabase.IsOpen;
|
IsOpen = _pwDatabase.IsOpen;
|
||||||
Name = databaseFile.DisplayName;
|
Name = databaseFile.DisplayName;
|
||||||
RootGroup = new GroupVm(_pwDatabase.RootGroup);
|
RootGroup = new GroupVm(_pwDatabase.RootGroup);
|
||||||
@@ -42,6 +42,10 @@ namespace ModernKeePass.Common
|
|||||||
{
|
{
|
||||||
return "Wrong password";
|
return "Wrong password";
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return ex.Message;
|
||||||
|
}
|
||||||
/*finally
|
/*finally
|
||||||
{
|
{
|
||||||
// TODO: move this when implementing write mode
|
// TODO: move this when implementing write mode
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace ModernKeePass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void openBbutton_Click(object sender, RoutedEventArgs e)
|
private void openBbutton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
/*var database = DataContext as DatabaseVm;
|
/*var database = DataContext as DatabaseVm;
|
||||||
database.Open();
|
database.Open();
|
||||||
@@ -47,7 +47,7 @@ namespace ModernKeePass
|
|||||||
Frame.Navigate(typeof(GroupDetailPage), database.RootGroup);*/
|
Frame.Navigate(typeof(GroupDetailPage), database.RootGroup);*/
|
||||||
var homeVm = DataContext as HomeVm;
|
var homeVm = DataContext as HomeVm;
|
||||||
var app = ((App)Application.Current);
|
var app = ((App)Application.Current);
|
||||||
homeVm.ErrorMessage = await app.Database.Open(homeVm.Password);
|
homeVm.ErrorMessage = app.Database.Open(homeVm.Password);
|
||||||
if (!app.Database.IsOpen) homeVm.NotifyPropertyChanged("ErrorMessage");
|
if (!app.Database.IsOpen) homeVm.NotifyPropertyChanged("ErrorMessage");
|
||||||
else Frame.Navigate(typeof(GroupDetailPage), app.Database.RootGroup);
|
else Frame.Navigate(typeof(GroupDetailPage), app.Database.RootGroup);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,8 +159,8 @@
|
|||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="ModernKeePassLib, Version=2.19.0.26255, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="ModernKeePassLib, Version=2.36.0.27373, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\ModernKeePassLib.2.19.0.26255\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
|
<HintPath>..\packages\ModernKeePassLib.2.36.0.27373\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
@@ -221,7 +221,9 @@
|
|||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Error Condition="!Exists('..\packages\NETStandard.Library.2.0.0\build\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NETStandard.Library.2.0.0\build\NETStandard.Library.targets'))" />
|
<Error Condition="!Exists('..\packages\NETStandard.Library.2.0.0\build\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NETStandard.Library.2.0.0\build\NETStandard.Library.targets'))" />
|
||||||
|
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
|
||||||
</Target>
|
</Target>
|
||||||
|
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using Windows.Storage;
|
|
||||||
|
|
||||||
using ModernKeePassLib;
|
|
||||||
using ModernKeePassLib.Keys;
|
|
||||||
using ModernKeePassLib.Serialization;
|
|
||||||
using ModernKeePassLib.Interfaces;
|
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace ModernKeePass.ViewModels
|
namespace ModernKeePass.ViewModels
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="win81" />
|
||||||
|
<package id="Microsoft.Bcl.Compression" version="3.9.85" targetFramework="win81" />
|
||||||
<package id="Microsoft.NETCore.Platforms" version="2.0.0" targetFramework="win81" />
|
<package id="Microsoft.NETCore.Platforms" version="2.0.0" targetFramework="win81" />
|
||||||
<package id="Microsoft.NETCore.Portable.Compatibility" version="1.0.2" targetFramework="win81" />
|
<package id="Microsoft.NETCore.Portable.Compatibility" version="1.0.2" targetFramework="win81" />
|
||||||
<package id="ModernKeePassLib" version="2.19.0.26255" targetFramework="win81" />
|
<package id="ModernKeePassLib" version="2.36.0.27373" targetFramework="win81" />
|
||||||
<package id="NETStandard.Library" version="2.0.0" targetFramework="win81" />
|
<package id="NETStandard.Library" version="2.0.0" targetFramework="win81" />
|
||||||
<package id="System.Net.Requests" version="4.3.0" targetFramework="win81" />
|
<package id="System.Net.Requests" version="4.3.0" targetFramework="win81" />
|
||||||
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="win81" />
|
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="win81" />
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -194,13 +194,6 @@ namespace ModernKeePassLib.Collections
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(AutoTypeAssociation a)
|
|
||||||
{
|
|
||||||
Debug.Assert(a != null); if(a == null) throw new ArgumentNullException("a");
|
|
||||||
|
|
||||||
m_lWindowAssocs.Add(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AutoTypeAssociation GetAt(int iIndex)
|
public AutoTypeAssociation GetAt(int iIndex)
|
||||||
{
|
{
|
||||||
if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count))
|
if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count))
|
||||||
@@ -209,6 +202,22 @@ namespace ModernKeePassLib.Collections
|
|||||||
return m_lWindowAssocs[iIndex];
|
return m_lWindowAssocs[iIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Add(AutoTypeAssociation a)
|
||||||
|
{
|
||||||
|
if(a == null) { Debug.Assert(false); throw new ArgumentNullException("a"); }
|
||||||
|
|
||||||
|
m_lWindowAssocs.Add(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(int iIndex, AutoTypeAssociation a)
|
||||||
|
{
|
||||||
|
if((iIndex < 0) || (iIndex > m_lWindowAssocs.Count))
|
||||||
|
throw new ArgumentOutOfRangeException("iIndex");
|
||||||
|
if(a == null) { Debug.Assert(false); throw new ArgumentNullException("a"); }
|
||||||
|
|
||||||
|
m_lWindowAssocs.Insert(iIndex, a);
|
||||||
|
}
|
||||||
|
|
||||||
public void RemoveAt(int iIndex)
|
public void RemoveAt(int iIndex)
|
||||||
{
|
{
|
||||||
if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count))
|
if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count))
|
||||||
@@ -216,5 +225,20 @@ namespace ModernKeePassLib.Collections
|
|||||||
|
|
||||||
m_lWindowAssocs.RemoveAt(iIndex);
|
m_lWindowAssocs.RemoveAt(iIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public void Sort()
|
||||||
|
// {
|
||||||
|
// m_lWindowAssocs.Sort(AutoTypeConfig.AssocCompareFn);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private static int AssocCompareFn(AutoTypeAssociation x,
|
||||||
|
// AutoTypeAssociation y)
|
||||||
|
// {
|
||||||
|
// if(x == null) { Debug.Assert(false); return ((y == null) ? 0 : -1); }
|
||||||
|
// if(y == null) { Debug.Assert(false); return 1; }
|
||||||
|
// int cn = x.WindowName.CompareTo(y.WindowName);
|
||||||
|
// if(cn != 0) return cn;
|
||||||
|
// return x.Sequence.CompareTo(y.Sequence);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -28,7 +28,7 @@ using ModernKeePassLib.Security;
|
|||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
#if KeePassLibSD
|
#if KeePassLibSD
|
||||||
using ModernKeePassLibSD;
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ModernKeePassLib.Collections
|
namespace ModernKeePassLib.Collections
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -28,7 +28,7 @@ using ModernKeePassLib.Security;
|
|||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
#if KeePassLibSD
|
#if KeePassLibSD
|
||||||
using ModernKeePassLibSD;
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ModernKeePassLib.Collections
|
namespace ModernKeePassLib.Collections
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -133,6 +133,14 @@ namespace ModernKeePassLib.Collections
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Insert(uint uIndex, T pwObject)
|
||||||
|
{
|
||||||
|
Debug.Assert(pwObject != null);
|
||||||
|
if(pwObject == null) throw new ArgumentNullException("pwObject");
|
||||||
|
|
||||||
|
m_vObjects.Insert((int)uIndex, pwObject);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get an object of the list.
|
/// Get an object of the list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -225,7 +233,7 @@ namespace ModernKeePassLib.Collections
|
|||||||
if(nCount <= 1) return;
|
if(nCount <= 1) return;
|
||||||
|
|
||||||
int nIndex = m_vObjects.IndexOf(tObject);
|
int nIndex = m_vObjects.IndexOf(tObject);
|
||||||
Debug.Assert(nIndex >= 0);
|
if(nIndex < 0) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
if(bUp && (nIndex > 0)) // No assert for top item
|
if(bUp && (nIndex > 0)) // No assert for top item
|
||||||
{
|
{
|
||||||
@@ -241,6 +249,68 @@ namespace ModernKeePassLib.Collections
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void MoveOne(T[] vObjects, bool bUp)
|
||||||
|
{
|
||||||
|
Debug.Assert(vObjects != null);
|
||||||
|
if(vObjects == null) throw new ArgumentNullException("vObjects");
|
||||||
|
|
||||||
|
List<int> lIndices = new List<int>();
|
||||||
|
foreach(T t in vObjects)
|
||||||
|
{
|
||||||
|
if(t == null) { Debug.Assert(false); continue; }
|
||||||
|
|
||||||
|
int p = IndexOf(t);
|
||||||
|
if(p >= 0) lIndices.Add(p);
|
||||||
|
else { Debug.Assert(false); }
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveOne(lIndices.ToArray(), bUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MoveOne(int[] vIndices, bool bUp)
|
||||||
|
{
|
||||||
|
Debug.Assert(vIndices != null);
|
||||||
|
if(vIndices == null) throw new ArgumentNullException("vIndices");
|
||||||
|
|
||||||
|
int n = m_vObjects.Count;
|
||||||
|
if(n <= 1) return; // No moving possible
|
||||||
|
|
||||||
|
int m = vIndices.Length;
|
||||||
|
if(m == 0) return; // Nothing to move
|
||||||
|
|
||||||
|
int[] v = new int[m];
|
||||||
|
Array.Copy(vIndices, v, m);
|
||||||
|
Array.Sort<int>(v);
|
||||||
|
|
||||||
|
if((bUp && (v[0] <= 0)) || (!bUp && (v[m - 1] >= (n - 1))))
|
||||||
|
return; // Moving as a block is not possible
|
||||||
|
|
||||||
|
int iStart = (bUp ? 0 : (m - 1));
|
||||||
|
int iExcl = (bUp ? m : -1);
|
||||||
|
int iStep = (bUp ? 1 : -1);
|
||||||
|
|
||||||
|
for(int i = iStart; i != iExcl; i += iStep)
|
||||||
|
{
|
||||||
|
int p = v[i];
|
||||||
|
if((p < 0) || (p >= n)) { Debug.Assert(false); continue; }
|
||||||
|
|
||||||
|
T t = m_vObjects[p];
|
||||||
|
|
||||||
|
if(bUp)
|
||||||
|
{
|
||||||
|
Debug.Assert(p > 0);
|
||||||
|
m_vObjects.RemoveAt(p);
|
||||||
|
m_vObjects.Insert(p - 1, t);
|
||||||
|
}
|
||||||
|
else // Down
|
||||||
|
{
|
||||||
|
Debug.Assert(p < (n - 1));
|
||||||
|
m_vObjects.RemoveAt(p);
|
||||||
|
m_vObjects.Insert(p + 1, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Move some of the objects in this list to the top/bottom.
|
/// Move some of the objects in this list to the top/bottom.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,15 +26,15 @@ using ModernKeePassLib.Delegates;
|
|||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
|
|
||||||
#if KeePassLibSD
|
#if KeePassLibSD
|
||||||
using ModernKeePassLibSD;
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ModernKeePassLib.Collections
|
namespace ModernKeePassLib.Collections
|
||||||
{
|
{
|
||||||
public sealed class PwObjectPool
|
public sealed class PwObjectPool
|
||||||
{
|
{
|
||||||
private SortedDictionary<PwUuidComparable, IStructureItem> m_dict =
|
private SortedDictionary<PwUuid, IStructureItem> m_dict =
|
||||||
new SortedDictionary<PwUuidComparable, IStructureItem>();
|
new SortedDictionary<PwUuid, IStructureItem>();
|
||||||
|
|
||||||
public static PwObjectPool FromGroupRecursive(PwGroup pgRoot, bool bEntries)
|
public static PwObjectPool FromGroupRecursive(PwGroup pgRoot, bool bEntries)
|
||||||
{
|
{
|
||||||
@@ -42,16 +42,16 @@ namespace ModernKeePassLib.Collections
|
|||||||
|
|
||||||
PwObjectPool p = new PwObjectPool();
|
PwObjectPool p = new PwObjectPool();
|
||||||
|
|
||||||
if(!bEntries) p.m_dict[new PwUuidComparable(pgRoot.Uuid)] = pgRoot;
|
if(!bEntries) p.m_dict[pgRoot.Uuid] = pgRoot;
|
||||||
GroupHandler gh = delegate(PwGroup pg)
|
GroupHandler gh = delegate(PwGroup pg)
|
||||||
{
|
{
|
||||||
p.m_dict[new PwUuidComparable(pg.Uuid)] = pg;
|
p.m_dict[pg.Uuid] = pg;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
EntryHandler eh = delegate(PwEntry pe)
|
EntryHandler eh = delegate(PwEntry pe)
|
||||||
{
|
{
|
||||||
p.m_dict[new PwUuidComparable(pe.Uuid)] = pe;
|
p.m_dict[pe.Uuid] = pe;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -63,13 +63,13 @@ namespace ModernKeePassLib.Collections
|
|||||||
public IStructureItem Get(PwUuid pwUuid)
|
public IStructureItem Get(PwUuid pwUuid)
|
||||||
{
|
{
|
||||||
IStructureItem pItem;
|
IStructureItem pItem;
|
||||||
m_dict.TryGetValue(new PwUuidComparable(pwUuid), out pItem);
|
m_dict.TryGetValue(pwUuid, out pItem);
|
||||||
return pItem;
|
return pItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ContainsOnlyType(Type t)
|
public bool ContainsOnlyType(Type t)
|
||||||
{
|
{
|
||||||
foreach(KeyValuePair<PwUuidComparable, IStructureItem> kvp in m_dict)
|
foreach(KeyValuePair<PwUuid, IStructureItem> kvp in m_dict)
|
||||||
{
|
{
|
||||||
if(kvp.Value.GetType() != t) return false;
|
if(kvp.Value.GetType() != t) return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,7 +26,7 @@ using System.Diagnostics;
|
|||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
|
|
||||||
#if KeePassLibSD
|
#if KeePassLibSD
|
||||||
using ModernKeePassLibSD;
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ModernKeePassLib.Collections
|
namespace ModernKeePassLib.Collections
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Security;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Cryptography.Cipher
|
namespace ModernKeePassLib.Cryptography.Cipher
|
||||||
{
|
{
|
||||||
@@ -65,7 +69,7 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
|
|
||||||
// Return if a cipher with that ID is registered already.
|
// Return if a cipher with that ID is registered already.
|
||||||
for(int i = 0; i < m_vCiphers.Count; ++i)
|
for(int i = 0; i < m_vCiphers.Count; ++i)
|
||||||
if(m_vCiphers[i].CipherUuid.EqualsValue(csEngine.CipherUuid))
|
if(m_vCiphers[i].CipherUuid.Equals(csEngine.CipherUuid))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_vCiphers.Add(csEngine);
|
m_vCiphers.Add(csEngine);
|
||||||
@@ -81,7 +85,7 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
{
|
{
|
||||||
foreach(ICipherEngine iEngine in m_vCiphers)
|
foreach(ICipherEngine iEngine in m_vCiphers)
|
||||||
{
|
{
|
||||||
if(iEngine.CipherUuid.EqualsValue(uuidCipher))
|
if(iEngine.CipherUuid.Equals(uuidCipher))
|
||||||
return iEngine;
|
return iEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +103,7 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
{
|
{
|
||||||
for(int i = 0; i < m_vCiphers.Count; ++i)
|
for(int i = 0; i < m_vCiphers.Count; ++i)
|
||||||
{
|
{
|
||||||
if(m_vCiphers[i].CipherUuid.EqualsValue(uuidCipher))
|
if(m_vCiphers[i].CipherUuid.Equals(uuidCipher))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,7 +26,7 @@ using ModernKeePassLib.Utility;
|
|||||||
|
|
||||||
namespace ModernKeePassLib.Cryptography.Cipher
|
namespace ModernKeePassLib.Cryptography.Cipher
|
||||||
{
|
{
|
||||||
public sealed class Salsa20Cipher
|
public sealed class Salsa20Cipher : IDisposable
|
||||||
{
|
{
|
||||||
private uint[] m_state = new uint[16];
|
private uint[] m_state = new uint[16];
|
||||||
private uint[] m_x = new uint[16]; // Working buffer
|
private uint[] m_x = new uint[16]; // Working buffer
|
||||||
@@ -34,7 +34,7 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
private byte[] m_output = new byte[64];
|
private byte[] m_output = new byte[64];
|
||||||
private int m_outputPos = 64;
|
private int m_outputPos = 64;
|
||||||
|
|
||||||
private static readonly uint[] m_sigma = new uint[4]{
|
private static readonly uint[] m_sigma = new uint[4] {
|
||||||
0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
|
0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,6 +45,17 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
}
|
}
|
||||||
|
|
||||||
~Salsa20Cipher()
|
~Salsa20Cipher()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Dispose(bool bDisposing)
|
||||||
{
|
{
|
||||||
// Clear sensitive data
|
// Clear sensitive data
|
||||||
Array.Clear(m_state, 0, m_state.Length);
|
Array.Clear(m_state, 0, m_state.Length);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,12 +17,32 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Security;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if !KeePassRT
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using Org.BouncyCastle.Crypto;
|
||||||
|
using Org.BouncyCastle.Crypto.Engines;
|
||||||
|
using Org.BouncyCastle.Crypto.IO;
|
||||||
|
using Org.BouncyCastle.Crypto.Modes;
|
||||||
|
using Org.BouncyCastle.Crypto.Paddings;
|
||||||
|
using Org.BouncyCastle.Crypto.Parameters;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Resources;
|
using ModernKeePassLib.Resources;
|
||||||
using ModernKeePassLib.Serialization;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.Cryptography.Cipher
|
namespace ModernKeePassLib.Cryptography.Cipher
|
||||||
{
|
{
|
||||||
@@ -31,8 +51,10 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class StandardAesEngine : ICipherEngine
|
public sealed class StandardAesEngine : ICipherEngine
|
||||||
{
|
{
|
||||||
// private const CipherMode m_rCipherMode = CipherMode.CBC;
|
#if !PCL && !KeePassRT
|
||||||
// private const PaddingMode m_rCipherPadding = PaddingMode.PKCS7;
|
private const CipherMode m_rCipherMode = CipherMode.CBC;
|
||||||
|
private const PaddingMode m_rCipherPadding = PaddingMode.PKCS7;
|
||||||
|
#endif
|
||||||
|
|
||||||
private static PwUuid m_uuidAes = null;
|
private static PwUuid m_uuidAes = null;
|
||||||
|
|
||||||
@@ -94,29 +116,39 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
|
|
||||||
private static Stream CreateStream(Stream s, bool bEncrypt, byte[] pbKey, byte[] pbIV)
|
private static Stream CreateStream(Stream s, bool bEncrypt, byte[] pbKey, byte[] pbIV)
|
||||||
{
|
{
|
||||||
StandardAesEngine.ValidateArguments(s, bEncrypt, pbKey, pbIV);
|
ValidateArguments(s, bEncrypt, pbKey, pbIV);
|
||||||
return new CryptoStream( s, "AES_CBC_PKCS7", bEncrypt, pbKey, pbIV);
|
#if PCL
|
||||||
|
var provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
|
||||||
|
var key = provider.CreateSymmetricKey(CryptographicBuffer.GenerateRandom(32));
|
||||||
|
using (var ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
s.CopyTo(ms);
|
||||||
|
if (bEncrypt)
|
||||||
|
{
|
||||||
|
return CryptographicEngine.Encrypt(key, ms.GetWindowsRuntimeBuffer(), CryptographicBuffer.GenerateRandom(16)).AsStream();
|
||||||
}
|
}
|
||||||
#if false
|
/*var encryptor = CryptographicEngine.CreateEncryptor(
|
||||||
|
key, pbLocalIV);
|
||||||
|
return new CryptoStream(s, encryptor, CryptoStreamMode.Write);*/
|
||||||
|
|
||||||
|
return CryptographicEngine.Decrypt(key, ms.GetWindowsRuntimeBuffer(), CryptographicBuffer.GenerateRandom(16)).AsStream();
|
||||||
|
/*var decryptor = CryptographicEngine.CreateDecryptor(
|
||||||
|
key, pbLocalIV);
|
||||||
|
return new CryptoStream(s, decryptor, CryptoStreamMode.Read);*/
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if !KeePassRT
|
||||||
RijndaelManaged r = new RijndaelManaged();
|
RijndaelManaged r = new RijndaelManaged();
|
||||||
|
|
||||||
if(r.BlockSize != 128) // AES block size
|
if(r.BlockSize != 128) // AES block size
|
||||||
{
|
{
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
r.BlockSize = 128;
|
r.BlockSize = 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] pbLocalIV = new byte[16];
|
|
||||||
Array.Copy(pbIV, pbLocalIV, 16);
|
|
||||||
r.IV = pbLocalIV;
|
r.IV = pbLocalIV;
|
||||||
|
|
||||||
byte[] pbLocalKey = new byte[32];
|
|
||||||
Array.Copy(pbKey, pbLocalKey, 32);
|
|
||||||
r.KeySize = 256;
|
r.KeySize = 256;
|
||||||
r.Key = pbLocalKey;
|
r.Key = pbLocalKey;
|
||||||
|
|
||||||
r.Mode = m_rCipherMode;
|
r.Mode = m_rCipherMode;
|
||||||
r.Padding = m_rCipherPadding;
|
r.Padding = m_rCipherPadding;
|
||||||
|
|
||||||
@@ -126,9 +158,22 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
|
|
||||||
return new CryptoStream(s, iTransform, bEncrypt ? CryptoStreamMode.Write :
|
return new CryptoStream(s, iTransform, bEncrypt ? CryptoStreamMode.Write :
|
||||||
CryptoStreamMode.Read);
|
CryptoStreamMode.Read);
|
||||||
}
|
#else
|
||||||
|
AesEngine aes = new AesEngine();
|
||||||
|
CbcBlockCipher cbc = new CbcBlockCipher(aes);
|
||||||
|
PaddedBufferedBlockCipher bc = new PaddedBufferedBlockCipher(cbc,
|
||||||
|
new Pkcs7Padding());
|
||||||
|
KeyParameter kp = new KeyParameter(pbLocalKey);
|
||||||
|
ParametersWithIV prmIV = new ParametersWithIV(kp, pbLocalIV);
|
||||||
|
bc.Init(bEncrypt, prmIV);
|
||||||
|
|
||||||
|
IBufferedCipher cpRead = (bEncrypt ? null : bc);
|
||||||
|
IBufferedCipher cpWrite = (bEncrypt ? bc : null);
|
||||||
|
return new CipherStream(s, cpRead, cpWrite);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
public Stream EncryptStream(Stream sPlainText, byte[] pbKey, byte[] pbIV)
|
public Stream EncryptStream(Stream sPlainText, byte[] pbKey, byte[] pbIV)
|
||||||
{
|
{
|
||||||
@@ -139,7 +184,5 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
{
|
{
|
||||||
return StandardAesEngine.CreateStream(sEncrypted, false, pbKey, pbIV);
|
return StandardAesEngine.CreateStream(sEncrypted, false, pbKey, pbIV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,10 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Security;
|
||||||
|
#if PCL
|
||||||
using Windows.Security.Cryptography;
|
using Windows.Security.Cryptography;
|
||||||
//using System.Windows.Forms;
|
#else
|
||||||
//using System.Drawing;
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
using System.IO;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Cryptography
|
namespace ModernKeePassLib.Cryptography
|
||||||
{
|
{
|
||||||
@@ -32,12 +39,16 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class CryptoRandom
|
public sealed class CryptoRandom
|
||||||
{
|
{
|
||||||
//private byte[] m_pbEntropyPool = new byte[64];
|
private byte[] m_pbEntropyPool = new byte[64];
|
||||||
//private uint m_uCounter;
|
private uint m_uCounter;
|
||||||
//private RNGCryptoServiceProvider m_rng = new RNGCryptoServiceProvider();
|
#if PCL
|
||||||
//private ulong m_uGeneratedBytesCount = 0;
|
//private IRandomNumberGenerator m_rng = NetFxCrypto.RandomNumberGenerator;
|
||||||
|
#else
|
||||||
|
private RNGCryptoServiceProvider m_rng = new RNGCryptoServiceProvider();
|
||||||
|
#endif
|
||||||
|
private ulong m_uGeneratedBytesCount = 0;
|
||||||
|
|
||||||
// private object m_oSyncRoot = new object();
|
private object m_oSyncRoot = new object();
|
||||||
|
|
||||||
private static CryptoRandom m_pInstance = null;
|
private static CryptoRandom m_pInstance = null;
|
||||||
public static CryptoRandom Instance
|
public static CryptoRandom Instance
|
||||||
@@ -51,43 +62,6 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if KeePassWinRT
|
|
||||||
private CryptoRandom()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update the internal seed of the random number generator based
|
|
||||||
/// on entropy data.
|
|
||||||
/// This method is thread-safe.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pbEntropy">Entropy bytes.</param>
|
|
||||||
public void AddEntropy(byte[] pbEntropy)
|
|
||||||
{
|
|
||||||
// Not used in WinRT version
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a number of cryptographically strong random bytes.
|
|
||||||
/// This method is thread-safe.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="uRequestedBytes">Number of requested random bytes.</param>
|
|
||||||
/// <returns>A byte array consisting of <paramref name="uRequestedBytes" />
|
|
||||||
/// random bytes.</returns>
|
|
||||||
public byte[] GetRandomBytes(uint uRequestedBytes)
|
|
||||||
{
|
|
||||||
if (uRequestedBytes == 0) return new byte[0]; // Allow zero-length array
|
|
||||||
|
|
||||||
byte[] pbRes;
|
|
||||||
|
|
||||||
Windows.Storage.Streams.IBuffer buffer = CryptographicBuffer.GenerateRandom(uRequestedBytes);
|
|
||||||
CryptographicBuffer.CopyToByteArray(buffer, out pbRes);
|
|
||||||
return pbRes;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the number of random bytes that this instance generated so far.
|
/// Get the number of random bytes that this instance generated so far.
|
||||||
/// Note that this number can be higher than the number of random bytes
|
/// Note that this number can be higher than the number of random bytes
|
||||||
@@ -126,19 +100,25 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
/// <param name="pbEntropy">Entropy bytes.</param>
|
/// <param name="pbEntropy">Entropy bytes.</param>
|
||||||
public void AddEntropy(byte[] pbEntropy)
|
public void AddEntropy(byte[] pbEntropy)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(pbEntropy == null) { Debug.Assert(false); return; }
|
if(pbEntropy == null) { Debug.Assert(false); return; }
|
||||||
if(pbEntropy.Length == 0) { Debug.Assert(false); return; }
|
if(pbEntropy.Length == 0) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
byte[] pbNewData = pbEntropy;
|
byte[] pbNewData = pbEntropy;
|
||||||
if(pbEntropy.Length >= 64)
|
if(pbEntropy.Length >= 64)
|
||||||
{
|
{
|
||||||
|
#if PCL
|
||||||
|
var shaNew = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha512);
|
||||||
|
pbNewData = shaNew.HashData(pbEntropy.AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
SHA512Managed shaNew = new SHA512Managed();
|
SHA512Managed shaNew = new SHA512Managed();
|
||||||
#else
|
#else
|
||||||
SHA256Managed shaNew = new SHA256Managed();
|
SHA256Managed shaNew = new SHA256Managed();
|
||||||
#endif
|
#endif
|
||||||
pbNewData = shaNew.ComputeHash(pbEntropy);
|
pbNewData = shaNew.ComputeHash(pbEntropy);
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryStream ms = new MemoryStream();
|
MemoryStream ms = new MemoryStream();
|
||||||
@@ -148,6 +128,11 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
ms.Write(pbNewData, 0, pbNewData.Length);
|
ms.Write(pbNewData, 0, pbNewData.Length);
|
||||||
|
|
||||||
byte[] pbFinal = ms.ToArray();
|
byte[] pbFinal = ms.ToArray();
|
||||||
|
#if PCL
|
||||||
|
var shaPool = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha512);
|
||||||
|
m_pbEntropyPool = shaPool.HashData(pbFinal.AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
Debug.Assert(pbFinal.Length == (64 + pbNewData.Length));
|
Debug.Assert(pbFinal.Length == (64 + pbNewData.Length));
|
||||||
SHA512Managed shaPool = new SHA512Managed();
|
SHA512Managed shaPool = new SHA512Managed();
|
||||||
@@ -155,16 +140,14 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
SHA256Managed shaPool = new SHA256Managed();
|
SHA256Managed shaPool = new SHA256Managed();
|
||||||
#endif
|
#endif
|
||||||
m_pbEntropyPool = shaPool.ComputeHash(pbFinal);
|
m_pbEntropyPool = shaPool.ComputeHash(pbFinal);
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
ms.Close();
|
ms.Dispose();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static byte[] GetSystemData(Random rWeak)
|
private static byte[] GetSystemData(Random rWeak)
|
||||||
{
|
{
|
||||||
|
|
||||||
MemoryStream ms = new MemoryStream();
|
MemoryStream ms = new MemoryStream();
|
||||||
byte[] pb;
|
byte[] pb;
|
||||||
|
|
||||||
@@ -174,21 +157,36 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
pb = TimeUtil.PackTime(DateTime.Now);
|
pb = TimeUtil.PackTime(DateTime.Now);
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
|
// In try-catch for systems without GUI;
|
||||||
|
// https://sourceforge.net/p/keepass/discussion/329221/thread/20335b73/
|
||||||
|
try
|
||||||
|
{
|
||||||
Point pt = Cursor.Position;
|
Point pt = Cursor.Position;
|
||||||
pb = MemUtil.UInt32ToBytes((uint)pt.X);
|
pb = MemUtil.UInt32ToBytes((uint)pt.X);
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
pb = MemUtil.UInt32ToBytes((uint)pt.Y);
|
pb = MemUtil.UInt32ToBytes((uint)pt.Y);
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
|
}
|
||||||
|
catch(Exception) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pb = MemUtil.UInt32ToBytes((uint)rWeak.Next());
|
pb = MemUtil.UInt32ToBytes((uint)rWeak.Next());
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
|
|
||||||
pb = MemUtil.UInt32ToBytes((uint)NativeLib.GetPlatformID());
|
#if PCL
|
||||||
|
pb = MemUtil.UInt32ToBytes((uint)Environment.ProcessorCount);
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
|
|
||||||
#if !KeePassLibSD
|
pb = MemUtil.UInt32ToBytes((uint)Environment.CurrentManagedThreadId);
|
||||||
|
ms.Write(pb, 0, pb.Length);
|
||||||
|
#else
|
||||||
|
pb = MemUtil.UInt32ToBytes((uint)NativeLib.GetPlatformID());
|
||||||
|
ms.Write(pb, 0, pb.Length);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
|
Process p = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pb = MemUtil.UInt32ToBytes((uint)Environment.ProcessorCount);
|
pb = MemUtil.UInt32ToBytes((uint)Environment.ProcessorCount);
|
||||||
@@ -197,13 +195,11 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
|
|
||||||
Version v = Environment.OSVersion.Version;
|
Version v = Environment.OSVersion.Version;
|
||||||
int nv = (v.Major << 28) + (v.MajorRevision << 24) +
|
pb = MemUtil.UInt32ToBytes((uint)v.GetHashCode());
|
||||||
(v.Minor << 20) + (v.MinorRevision << 16) +
|
|
||||||
(v.Revision << 12) + v.Build;
|
|
||||||
pb = MemUtil.UInt32ToBytes((uint)nv);
|
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
|
|
||||||
Process p = Process.GetCurrentProcess();
|
p = Process.GetCurrentProcess();
|
||||||
|
|
||||||
pb = MemUtil.UInt64ToBytes((ulong)p.Handle.ToInt64());
|
pb = MemUtil.UInt64ToBytes((ulong)p.Handle.ToInt64());
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
pb = MemUtil.UInt32ToBytes((uint)p.HandleCount);
|
pb = MemUtil.UInt32ToBytes((uint)p.HandleCount);
|
||||||
@@ -236,33 +232,31 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
// ms.Write(pb, 0, pb.Length);
|
// ms.Write(pb, 0, pb.Length);
|
||||||
}
|
}
|
||||||
catch(Exception) { }
|
catch(Exception) { }
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try { if(p != null) p.Dispose(); }
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pb = Guid.NewGuid().ToByteArray();
|
pb = Guid.NewGuid().ToByteArray();
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
|
|
||||||
byte[] pbAll = ms.ToArray();
|
byte[] pbAll = ms.ToArray();
|
||||||
ms.Close();
|
ms.Dispose();
|
||||||
return pbAll;
|
return pbAll;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private byte[] GetCspData()
|
private byte[] GetCspData()
|
||||||
{
|
{
|
||||||
uint length = 32;
|
//byte[] pbCspRandom = new byte[32];
|
||||||
byte[] pbCspRandom = new byte[length];
|
var pbCspRandom = CryptographicBuffer.GenerateRandom(32);
|
||||||
|
|
||||||
Windows.Storage.Streams.IBuffer buffer = CryptographicBuffer.GenerateRandom(length);
|
|
||||||
|
|
||||||
CryptographicBuffer.CopyToByteArray(buffer, pbCspRandom);
|
|
||||||
//m_rng.GetBytes(pbCspRandom);
|
//m_rng.GetBytes(pbCspRandom);
|
||||||
return pbCspRandom;
|
return pbCspRandom.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] GenerateRandom256()
|
private byte[] GenerateRandom256()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(this.GenerateRandom256Pre != null)
|
if(this.GenerateRandom256Pre != null)
|
||||||
this.GenerateRandom256Pre(this, EventArgs.Empty);
|
this.GenerateRandom256Pre(this, EventArgs.Empty);
|
||||||
|
|
||||||
@@ -281,16 +275,20 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
pbFinal = ms.ToArray();
|
pbFinal = ms.ToArray();
|
||||||
Debug.Assert(pbFinal.Length == (m_pbEntropyPool.Length +
|
Debug.Assert(pbFinal.Length == (m_pbEntropyPool.Length +
|
||||||
pbCounter.Length + pbCspRandom.Length));
|
pbCounter.Length + pbCspRandom.Length));
|
||||||
ms.Close();
|
ms.Dispose();
|
||||||
|
|
||||||
m_uGeneratedBytesCount += 32;
|
m_uGeneratedBytesCount += 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
return sha256.HashData(pbFinal.AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
SHA256Managed sha256 = new SHA256Managed();
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
return sha256.ComputeHash(pbFinal);
|
return sha256.ComputeHash(pbFinal);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a number of cryptographically strong random bytes.
|
/// Get a number of cryptographically strong random bytes.
|
||||||
/// This method is thread-safe.
|
/// This method is thread-safe.
|
||||||
@@ -312,7 +310,7 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
|
|
||||||
long lCopy = (long)((uRequestedBytes < 32) ? uRequestedBytes : 32);
|
long lCopy = (long)((uRequestedBytes < 32) ? uRequestedBytes : 32);
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
Array.Copy(pbRandom256, 0, pbRes, lPos, lCopy);
|
Array.Copy(pbRandom256, 0, pbRes, lPos, lCopy);
|
||||||
#else
|
#else
|
||||||
Array.Copy(pbRandom256, 0, pbRes, (int)lPos, (int)lCopy);
|
Array.Copy(pbRandom256, 0, pbRes, (int)lPos, (int)lCopy);
|
||||||
@@ -325,8 +323,5 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
Debug.Assert((int)lPos == pbRes.Length);
|
Debug.Assert((int)lPos == pbRes.Length);
|
||||||
return pbRes;
|
return pbRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !KeePassWinRT
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,6 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Cryptography.Cipher;
|
using ModernKeePassLib.Cryptography.Cipher;
|
||||||
|
|
||||||
@@ -109,13 +117,17 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
}
|
}
|
||||||
else if(genAlgorithm == CrsAlgorithm.Salsa20)
|
else if(genAlgorithm == CrsAlgorithm.Salsa20)
|
||||||
{
|
{
|
||||||
byte[] pbKey32 = SHA256Managed.Instance.ComputeHash(pbKey);
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
byte[] pbIV = new byte[]{ 0xE8, 0x30, 0x09, 0x4B,
|
var pbKey32 = sha256.HashData(pbKey.AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
|
byte[] pbKey32 = sha256.ComputeHash(pbKey);
|
||||||
|
#endif
|
||||||
|
byte[] pbIV = new byte[8] { 0xE8, 0x30, 0x09, 0x4B,
|
||||||
0x97, 0x20, 0x5D, 0x2A }; // Unique constant
|
0x97, 0x20, 0x5D, 0x2A }; // Unique constant
|
||||||
|
|
||||||
m_salsa20 = new Salsa20Cipher(pbKey32, pbIV);
|
m_salsa20 = new Salsa20Cipher(pbKey32, pbIV);
|
||||||
|
|
||||||
}
|
}
|
||||||
else // Unknown algorithm
|
else // Unknown algorithm
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,12 +17,20 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using ModernKeePassLib.Utility;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
#if PCL
|
||||||
using Windows.Security.Cryptography;
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
using Windows.Security.Cryptography.Core;
|
using Windows.Security.Cryptography.Core;
|
||||||
|
using ModernKeePassLib.Utility;
|
||||||
|
using CryptographicHash = Windows.Security.Cryptography.Core.CryptographicHash;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Cryptography
|
namespace ModernKeePassLib.Cryptography
|
||||||
{
|
{
|
||||||
@@ -30,30 +38,17 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
{
|
{
|
||||||
private Stream m_sBaseStream;
|
private Stream m_sBaseStream;
|
||||||
private bool m_bWriting;
|
private bool m_bWriting;
|
||||||
private Queue<byte[]> m_DataToHash;
|
#if PCL
|
||||||
//private HashAlgorithm m_hash;
|
private CryptographicHash m_hash;
|
||||||
|
#else
|
||||||
|
private HashAlgorithm m_hash;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private byte[] m_pbFinalHash = null;
|
||||||
|
|
||||||
public byte[] Hash
|
public byte[] Hash
|
||||||
{
|
{
|
||||||
get
|
get { return m_pbFinalHash; }
|
||||||
{
|
|
||||||
int len = 0;
|
|
||||||
foreach (byte[] block in m_DataToHash)
|
|
||||||
{
|
|
||||||
len += block.Length;
|
|
||||||
}
|
|
||||||
byte[] dataToHash = new byte[len];
|
|
||||||
int pos = 0;
|
|
||||||
while(m_DataToHash.Count > 0)
|
|
||||||
{
|
|
||||||
byte[] block = m_DataToHash.Dequeue();
|
|
||||||
Array.Copy(block, 0, dataToHash, pos, block.Length);
|
|
||||||
pos += block.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] hash = SHA256Managed.Instance.ComputeHash(dataToHash);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanRead
|
public override bool CanRead
|
||||||
@@ -82,20 +77,20 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
set { throw new NotSupportedException(); }
|
set { throw new NotSupportedException(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashingStreamEx(Stream sBaseStream, bool bWriting, CryptographicHash hashAlgorithm)
|
#if PCL
|
||||||
|
public HashingStreamEx(Stream sBaseStream, bool bWriting, string hashAlgorithm)
|
||||||
|
#else
|
||||||
|
public HashingStreamEx(Stream sBaseStream, bool bWriting, HashAlgorithm hashAlgorithm)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (sBaseStream == null) throw new ArgumentNullException("sBaseStream");
|
if(sBaseStream == null)
|
||||||
|
throw new ArgumentNullException("sBaseStream");
|
||||||
|
|
||||||
m_sBaseStream = sBaseStream;
|
m_sBaseStream = sBaseStream;
|
||||||
m_bWriting = bWriting;
|
m_bWriting = bWriting;
|
||||||
|
#if PCL
|
||||||
#if KeePassWinRT
|
m_hash = HashAlgorithmProvider.OpenAlgorithm(hashAlgorithm ?? HashAlgorithmNames.Sha256).CreateHash();
|
||||||
|
#elif !KeePassLibSD
|
||||||
m_DataToHash = new Queue<byte[]>();
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
#if !KeePassLibSD
|
|
||||||
m_hash = (hashAlgorithm ?? new SHA256Managed());
|
m_hash = (hashAlgorithm ?? new SHA256Managed());
|
||||||
#else // KeePassLibSD
|
#else // KeePassLibSD
|
||||||
m_hash = null;
|
m_hash = null;
|
||||||
@@ -105,22 +100,17 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
try { if(m_hash == null) m_hash = HashAlgorithm.Create(); }
|
try { if(m_hash == null) m_hash = HashAlgorithm.Create(); }
|
||||||
catch(Exception) { }
|
catch(Exception) { }
|
||||||
#endif
|
#endif
|
||||||
#endif // KeePassWinRT
|
if(m_hash == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
|
||||||
#if TODO
|
|
||||||
// Bert TODO: For the time being, only built-in Hash algorithm are supported.
|
|
||||||
if (m_hash == null) { Debug.Assert(false); return; }
|
|
||||||
// Validate hash algorithm
|
// Validate hash algorithm
|
||||||
if((!m_hash.CanReuseTransform) || (!m_hash.CanTransformMultipleBlocks) ||
|
/*if((!m_hash.CanReuseTransform) || (!m_hash.CanTransformMultipleBlocks) ||
|
||||||
(m_hash.InputBlockSize != 1) || (m_hash.OutputBlockSize != 1))
|
(m_hash.InputBlockSize != 1) || (m_hash.OutputBlockSize != 1))
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if false && DEBUG
|
||||||
MessageService.ShowWarning("Broken HashAlgorithm object in HashingStreamEx.");
|
MessageService.ShowWarning("Broken HashAlgorithm object in HashingStreamEx.");
|
||||||
#endif
|
#endif
|
||||||
m_hash = null;
|
m_hash = null;
|
||||||
}
|
}*/
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Flush()
|
public override void Flush()
|
||||||
@@ -128,25 +118,32 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
m_sBaseStream.Flush();
|
m_sBaseStream.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public override void Close()
|
#if PCL || KeePassRT
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
|
if(!disposing) return;
|
||||||
|
#else
|
||||||
|
public override void Close()
|
||||||
|
{
|
||||||
|
#endif
|
||||||
if(m_hash != null)
|
if(m_hash != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_hash.TransformFinalBlock(new byte[0], 0, 0);
|
//m_hash.TransformFinalBlock(new byte[0], 0, 0);
|
||||||
|
#if PCL
|
||||||
|
m_pbFinalHash = m_hash.GetValueAndReset().ToArray();
|
||||||
|
#else
|
||||||
m_pbFinalHash = m_hash.Hash;
|
m_pbFinalHash = m_hash.Hash;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch(Exception) { Debug.Assert(false); }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
m_hash = null;
|
m_hash = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sBaseStream.Close();
|
m_sBaseStream.Dispose();
|
||||||
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
public override long Seek(long lOffset, SeekOrigin soOrigin)
|
public override long Seek(long lOffset, SeekOrigin soOrigin)
|
||||||
{
|
{
|
||||||
@@ -160,23 +157,28 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
|
|
||||||
public override int Read(byte[] pbBuffer, int nOffset, int nCount)
|
public override int Read(byte[] pbBuffer, int nOffset, int nCount)
|
||||||
{
|
{
|
||||||
|
if(m_bWriting) throw new InvalidOperationException();
|
||||||
if (m_bWriting) throw new InvalidOperationException();
|
|
||||||
|
|
||||||
int nRead = m_sBaseStream.Read(pbBuffer, nOffset, nCount);
|
int nRead = m_sBaseStream.Read(pbBuffer, nOffset, nCount);
|
||||||
|
|
||||||
// Mono bug workaround (LaunchPad 798910)
|
|
||||||
int nPartialRead = nRead;
|
int nPartialRead = nRead;
|
||||||
while ((nRead < nCount) && (nPartialRead != 0))
|
while((nRead < nCount) && (nPartialRead != 0))
|
||||||
{
|
{
|
||||||
nPartialRead = m_sBaseStream.Read(pbBuffer, nOffset + nRead,
|
nPartialRead = m_sBaseStream.Read(pbBuffer, nOffset + nRead,
|
||||||
nCount - nRead);
|
nCount - nRead);
|
||||||
nRead += nPartialRead;
|
nRead += nPartialRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] pbOrg = new byte[nRead];
|
#if DEBUG
|
||||||
Array.Copy(pbBuffer, pbOrg, nRead);
|
byte[] pbOrg = new byte[pbBuffer.Length];
|
||||||
m_DataToHash.Enqueue(pbOrg);
|
Array.Copy(pbBuffer, pbOrg, pbBuffer.Length);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*if((m_hash != null) && (nRead > 0))
|
||||||
|
m_hash.TransformBlock(pbBuffer, nOffset, nRead, pbBuffer, nOffset);*/
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
Debug.Assert(MemUtil.ArraysEqual(pbBuffer, pbOrg));
|
||||||
|
#endif
|
||||||
|
|
||||||
return nRead;
|
return nRead;
|
||||||
}
|
}
|
||||||
@@ -189,7 +191,7 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
byte[] pbOrg = new byte[pbBuffer.Length];
|
byte[] pbOrg = new byte[pbBuffer.Length];
|
||||||
Array.Copy(pbBuffer, pbOrg, pbBuffer.Length);
|
Array.Copy(pbBuffer, pbOrg, pbBuffer.Length);
|
||||||
#endif
|
#endif
|
||||||
// TODO: implement this
|
|
||||||
/*if((m_hash != null) && (nCount > 0))
|
/*if((m_hash != null) && (nCount > 0))
|
||||||
m_hash.TransformBlock(pbBuffer, nOffset, nCount, pbBuffer, nOffset);*/
|
m_hash.TransformBlock(pbBuffer, nOffset, nCount, pbBuffer, nOffset);*/
|
||||||
|
|
||||||
@@ -198,7 +200,6 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_sBaseStream.Write(pbBuffer, nOffset, nCount);
|
m_sBaseStream.Write(pbBuffer, nOffset, nCount);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,9 +17,17 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
#if !KeePassLibSD
|
|
||||||
namespace ModernKeePassLib.Cryptography
|
namespace ModernKeePassLib.Cryptography
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -33,14 +41,17 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
public static string Generate(byte[] pbSecret, ulong uFactor,
|
public static string Generate(byte[] pbSecret, ulong uFactor,
|
||||||
uint uCodeDigits, bool bAddChecksum, int iTruncationOffset)
|
uint uCodeDigits, bool bAddChecksum, int iTruncationOffset)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "Not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
byte[] pbText = MemUtil.UInt64ToBytes(uFactor);
|
byte[] pbText = MemUtil.UInt64ToBytes(uFactor);
|
||||||
Array.Reverse(pbText); // Big-Endian
|
Array.Reverse(pbText); // Big-Endian
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
var hsha1 = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha1).CreateHash(pbSecret.AsBuffer());
|
||||||
|
hsha1.Append(pbText.AsBuffer());
|
||||||
|
var pbHash = hsha1.GetValueAndReset().ToArray();
|
||||||
|
#else
|
||||||
HMACSHA1 hsha1 = new HMACSHA1(pbSecret);
|
HMACSHA1 hsha1 = new HMACSHA1(pbSecret);
|
||||||
byte[] pbHash = hsha1.ComputeHash(pbText);
|
byte[] pbHash = hsha1.ComputeHash(pbText);
|
||||||
|
#endif
|
||||||
|
|
||||||
uint uOffset = (uint)(pbHash[pbHash.Length - 1] & 0xF);
|
uint uOffset = (uint)(pbHash[pbHash.Length - 1] & 0xF);
|
||||||
if((iTruncationOffset >= 0) && (iTruncationOffset < (pbHash.Length - 4)))
|
if((iTruncationOffset >= 0) && (iTruncationOffset < (pbHash.Length - 4)))
|
||||||
@@ -56,8 +67,8 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
uOtp = ((uOtp * 10) + CalculateChecksum(uOtp, uCodeDigits));
|
uOtp = ((uOtp * 10) + CalculateChecksum(uOtp, uCodeDigits));
|
||||||
|
|
||||||
uint uDigits = (bAddChecksum ? (uCodeDigits + 1) : uCodeDigits);
|
uint uDigits = (bAddChecksum ? (uCodeDigits + 1) : uCodeDigits);
|
||||||
return uOtp.ToString().PadLeft((int)uDigits, '0');
|
return uOtp.ToString(NumberFormatInfo.InvariantInfo).PadLeft(
|
||||||
#endif
|
(int)uDigits, '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly uint[] vDoubleDigits = new uint[]{ 0, 2, 4, 6, 8,
|
private static readonly uint[] vDoubleDigits = new uint[]{ 0, 2, 4, 6, 8,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -66,7 +66,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
|
|
||||||
foreach(CustomPwGenerator pwg in m_vGens)
|
foreach(CustomPwGenerator pwg in m_vGens)
|
||||||
{
|
{
|
||||||
if(uuid.EqualsValue(pwg.Uuid)) return pwg;
|
if(uuid.Equals(pwg.Uuid)) return pwg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -90,7 +90,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
|
|
||||||
for(int i = 0; i < m_vGens.Count; ++i)
|
for(int i = 0; i < m_vGens.Count; ++i)
|
||||||
{
|
{
|
||||||
if(uuid.EqualsValue(m_vGens[i].Uuid)) return i;
|
if(uuid.Equals(m_vGens[i].Uuid)) return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -67,6 +67,17 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
pcsUsed.Add(ch);
|
pcsUsed.Add(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(ch == '^')
|
||||||
|
{
|
||||||
|
ch = csStream.ReadChar();
|
||||||
|
if(ch == char.MinValue) // ^ at the end
|
||||||
|
{
|
||||||
|
vGenerated.AddLast('^');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bInCharSetDef) pcsCustom.Remove(ch);
|
||||||
|
}
|
||||||
else if(ch == '[')
|
else if(ch == '[')
|
||||||
{
|
{
|
||||||
pcsCustom.Clear();
|
pcsCustom.Clear();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -46,52 +46,88 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
public const string Invalid = "\t\r\n";
|
public const string Invalid = "\t\r\n";
|
||||||
public const string LookAlike = @"O0l1I|";
|
public const string LookAlike = @"O0l1I|";
|
||||||
|
|
||||||
|
internal const string MenuAccels = PwCharSet.LowerCase + PwCharSet.Digits;
|
||||||
|
|
||||||
private const int CharTabSize = (0x10000 / 8);
|
private const int CharTabSize = (0x10000 / 8);
|
||||||
|
|
||||||
private List<char> m_vChars = new List<char>();
|
private List<char> m_vChars = new List<char>();
|
||||||
private byte[] m_vTab = new byte[CharTabSize];
|
private byte[] m_vTab = new byte[CharTabSize];
|
||||||
|
|
||||||
private string m_strHighAnsi = string.Empty;
|
private static string m_strHighAnsi = null;
|
||||||
private string m_strSpecial = string.Empty;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new, empty character set collection object.
|
/// Create a new, empty character set collection object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PwCharSet()
|
public PwCharSet()
|
||||||
{
|
{
|
||||||
this.Initialize(true);
|
Initialize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PwCharSet(string strCharSet)
|
public PwCharSet(string strCharSet)
|
||||||
{
|
{
|
||||||
this.Initialize(true);
|
Initialize(true);
|
||||||
this.Add(strCharSet);
|
Add(strCharSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PwCharSet(bool bFullInitialize)
|
private PwCharSet(bool bFullInitialize)
|
||||||
{
|
{
|
||||||
this.Initialize(bFullInitialize);
|
Initialize(bFullInitialize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize(bool bFullInitialize)
|
private void Initialize(bool bFullInitialize)
|
||||||
{
|
{
|
||||||
this.Clear();
|
Clear();
|
||||||
|
|
||||||
if(bFullInitialize == false) return;
|
if(!bFullInitialize) return;
|
||||||
|
|
||||||
|
if(m_strHighAnsi == null)
|
||||||
|
{
|
||||||
StringBuilder sbHighAnsi = new StringBuilder();
|
StringBuilder sbHighAnsi = new StringBuilder();
|
||||||
for(char ch = '~'; ch < 255; ++ch)
|
// [U+0080, U+009F] are C1 control characters,
|
||||||
|
// U+00A0 is non-breaking space
|
||||||
|
for(char ch = '\u00A1'; ch <= '\u00AC'; ++ch)
|
||||||
sbHighAnsi.Append(ch);
|
sbHighAnsi.Append(ch);
|
||||||
m_strHighAnsi = sbHighAnsi.ToString();
|
// 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);
|
PwCharSet pcs = new PwCharSet(false);
|
||||||
pcs.AddRange('!', '/');
|
pcs.AddRange('!', '/');
|
||||||
pcs.AddRange(':', '@');
|
pcs.AddRange(':', '@');
|
||||||
pcs.AddRange('[', '`');
|
pcs.AddRange('[', '`');
|
||||||
|
pcs.Add(@"|~");
|
||||||
pcs.Remove(@"-_ ");
|
pcs.Remove(@"-_ ");
|
||||||
pcs.Remove(PwCharSet.Brackets);
|
pcs.Remove(PwCharSet.Brackets);
|
||||||
|
|
||||||
m_strSpecial = pcs.ToString();
|
m_strSpecial = pcs.ToString();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Number of characters in this set.
|
/// Number of characters in this set.
|
||||||
@@ -118,9 +154,6 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string SpecialChars { get { return m_strSpecial; } }
|
|
||||||
public string HighAnsiChars { get { return m_strHighAnsi; } }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove all characters from this set.
|
/// Remove all characters from this set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -142,7 +175,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
|
|
||||||
foreach(char ch in strCharacters)
|
foreach(char ch in strCharacters)
|
||||||
{
|
{
|
||||||
if(this.Contains(ch) == false) return false;
|
if(!Contains(ch)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -156,7 +189,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
{
|
{
|
||||||
if(ch == char.MinValue) { Debug.Assert(false); return; }
|
if(ch == char.MinValue) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
if(this.Contains(ch) == false)
|
if(!Contains(ch))
|
||||||
{
|
{
|
||||||
m_vChars.Add(ch);
|
m_vChars.Add(ch);
|
||||||
m_vTab[ch / 8] |= (byte)(1 << (ch % 8));
|
m_vTab[ch / 8] |= (byte)(1 << (ch % 8));
|
||||||
@@ -175,20 +208,20 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
m_vChars.Capacity = m_vChars.Count + strCharSet.Length;
|
m_vChars.Capacity = m_vChars.Count + strCharSet.Length;
|
||||||
|
|
||||||
foreach(char ch in strCharSet)
|
foreach(char ch in strCharSet)
|
||||||
this.Add(ch);
|
Add(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(string strCharSet1, string strCharSet2)
|
public void Add(string strCharSet1, string strCharSet2)
|
||||||
{
|
{
|
||||||
this.Add(strCharSet1);
|
Add(strCharSet1);
|
||||||
this.Add(strCharSet2);
|
Add(strCharSet2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(string strCharSet1, string strCharSet2, string strCharSet3)
|
public void Add(string strCharSet1, string strCharSet2, string strCharSet3)
|
||||||
{
|
{
|
||||||
this.Add(strCharSet1);
|
Add(strCharSet1);
|
||||||
this.Add(strCharSet2);
|
Add(strCharSet2);
|
||||||
this.Add(strCharSet3);
|
Add(strCharSet3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRange(char chMin, char chMax)
|
public void AddRange(char chMin, char chMax)
|
||||||
@@ -196,9 +229,9 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
m_vChars.Capacity = m_vChars.Count + (chMax - chMin) + 1;
|
m_vChars.Capacity = m_vChars.Count + (chMax - chMin) + 1;
|
||||||
|
|
||||||
for(char ch = chMin; ch < chMax; ++ch)
|
for(char ch = chMin; ch < chMax; ++ch)
|
||||||
this.Add(ch);
|
Add(ch);
|
||||||
|
|
||||||
this.Add(chMax);
|
Add(chMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddCharSet(char chCharSetIdentifier)
|
public bool AddCharSet(char chCharSetIdentifier)
|
||||||
@@ -207,29 +240,29 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
|
|
||||||
switch(chCharSetIdentifier)
|
switch(chCharSetIdentifier)
|
||||||
{
|
{
|
||||||
case 'a': this.Add(PwCharSet.LowerCase, PwCharSet.Digits); break;
|
case 'a': Add(PwCharSet.LowerCase, PwCharSet.Digits); break;
|
||||||
case 'A': this.Add(PwCharSet.LowerCase, PwCharSet.UpperCase,
|
case 'A': Add(PwCharSet.LowerCase, PwCharSet.UpperCase,
|
||||||
PwCharSet.Digits); break;
|
PwCharSet.Digits); break;
|
||||||
case 'U': this.Add(PwCharSet.UpperCase, PwCharSet.Digits); break;
|
case 'U': Add(PwCharSet.UpperCase, PwCharSet.Digits); break;
|
||||||
case 'c': this.Add(PwCharSet.LowerConsonants); break;
|
case 'c': Add(PwCharSet.LowerConsonants); break;
|
||||||
case 'C': this.Add(PwCharSet.LowerConsonants,
|
case 'C': Add(PwCharSet.LowerConsonants,
|
||||||
PwCharSet.UpperConsonants); break;
|
PwCharSet.UpperConsonants); break;
|
||||||
case 'z': this.Add(PwCharSet.UpperConsonants); break;
|
case 'z': Add(PwCharSet.UpperConsonants); break;
|
||||||
case 'd': this.Add(PwCharSet.Digits); break; // Digit
|
case 'd': Add(PwCharSet.Digits); break; // Digit
|
||||||
case 'h': this.Add(PwCharSet.LowerHex); break;
|
case 'h': Add(PwCharSet.LowerHex); break;
|
||||||
case 'H': this.Add(PwCharSet.UpperHex); break;
|
case 'H': Add(PwCharSet.UpperHex); break;
|
||||||
case 'l': this.Add(PwCharSet.LowerCase); break;
|
case 'l': Add(PwCharSet.LowerCase); break;
|
||||||
case 'L': this.Add(PwCharSet.LowerCase, PwCharSet.UpperCase); break;
|
case 'L': Add(PwCharSet.LowerCase, PwCharSet.UpperCase); break;
|
||||||
case 'u': this.Add(PwCharSet.UpperCase); break;
|
case 'u': Add(PwCharSet.UpperCase); break;
|
||||||
case 'p': this.Add(PwCharSet.Punctuation); break;
|
case 'p': Add(PwCharSet.Punctuation); break;
|
||||||
case 'b': this.Add(PwCharSet.Brackets); break;
|
case 'b': Add(PwCharSet.Brackets); break;
|
||||||
case 's': this.Add(PwCharSet.PrintableAsciiSpecial); break;
|
case 's': Add(PwCharSet.PrintableAsciiSpecial); break;
|
||||||
case 'S': this.Add(PwCharSet.UpperCase, PwCharSet.LowerCase);
|
case 'S': Add(PwCharSet.UpperCase, PwCharSet.LowerCase);
|
||||||
this.Add(PwCharSet.Digits, PwCharSet.PrintableAsciiSpecial); break;
|
Add(PwCharSet.Digits, PwCharSet.PrintableAsciiSpecial); break;
|
||||||
case 'v': this.Add(PwCharSet.LowerVowels); break;
|
case 'v': Add(PwCharSet.LowerVowels); break;
|
||||||
case 'V': this.Add(PwCharSet.LowerVowels, PwCharSet.UpperVowels); break;
|
case 'V': Add(PwCharSet.LowerVowels, PwCharSet.UpperVowels); break;
|
||||||
case 'Z': this.Add(PwCharSet.UpperVowels); break;
|
case 'Z': Add(PwCharSet.UpperVowels); break;
|
||||||
case 'x': this.Add(m_strHighAnsi); break;
|
case 'x': Add(m_strHighAnsi); break;
|
||||||
default: bResult = false; break;
|
default: bResult = false; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +271,7 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
|
|
||||||
public bool Remove(char ch)
|
public bool Remove(char ch)
|
||||||
{
|
{
|
||||||
m_vTab[ch / 8] &= (byte)~(1 << (ch % 8));
|
m_vTab[ch / 8] &= (byte)(~(1 << (ch % 8)));
|
||||||
return m_vChars.Remove(ch);
|
return m_vChars.Remove(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,10 +294,10 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
Debug.Assert(strCharacters != null);
|
Debug.Assert(strCharacters != null);
|
||||||
if(strCharacters == null) throw new ArgumentNullException("strCharacters");
|
if(strCharacters == null) throw new ArgumentNullException("strCharacters");
|
||||||
|
|
||||||
if(this.Contains(strCharacters) == false)
|
if(!Contains(strCharacters))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return this.Remove(strCharacters);
|
return Remove(strCharacters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -284,16 +317,16 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
sb.Append(this.RemoveIfAllExist(PwCharSet.UpperCase) ? 'U' : '_');
|
sb.Append(RemoveIfAllExist(PwCharSet.UpperCase) ? 'U' : '_');
|
||||||
sb.Append(this.RemoveIfAllExist(PwCharSet.LowerCase) ? 'L' : '_');
|
sb.Append(RemoveIfAllExist(PwCharSet.LowerCase) ? 'L' : '_');
|
||||||
sb.Append(this.RemoveIfAllExist(PwCharSet.Digits) ? 'D' : '_');
|
sb.Append(RemoveIfAllExist(PwCharSet.Digits) ? 'D' : '_');
|
||||||
sb.Append(this.RemoveIfAllExist(m_strSpecial) ? 'S' : '_');
|
sb.Append(RemoveIfAllExist(m_strSpecial) ? 'S' : '_');
|
||||||
sb.Append(this.RemoveIfAllExist(PwCharSet.Punctuation) ? 'P' : '_');
|
sb.Append(RemoveIfAllExist(PwCharSet.Punctuation) ? 'P' : '_');
|
||||||
sb.Append(this.RemoveIfAllExist(@"-") ? 'm' : '_');
|
sb.Append(RemoveIfAllExist(@"-") ? 'm' : '_');
|
||||||
sb.Append(this.RemoveIfAllExist(@"_") ? 'u' : '_');
|
sb.Append(RemoveIfAllExist(@"_") ? 'u' : '_');
|
||||||
sb.Append(this.RemoveIfAllExist(@" ") ? 's' : '_');
|
sb.Append(RemoveIfAllExist(@" ") ? 's' : '_');
|
||||||
sb.Append(this.RemoveIfAllExist(PwCharSet.Brackets) ? 'B' : '_');
|
sb.Append(RemoveIfAllExist(PwCharSet.Brackets) ? 'B' : '_');
|
||||||
sb.Append(this.RemoveIfAllExist(m_strHighAnsi) ? 'H' : '_');
|
sb.Append(RemoveIfAllExist(m_strHighAnsi) ? 'H' : '_');
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
@@ -303,16 +336,16 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
if(strRanges == null) { Debug.Assert(false); return; }
|
if(strRanges == null) { Debug.Assert(false); return; }
|
||||||
if(strRanges.Length < 10) { Debug.Assert(false); return; }
|
if(strRanges.Length < 10) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
if(strRanges[0] != '_') this.Add(PwCharSet.UpperCase);
|
if(strRanges[0] != '_') Add(PwCharSet.UpperCase);
|
||||||
if(strRanges[1] != '_') this.Add(PwCharSet.LowerCase);
|
if(strRanges[1] != '_') Add(PwCharSet.LowerCase);
|
||||||
if(strRanges[2] != '_') this.Add(PwCharSet.Digits);
|
if(strRanges[2] != '_') Add(PwCharSet.Digits);
|
||||||
if(strRanges[3] != '_') this.Add(m_strSpecial);
|
if(strRanges[3] != '_') Add(m_strSpecial);
|
||||||
if(strRanges[4] != '_') this.Add(PwCharSet.Punctuation);
|
if(strRanges[4] != '_') Add(PwCharSet.Punctuation);
|
||||||
if(strRanges[5] != '_') this.Add('-');
|
if(strRanges[5] != '_') Add('-');
|
||||||
if(strRanges[6] != '_') this.Add('_');
|
if(strRanges[6] != '_') Add('_');
|
||||||
if(strRanges[7] != '_') this.Add(' ');
|
if(strRanges[7] != '_') Add(' ');
|
||||||
if(strRanges[8] != '_') this.Add(PwCharSet.Brackets);
|
if(strRanges[8] != '_') Add(PwCharSet.Brackets);
|
||||||
if(strRanges[9] != '_') this.Add(m_strHighAnsi);
|
if(strRanges[9] != '_') Add(m_strHighAnsi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,8 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
@@ -250,14 +253,15 @@ namespace ModernKeePassLib.Cryptography.PasswordGenerator
|
|||||||
if((ch >= 'A') && (ch <= 'Z')) pcs.Add(PwCharSet.UpperCase);
|
if((ch >= 'A') && (ch <= 'Z')) pcs.Add(PwCharSet.UpperCase);
|
||||||
else if((ch >= 'a') && (ch <= 'z')) pcs.Add(PwCharSet.LowerCase);
|
else if((ch >= 'a') && (ch <= 'z')) pcs.Add(PwCharSet.LowerCase);
|
||||||
else if((ch >= '0') && (ch <= '9')) pcs.Add(PwCharSet.Digits);
|
else if((ch >= '0') && (ch <= '9')) pcs.Add(PwCharSet.Digits);
|
||||||
else if((@"!#$%&'*+,./:;=?@^").IndexOf(ch) >= 0) pcs.Add(pcs.SpecialChars);
|
else if(PwCharSet.SpecialChars.IndexOf(ch) >= 0)
|
||||||
|
pcs.Add(PwCharSet.SpecialChars);
|
||||||
else if(ch == ' ') pcs.Add(' ');
|
else if(ch == ' ') pcs.Add(' ');
|
||||||
else if(ch == '-') pcs.Add('-');
|
else if(ch == '-') pcs.Add('-');
|
||||||
else if(ch == '_') pcs.Add('_');
|
else if(ch == '_') pcs.Add('_');
|
||||||
else if(ch == '\"') pcs.Add(pcs.SpecialChars);
|
else if(PwCharSet.Brackets.IndexOf(ch) >= 0)
|
||||||
else if(ch == '\\') pcs.Add(pcs.SpecialChars);
|
pcs.Add(PwCharSet.Brackets);
|
||||||
else if((@"()[]{}<>").IndexOf(ch) >= 0) pcs.Add(PwCharSet.Brackets);
|
else if(PwCharSet.HighAnsiChars.IndexOf(ch) >= 0)
|
||||||
else if((ch >= '~') && (ch <= 255)) pcs.Add(pcs.HighAnsiChars);
|
pcs.Add(PwCharSet.HighAnsiChars);
|
||||||
else pcs.Add(ch);
|
else pcs.Add(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,522 +18,117 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
#if !KeePassLibSD
|
|
||||||
namespace ModernKeePassLib.Cryptography
|
namespace ModernKeePassLib.Cryptography
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Bloom filter-based popular password checking.
|
|
||||||
/// </summary>
|
|
||||||
public static class PopularPasswords
|
public static class PopularPasswords
|
||||||
{
|
{
|
||||||
private const int PpcTableSize = 8192 * 8; // Bits, multiple of 64
|
private static Dictionary<int, Dictionary<string, bool>> m_dicts =
|
||||||
|
new Dictionary<int, Dictionary<string, bool>>();
|
||||||
|
|
||||||
// Bits set: 32433 of 65536
|
internal static int MaxLength
|
||||||
// Hash functions: 32
|
{
|
||||||
// Phi (bits unset ratio) estimation: 0.505455388896019
|
get
|
||||||
// Exact Phi: 0.505111694335938
|
{
|
||||||
// False positives ratio: 1.67583063859565E-10
|
Debug.Assert(m_dicts.Count > 0); // Should be initialized
|
||||||
private static readonly ulong[] PpcTable = {
|
|
||||||
0x60383D3A85560B9BUL, 0x2578CE9D37C6AEB7UL, 0xF509A5743FD03228UL,
|
int iMaxLen = 0;
|
||||||
0x19B7455E8933EE56UL, 0x5EA419ADCFD9C20EUL, 0xEA618EFC0B37A162UL,
|
foreach(int iLen in m_dicts.Keys)
|
||||||
0xE0FD4D1FFF1CE415UL, 0x7A649E0301BB6060UL, 0x80D9CD9F9EEB603DUL,
|
{
|
||||||
0x47D6010D0D6E6CDEUL, 0x2552708C589EB554UL, 0x073F1A3DB3267502UL,
|
if(iLen > iMaxLen) iMaxLen = iLen;
|
||||||
0x3313FEC2A2FEA475UL, 0x4593665C44934FEBUL, 0x410A301A23660395UL,
|
}
|
||||||
0x6AD06DA533FF5659UL, 0x423DAF86F3E41F4AUL, 0x82F035A971C6FD18UL,
|
|
||||||
0xB5E9139F28C93223UL, 0x1D07C3F4160585CAUL, 0x24B01EDB6B23E2C5UL,
|
return iMaxLen;
|
||||||
0xD52F25B724F936C9UL, 0x8018392517836928UL, 0x3AA4C0F8E181EDA2UL,
|
}
|
||||||
0x8D93683EF7D52529UL, 0x6164BB6208114460UL, 0x737A04D8FEF3D88FUL,
|
}
|
||||||
0x3400097098D5C2CBUL, 0x3C2B9ABE5C455B2EUL, 0x3A3819973AB32DA2UL,
|
|
||||||
0x38ACB428510AF40BUL, 0x83320D5114B74771UL, 0xC25BEC333B90DCD1UL,
|
internal static bool ContainsLength(int nLength)
|
||||||
0x0E9F412FBA3813D1UL, 0x047E31E3098EB2B8UL, 0xBB686AC643F1741FUL,
|
{
|
||||||
0x0BE22E9C0EF0E8F2UL, 0x65AA9504E5F40D31UL, 0xE018DF5D64C62AC7UL,
|
Dictionary<string, bool> dDummy;
|
||||||
0x17020E9A7EFA12EDUL, 0xFC12A7C16006DE82UL, 0x8DE4747E3745346DUL,
|
return m_dicts.TryGetValue(nLength, out dDummy);
|
||||||
0x31D8C051A43CECAFUL, 0xBE9AFBEF127C1B12UL, 0xAEE94B4B808BBEE2UL,
|
}
|
||||||
0x3A0099CA32835B41UL, 0x59EB3173468D8C49UL, 0x6F89DB1E6DAAE9E1UL,
|
|
||||||
0x4C1ADAA837E968E4UL, 0x6E3593A56C682769UL, 0x022AD591689B5B82UL,
|
|
||||||
0x4AC33861ED978032UL, 0xF6F476E4E6A1318DUL, 0x2DA690A11AA05A23UL,
|
|
||||||
0x916FC56378C29D77UL, 0xAB3238BE22294659UL, 0x2D73A29019B28C77UL,
|
|
||||||
0xAAF26C12EC9C3C42UL, 0x058A278A24B334F9UL, 0x033BD18FB8D9BACDUL,
|
|
||||||
0x8B3833596008B07CUL, 0x280B6D093333E5E5UL, 0x2128DBE126CA3E1EUL,
|
|
||||||
0xCCF09769382472D8UL, 0x0CB6E495BD90CED6UL, 0x1303A37577C01C5AUL,
|
|
||||||
0xC8BBF4734FC34C53UL, 0x1B38B72B10F86CD5UL, 0x5098E2D6C1892E51UL,
|
|
||||||
0x2DD8065B79DB5380UL, 0x5B9A1A6D6A2292B7UL, 0xC70F751604D0497CUL,
|
|
||||||
0x911E08D7363B5213UL, 0x9F2E245273308D2EUL, 0x64D354827957F50EUL,
|
|
||||||
0x09856750F560342CUL, 0xDE091F26603F0E70UL, 0xDDE6B4E76173E3B1UL,
|
|
||||||
0xC1584AE1B26FA08EUL, 0x1EA29887837838D2UL, 0x6D7643FC67B15C54UL,
|
|
||||||
0x921E60571ED103EAUL, 0x63EB1EB33E7AFFF1UL, 0x80BA4D1F95BFD615UL,
|
|
||||||
0xEC8A1D4FC1A6B8E0UL, 0x2C46861B6DB17D1AUL, 0x01F05D06927E443BUL,
|
|
||||||
0x6172EC2EABEAD454UL, 0x21B8726C6F7C4102UL, 0x3C016CD9945C72ECUL,
|
|
||||||
0x708F77B2C0E8B665UL, 0xFC35BE2BB88974DAUL, 0x805897A33702BD61UL,
|
|
||||||
0x9A93367A6041226CUL, 0xFDAB188B6158F6BEUL, 0x5F21014A065E918CUL,
|
|
||||||
0xF4381DD77772D19CUL, 0xC664B6358AA85011UL, 0xF2639D7B3E2307E6UL,
|
|
||||||
0x3FA000D4A5A9C37AUL, 0x8F45D116ED8DC70FUL, 0x8CB8758E45C140D0UL,
|
|
||||||
0x49832B46D716236DUL, 0xCC8E4961A93065B8UL, 0x8A996533EDACEB0EUL,
|
|
||||||
0x15B35155EC56FAC1UL, 0xE7E0C6C05A9F1885UL, 0x05914F9A1D1C79F9UL,
|
|
||||||
0x730000A30B6725F0UL, 0xC95E671F8E543780UL, 0x47D68382400AF94EUL,
|
|
||||||
0x1A27F2734FE2249AUL, 0x828079C332D9C0ABUL, 0x2E9BC798EA09170EUL,
|
|
||||||
0x6B7CDAC829018C91UL, 0x7B89604901736993UL, 0xABE4EB26F47608F0UL,
|
|
||||||
0x70D5FDC88A0FF1B1UL, 0x5A1F0BAB9AB8A158UL, 0xDC89AE0A735C51A4UL,
|
|
||||||
0x36C1EA01E9C89B84UL, 0x3A9757AF204096DBUL, 0x1D56C8328540F963UL,
|
|
||||||
0x910A8694692472FAUL, 0x697192C9DF145604UL, 0xB20F7A4438712AA2UL,
|
|
||||||
0xE8C99185243F4896UL, 0xFBC8970EDBC39CA7UL, 0x33485403868C3761UL,
|
|
||||||
0xAFA97DDEDB1D6AD8UL, 0x54A1A6F24476A3BBUL, 0xFE4E078B184BDB7FUL,
|
|
||||||
0x5ED1543919754CD8UL, 0x86F8C775160FC08CUL, 0x9B4098F57019040DUL,
|
|
||||||
0x039518BBE841327BUL, 0x111D0D420A3F5F6AUL, 0x0666067346AF34ACUL,
|
|
||||||
0xD43F1D14EB239B9BUL, 0xA6BB91FEB5618F5BUL, 0xA2B5218B202409ADUL,
|
|
||||||
0xC004FA688C3AC25EUL, 0xF0E2D9EA2935E1DCUL, 0x380B31CFA2F2AF43UL,
|
|
||||||
0x50E050AE426250EAUL, 0x628ED94D1AA8F55BUL, 0xF8EB0654F0166311UL,
|
|
||||||
0x1F8858D26DDA5CC5UL, 0x931425D11CB1EFEBUL, 0xF661D461DC1A05D3UL,
|
|
||||||
0x7B75ED7EC6936DA8UL, 0x8713C59690985202UL, 0xF61D6F93F07C0E85UL,
|
|
||||||
0xFD1771F6711D6F4FUL, 0x5835A67E1B11419FUL, 0x33EF08ABD56A1050UL,
|
|
||||||
0x55B5D0043FA2C01CUL, 0x53316ED963B92D9DUL, 0x6A8C93744E521EDBUL,
|
|
||||||
0x083E948062EB9543UL, 0x1C15289B3189AFB1UL, 0xA6A0A5053AE2212DUL,
|
|
||||||
0x6573AF7F01FAFF3BUL, 0x58B6F034CFCFE843UL, 0xEB2837CA5AEA6AEDUL,
|
|
||||||
0x633E7897097AC328UL, 0x7FA91789B6CCEE82UL, 0xBEE2402F4E7D65EEUL,
|
|
||||||
0x616A103EC8FB0DBEUL, 0x65991F9FB25E13FCUL, 0x54EA8A3FADEC1F4BUL,
|
|
||||||
0x6D497C5ACDEA0E7AUL, 0x5865045E8CA18527UL, 0xA406C09215ABD61FUL,
|
|
||||||
0x68F81F5745FC9875UL, 0xE496D850CEFF3FA9UL, 0xD225C88D63212CB1UL,
|
|
||||||
0x37676390525116D2UL, 0x415614AB14188A7DUL, 0xABE58EBC1F6DDC63UL,
|
|
||||||
0xDE10312B2C25D28CUL, 0x86C86D7A0B847635UL, 0x408B511D584DC3DCUL,
|
|
||||||
0x6711FCC14B303FEDUL, 0x1284DF9CC6972023UL, 0xC3CE0B33141BFA8FUL,
|
|
||||||
0x0F3F58367D4A1819UL, 0x9313F83058FBE6D0UL, 0x6FCA5EF39B8E2F47UL,
|
|
||||||
0xA90F5C95D887756DUL, 0x96C4E2AD85D5AF6EUL, 0x0ED68A81F526F0A0UL,
|
|
||||||
0x53E4472DB4255A35UL, 0xAC581015134D58A6UL, 0x12C000D85C644FC7UL,
|
|
||||||
0x124D489B2C0FE6E4UL, 0x8FF83531C6F5D61AUL, 0x132BD6488304F73BUL,
|
|
||||||
0x110E99BC59604CB9UL, 0xC28186ACBC940C9BUL, 0x2094C07F48141230UL,
|
|
||||||
0x65FB9881A5053589UL, 0x940A3E6D72F09D69UL, 0x972A922CB14BA66EUL,
|
|
||||||
0x8D07E59C6DDD4327UL, 0xCB67F993F820157CUL, 0x65B7A54E5FB2ED6CUL,
|
|
||||||
0xC235828849576653UL, 0xA695F85479467538UL, 0x9E2BA885E63C4243UL,
|
|
||||||
0xDE64A6A5EF84C222UL, 0xC2AB9AF302080621UL, 0x88DBA09B87FA0734UL,
|
|
||||||
0xDF002765B44D02E1UL, 0xD50D8D90587CD820UL, 0x1B68B70ED179EFE1UL,
|
|
||||||
0xD6E77F8EC26AE95CUL, 0xEE57EB7C45051872UL, 0x4D2B445F36A7F9FDUL,
|
|
||||||
0x5502ABB8BB14D7F1UL, 0xAF2C0DF0406FA901UL, 0x6522833444BF4A83UL,
|
|
||||||
0xD7CB2E3FC691BE8DUL, 0x4F36F70D2E80D19AUL, 0xF6945FE911D4923BUL,
|
|
||||||
0xE3C6FE1EA47399C1UL, 0xF09EA1B2F837702CUL, 0x5122537CF97B5CB5UL,
|
|
||||||
0x0C8202B70E9BF154UL, 0x68B554AB58EB5E68UL, 0x7BF9B8052C9BEADEUL,
|
|
||||||
0x33612BFCD303810DUL, 0x03E38CF67B37DC53UL, 0x2BFDFF8691F37D5CUL,
|
|
||||||
0x4AB483D1CB1D07F6UL, 0xF071A58640639A5CUL, 0x9D6B98169B745CE1UL,
|
|
||||||
0x5F42D3E870FDCD93UL, 0x4EDF04404F258238UL, 0x2EAB6E10D65C9BB3UL,
|
|
||||||
0x5BB71411EF78DAD2UL, 0x0DE8128636A5D689UL, 0x18FDD1F484DC9365UL,
|
|
||||||
0x9896B8896941DA5BUL, 0x8BEF8E3BA4448E5FUL, 0x963A1E977CB1D2CAUL,
|
|
||||||
0x02BCF5F068D52851UL, 0x0CD783F09BFBE381UL, 0x350DA833D8C5DB47UL,
|
|
||||||
0x8D444C914D795C43UL, 0x8A00B4DFC44D9476UL, 0x4B36CBEC089E55FDUL,
|
|
||||||
0xD9D2FA1B0AC66211UL, 0x6C7FC30FA31A8B60UL, 0x9EF4504CC985AD6BUL,
|
|
||||||
0x8F2E7E5E0C00EE73UL, 0x819131CFEEBEA069UL, 0xB1E406A863E7A1B4UL,
|
|
||||||
0x501F072FF1F2AB67UL, 0xDE578BFC5ADBC264UL, 0xCDD66A09C8E13881UL,
|
|
||||||
0x4D443460CE52957FUL, 0x3B198C267976ECFAUL, 0x6B98323D8BD26522UL,
|
|
||||||
0x80161F6A489E4BF8UL, 0xE03A8AFCC7AE6872UL, 0x2484BD95A305AB27UL,
|
|
||||||
0x6ADDAA46BF25DD0EUL, 0xA429D8B00100477CUL, 0x55AEDB88A074BF2CUL,
|
|
||||||
0x63D9F9021AB8F5F3UL, 0x37858538A10C265CUL, 0xEF54C2CE9D063149UL,
|
|
||||||
0xFA5CE5AF33E2C136UL, 0xE601A559D0C391D7UL, 0x7C4ED29BBF57DC7EUL,
|
|
||||||
0x8FD0D4146DE9E900UL, 0xB58ABFA6CE6C0733UL, 0xF8D7F7743B33EAFFUL,
|
|
||||||
0x453FA782F454643CUL, 0xD01752C21AF21E66UL, 0xA50BB7913EAF05DFUL,
|
|
||||||
0x966D5B140B2F4189UL, 0x956F5638AFF3D148UL, 0x93FAA838420E8AB3UL,
|
|
||||||
0x715E26043071EABDUL, 0x01E7B458B5FD3A41UL, 0x5CFA99C4CC0492AAUL,
|
|
||||||
0x761FD391C3623044UL, 0xD39E44E9DB96B5BCUL, 0x8806C544F0534A07UL,
|
|
||||||
0x9B225CAFE97EAAC1UL, 0xEAE5E18583492767UL, 0x6B4E51E4C297F096UL,
|
|
||||||
0xFC512662EF47E41DUL, 0xB6AC60427DB46F8BUL, 0x8F137F3DB4429C9DUL,
|
|
||||||
0x04C65FBEAE9FD8D0UL, 0xEB72305958AE5022UL, 0xAA93AA14BCA2961EUL,
|
|
||||||
0x6C7547F9456CA37AUL, 0xEE6094871615BA34UL, 0x489BC8EDE0940402UL,
|
|
||||||
0x1108AEFAAD892229UL, 0x673B8B1CF6BED23EUL, 0xFDB781A75FD94DEAUL,
|
|
||||||
0x11D9E0F5D914A7BEUL, 0x02830D07F018143DUL, 0x9B3163B8188FD2BAUL,
|
|
||||||
0x32C1BEC97D06117EUL, 0x697268B761240CFFUL, 0xBD89CE3037C2E7A9UL,
|
|
||||||
0xF21C158125B19600UL, 0x632CB1931601B70AUL, 0x7BB3FB131338085CUL,
|
|
||||||
0xA9C06689B8138384UL, 0x161CCBF83EBDC2A1UL, 0x2CF83C01A80B7935UL,
|
|
||||||
0x9E51FE393B8E2FF0UL, 0xFE96E52B1606C1A7UL, 0x5E20DFB87F81ACCEUL,
|
|
||||||
0xF95DB9602CDAE467UL, 0xDEA155CD35555FEBUL, 0xF0669B810F70CDC6UL,
|
|
||||||
0xD36C2FBEB6A449ACUL, 0xCE500C6621C0A445UL, 0x41308909E366460AUL,
|
|
||||||
0xAC4D8178DA0CEC24UL, 0xC69049179ED09F7DUL, 0x36B608A0BA2FD848UL,
|
|
||||||
0xDF511894DD9568B4UL, 0xB3BFDF78EC861A6CUL, 0xCD50F39D19848153UL,
|
|
||||||
0xD2C1BC57E78A408CUL, 0x1E6613EFBB11B5EBUL, 0xF58E30D2D90F73D3UL,
|
|
||||||
0xCCB5E2F5E168D742UL, 0xEE97259469BDB672UL, 0x6784D35AF65935A8UL,
|
|
||||||
0x71032765ADED1FE8UL, 0x4BBF2FE54D9B72E3UL, 0x5A1BB7831E876A05UL,
|
|
||||||
0x12A8FC949EE91686UL, 0x8296F8FA83BD112CUL, 0xAAA7E3BFF64D34D5UL,
|
|
||||||
0x0301655E1794EE4BUL, 0x1E547C011BBF30E1UL, 0x39D74FEC536F31D6UL,
|
|
||||||
0x3C31A7478B1815BAUL, 0x525C774F82D5836EUL, 0xECF7186DC612FD8CUL,
|
|
||||||
0x96B7C4EDD1F3536FUL, 0x7E8C21F19C08541CUL, 0xEE92DB0CF91E4B09UL,
|
|
||||||
0xF666190D1591AE5DUL, 0x5E9B45102C895361UL, 0x9A95597AAE5C905DUL,
|
|
||||||
0x6E1272E5BB93F93FUL, 0x0E39E612402BFCF8UL, 0x576C9E8CA2A3B35EUL,
|
|
||||||
0x7E2E629996D0C35FUL, 0xC95DFF54E3524FCCUL, 0x260F9DEBDEB0E5CBUL,
|
|
||||||
0x577B6C6640BAF1ABUL, 0xCA76677779CA358EUL, 0x9E2714BEBCFDB144UL,
|
|
||||||
0xD660595CE30FD3EEUL, 0x72DE172D55A5706EUL, 0xB4C84D564489D420UL,
|
|
||||||
0x160AA2B9399D5A9DUL, 0x2906ECE619DAC4D2UL, 0x12CE8E8E68A4C317UL,
|
|
||||||
0x6BE2DFE89901CAA1UL, 0xEE1D68158102EB77UL, 0x64EB75E45BDA1AC5UL,
|
|
||||||
0xEFECF9F98720B55DUL, 0x41CDF813931315BFUL, 0x5F1E4F50CF98FFD4UL,
|
|
||||||
0xE69E09EED12E173BUL, 0x89A3707F0396FF65UL, 0x81E36B9DF4FFB492UL,
|
|
||||||
0x58C32E883D4DE6DDUL, 0x2D4725C2A5F0B469UL, 0x6B2B9C27CC421CACUL,
|
|
||||||
0x3C30F2AD966800C7UL, 0xFF74938BB76B8A7CUL, 0x52B5C99114FD93FAUL,
|
|
||||||
0x51647EDCA6C104DAUL, 0xEB47684CF796DF4EUL, 0x376D74A5AB14BD71UL,
|
|
||||||
0xF0871FEF8E9DAA3EUL, 0x1D65B134B2E045B6UL, 0x9DC8C0D8623BBA48UL,
|
|
||||||
0xAD6FC3C59DBDADF4UL, 0x66F6EBA55488B569UL, 0xB00D53E0E2D38F0AUL,
|
|
||||||
0x43A4212CEAD34593UL, 0x44724185FF7019FFUL, 0x50F46061432B3635UL,
|
|
||||||
0x880AA4C24E6B320BUL, 0xCAFCB3409A0DB43FUL, 0xA7F1A13DEF47514BUL,
|
|
||||||
0x3DC8A385A698220CUL, 0xFA17F82E30B85580UL, 0x430E7F0E88655F47UL,
|
|
||||||
0x45A1566013837B47UL, 0x84B2306D2292804EUL, 0xE7A3AF21D074E419UL,
|
|
||||||
0x09D08E2C5E569D4DUL, 0x84228F8908383FA2UL, 0xC34079610C8D3E82UL,
|
|
||||||
0x66C96426C54A5453UL, 0xD41F164117D32C93UL, 0x7829A66BF1FEC186UL,
|
|
||||||
0x4BB6846694BDFC18UL, 0x857D1C1C01352C01UL, 0xAB8E68BA85402A45UL,
|
|
||||||
0x74B3C4F101FE76C8UL, 0x6CF482CFAFB29FFEUL, 0x28B174A18F4DC3D1UL,
|
|
||||||
0x833C3425B2AA3755UL, 0x8AA58A32747F4432UL, 0xFE7B9FB4BCE3CD58UL,
|
|
||||||
0xB0836B2C16FA5553UL, 0x1D08EE6861BF3F23UL, 0x0FAE41E914562DF3UL,
|
|
||||||
0xB10A2E041937FC57UL, 0xDA60BB363415BF4CUL, 0xEEC67DBAB4CF4F0AUL,
|
|
||||||
0x9A6ED59FCC923B5CUL, 0x9A913C01A8EC7A83UL, 0xAD4779F2F9C7721FUL,
|
|
||||||
0x2BF0B7D105BE7459UL, 0x189EFA9AD5195EC6UL, 0xB5C9A2DD64B2A903UL,
|
|
||||||
0x5BCD642B2C2FD32CUL, 0xFED3FBF78CB0891FUL, 0x1ED958EE3C36DD3FUL,
|
|
||||||
0x030F5DE9CA65E97CUL, 0xBB5BCF8C931B85FEUL, 0xFD128759EA1D8061UL,
|
|
||||||
0x2C0238AC416BE6BCUL, 0xBB018584EEACFA27UL, 0xCEA7288C1964DE15UL,
|
|
||||||
0x7EA5C3840F29AA4DUL, 0x5DA841BA609E4A50UL, 0xE53AF84845985EB1UL,
|
|
||||||
0x93264DA9487183E4UL, 0xC3A4E367AF6D8D15UL, 0xDD4EB6450577BAF8UL,
|
|
||||||
0x2AA3093EE2C658ACUL, 0x3D036EC45055C580UL, 0xDDEDB34341C5B7DFUL,
|
|
||||||
0x524FFBDC4A1FAC90UL, 0x1B9D63DE13D82907UL, 0x69F9BAF0E868B640UL,
|
|
||||||
0xFC1A453A9253013CUL, 0x08B900DECAA77377UL, 0xFF24C72324153C59UL,
|
|
||||||
0x6182C1285C507A9BUL, 0x4E6680A54A03CCC8UL, 0x7165680200B67F1FUL,
|
|
||||||
0xC3290B26A07DCE5BUL, 0x2AD16584AA5BECE9UL, 0x5F10DF677C91B05EUL,
|
|
||||||
0x4BE1B0E2334B198AUL, 0xEA2466E4F4E4406DUL, 0x6ECAA92FF91E6F1DUL,
|
|
||||||
0x0267738EFA75CADDUL, 0x4282ED10A0EBFCF2UL, 0xD3F84CE8E1685271UL,
|
|
||||||
0xB667ED35716CA215UL, 0x97B4623D70DB7FA8UL, 0xB7BA3AA5E6C2E7CBUL,
|
|
||||||
0x8942B2F97118255BUL, 0x009050F842FB52ADUL, 0x114F5511999F5BD5UL,
|
|
||||||
0x70C1CAAF1E83F00AUL, 0xAC8EE25D462BB1AAUL, 0x63EEF42AD4E1BED9UL,
|
|
||||||
0x58DFBB3D22D3D1A5UL, 0x82B0027C0C63D816UL, 0x48D038F08F3D848BUL,
|
|
||||||
0xCE262D5F9A12610EUL, 0xA54BF51C21BD0167UL, 0xF3645F6FB948397DUL,
|
|
||||||
0x9188AE58532DA501UL, 0xEC90B0E1479DB767UL, 0x37F4886B83724F80UL,
|
|
||||||
0x232B8FF20ACD95AFUL, 0x88A228285D6BCDF0UL, 0x321FB91600259AEEUL,
|
|
||||||
0xA1F875F161D18E5EUL, 0x5B6087CDA21AEA0CUL, 0x0156923ED1A3D5F1UL,
|
|
||||||
0xC2892C8A6133B5D3UL, 0x015CA4DF0EA6354DUL, 0x5E25EB261B69A7D4UL,
|
|
||||||
0xAAA8CF0C012EFBA7UL, 0xCF3466248C37868BUL, 0x0D744514BD1D82C0UL,
|
|
||||||
0xB00FF1431EDDF490UL, 0xC79B86A0E3A8AB08UL, 0xFC361529BC9F1252UL,
|
|
||||||
0x869285653FB82865UL, 0x9F1C7A17546339ABUL, 0xE31AA66DBD5C4760UL,
|
|
||||||
0x51B9D2A765E0FC31UL, 0x31F39528C4CD13D8UL, 0x16C6C35B0D3A341DUL,
|
|
||||||
0x90296B1B0F28E2CDUL, 0x36338472A8DB5830UL, 0xA648E6D44DF14F87UL,
|
|
||||||
0x93E231E65EB1823FUL, 0x95AA7B9D08E2B627UL, 0x7932D149374700C7UL,
|
|
||||||
0x09EFE0A8BF245193UL, 0x742AA63BCEAFD6D8UL, 0x82D4BC5FEDF158B7UL,
|
|
||||||
0x02CDEA673CFF150DUL, 0xD8D7B5813B602D15UL, 0xA5A7B670EF15A5EDUL,
|
|
||||||
0x4C08E580A1D46AF2UL, 0xC3CA9B905D035647UL, 0x6A39ABB02F6F1B83UL,
|
|
||||||
0xD2EC2169F4D02436UL, 0x8E6AEA4DF8515AF2UL, 0x7B3DD4A8693CA2DAUL,
|
|
||||||
0xC2ABF17A50AEC383UL, 0xD4FB84F8B6D4F709UL, 0x2839A3EAA2E4C8A7UL,
|
|
||||||
0x5D5FD278FE10E1E9UL, 0x5610DDF74125D5A7UL, 0xA484B0B83461DCEAUL,
|
|
||||||
0xA511920C0A502369UL, 0xC53F30C6A5394CA4UL, 0x528799285D304DD4UL,
|
|
||||||
0xF6D7914CB252BB48UL, 0x892129CB52E65D15UL, 0x15A81B70519ACE6FUL,
|
|
||||||
0x5CFBFFD7A2A1C630UL, 0x3B900509C82DF46DUL, 0x19C3CE05D66D5FFCUL,
|
|
||||||
0x937D521A4A4799A0UL, 0xD0AE34A6EAD7207DUL, 0x3258A69F1D1A1B38UL,
|
|
||||||
0xB173E3255723CC02UL, 0xD7E48FEF7F414F1BUL, 0xDCEBA75F5C761ABEUL,
|
|
||||||
0x6DA10C618DEA0D17UL, 0x423FA8B05954FBD1UL, 0x7E73C2E7D923F3C9UL,
|
|
||||||
0xC22E21C927C684D1UL, 0x756BAA758764685FUL, 0x8C90B4C4E741D880UL,
|
|
||||||
0x1B658C9F4B41D846UL, 0x5D80C14094366707UL, 0xB55FED3E03C00F2DUL,
|
|
||||||
0x9B69EB7964C69C83UL, 0x356ED81C9494DADDUL, 0x7599AFF0B2A339D6UL,
|
|
||||||
0xA5EBFD25C9B5816BUL, 0xA481DC1C8995E1EFUL, 0xE42C63DF0D402397UL,
|
|
||||||
0x3B497B4C30873BAAUL, 0xA950B78BA8772C96UL, 0xD46308D4C76F115DUL,
|
|
||||||
0x73714A4ACA76A857UL, 0x0DA86B958FF8CB7DUL, 0xEB61F617B90E0A75UL,
|
|
||||||
0xD6106C9B39F51F55UL, 0xB179F73A6BD23B59UL, 0xE7F056E50104A460UL,
|
|
||||||
0xBC5B5387634A8642UL, 0xE1678D8752996AF4UL, 0xB508F3D394664A4BUL,
|
|
||||||
0xC88536DC4A219B0FUL, 0x39964CBB8CE367B1UL, 0xD51E211D5E9E1417UL,
|
|
||||||
0x6821B97B496870F2UL, 0xA596257350CA0A99UL, 0x6D051EE2C49D4D1DUL,
|
|
||||||
0xCB426AD61AA8D9B5UL, 0x5FFD3A4062B06D22UL, 0xDAD37BF2A4C594EBUL,
|
|
||||||
0x6B9CC848E2B0C686UL, 0x19B4232F3BC622AEUL, 0x70C13C7E5950B702UL,
|
|
||||||
0x383318CA622101ACUL, 0xD9647C028CD1C4DFUL, 0x006D123BC553B93CUL,
|
|
||||||
0x2CA9D7D896EAE722UL, 0xF19872AC8A0BD5A8UL, 0x59838578EB9E8E5CUL,
|
|
||||||
0xB948621EE99B27D4UL, 0x2B470E6036E0E387UL, 0xD0A7E8F0C8A32A84UL,
|
|
||||||
0xCBF869271A8E0914UL, 0x705F76A5EA4437CFUL, 0xBAD2BF4933215152UL,
|
|
||||||
0xE52EDE847038EA23UL, 0xB8A3EFD3D58D7607UL, 0x748472F5AD330239UL,
|
|
||||||
0xCC079CFD428690F6UL, 0x3687450CB7534DACUL, 0x0FEF82D5CC8ACE2AUL,
|
|
||||||
0x214653D5C552CA9AUL, 0x9FCA4E87BF6A04FDUL, 0x78D4B114D234A0D7UL,
|
|
||||||
0x22840422BD6A5BB5UL, 0x5B9ABE0DE1B4410FUL, 0xB3B50007963FDD6BUL,
|
|
||||||
0x53A8A46793B68E35UL, 0x8CDD8E8D188B6033UL, 0x5DD22B6E3ED49572UL,
|
|
||||||
0xE561F5D27F5302D6UL, 0xDF89CEC3322E56CDUL, 0x87167F503D600F90UL,
|
|
||||||
0x1698BB71C8201862UL, 0xF7BF5DFDB023108EUL, 0xA17FB15B66ACFB5FUL,
|
|
||||||
0x2DD771987768073BUL, 0x19299D2D86E0EB29UL, 0x8B537B7F206EED29UL,
|
|
||||||
0xE536DA153325ABFCUL, 0x30A69976796DB3B9UL, 0x8E65A2C94E2D4981UL,
|
|
||||||
0xC301D53553BD6514UL, 0x46DF3639B9E43790UL, 0x3004CD0E5AFD0463UL,
|
|
||||||
0x46E460B0F6ACA1A0UL, 0xCBA210E7372D9BD5UL, 0x45064274A74CA582UL,
|
|
||||||
0xFDD57EA43CE631AEUL, 0xF2BA08FFA4A683D0UL, 0x8DA658C4DAD42999UL,
|
|
||||||
0x7418042943E88040UL, 0x96000F72E9371FEFUL, 0xE9F1212DC8F47302UL,
|
|
||||||
0x2AFB565ECC3553EDUL, 0xCD3D55137EFF7FD6UL, 0xD36F11059388E442UL,
|
|
||||||
0xC4B47515DB5709DDUL, 0x5C363EFBF0BAAB67UL, 0x28C63B5A31650BBBUL,
|
|
||||||
0x6AE54E5068061C81UL, 0xDEE62000F4E0AA21UL, 0xE8238672FE088A8BUL,
|
|
||||||
0x9869CB6370F075B9UL, 0xBA376E2FC7DB330FUL, 0xB0F73E208487CDEEUL,
|
|
||||||
0x359D5017BE37FE97UL, 0x684D828C7F95E2DCUL, 0x9985ECA20E46AE1FUL,
|
|
||||||
0x8030A5137D1A21C4UL, 0xF78CDC00FC37AC39UL, 0x41CDDC8E61D9C644UL,
|
|
||||||
0xB6F3CD1D833BAD1DUL, 0x301D0D858A23DE22UL, 0xA51FCA12AD849BC8UL,
|
|
||||||
0x9F55E615986AB10EUL, 0x904AAA59854F2215UL, 0x12ECEA4AB40F51A7UL,
|
|
||||||
0xB4EDF5807735E23BUL, 0x6190200F1C589478UL, 0xA3CA57F321909A5AUL,
|
|
||||||
0x0BFAEE04B7325B63UL, 0x10C393E7FBCF826DUL, 0x4050A2CA53FDA708UL,
|
|
||||||
0xF31114A9B462B680UL, 0x6FB9A6F121BA2006UL, 0x04550CF09389D602UL,
|
|
||||||
0xB8C7D6D8CA8942F7UL, 0x71BB430C6436E9D1UL, 0xD9070DD5FAA0A10AUL,
|
|
||||||
0x8FD6827757D07E5BUL, 0xD04E6C313F8FD974UL, 0x2CFDEA1187909B9AUL,
|
|
||||||
0xC7A8E758C115F593UL, 0xA79A17663009ACC2UL, 0x8091A6B5372B141DUL,
|
|
||||||
0xEB33B08767F5BA73UL, 0xDAC1F6823B6111C7UL, 0x697DF90C3515611BUL,
|
|
||||||
0xCC1005F198761F48UL, 0x5067E4F5303B45A1UL, 0x04816D292A2D9AC2UL,
|
|
||||||
0x2949C7A0874DD5E9UL, 0x25DB2547804CEE5EUL, 0x7EDC3A8946D6F229UL,
|
|
||||||
0x00B586F67FD0C622UL, 0x3CAE5798E40324E0UL, 0x0A4F1437DE637164UL,
|
|
||||||
0x5F59B2B715871981UL, 0x5D68FF31051E48FBUL, 0x0F2C369D73A2AA46UL,
|
|
||||||
0xB009C6B53DD23399UL, 0xC366A81277084988UL, 0x5AF0E0CA0711E730UL,
|
|
||||||
0x7AD831A9E9E854BAUL, 0x1DD5EDB0CA4E85AEUL, 0x54651209D259E9DDUL,
|
|
||||||
0x3EBB1D9DAB237EADUL, 0xDA96989317AC464CUL, 0xBFCB0F8FBC52C74EUL,
|
|
||||||
0x9597ACB9E27B692EUL, 0x6F436B1643C95B23UL, 0xB81A1253E1C3CD9DUL,
|
|
||||||
0x7B35F37E905EC67EUL, 0x29CE62666EDA76DDUL, 0xFF2490DC1EC4014DUL,
|
|
||||||
0x2D4FF9124DD6B5C4UL, 0xB9510FEC23E0E9D1UL, 0x8BCDBC56541ED071UL,
|
|
||||||
0x5414E097C1B0CCB2UL, 0x82BEF8213076F5C7UL, 0xE9FC9A71BD512615UL,
|
|
||||||
0xCF15ECC39490DF5AUL, 0x49FA9328D8EE97DBUL, 0x5F80FF0153BC2145UL,
|
|
||||||
0xF63BA156B55BCB02UL, 0x0E3B9113109FDF36UL, 0x8FCD6528F54EDE69UL,
|
|
||||||
0x5D6AE9C000054763UL, 0x326D873633431FBBUL, 0x380E07FFCEF7A978UL,
|
|
||||||
0xDCAA09874A1DF230UL, 0x601494F49F6D261EUL, 0x856159486C9B60E3UL,
|
|
||||||
0x85C7F822D07089A5UL, 0xAFFB99CF5AB836C2UL, 0x241AD414FBBB956BUL,
|
|
||||||
0x0CFC042822831692UL, 0x382B16D049727FF2UL, 0x784F9997633C819AUL,
|
|
||||||
0x5C40ED725F6C390AUL, 0x2CE78B7A3331BA9CUL, 0x9C80636639963B41UL,
|
|
||||||
0x1B2D41C968355018UL, 0xD189B57691FB60E4UL, 0x3BD599A9DD85CE31UL,
|
|
||||||
0x46FC8E2EF0B9A77CUL, 0x1A389E07D0075EA4UL, 0x1622CA52401DF2ACUL,
|
|
||||||
0x528F3FF9B7993BFAUL, 0xF16C176CCA292DDBUL, 0x6C154010961EF542UL,
|
|
||||||
0x04B78E92BF6C82DFUL, 0x7D9AFEA6ABB46072UL, 0x3BC573291CBFFC2EUL,
|
|
||||||
0x277FFF096D567AF3UL, 0x1CBEB86841A6F757UL, 0xD0BCD49E76CA20A7UL,
|
|
||||||
0x25B6024756B1FE90UL, 0xE685C04EF84881FBUL, 0xDCAB14B352FC442EUL,
|
|
||||||
0x4FF80A521719953DUL, 0xD10425E411DBE94BUL, 0x60998D0507D6E38DUL,
|
|
||||||
0x146AA432C981BD5EUL, 0x1729A596282AAA41UL, 0x152BE1A263BAF963UL,
|
|
||||||
0x15278DF497D254CAUL, 0xE4B5E9891E88A5DAUL, 0x087FA3472067D0ACUL,
|
|
||||||
0xD99C2899A0AD9158UL, 0x5040F234DC531236UL, 0x9D7E1531259EEE90UL,
|
|
||||||
0x29AFB8B49391036EUL, 0x84B619599642D68EUL, 0xE838AAE0F249545CUL,
|
|
||||||
0x42D524BA8BB96959UL, 0x9A5B3E817A20EE59UL, 0x584F0530EC4C566BUL,
|
|
||||||
0xD6544FD14B47F945UL, 0x3613FB3B553A7CDEUL, 0x284E92B56831AA56UL,
|
|
||||||
0xCEE89BA10E951A22UL, 0x476806FA1A8A44E0UL, 0xC84CEF151885C1DFUL,
|
|
||||||
0x3DB1D5C1B0B73936UL, 0x45D2D90FDF452388UL, 0x038A7DD71BC5DD21UL,
|
|
||||||
0x2AC90C7422C56819UL, 0x4742046638ECE0FBUL, 0x553B44360FC8495DUL,
|
|
||||||
0xC8DBA1CF3F9A6E97UL, 0xF85919F494CAB021UL, 0x1479455C2FF236AFUL,
|
|
||||||
0x29BCAD159F7D018DUL, 0x016DFF51CBA3BCC5UL, 0x234BF8A77F6B1CF5UL,
|
|
||||||
0x20564C6F44F9E641UL, 0x063A550C5AA50FA8UL, 0xB063D0AAAA96DFECUL,
|
|
||||||
0x3EC659DF42C092F8UL, 0x29D4A76A5A5F7E09UL, 0x65EFF3EE6E691D1EUL,
|
|
||||||
0xBD1634F5721CF799UL, 0xE85BD016723B43FFUL, 0x5233E9E7AEA11022UL,
|
|
||||||
0x8C68852EA9039B4CUL, 0x2C978ADBE885BC15UL, 0x726615ED9D497550UL,
|
|
||||||
0x7C1E145EB8D2BD96UL, 0xC2FEFB25935A5D71UL, 0x9EE9C3E1C3DE416FUL,
|
|
||||||
0xFFD568A03E20E0B3UL, 0xF53649AD90156F2AUL, 0x0331B91DCE54E7EDUL,
|
|
||||||
0x67CED5A86E99392FUL, 0x16FC0A5815500B05UL, 0x030392E8D24A7C00UL,
|
|
||||||
0x232E5E31DF32A7B5UL, 0xCC8BF22B1947DF21UL, 0x4EC2C72D9C1EEABDUL,
|
|
||||||
0x0B1B79F45220E668UL, 0xCC3CF0EE9C4A899BUL, 0xFC260A60592EBC80UL,
|
|
||||||
0xC1989A0382CB03EDUL, 0x35FE679A6CD800B2UL, 0x8A6B1ADE4FBB162FUL,
|
|
||||||
0xB0FD284563625295UL, 0xCDCC1C7B2181D024UL, 0x5B8BA0C895C0BB23UL,
|
|
||||||
0xA681FEA9ADCD43DBUL, 0x0FE30FB6876DE718UL, 0x6DDD1E27B769C494UL,
|
|
||||||
0x83A1E58460FFE8BBUL, 0x8FAD6FD2DC90FF65UL, 0x41BB28B81201CB24UL,
|
|
||||||
0xA148CE79B2597204UL, 0x7CB87DF97BB477A6UL, 0x9F79E6DED87DC688UL,
|
|
||||||
0xE044D84A6C758171UL, 0x1A29E750D9EC4097UL, 0x8445FC2B80C4A0F5UL,
|
|
||||||
0x5EFD9784AFED4ED2UL, 0x344C252BD90EB0E4UL, 0xEAD18D2E4418E5B5UL,
|
|
||||||
0x207EF4FFC260BD24UL, 0xD2E5C3AE534EC538UL, 0x2F5A59BF3D10E7E1UL,
|
|
||||||
0x9528E29266C2924CUL, 0x0121B6BDAB45D138UL, 0xADD0256ACBC771DDUL,
|
|
||||||
0x7301769600C6C50DUL, 0x3E7404EA8231D497UL, 0xB39B3840B8D03117UL,
|
|
||||||
0x56EFCEDDEF5B6634UL, 0xE6BE2C0D73B72098UL, 0x5A2841A21A5E4959UL,
|
|
||||||
0xCFEB3586156DF6E0UL, 0xD84F58901E2D65B8UL, 0x79796786CCC59703UL,
|
|
||||||
0x13BFA9A94DD07696UL, 0x7B63116A6B5458B6UL, 0x1406628176C932E0UL,
|
|
||||||
0xDD7ACC4E97F91B1AUL, 0xC82B8F84A56BDBE8UL, 0x325D87D08ED8B0B0UL,
|
|
||||||
0x3F7847B1E82002DDUL, 0x4662900D2ADAF6BFUL, 0x12AE9F58561DB1D7UL,
|
|
||||||
0xA896E956A95CC074UL, 0xAA4FA3A2F8BA4084UL, 0x1D577E35F5DCA67FUL,
|
|
||||||
0x796FF2D75469DEC2UL, 0xBD3F3F87E4DE894EUL, 0x3666B2262DEBFB6BUL,
|
|
||||||
0x1E26D7AEEF976C2EUL, 0x6BC3854F867AC4A0UL, 0x743DBF8C2E95A821UL,
|
|
||||||
0xA62A76B9AE2E645AUL, 0xB4D76561F40187C1UL, 0xD3E5F23F9FA5DB25UL,
|
|
||||||
0x34B1F6B39E6A87E2UL, 0x7DA5C3DFF7BE72CFUL, 0xFDF46B1BE80AD4F9UL,
|
|
||||||
0x0B21121CA9653B8AUL, 0x1199CA9D0A90F21AUL, 0x6021EA302D01E0BAUL,
|
|
||||||
0x8101D063C05CF5D4UL, 0xE2652410DFE78F23UL, 0x84095ACF47C21A25UL,
|
|
||||||
0xD7E29A4DB2FD3A99UL, 0x7793C0CB57959F93UL, 0x94C605308B9E5AA7UL,
|
|
||||||
0x943DB1AC54165B8FUL, 0xC1391A544C07447CUL, 0x3FEF1A61F785D97BUL,
|
|
||||||
0x6DFCC3152478BDE4UL, 0x312AFB0E1982933AUL, 0xB8069C2605631ED3UL,
|
|
||||||
0x5A6076423430BED2UL, 0x34E379F09E2D4F42UL, 0x9167F5E4019573E3UL,
|
|
||||||
0x18F81157828D2A49UL, 0xF4A8723B4955EAB8UL, 0x0BE6C0ABFEA9E8A6UL,
|
|
||||||
0xC63ADCF2CEF25556UL, 0xC5EBD3BEAE9F364FUL, 0xA301D60CF5B6F2FCUL,
|
|
||||||
0x8C606CA881D27A00UL, 0x826FEE13B554C18AUL, 0x8DF251716F10B776UL,
|
|
||||||
0xB2573A33AC7D94FFUL, 0xC0E771248CB7ABB9UL, 0x753DD605DB38F4EAUL,
|
|
||||||
0x21901664C3D92114UL, 0xA408FCB7A1892612UL, 0x3084FC64A03D6722UL,
|
|
||||||
0xC8C9D9569AD42A34UL, 0x1FBFBAFC1694B383UL, 0x1894280CC3F94ABEUL,
|
|
||||||
0xE14C38A7BBB54651UL, 0x23A48CC84A6EB704UL, 0xD034ADC45AABEDBDUL,
|
|
||||||
0xC93F2C21C973C766UL, 0x66A8AEC11D743CC6UL, 0xB4F72AA52E37C145UL,
|
|
||||||
0xB02834DF0D9266B4UL, 0xDB8E724EA1FF402FUL, 0x531E9C058112E352UL,
|
|
||||||
0xC2F692531DB317D2UL, 0xEFC9586498D263A7UL, 0x84F2C524D2F3ADB9UL,
|
|
||||||
0xAFAF02C27CF25D08UL, 0x385873595F9CFC09UL, 0x36DDA10D1A152B7AUL,
|
|
||||||
0x9F9B997A0DACFB55UL, 0x10AB5EB5C4714882UL, 0x7BA4E8703E22B7EEUL,
|
|
||||||
0x0A2BFD558607BCC8UL, 0x201D3706F74F8BA1UL, 0x3DBD573B1358F02EUL,
|
|
||||||
0x5B37645FA93BCEBCUL, 0xC0166864BC1A7544UL, 0x45C7AA5559FC65D7UL,
|
|
||||||
0xEFEA04AA83349B78UL, 0x607859194F9E9FD8UL, 0xA6B9AE5B53CF7710UL,
|
|
||||||
0x73B9142ACBC50821UL, 0x8B7D67495887E65CUL, 0x39B6C4FB2B232E56UL,
|
|
||||||
0xD212DB10E31D2A68UL, 0x629AC0A3D263DC6EUL, 0x6BC2E7FF912050BAUL,
|
|
||||||
0xE0AD5A8FDB183F62UL, 0xF05648134F0C6F0FUL, 0x31E146F4AF980FDAUL,
|
|
||||||
0x7FAF0078D84D62CCUL, 0xE13F044C2830D21EUL, 0x49A047AD204B4C4BUL,
|
|
||||||
0xF3AFBE2237351A74UL, 0x32826C9217BB07EDUL, 0xD4C3AEB099319B5CUL,
|
|
||||||
0x49CE5BD05B2B0F61UL, 0x75DD36984DCBD0A2UL, 0x84EC5D7C2F0AAC6CUL,
|
|
||||||
0x8E59CC9B9942EDDFUL, 0x89FF85DCDF9AE895UL, 0x6F9EE0D8D9E8D414UL,
|
|
||||||
0x10E01A59058D3904UL, 0x1DFAF567BFF55D2EUL, 0x8DD6A18C03382CD4UL,
|
|
||||||
0xE12FD89A0CF58553UL, 0xE245DA902C0C4F5CUL, 0x8BE7566B9987520DUL,
|
|
||||||
0x4CA1C0A4B38A3098UL, 0x81E45015BE618A72UL, 0xA80E0344FF27EFDFUL,
|
|
||||||
0xC98DAEC6DC5005BAUL, 0xF56873F3A958AE5EUL, 0xDB88604670C794ACUL,
|
|
||||||
0x4F68E448DDF6535FUL, 0x3443DBF1CA6031A8UL, 0x73DFA5DEEF409A41UL,
|
|
||||||
0xA7C556941F6643B2UL, 0x424BC40D8C83D962UL, 0x6F292A325B99B726UL,
|
|
||||||
0x6EECB1009717D65EUL, 0x899BE4CE7BB2D8EEUL, 0x25285FED3E59781DUL,
|
|
||||||
0x14C5AEDD76E092D3UL, 0x9BB5EE10567640AEUL, 0xCD62A1D43558FD06UL,
|
|
||||||
0x70A7B09FC5F39447UL, 0xF10064AE92EFFB99UL, 0xD55FA1A918A23082UL,
|
|
||||||
0xD03F28AD25C73A78UL, 0x76CFFFEE094D8B0EUL, 0x4FD5A46AD5A4B4CFUL,
|
|
||||||
0x8F3A36F9D7BF87E3UL, 0x64224315210625BEUL, 0x749A131B71B64350UL,
|
|
||||||
0x9034FF9DAC089F48UL, 0xB58D3017E7321217UL, 0x549D818937D5CE90UL,
|
|
||||||
0x903CE1452419E99CUL, 0xFD052F0388DB2E76UL, 0x7390051E3972480EUL,
|
|
||||||
0x5E5F6EC3F27B3679UL, 0x3E3637D4D4EE917DUL, 0x4FE04068CA2A4309UL,
|
|
||||||
0x98C9C17454AAE42DUL, 0x659AE0BDB113BC21UL, 0x4C0BDECB1511AF4CUL,
|
|
||||||
0x17048BFAEAC0006DUL, 0x68F106AADAA64912UL, 0x2286234ECEB7EAF0UL,
|
|
||||||
0x350CD42CAF697E51UL, 0x8DCDE6D1FAC19A9FUL, 0xF97E55A245A8A8A2UL,
|
|
||||||
0xAAE86B2092DA90A3UL, 0x5123E878AA8AEF76UL, 0x022B88B9694A55F6UL,
|
|
||||||
0xC4C1A9B1C0221985UL, 0x20056D91DD5E0FFEUL, 0xF5BF61EC225C9843UL,
|
|
||||||
0x1A315A05BDCF4A31UL, 0x5710A21A8DF4F15FUL, 0x99BD1A0AF97AD027UL,
|
|
||||||
0x7602C5997AD4E12CUL
|
|
||||||
};
|
|
||||||
|
|
||||||
public static bool IsPopularPassword(char[] vPassword)
|
public static bool IsPopularPassword(char[] vPassword)
|
||||||
{
|
{
|
||||||
Debug.Assert(PpcTable.Length == (PpcTableSize / 64));
|
ulong uDummy;
|
||||||
|
return IsPopularPassword(vPassword, out uDummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsPopularPassword(char[] vPassword, out ulong uDictSize)
|
||||||
|
{
|
||||||
if(vPassword == null) throw new ArgumentNullException("vPassword");
|
if(vPassword == null) throw new ArgumentNullException("vPassword");
|
||||||
if(vPassword.Length == 0) return false;
|
if(vPassword.Length == 0) { uDictSize = 0; return false; }
|
||||||
|
|
||||||
foreach(char ch in vPassword)
|
string str = new string(vPassword);
|
||||||
{
|
|
||||||
if(!IsPopularChar(ch)) return false;
|
try { return IsPopularPasswordPriv(str, out uDictSize); }
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
|
uDictSize = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vPassword);
|
private static bool IsPopularPasswordPriv(string str, out ulong uDictSize)
|
||||||
|
|
||||||
int[] vIndices = GetTableIndices(pbUtf8, PpcTableSize);
|
|
||||||
Array.Clear(pbUtf8, 0, pbUtf8.Length);
|
|
||||||
|
|
||||||
foreach(int iIndex in vIndices)
|
|
||||||
{
|
{
|
||||||
if(!GetTableBit(PpcTable, iIndex)) return false;
|
Debug.Assert(m_dicts.Count > 0); // Should be initialized with data
|
||||||
|
|
||||||
|
Dictionary<string, bool> d;
|
||||||
|
if(!m_dicts.TryGetValue(str.Length, out d))
|
||||||
|
{
|
||||||
|
uDictSize = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
uDictSize = (ulong)d.Count;
|
||||||
|
return d.ContainsKey(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsPopularChar(char ch)
|
public static void Add(byte[] pbData, bool bGZipped)
|
||||||
{
|
{
|
||||||
return (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) ||
|
try
|
||||||
((ch >= '0') && (ch <= '9')) || (ch == '_') || (ch == '!'));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int[] GetTableIndices(byte[] pbPasswordUtf8, int nTableSize)
|
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
if(bGZipped)
|
||||||
return null;
|
pbData = MemUtil.Decompress(pbData);
|
||||||
#if TODO
|
|
||||||
Debug.Assert((nTableSize >= 2) && (nTableSize <= 0x10000));
|
|
||||||
Debug.Assert((nTableSize % 64) == 0);
|
|
||||||
|
|
||||||
SHA512Managed sha = new SHA512Managed();
|
string strData = StrUtil.Utf8.GetString(pbData, 0, pbData.Length);
|
||||||
byte[] pbHash = sha.ComputeHash(pbPasswordUtf8);
|
if(string.IsNullOrEmpty(strData)) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
int[] vIndices = new int[pbHash.Length / 2];
|
if(!char.IsWhiteSpace(strData[strData.Length - 1]))
|
||||||
for(int i = 0; i < vIndices.Length; ++i)
|
strData += "\n";
|
||||||
vIndices[i] = ((((int)pbHash[i * 2] << 8) |
|
|
||||||
(int)pbHash[i * 2 + 1]) % nTableSize);
|
|
||||||
|
|
||||||
return vIndices;
|
StringBuilder sb = new StringBuilder();
|
||||||
#endif
|
for(int i = 0; i < strData.Length; ++i)
|
||||||
}
|
|
||||||
|
|
||||||
private static bool GetTableBit(ulong[] vTable, int iBit)
|
|
||||||
{
|
{
|
||||||
return ((vTable[iBit >> 6] & (1UL << (iBit & 0x3F))) != 0UL);
|
char ch = strData[i];
|
||||||
}
|
|
||||||
|
|
||||||
#if (DEBUG && !KeePassLibSD && TODO)
|
|
||||||
private static bool SetTableBit(ulong[] vTable, int iBit)
|
|
||||||
{
|
|
||||||
if(GetTableBit(vTable, iBit)) return false;
|
|
||||||
|
|
||||||
vTable[iBit >> 6] = (vTable[iBit >> 6] | (1UL << (iBit & 0x3F)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void MakeList()
|
|
||||||
{
|
|
||||||
|
|
||||||
string strData = File.ReadAllText("MostPopularPasswords.txt", StrUtil.Utf8);
|
|
||||||
strData += " ";
|
|
||||||
CharStream cs = new CharStream(strData);
|
|
||||||
|
|
||||||
List<string> vPasswords = new List<string>();
|
|
||||||
StringBuilder sbPassword = new StringBuilder();
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
char ch = cs.ReadChar();
|
|
||||||
if(ch == char.MinValue) break;
|
|
||||||
|
|
||||||
if(char.IsWhiteSpace(ch))
|
if(char.IsWhiteSpace(ch))
|
||||||
{
|
{
|
||||||
string strPassword = sbPassword.ToString();
|
int cc = sb.Length;
|
||||||
strPassword = strPassword.ToLower();
|
if(cc > 0)
|
||||||
|
|
||||||
if(strPassword.Length > 3)
|
|
||||||
{
|
{
|
||||||
if(vPasswords.IndexOf(strPassword) < 0)
|
string strWord = sb.ToString();
|
||||||
vPasswords.Add(strPassword);
|
Debug.Assert(strWord.Length == cc);
|
||||||
}
|
|
||||||
|
|
||||||
sbPassword = new StringBuilder();
|
Dictionary<string, bool> d;
|
||||||
}
|
if(!m_dicts.TryGetValue(cc, out d))
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Debug.Assert(!char.IsControl(ch) && !char.IsHighSurrogate(ch) &&
|
d = new Dictionary<string, bool>();
|
||||||
!char.IsLowSurrogate(ch) && !char.IsSurrogate(ch));
|
m_dicts[cc] = d;
|
||||||
Debug.Assert(IsPopularChar(ch));
|
|
||||||
sbPassword.Append(ch);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong[] vTable = new ulong[PpcTableSize / 64];
|
d[strWord] = true;
|
||||||
Array.Clear(vTable, 0, vTable.Length);
|
sb.Remove(0, cc);
|
||||||
|
|
||||||
long lBitsInTable = 0;
|
|
||||||
foreach(string strPassword in vPasswords)
|
|
||||||
{
|
|
||||||
byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strPassword);
|
|
||||||
int[] vIndices = GetTableIndices(pbUtf8, PpcTableSize);
|
|
||||||
|
|
||||||
foreach(int i in vIndices)
|
|
||||||
{
|
|
||||||
if(SetTableBit(vTable, i)) ++lBitsInTable;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else sb.Append(char.ToLower(ch));
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.Append("\t\t\t");
|
|
||||||
for(int i = 0; i < vTable.Length; ++i)
|
|
||||||
{
|
|
||||||
if(i > 0)
|
|
||||||
{
|
|
||||||
if((i % 3) == 0)
|
|
||||||
{
|
|
||||||
sb.AppendLine(",");
|
|
||||||
sb.Append("\t\t\t");
|
|
||||||
}
|
}
|
||||||
else sb.Append(", ");
|
|
||||||
}
|
}
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
sb.Append("0x");
|
|
||||||
sb.Append(vTable[i].ToString("X16"));
|
|
||||||
sb.Append("UL");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("Bits set: " + lBitsInTable.ToString() + " of " +
|
|
||||||
PpcTableSize.ToString());
|
|
||||||
int cHashFn = GetTableIndices(StrUtil.Utf8.GetBytes("Dummy"), PpcTableSize).Length;
|
|
||||||
sb.AppendLine("Hash functions: " + cHashFn.ToString());
|
|
||||||
double dblPhi = Math.Pow(1.0 - ((double)cHashFn / PpcTableSize),
|
|
||||||
(double)vPasswords.Count);
|
|
||||||
sb.AppendLine("Phi (bits unset ratio) estimation: " +
|
|
||||||
dblPhi.ToString(CultureInfo.InvariantCulture));
|
|
||||||
dblPhi = ((double)(PpcTableSize - lBitsInTable) / (double)PpcTableSize);
|
|
||||||
sb.AppendLine("Exact Phi: " + dblPhi.ToString(CultureInfo.InvariantCulture));
|
|
||||||
sb.AppendLine("False positives ratio: " + Math.Pow(1.0 - dblPhi,
|
|
||||||
(double)cHashFn).ToString(CultureInfo.InvariantCulture));
|
|
||||||
|
|
||||||
File.WriteAllText("Table.txt", sb.ToString());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,9 +19,10 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
using ModernKeePassLib.Cryptography.PasswordGenerator;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Cryptography
|
namespace ModernKeePassLib.Cryptography
|
||||||
@@ -32,13 +33,286 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class QualityEstimation
|
public static class QualityEstimation
|
||||||
{
|
{
|
||||||
private enum CharSpaceBits : uint
|
private static class PatternID
|
||||||
{
|
{
|
||||||
Control = 32,
|
public const char LowerAlpha = 'L';
|
||||||
Alpha = 26,
|
public const char UpperAlpha = 'U';
|
||||||
Number = 10,
|
public const char Digit = 'D';
|
||||||
Special = 33,
|
public const char Special = 'S';
|
||||||
High = 112
|
public const char High = 'H';
|
||||||
|
public const char Other = 'X';
|
||||||
|
|
||||||
|
public const char Dictionary = 'W';
|
||||||
|
public const char Repetition = 'R';
|
||||||
|
public const char Number = 'N';
|
||||||
|
public const char DiffSeq = 'C';
|
||||||
|
|
||||||
|
public const string All = "LUDSHXWRNC";
|
||||||
|
}
|
||||||
|
|
||||||
|
// private static class CharDistrib
|
||||||
|
// {
|
||||||
|
// public static readonly ulong[] LowerAlpha = new ulong[26] {
|
||||||
|
// 884, 211, 262, 249, 722, 98, 172, 234, 556, 124, 201, 447, 321,
|
||||||
|
// 483, 518, 167, 18, 458, 416, 344, 231, 105, 80, 48, 238, 76
|
||||||
|
// };
|
||||||
|
// public static readonly ulong[] UpperAlpha = new ulong[26] {
|
||||||
|
// 605, 188, 209, 200, 460, 81, 130, 163, 357, 122, 144, 332, 260,
|
||||||
|
// 317, 330, 132, 18, 320, 315, 250, 137, 76, 60, 36, 161, 54
|
||||||
|
// };
|
||||||
|
// public static readonly ulong[] Digit = new ulong[10] {
|
||||||
|
// 574, 673, 524, 377, 339, 336, 312, 310, 357, 386
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
private sealed class QeCharType
|
||||||
|
{
|
||||||
|
private readonly char m_chTypeID;
|
||||||
|
public char TypeID { get { return m_chTypeID; } }
|
||||||
|
|
||||||
|
private readonly string m_strAlph;
|
||||||
|
public string Alphabet { get { return m_strAlph; } }
|
||||||
|
|
||||||
|
private readonly int m_nChars;
|
||||||
|
public int CharCount { get { return m_nChars; } }
|
||||||
|
|
||||||
|
private readonly char m_chFirst;
|
||||||
|
private readonly char m_chLast;
|
||||||
|
|
||||||
|
private readonly double m_dblCharSize;
|
||||||
|
public double CharSize { get { return m_dblCharSize; } }
|
||||||
|
|
||||||
|
public QeCharType(char chTypeID, string strAlphabet, bool bIsConsecutive)
|
||||||
|
{
|
||||||
|
if(strAlphabet == null) throw new ArgumentNullException();
|
||||||
|
if(strAlphabet.Length == 0) throw new ArgumentException();
|
||||||
|
|
||||||
|
m_chTypeID = chTypeID;
|
||||||
|
m_strAlph = strAlphabet;
|
||||||
|
m_nChars = m_strAlph.Length;
|
||||||
|
m_chFirst = (bIsConsecutive ? m_strAlph[0] : char.MinValue);
|
||||||
|
m_chLast = (bIsConsecutive ? m_strAlph[m_nChars - 1] : char.MinValue);
|
||||||
|
|
||||||
|
m_dblCharSize = Log2(m_nChars);
|
||||||
|
|
||||||
|
Debug.Assert(((int)(m_chLast - m_chFirst) == (m_nChars - 1)) ||
|
||||||
|
!bIsConsecutive);
|
||||||
|
}
|
||||||
|
|
||||||
|
public QeCharType(char chTypeID, int nChars) // Catch-none set
|
||||||
|
{
|
||||||
|
if(nChars <= 0) throw new ArgumentOutOfRangeException();
|
||||||
|
|
||||||
|
m_chTypeID = chTypeID;
|
||||||
|
m_strAlph = string.Empty;
|
||||||
|
m_nChars = nChars;
|
||||||
|
m_chFirst = char.MinValue;
|
||||||
|
m_chLast = char.MinValue;
|
||||||
|
|
||||||
|
m_dblCharSize = Log2(m_nChars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(char ch)
|
||||||
|
{
|
||||||
|
if(m_chLast != char.MinValue)
|
||||||
|
return ((ch >= m_chFirst) && (ch <= m_chLast));
|
||||||
|
|
||||||
|
Debug.Assert(m_strAlph.Length > 0); // Don't call for catch-none set
|
||||||
|
return (m_strAlph.IndexOf(ch) >= 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class EntropyEncoder
|
||||||
|
{
|
||||||
|
private readonly string m_strAlph;
|
||||||
|
private Dictionary<char, ulong> m_dHisto = new Dictionary<char, ulong>();
|
||||||
|
private readonly ulong m_uBaseWeight;
|
||||||
|
private readonly ulong m_uCharWeight;
|
||||||
|
private readonly ulong m_uOccExclThreshold;
|
||||||
|
|
||||||
|
public EntropyEncoder(string strAlphabet, ulong uBaseWeight,
|
||||||
|
ulong uCharWeight, ulong uOccExclThreshold)
|
||||||
|
{
|
||||||
|
if(strAlphabet == null) throw new ArgumentNullException();
|
||||||
|
if(strAlphabet.Length == 0) throw new ArgumentException();
|
||||||
|
|
||||||
|
m_strAlph = strAlphabet;
|
||||||
|
m_uBaseWeight = uBaseWeight;
|
||||||
|
m_uCharWeight = uCharWeight;
|
||||||
|
m_uOccExclThreshold = uOccExclThreshold;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
Dictionary<char, bool> d = new Dictionary<char, bool>();
|
||||||
|
foreach(char ch in m_strAlph) { d[ch] = true; }
|
||||||
|
Debug.Assert(d.Count == m_strAlph.Length); // No duplicates
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
m_dHisto.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(char ch)
|
||||||
|
{
|
||||||
|
Debug.Assert(m_strAlph.IndexOf(ch) >= 0);
|
||||||
|
|
||||||
|
ulong uOcc;
|
||||||
|
m_dHisto.TryGetValue(ch, out uOcc);
|
||||||
|
Debug.Assert(m_dHisto.ContainsKey(ch) || (uOcc == 0));
|
||||||
|
m_dHisto[ch] = uOcc + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double GetOutputSize()
|
||||||
|
{
|
||||||
|
ulong uTotalWeight = m_uBaseWeight * (ulong)m_strAlph.Length;
|
||||||
|
foreach(ulong u in m_dHisto.Values)
|
||||||
|
{
|
||||||
|
Debug.Assert(u >= 1);
|
||||||
|
if(u > m_uOccExclThreshold)
|
||||||
|
uTotalWeight += (u - m_uOccExclThreshold) * m_uCharWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dSize = 0.0, dTotalWeight = (double)uTotalWeight;
|
||||||
|
foreach(ulong u in m_dHisto.Values)
|
||||||
|
{
|
||||||
|
ulong uWeight = m_uBaseWeight;
|
||||||
|
if(u > m_uOccExclThreshold)
|
||||||
|
uWeight += (u - m_uOccExclThreshold) * m_uCharWeight;
|
||||||
|
|
||||||
|
dSize -= (double)u * Log2((double)uWeight / dTotalWeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class MultiEntropyEncoder
|
||||||
|
{
|
||||||
|
private Dictionary<char, EntropyEncoder> m_dEncs =
|
||||||
|
new Dictionary<char, EntropyEncoder>();
|
||||||
|
|
||||||
|
public MultiEntropyEncoder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddEncoder(char chTypeID, EntropyEncoder ec)
|
||||||
|
{
|
||||||
|
if(ec == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
Debug.Assert(!m_dEncs.ContainsKey(chTypeID));
|
||||||
|
m_dEncs[chTypeID] = ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
foreach(EntropyEncoder ec in m_dEncs.Values) { ec.Reset(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Write(char chTypeID, char chData)
|
||||||
|
{
|
||||||
|
EntropyEncoder ec;
|
||||||
|
if(!m_dEncs.TryGetValue(chTypeID, out ec))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ec.Write(chData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double GetOutputSize()
|
||||||
|
{
|
||||||
|
double d = 0.0;
|
||||||
|
|
||||||
|
foreach(EntropyEncoder ec in m_dEncs.Values)
|
||||||
|
{
|
||||||
|
d += ec.GetOutputSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class QePatternInstance
|
||||||
|
{
|
||||||
|
private readonly int m_iPos;
|
||||||
|
public int Position { get { return m_iPos; } }
|
||||||
|
|
||||||
|
private readonly int m_nLen;
|
||||||
|
public int Length { get { return m_nLen; } }
|
||||||
|
|
||||||
|
private readonly char m_chPatternID;
|
||||||
|
public char PatternID { get { return m_chPatternID; } }
|
||||||
|
|
||||||
|
private readonly double m_dblCost;
|
||||||
|
public double Cost { get { return m_dblCost; } }
|
||||||
|
|
||||||
|
private readonly QeCharType m_ctSingle;
|
||||||
|
public QeCharType SingleCharType { get { return m_ctSingle; } }
|
||||||
|
|
||||||
|
public QePatternInstance(int iPosition, int nLength, char chPatternID,
|
||||||
|
double dblCost)
|
||||||
|
{
|
||||||
|
m_iPos = iPosition;
|
||||||
|
m_nLen = nLength;
|
||||||
|
m_chPatternID = chPatternID;
|
||||||
|
m_dblCost = dblCost;
|
||||||
|
m_ctSingle = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QePatternInstance(int iPosition, int nLength, QeCharType ctSingle)
|
||||||
|
{
|
||||||
|
m_iPos = iPosition;
|
||||||
|
m_nLen = nLength;
|
||||||
|
m_chPatternID = ctSingle.TypeID;
|
||||||
|
m_dblCost = ctSingle.CharSize;
|
||||||
|
m_ctSingle = ctSingle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class QePathState
|
||||||
|
{
|
||||||
|
public readonly int Position;
|
||||||
|
public readonly List<QePatternInstance> Path;
|
||||||
|
|
||||||
|
public QePathState(int iPosition, List<QePatternInstance> lPath)
|
||||||
|
{
|
||||||
|
this.Position = iPosition;
|
||||||
|
this.Path = lPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object m_objSyncInit = new object();
|
||||||
|
private static List<QeCharType> m_lCharTypes = null;
|
||||||
|
|
||||||
|
private static void EnsureInitialized()
|
||||||
|
{
|
||||||
|
lock(m_objSyncInit)
|
||||||
|
{
|
||||||
|
if(m_lCharTypes == null)
|
||||||
|
{
|
||||||
|
string strSpecial = PwCharSet.PrintableAsciiSpecial;
|
||||||
|
if(strSpecial.IndexOf(' ') >= 0) { Debug.Assert(false); }
|
||||||
|
else strSpecial = strSpecial + " ";
|
||||||
|
|
||||||
|
int nSp = strSpecial.Length;
|
||||||
|
int nHi = PwCharSet.HighAnsiChars.Length;
|
||||||
|
|
||||||
|
m_lCharTypes = new List<QeCharType>();
|
||||||
|
|
||||||
|
m_lCharTypes.Add(new QeCharType(PatternID.LowerAlpha,
|
||||||
|
PwCharSet.LowerCase, true));
|
||||||
|
m_lCharTypes.Add(new QeCharType(PatternID.UpperAlpha,
|
||||||
|
PwCharSet.UpperCase, true));
|
||||||
|
m_lCharTypes.Add(new QeCharType(PatternID.Digit,
|
||||||
|
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.Other,
|
||||||
|
0x10000 - (2 * 26) - 10 - nSp - nHi));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -46,84 +320,95 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vPasswordChars">Password to check.</param>
|
/// <param name="vPasswordChars">Password to check.</param>
|
||||||
/// <returns>Estimated bit-strength of the password.</returns>
|
/// <returns>Estimated bit-strength of the password.</returns>
|
||||||
/// <exception cref="System.ArgumentNullException">Thrown if the input
|
|
||||||
/// parameter is <c>null</c>.</exception>
|
|
||||||
public static uint EstimatePasswordBits(char[] vPasswordChars)
|
public static uint EstimatePasswordBits(char[] vPasswordChars)
|
||||||
{
|
{
|
||||||
Debug.Assert(vPasswordChars != null);
|
if(vPasswordChars == null) { Debug.Assert(false); return 0; }
|
||||||
if(vPasswordChars == null) throw new ArgumentNullException("vPasswordChars");
|
if(vPasswordChars.Length == 0) return 0;
|
||||||
|
|
||||||
bool bChLower = false, bChUpper = false, bChNumber = false;
|
EnsureInitialized();
|
||||||
bool bChSpecial = false, bChHigh = false, bChControl = false;
|
|
||||||
Dictionary<char, uint> vCharCounts = new Dictionary<char, uint>();
|
|
||||||
Dictionary<int, uint> vDifferences = new Dictionary<int, uint>();
|
|
||||||
double dblEffectiveLength = 0.0;
|
|
||||||
|
|
||||||
for(int i = 0; i < vPasswordChars.Length; ++i) // Get character types
|
int n = vPasswordChars.Length;
|
||||||
|
List<QePatternInstance>[] vPatterns = new List<QePatternInstance>[n];
|
||||||
|
for(int i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
char tch = vPasswordChars[i];
|
vPatterns[i] = new List<QePatternInstance>();
|
||||||
|
|
||||||
if(tch < ' ') bChControl = true;
|
QePatternInstance piChar = new QePatternInstance(i, 1,
|
||||||
else if((tch >= 'A') && (tch <= 'Z')) bChUpper = true;
|
GetCharType(vPasswordChars[i]));
|
||||||
else if((tch >= 'a') && (tch <= 'z')) bChLower = true;
|
vPatterns[i].Add(piChar);
|
||||||
else if((tch >= '0') && (tch <= '9')) bChNumber = true;
|
|
||||||
else if((tch >= ' ') && (tch <= '/')) bChSpecial = true;
|
|
||||||
else if((tch >= ':') && (tch <= '@')) bChSpecial = true;
|
|
||||||
else if((tch >= '[') && (tch <= '`')) bChSpecial = true;
|
|
||||||
else if((tch >= '{') && (tch <= '~')) bChSpecial = true;
|
|
||||||
else if(tch > '~') bChHigh = true;
|
|
||||||
|
|
||||||
double dblDiffFactor = 1.0;
|
|
||||||
if(i >= 1)
|
|
||||||
{
|
|
||||||
int iDiff = (int)tch - (int)vPasswordChars[i - 1];
|
|
||||||
|
|
||||||
uint uDiffCount;
|
|
||||||
if(vDifferences.TryGetValue(iDiff, out uDiffCount))
|
|
||||||
{
|
|
||||||
++uDiffCount;
|
|
||||||
vDifferences[iDiff] = uDiffCount;
|
|
||||||
dblDiffFactor /= (double)uDiffCount;
|
|
||||||
}
|
|
||||||
else vDifferences.Add(iDiff, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint uCharCount;
|
FindRepetitions(vPasswordChars, vPatterns);
|
||||||
if(vCharCounts.TryGetValue(tch, out uCharCount))
|
FindNumbers(vPasswordChars, vPatterns);
|
||||||
|
FindDiffSeqs(vPasswordChars, vPatterns);
|
||||||
|
FindPopularPasswords(vPasswordChars, vPatterns);
|
||||||
|
|
||||||
|
// Encoders must not be static, because the entropy estimation
|
||||||
|
// may run concurrently in multiple threads and the encoders are
|
||||||
|
// not read-only
|
||||||
|
EntropyEncoder ecPattern = new EntropyEncoder(PatternID.All, 0, 1, 0);
|
||||||
|
MultiEntropyEncoder mcData = new MultiEntropyEncoder();
|
||||||
|
for(int i = 0; i < (m_lCharTypes.Count - 1); ++i)
|
||||||
{
|
{
|
||||||
++uCharCount;
|
// Let m be the alphabet size. In order to ensure that two same
|
||||||
vCharCounts[tch] = uCharCount;
|
// characters cost at least as much as a single character, for
|
||||||
dblEffectiveLength += dblDiffFactor * (1.0 / (double)uCharCount);
|
// the probability p and weight w of the character it must hold:
|
||||||
|
// -log(1/m) >= -2*log(p)
|
||||||
|
// <=> log(1/m) <= log(p^2) <=> 1/m <= p^2 <=> p >= sqrt(1/m);
|
||||||
|
// sqrt(1/m) = (1+w)/(m+w)
|
||||||
|
// <=> m+w = (1+w)*sqrt(m) <=> m+w = sqrt(m) + w*sqrt(m)
|
||||||
|
// <=> w*(1-sqrt(m)) = sqrt(m) - m <=> w = (sqrt(m)-m)/(1-sqrt(m))
|
||||||
|
// <=> w = (sqrt(m)-m)*(1+sqrt(m))/(1-m)
|
||||||
|
// <=> w = (sqrt(m)-m+m-m*sqrt(m))/(1-m) <=> w = sqrt(m)
|
||||||
|
ulong uw = (ulong)Math.Sqrt((double)m_lCharTypes[i].CharCount);
|
||||||
|
|
||||||
|
mcData.AddEncoder(m_lCharTypes[i].TypeID, new EntropyEncoder(
|
||||||
|
m_lCharTypes[i].Alphabet, 1, uw, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
double dblMinCost = (double)int.MaxValue;
|
||||||
|
int tStart = Environment.TickCount;
|
||||||
|
|
||||||
|
Stack<QePathState> sRec = new Stack<QePathState>();
|
||||||
|
sRec.Push(new QePathState(0, new List<QePatternInstance>()));
|
||||||
|
while(sRec.Count > 0)
|
||||||
|
{
|
||||||
|
int tDiff = Environment.TickCount - tStart;
|
||||||
|
if(tDiff > 500) break;
|
||||||
|
|
||||||
|
QePathState s = sRec.Pop();
|
||||||
|
|
||||||
|
if(s.Position >= n)
|
||||||
|
{
|
||||||
|
Debug.Assert(s.Position == n);
|
||||||
|
|
||||||
|
double dblCost = ComputePathCost(s.Path, vPasswordChars,
|
||||||
|
ecPattern, mcData);
|
||||||
|
if(dblCost < dblMinCost) dblMinCost = dblCost;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vCharCounts.Add(tch, 1);
|
List<QePatternInstance> lSubs = vPatterns[s.Position];
|
||||||
dblEffectiveLength += dblDiffFactor;
|
for(int i = lSubs.Count - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
QePatternInstance pi = lSubs[i];
|
||||||
|
Debug.Assert(pi.Position == s.Position);
|
||||||
|
Debug.Assert(pi.Length >= 1);
|
||||||
|
|
||||||
|
List<QePatternInstance> lNewPath =
|
||||||
|
new List<QePatternInstance>(s.Path.Count + 1);
|
||||||
|
lNewPath.AddRange(s.Path);
|
||||||
|
lNewPath.Add(pi);
|
||||||
|
Debug.Assert(lNewPath.Capacity == (s.Path.Count + 1));
|
||||||
|
|
||||||
|
QePathState sNew = new QePathState(s.Position +
|
||||||
|
pi.Length, lNewPath);
|
||||||
|
sRec.Push(sNew);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint uCharSpace = 0;
|
return (uint)Math.Ceiling(dblMinCost);
|
||||||
if(bChControl) uCharSpace += (uint)CharSpaceBits.Control;
|
|
||||||
if(bChUpper) uCharSpace += (uint)CharSpaceBits.Alpha;
|
|
||||||
if(bChLower) uCharSpace += (uint)CharSpaceBits.Alpha;
|
|
||||||
if(bChNumber) uCharSpace += (uint)CharSpaceBits.Number;
|
|
||||||
if(bChSpecial) uCharSpace += (uint)CharSpaceBits.Special;
|
|
||||||
if(bChHigh) uCharSpace += (uint)CharSpaceBits.High;
|
|
||||||
|
|
||||||
if(uCharSpace == 0) return 0;
|
|
||||||
|
|
||||||
double dblBitsPerChar = Math.Log((double)uCharSpace) / Math.Log(2.0);
|
|
||||||
double dblRating = dblBitsPerChar * dblEffectiveLength;
|
|
||||||
|
|
||||||
#if !KeePassLibSD
|
|
||||||
char[] vLowerCopy = new char[vPasswordChars.Length];
|
|
||||||
for(int ilc = 0; ilc < vLowerCopy.Length; ++ilc)
|
|
||||||
vLowerCopy[ilc] = char.ToLower(vPasswordChars[ilc]);
|
|
||||||
if(PopularPasswords.IsPopularPassword(vLowerCopy)) dblRating /= 8.0;
|
|
||||||
Array.Clear(vLowerCopy, 0, vLowerCopy.Length);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (uint)Math.Ceiling(dblRating);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -141,5 +426,343 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
|
|
||||||
return uResult;
|
return uResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static QeCharType GetCharType(char ch)
|
||||||
|
{
|
||||||
|
int nTypes = m_lCharTypes.Count;
|
||||||
|
Debug.Assert((nTypes > 0) && (m_lCharTypes[nTypes - 1].CharCount > 256));
|
||||||
|
|
||||||
|
for(int i = 0; i < (nTypes - 1); ++i)
|
||||||
|
{
|
||||||
|
if(m_lCharTypes[i].Contains(ch))
|
||||||
|
return m_lCharTypes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_lCharTypes[nTypes - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double ComputePathCost(List<QePatternInstance> l,
|
||||||
|
char[] vPassword, EntropyEncoder ecPattern, MultiEntropyEncoder mcData)
|
||||||
|
{
|
||||||
|
ecPattern.Reset();
|
||||||
|
for(int i = 0; i < l.Count; ++i)
|
||||||
|
ecPattern.Write(l[i].PatternID);
|
||||||
|
double dblPatternCost = ecPattern.GetOutputSize();
|
||||||
|
|
||||||
|
mcData.Reset();
|
||||||
|
double dblDataCost = 0.0;
|
||||||
|
foreach(QePatternInstance pi in l)
|
||||||
|
{
|
||||||
|
QeCharType tChar = pi.SingleCharType;
|
||||||
|
if(tChar != null)
|
||||||
|
{
|
||||||
|
char ch = vPassword[pi.Position];
|
||||||
|
if(!mcData.Write(tChar.TypeID, ch))
|
||||||
|
dblDataCost += pi.Cost;
|
||||||
|
}
|
||||||
|
else dblDataCost += pi.Cost;
|
||||||
|
}
|
||||||
|
dblDataCost += mcData.GetOutputSize();
|
||||||
|
|
||||||
|
return (dblPatternCost + dblDataCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FindPopularPasswords(char[] vPassword,
|
||||||
|
List<QePatternInstance>[] vPatterns)
|
||||||
|
{
|
||||||
|
int n = vPassword.Length;
|
||||||
|
|
||||||
|
char[] vLower = new char[n];
|
||||||
|
char[] vLeet = new char[n];
|
||||||
|
for(int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
char ch = vPassword[i];
|
||||||
|
|
||||||
|
vLower[i] = char.ToLower(ch);
|
||||||
|
vLeet[i] = char.ToLower(DecodeLeetChar(ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
char chErased = default(char);
|
||||||
|
Debug.Assert(chErased == char.MinValue);
|
||||||
|
|
||||||
|
int nMaxLen = Math.Min(n, PopularPasswords.MaxLength);
|
||||||
|
for(int nSubLen = nMaxLen; nSubLen >= 3; --nSubLen)
|
||||||
|
{
|
||||||
|
if(!PopularPasswords.ContainsLength(nSubLen)) continue;
|
||||||
|
|
||||||
|
char[] vSub = new char[nSubLen];
|
||||||
|
|
||||||
|
for(int i = 0; i <= (n - nSubLen); ++i)
|
||||||
|
{
|
||||||
|
if(Array.IndexOf<char>(vLower, chErased, i, nSubLen) >= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Array.Copy(vLower, i, vSub, 0, nSubLen);
|
||||||
|
if(!EvalAddPopularPasswordPattern(vPatterns, vPassword,
|
||||||
|
i, vSub, 0.0))
|
||||||
|
{
|
||||||
|
Array.Copy(vLeet, i, vSub, 0, nSubLen);
|
||||||
|
if(EvalAddPopularPasswordPattern(vPatterns, vPassword,
|
||||||
|
i, vSub, 1.5))
|
||||||
|
{
|
||||||
|
Array.Clear(vLower, i, nSubLen); // Not vLeet
|
||||||
|
Debug.Assert(vLower[i] == chErased);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array.Clear(vLower, i, nSubLen);
|
||||||
|
Debug.Assert(vLower[i] == chErased);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool EvalAddPopularPasswordPattern(List<QePatternInstance>[] vPatterns,
|
||||||
|
char[] vPassword, int i, char[] vSub, double dblCostPerMod)
|
||||||
|
{
|
||||||
|
ulong uDictSize;
|
||||||
|
if(!PopularPasswords.IsPopularPassword(vSub, out uDictSize))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int n = vSub.Length;
|
||||||
|
int d = HammingDist(vSub, 0, vPassword, i, n);
|
||||||
|
|
||||||
|
double dblCost = Log2((double)uDictSize);
|
||||||
|
|
||||||
|
// dblCost += log2(n binom d)
|
||||||
|
int k = Math.Min(d, n - d);
|
||||||
|
for(int j = n; j > (n - k); --j)
|
||||||
|
dblCost += Log2(j);
|
||||||
|
for(int j = k; j >= 2; --j)
|
||||||
|
dblCost -= Log2(j);
|
||||||
|
|
||||||
|
dblCost += dblCostPerMod * (double)d;
|
||||||
|
|
||||||
|
vPatterns[i].Add(new QePatternInstance(i, n, PatternID.Dictionary,
|
||||||
|
dblCost));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static char DecodeLeetChar(char chLeet)
|
||||||
|
{
|
||||||
|
if((chLeet >= '\u00C0') && (chLeet <= '\u00C6')) return 'a';
|
||||||
|
if((chLeet >= '\u00C8') && (chLeet <= '\u00CB')) return 'e';
|
||||||
|
if((chLeet >= '\u00CC') && (chLeet <= '\u00CF')) return 'i';
|
||||||
|
if((chLeet >= '\u00D2') && (chLeet <= '\u00D6')) return 'o';
|
||||||
|
if((chLeet >= '\u00D9') && (chLeet <= '\u00DC')) return 'u';
|
||||||
|
if((chLeet >= '\u00E0') && (chLeet <= '\u00E6')) return 'a';
|
||||||
|
if((chLeet >= '\u00E8') && (chLeet <= '\u00EB')) return 'e';
|
||||||
|
if((chLeet >= '\u00EC') && (chLeet <= '\u00EF')) return 'i';
|
||||||
|
if((chLeet >= '\u00F2') && (chLeet <= '\u00F6')) return 'o';
|
||||||
|
if((chLeet >= '\u00F9') && (chLeet <= '\u00FC')) return 'u';
|
||||||
|
|
||||||
|
char ch;
|
||||||
|
switch(chLeet)
|
||||||
|
{
|
||||||
|
case '4':
|
||||||
|
case '@':
|
||||||
|
case '?':
|
||||||
|
case '^':
|
||||||
|
case '\u00AA': ch = 'a'; break;
|
||||||
|
case '8':
|
||||||
|
case '\u00DF': ch = 'b'; break;
|
||||||
|
case '(':
|
||||||
|
case '{':
|
||||||
|
case '[':
|
||||||
|
case '<':
|
||||||
|
case '\u00A2':
|
||||||
|
case '\u00A9':
|
||||||
|
case '\u00C7':
|
||||||
|
case '\u00E7': ch = 'c'; break;
|
||||||
|
case '\u00D0':
|
||||||
|
case '\u00F0': ch = 'd'; break;
|
||||||
|
case '3':
|
||||||
|
case '\u20AC':
|
||||||
|
case '&':
|
||||||
|
case '\u00A3': ch = 'e'; break;
|
||||||
|
case '6':
|
||||||
|
case '9': ch = 'g'; break;
|
||||||
|
case '#': ch = 'h'; break;
|
||||||
|
case '1':
|
||||||
|
case '!':
|
||||||
|
case '|':
|
||||||
|
case '\u00A1':
|
||||||
|
case '\u00A6': ch = 'i'; break;
|
||||||
|
case '\u00D1':
|
||||||
|
case '\u00F1': ch = 'n'; break;
|
||||||
|
case '0':
|
||||||
|
case '*':
|
||||||
|
case '\u00A4': // Currency
|
||||||
|
case '\u00B0': // Degree
|
||||||
|
case '\u00D8':
|
||||||
|
case '\u00F8': ch = 'o'; break;
|
||||||
|
case '\u00AE': ch = 'r'; break;
|
||||||
|
case '$':
|
||||||
|
case '5':
|
||||||
|
case '\u00A7': ch = 's'; break;
|
||||||
|
case '+':
|
||||||
|
case '7': ch = 't'; break;
|
||||||
|
case '\u00B5': ch = 'u'; break;
|
||||||
|
case '%':
|
||||||
|
case '\u00D7': ch = 'x'; break;
|
||||||
|
case '\u00A5':
|
||||||
|
case '\u00DD':
|
||||||
|
case '\u00FD':
|
||||||
|
case '\u00FF': ch = 'y'; break;
|
||||||
|
case '2': ch = 'z'; break;
|
||||||
|
default: ch = chLeet; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int HammingDist(char[] v1, int iOffset1,
|
||||||
|
char[] v2, int iOffset2, int nLength)
|
||||||
|
{
|
||||||
|
int nDist = 0;
|
||||||
|
for(int i = 0; i < nLength; ++i)
|
||||||
|
{
|
||||||
|
if(v1[iOffset1 + i] != v2[iOffset2 + i]) ++nDist;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nDist;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FindRepetitions(char[] vPassword,
|
||||||
|
List<QePatternInstance>[] vPatterns)
|
||||||
|
{
|
||||||
|
int n = vPassword.Length;
|
||||||
|
char[] v = new char[n];
|
||||||
|
Array.Copy(vPassword, v, n);
|
||||||
|
|
||||||
|
char chErased = char.MaxValue;
|
||||||
|
for(int m = (n / 2); m >= 3; --m)
|
||||||
|
{
|
||||||
|
for(int x1 = 0; x1 <= (n - (2 * m)); ++x1)
|
||||||
|
{
|
||||||
|
bool bFoundRep = false;
|
||||||
|
|
||||||
|
for(int x2 = (x1 + m); x2 <= (n - m); ++x2)
|
||||||
|
{
|
||||||
|
if(PartsEqual(v, x1, x2, m))
|
||||||
|
{
|
||||||
|
double dblCost = Log2(x1 + 1) + Log2(m);
|
||||||
|
vPatterns[x2].Add(new QePatternInstance(x2, m,
|
||||||
|
PatternID.Repetition, dblCost));
|
||||||
|
|
||||||
|
ErasePart(v, x2, m, ref chErased);
|
||||||
|
bFoundRep = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bFoundRep) ErasePart(v, x1, m, ref chErased);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool PartsEqual(char[] v, int x1, int x2, int nLength)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < nLength; ++i)
|
||||||
|
{
|
||||||
|
if(v[x1 + i] != v[x2 + i]) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ErasePart(char[] v, int i, int n, ref char chErased)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < n; ++j)
|
||||||
|
{
|
||||||
|
v[i + j] = chErased;
|
||||||
|
--chErased;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FindNumbers(char[] vPassword,
|
||||||
|
List<QePatternInstance>[] vPatterns)
|
||||||
|
{
|
||||||
|
int n = vPassword.Length;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for(int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
char ch = vPassword[i];
|
||||||
|
if((ch >= '0') && (ch <= '9')) sb.Append(ch);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddNumberPattern(vPatterns, sb.ToString(), i - sb.Length);
|
||||||
|
sb.Remove(0, sb.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AddNumberPattern(vPatterns, sb.ToString(), n - sb.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddNumberPattern(List<QePatternInstance>[] vPatterns,
|
||||||
|
string strNumber, int i)
|
||||||
|
{
|
||||||
|
if(strNumber.Length <= 2) return;
|
||||||
|
|
||||||
|
int nZeros = 0;
|
||||||
|
for(int j = 0; j < strNumber.Length; ++j)
|
||||||
|
{
|
||||||
|
if(strNumber[j] != '0') break;
|
||||||
|
++nZeros;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dblCost = Log2(nZeros + 1);
|
||||||
|
if(nZeros < strNumber.Length)
|
||||||
|
{
|
||||||
|
string strNonZero = strNumber.Substring(nZeros);
|
||||||
|
|
||||||
|
#if KeePassLibSD
|
||||||
|
try { dblCost += Log2(double.Parse(strNonZero)); }
|
||||||
|
catch(Exception) { Debug.Assert(false); return; }
|
||||||
|
#else
|
||||||
|
double d;
|
||||||
|
if(double.TryParse(strNonZero, out d))
|
||||||
|
dblCost += Log2(d);
|
||||||
|
else { Debug.Assert(false); return; }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vPatterns[i].Add(new QePatternInstance(i, strNumber.Length,
|
||||||
|
PatternID.Number, dblCost));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FindDiffSeqs(char[] vPassword,
|
||||||
|
List<QePatternInstance>[] vPatterns)
|
||||||
|
{
|
||||||
|
int d = int.MinValue, p = 0;
|
||||||
|
string str = new string(vPassword) + new string(char.MaxValue, 1);
|
||||||
|
|
||||||
|
for(int i = 1; i < str.Length; ++i)
|
||||||
|
{
|
||||||
|
int dCur = (int)str[i] - (int)str[i - 1];
|
||||||
|
if(dCur != d)
|
||||||
|
{
|
||||||
|
if((i - p) >= 3) // At least 3 chars involved
|
||||||
|
{
|
||||||
|
QeCharType ct = GetCharType(str[p]);
|
||||||
|
double dblCost = ct.CharSize + Log2(i - p - 1);
|
||||||
|
|
||||||
|
vPatterns[p].Add(new QePatternInstance(p,
|
||||||
|
i - p, PatternID.DiffSeq, dblCost));
|
||||||
|
}
|
||||||
|
|
||||||
|
d = dCur;
|
||||||
|
p = i - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double Log2(double dblValue)
|
||||||
|
{
|
||||||
|
#if KeePassLibSD
|
||||||
|
return (Math.Log(dblValue) / Math.Log(2.0));
|
||||||
|
#else
|
||||||
|
return Math.Log(dblValue, 2.0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.Security.Cryptography;
|
|
||||||
using Windows.Security.Cryptography.Core;
|
|
||||||
using Windows.Storage.Streams;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.Cryptography
|
|
||||||
{
|
|
||||||
// Singleton adaptor that provides a part of the .net SHA256Managed class
|
|
||||||
|
|
||||||
class SHA256Managed
|
|
||||||
{
|
|
||||||
private static SHA256Managed instance;
|
|
||||||
private static HashAlgorithmProvider m_AlgProv;
|
|
||||||
|
|
||||||
private SHA256Managed()
|
|
||||||
{
|
|
||||||
String strAlgName = "SHA256";
|
|
||||||
m_AlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);
|
|
||||||
m_AlgProv.CreateHash();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SHA256Managed Instance
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (instance == null)
|
|
||||||
{
|
|
||||||
instance = new SHA256Managed();
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] ComputeHash(byte[] buffer )
|
|
||||||
{
|
|
||||||
IBuffer input = CryptographicBuffer.CreateFromByteArray( buffer);
|
|
||||||
IBuffer hashBuffer = m_AlgProv.HashData(input);
|
|
||||||
byte[] hash;
|
|
||||||
CryptographicBuffer.CopyToByteArray(hashBuffer, out hash);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,18 +20,24 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using Windows.Security.Cryptography.Core;
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
using System.Text;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
using ModernKeePassLib.Cryptography.Cipher;
|
using ModernKeePassLib.Cryptography.Cipher;
|
||||||
|
using ModernKeePassLib.Keys;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
using ModernKeePassLib.Resources;
|
using ModernKeePassLib.Resources;
|
||||||
using Windows.Storage.Streams;
|
using ModernKeePassLib.Security;
|
||||||
using Windows.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.Cryptography
|
namespace ModernKeePassLib.Cryptography
|
||||||
{
|
{
|
||||||
/* #pragma warning disable 1591
|
/* /// <summary>
|
||||||
/// <summary>
|
|
||||||
/// Return values of the <c>SelfTest.Perform</c> method.
|
/// Return values of the <c>SelfTest.Perform</c> method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum SelfTestResult
|
public enum SelfTestResult
|
||||||
@@ -40,8 +46,7 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
RijndaelEcbError = 1,
|
RijndaelEcbError = 1,
|
||||||
Salsa20Error = 2,
|
Salsa20Error = 2,
|
||||||
NativeKeyTransformationError = 3
|
NativeKeyTransformationError = 3
|
||||||
}
|
} */
|
||||||
#pragma warning restore 1591 */
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class containing self-test methods.
|
/// Class containing self-test methods.
|
||||||
@@ -58,7 +63,9 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
TestRijndael();
|
TestRijndael();
|
||||||
TestSalsa20();
|
TestSalsa20();
|
||||||
|
|
||||||
|
#if !PCL
|
||||||
TestNativeKeyTransform();
|
TestNativeKeyTransform();
|
||||||
|
#endif
|
||||||
|
|
||||||
TestHmacOtp();
|
TestHmacOtp();
|
||||||
|
|
||||||
@@ -74,7 +81,7 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
|
|
||||||
internal static void TestFipsComplianceProblems()
|
internal static void TestFipsComplianceProblems()
|
||||||
{
|
{
|
||||||
#if !KeePassWinRT
|
#if !PCL && !KeePassRT
|
||||||
try { new RijndaelManaged(); }
|
try { new RijndaelManaged(); }
|
||||||
catch(Exception exAes)
|
catch(Exception exAes)
|
||||||
{
|
{
|
||||||
@@ -91,7 +98,7 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
|
|
||||||
private static void TestRijndael()
|
private static void TestRijndael()
|
||||||
{
|
{
|
||||||
|
#if !PCL && !KeePassRT
|
||||||
// Test vector (official ECB test vector #356)
|
// Test vector (official ECB test vector #356)
|
||||||
byte[] pbIV = new byte[16];
|
byte[] pbIV = new byte[16];
|
||||||
byte[] pbTestKey = new byte[32];
|
byte[] pbTestKey = new byte[32];
|
||||||
@@ -106,24 +113,6 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
for(i = 0; i < 16; ++i) pbTestData[i] = 0;
|
for(i = 0; i < 16; ++i) pbTestData[i] = 0;
|
||||||
pbTestData[0] = 0x04;
|
pbTestData[0] = 0x04;
|
||||||
|
|
||||||
String strAlgName = "AES_ECB"; // Algorithm name
|
|
||||||
|
|
||||||
IBuffer iv = null; // no IV used in ECB.
|
|
||||||
IBuffer buffMsg = CryptographicBuffer.CreateFromByteArray(pbTestData);
|
|
||||||
IBuffer keyMaterial = CryptographicBuffer.CreateFromByteArray(pbTestKey);
|
|
||||||
SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(strAlgName);
|
|
||||||
CryptographicKey key = objAlg.CreateSymmetricKey(keyMaterial);
|
|
||||||
|
|
||||||
// Encrypt the data and return.
|
|
||||||
IBuffer buffEncrypt = CryptographicEngine.Encrypt(key, buffMsg, iv);
|
|
||||||
CryptographicBuffer.CopyToByteArray(buffEncrypt, out pbTestData);
|
|
||||||
|
|
||||||
if (!MemUtil.ArraysEqual(pbTestData, pbReferenceCT))
|
|
||||||
throw new SecurityException(KLRes.EncAlgorithmAes + ".");
|
|
||||||
|
|
||||||
|
|
||||||
#if false
|
|
||||||
|
|
||||||
RijndaelManaged r = new RijndaelManaged();
|
RijndaelManaged r = new RijndaelManaged();
|
||||||
|
|
||||||
if(r.BlockSize != 128) // AES block size
|
if(r.BlockSize != 128) // AES block size
|
||||||
@@ -142,7 +131,6 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
|
|
||||||
if(!MemUtil.ArraysEqual(pbTestData, pbReferenceCT))
|
if(!MemUtil.ArraysEqual(pbTestData, pbReferenceCT))
|
||||||
throw new SecurityException(KLRes.EncAlgorithmAes + ".");
|
throw new SecurityException(KLRes.EncAlgorithmAes + ".");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +154,7 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
Salsa20Cipher c = new Salsa20Cipher(pbKey, pbIV);
|
Salsa20Cipher c = new Salsa20Cipher(pbKey, pbIV);
|
||||||
c.Encrypt(pb, pb.Length, false);
|
c.Encrypt(pb, pb.Length, false);
|
||||||
if(!MemUtil.ArraysEqual(pb, pbExpected))
|
if(!MemUtil.ArraysEqual(pb, pbExpected))
|
||||||
throw new SecurityException("Salsa20.");
|
throw new SecurityException("Salsa20-1");
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// Extended test in debug mode
|
// Extended test in debug mode
|
||||||
@@ -183,13 +171,24 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
int nPos = Salsa20ToPos(c, r, pb.Length, 65536);
|
int nPos = Salsa20ToPos(c, r, pb.Length, 65536);
|
||||||
c.Encrypt(pb, pb.Length, false);
|
c.Encrypt(pb, pb.Length, false);
|
||||||
if(!MemUtil.ArraysEqual(pb, pbExpected2))
|
if(!MemUtil.ArraysEqual(pb, pbExpected2))
|
||||||
throw new SecurityException("Salsa20-2.");
|
throw new SecurityException("Salsa20-2");
|
||||||
|
|
||||||
nPos = Salsa20ToPos(c, r, nPos + pb.Length, 131008);
|
nPos = Salsa20ToPos(c, r, nPos + pb.Length, 131008);
|
||||||
Array.Clear(pb, 0, pb.Length);
|
Array.Clear(pb, 0, pb.Length);
|
||||||
c.Encrypt(pb, pb.Length, true);
|
c.Encrypt(pb, pb.Length, true);
|
||||||
if(!MemUtil.ArraysEqual(pb, pbExpected3))
|
if(!MemUtil.ArraysEqual(pb, pbExpected3))
|
||||||
throw new SecurityException("Salsa20-3.");
|
throw new SecurityException("Salsa20-3");
|
||||||
|
|
||||||
|
Dictionary<string, bool> d = new Dictionary<string, bool>();
|
||||||
|
const int nRounds = 100;
|
||||||
|
for(int i = 0; i < nRounds; ++i)
|
||||||
|
{
|
||||||
|
byte[] z = new byte[32];
|
||||||
|
c = new Salsa20Cipher(z, BitConverter.GetBytes((long)i));
|
||||||
|
c.Encrypt(z, z.Length, true);
|
||||||
|
d[MemUtil.ByteArrayToHexString(z)] = true;
|
||||||
|
}
|
||||||
|
if(d.Count != nRounds) throw new SecurityException("Salsa20-4");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,9 +210,10 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !PCL
|
||||||
private static void TestNativeKeyTransform()
|
private static void TestNativeKeyTransform()
|
||||||
{
|
{
|
||||||
#if DEBUG && TODO
|
#if DEBUG
|
||||||
byte[] pbOrgKey = CryptoRandom.Instance.GetRandomBytes(32);
|
byte[] pbOrgKey = CryptoRandom.Instance.GetRandomBytes(32);
|
||||||
byte[] pbSeed = CryptoRandom.Instance.GetRandomBytes(32);
|
byte[] pbSeed = CryptoRandom.Instance.GetRandomBytes(32);
|
||||||
ulong uRounds = (ulong)((new Random()).Next(1, 0x3FFF));
|
ulong uRounds = (ulong)((new Random()).Next(1, 0x3FFF));
|
||||||
@@ -232,10 +232,11 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
throw new SecurityException("Native transform.");
|
throw new SecurityException("Native transform.");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private static void TestMemUtil()
|
private static void TestMemUtil()
|
||||||
{
|
{
|
||||||
#if DEBUG && !KeePassWinRT
|
#if DEBUG
|
||||||
Random r = new Random();
|
Random r = new Random();
|
||||||
byte[] pb = CryptoRandom.Instance.GetRandomBytes((uint)r.Next(
|
byte[] pb = CryptoRandom.Instance.GetRandomBytes((uint)r.Next(
|
||||||
0, 0x2FFFF));
|
0, 0x2FFFF));
|
||||||
@@ -244,35 +245,64 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
if(!MemUtil.ArraysEqual(MemUtil.Decompress(pbCompressed), pb))
|
if(!MemUtil.ArraysEqual(MemUtil.Decompress(pbCompressed), pb))
|
||||||
throw new InvalidOperationException("GZip");
|
throw new InvalidOperationException("GZip");
|
||||||
|
|
||||||
pb = Encoding.ASCII.GetBytes("012345678901234567890a");
|
Encoding enc = StrUtil.Utf8;
|
||||||
byte[] pbN = Encoding.ASCII.GetBytes("9012");
|
pb = enc.GetBytes("012345678901234567890a");
|
||||||
|
byte[] pbN = enc.GetBytes("9012");
|
||||||
if(MemUtil.IndexOf<byte>(pb, pbN) != 9)
|
if(MemUtil.IndexOf<byte>(pb, pbN) != 9)
|
||||||
throw new InvalidOperationException("MemUtil-1");
|
throw new InvalidOperationException("MemUtil-1");
|
||||||
pbN = Encoding.ASCII.GetBytes("01234567890123");
|
pbN = enc.GetBytes("01234567890123");
|
||||||
if(MemUtil.IndexOf<byte>(pb, pbN) != 0)
|
if(MemUtil.IndexOf<byte>(pb, pbN) != 0)
|
||||||
throw new InvalidOperationException("MemUtil-2");
|
throw new InvalidOperationException("MemUtil-2");
|
||||||
pbN = Encoding.ASCII.GetBytes("a");
|
pbN = enc.GetBytes("a");
|
||||||
if(MemUtil.IndexOf<byte>(pb, pbN) != 21)
|
if(MemUtil.IndexOf<byte>(pb, pbN) != 21)
|
||||||
throw new InvalidOperationException("MemUtil-3");
|
throw new InvalidOperationException("MemUtil-3");
|
||||||
pbN = Encoding.ASCII.GetBytes("0a");
|
pbN = enc.GetBytes("0a");
|
||||||
if(MemUtil.IndexOf<byte>(pb, pbN) != 20)
|
if(MemUtil.IndexOf<byte>(pb, pbN) != 20)
|
||||||
throw new InvalidOperationException("MemUtil-4");
|
throw new InvalidOperationException("MemUtil-4");
|
||||||
pbN = Encoding.ASCII.GetBytes("1");
|
pbN = enc.GetBytes("1");
|
||||||
if(MemUtil.IndexOf<byte>(pb, pbN) != 1)
|
if(MemUtil.IndexOf<byte>(pb, pbN) != 1)
|
||||||
throw new InvalidOperationException("MemUtil-5");
|
throw new InvalidOperationException("MemUtil-5");
|
||||||
pbN = Encoding.ASCII.GetBytes("b");
|
pbN = enc.GetBytes("b");
|
||||||
if(MemUtil.IndexOf<byte>(pb, pbN) >= 0)
|
if(MemUtil.IndexOf<byte>(pb, pbN) >= 0)
|
||||||
throw new InvalidOperationException("MemUtil-6");
|
throw new InvalidOperationException("MemUtil-6");
|
||||||
pbN = Encoding.ASCII.GetBytes("012b");
|
pbN = enc.GetBytes("012b");
|
||||||
if(MemUtil.IndexOf<byte>(pb, pbN) >= 0)
|
if(MemUtil.IndexOf<byte>(pb, pbN) >= 0)
|
||||||
throw new InvalidOperationException("MemUtil-7");
|
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");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void TestHmacOtp()
|
private static void TestHmacOtp()
|
||||||
{
|
{
|
||||||
#if (DEBUG && !KeePassLibSD && TODO)
|
#if (DEBUG && !KeePassLibSD && !KeePassRT)
|
||||||
byte[] pbSecret = Encoding.ASCII.GetBytes("12345678901234567890");
|
byte[] pbSecret = StrUtil.Utf8.GetBytes("12345678901234567890");
|
||||||
string[] vExp = new string[]{ "755224", "287082", "359152",
|
string[] vExp = new string[]{ "755224", "287082", "359152",
|
||||||
"969429", "338314", "254676", "287922", "162583", "399871",
|
"969429", "338314", "254676", "287922", "162583", "399871",
|
||||||
"520489" };
|
"520489" };
|
||||||
@@ -287,10 +317,10 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
|
|
||||||
private static void TestProtectedObjects()
|
private static void TestProtectedObjects()
|
||||||
{
|
{
|
||||||
|
|
||||||
#if TODO
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
byte[] pbData = Encoding.UTF8.GetBytes("Test Test Test Test");
|
Encoding enc = StrUtil.Utf8;
|
||||||
|
|
||||||
|
byte[] pbData = enc.GetBytes("Test Test Test Test");
|
||||||
ProtectedBinary pb = new ProtectedBinary(true, pbData);
|
ProtectedBinary pb = new ProtectedBinary(true, pbData);
|
||||||
if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-1");
|
if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-1");
|
||||||
|
|
||||||
@@ -299,8 +329,8 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
throw new SecurityException("ProtectedBinary-2");
|
throw new SecurityException("ProtectedBinary-2");
|
||||||
if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-3");
|
if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-3");
|
||||||
|
|
||||||
byte[] pbData2 = Encoding.UTF8.GetBytes("Test Test Test Test");
|
byte[] pbData2 = enc.GetBytes("Test Test Test Test");
|
||||||
byte[] pbData3 = Encoding.UTF8.GetBytes("Test Test Test Test Test");
|
byte[] pbData3 = enc.GetBytes("Test Test Test Test Test");
|
||||||
ProtectedBinary pb2 = new ProtectedBinary(true, pbData2);
|
ProtectedBinary pb2 = new ProtectedBinary(true, pbData2);
|
||||||
ProtectedBinary pb3 = new ProtectedBinary(true, pbData3);
|
ProtectedBinary pb3 = new ProtectedBinary(true, pbData3);
|
||||||
if(!pb.Equals(pb2)) throw new SecurityException("ProtectedBinary-4");
|
if(!pb.Equals(pb2)) throw new SecurityException("ProtectedBinary-4");
|
||||||
@@ -323,8 +353,7 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
throw new SecurityException("ProtectedString-3");
|
throw new SecurityException("ProtectedString-3");
|
||||||
|
|
||||||
ps = new ProtectedString(true, "Test");
|
ps = new ProtectedString(true, "Test");
|
||||||
ProtectedString ps2 = new ProtectedString(true,
|
ProtectedString ps2 = new ProtectedString(true, enc.GetBytes("Test"));
|
||||||
StrUtil.Utf8.GetBytes("Test"));
|
|
||||||
if(ps.IsEmpty) throw new SecurityException("ProtectedString-4");
|
if(ps.IsEmpty) throw new SecurityException("ProtectedString-4");
|
||||||
pbData = ps.ReadUtf8();
|
pbData = ps.ReadUtf8();
|
||||||
pbData2 = ps2.ReadUtf8();
|
pbData2 = ps2.ReadUtf8();
|
||||||
@@ -340,7 +369,41 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
throw new SecurityException("ProtectedString-8");
|
throw new SecurityException("ProtectedString-8");
|
||||||
if(!ps.IsProtected) throw new SecurityException("ProtectedString-9");
|
if(!ps.IsProtected) throw new SecurityException("ProtectedString-9");
|
||||||
if(!ps2.IsProtected) throw new SecurityException("ProtectedString-10");
|
if(!ps2.IsProtected) throw new SecurityException("ProtectedString-10");
|
||||||
#endif
|
|
||||||
|
Random r = new Random();
|
||||||
|
string str = string.Empty;
|
||||||
|
ps = new ProtectedString();
|
||||||
|
for(int i = 0; i < 100; ++i)
|
||||||
|
{
|
||||||
|
bool bProt = ((r.Next() % 4) != 0);
|
||||||
|
ps = ps.WithProtection(bProt);
|
||||||
|
|
||||||
|
int x = r.Next(str.Length + 1);
|
||||||
|
int c = r.Next(20);
|
||||||
|
char ch = (char)r.Next(1, 256);
|
||||||
|
|
||||||
|
string strIns = new string(ch, c);
|
||||||
|
str = str.Insert(x, strIns);
|
||||||
|
ps = ps.Insert(x, strIns);
|
||||||
|
|
||||||
|
if(ps.IsProtected != bProt)
|
||||||
|
throw new SecurityException("ProtectedString-11");
|
||||||
|
if(ps.ReadString() != str)
|
||||||
|
throw new SecurityException("ProtectedString-12");
|
||||||
|
|
||||||
|
ps = ps.WithProtection(bProt);
|
||||||
|
|
||||||
|
x = r.Next(str.Length);
|
||||||
|
c = r.Next(str.Length - x + 1);
|
||||||
|
|
||||||
|
str = str.Remove(x, c);
|
||||||
|
ps = ps.Remove(x, c);
|
||||||
|
|
||||||
|
if(ps.IsProtected != bProt)
|
||||||
|
throw new SecurityException("ProtectedString-13");
|
||||||
|
if(ps.ReadString() != str)
|
||||||
|
throw new SecurityException("ProtectedString-14");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,16 +444,64 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
throw new InvalidOperationException("StrUtil-V3");
|
throw new InvalidOperationException("StrUtil-V3");
|
||||||
if(StrUtil.VersionToString(0x00FF000000000000UL) != "255")
|
if(StrUtil.VersionToString(0x00FF000000000000UL) != "255")
|
||||||
throw new InvalidOperationException("StrUtil-V4");
|
throw new InvalidOperationException("StrUtil-V4");
|
||||||
if(StrUtil.VersionToString(0x00FF000000000000UL, true) != "255.0")
|
if(StrUtil.VersionToString(0x00FF000000000000UL, 2) != "255.0")
|
||||||
throw new InvalidOperationException("StrUtil-V5");
|
throw new InvalidOperationException("StrUtil-V5");
|
||||||
if(StrUtil.VersionToString(0x0000000000070000UL, true) != "0.0.7")
|
if(StrUtil.VersionToString(0x0000000000070000UL) != "0.0.7")
|
||||||
throw new InvalidOperationException("StrUtil-V6");
|
throw new InvalidOperationException("StrUtil-V6");
|
||||||
|
if(StrUtil.VersionToString(0x0000000000000000UL) != "0")
|
||||||
|
throw new InvalidOperationException("StrUtil-V7");
|
||||||
|
if(StrUtil.VersionToString(0x00000000FFFF0000UL, 4) != "0.0.65535.0")
|
||||||
|
throw new InvalidOperationException("StrUtil-V8");
|
||||||
|
if(StrUtil.VersionToString(0x0000000000000000UL, 4) != "0.0.0.0")
|
||||||
|
throw new InvalidOperationException("StrUtil-V9");
|
||||||
|
|
||||||
|
if(StrUtil.RtfEncodeChar('\u0000') != "\\u0?")
|
||||||
|
throw new InvalidOperationException("StrUtil-Rtf1");
|
||||||
|
if(StrUtil.RtfEncodeChar('\u7FFF') != "\\u32767?")
|
||||||
|
throw new InvalidOperationException("StrUtil-Rtf2");
|
||||||
|
if(StrUtil.RtfEncodeChar('\u8000') != "\\u-32768?")
|
||||||
|
throw new InvalidOperationException("StrUtil-Rtf3");
|
||||||
|
if(StrUtil.RtfEncodeChar('\uFFFF') != "\\u-1?")
|
||||||
|
throw new InvalidOperationException("StrUtil-Rtf4");
|
||||||
|
|
||||||
|
if(!StrUtil.StringToBool(Boolean.TrueString))
|
||||||
|
throw new InvalidOperationException("StrUtil-Bool1");
|
||||||
|
if(StrUtil.StringToBool(Boolean.FalseString))
|
||||||
|
throw new InvalidOperationException("StrUtil-Bool2");
|
||||||
|
|
||||||
|
if(StrUtil.Count("Abracadabra", "a") != 4)
|
||||||
|
throw new InvalidOperationException("StrUtil-Count1");
|
||||||
|
if(StrUtil.Count("Bla", "U") != 0)
|
||||||
|
throw new InvalidOperationException("StrUtil-Count2");
|
||||||
|
if(StrUtil.Count("AAAAA", "AA") != 4)
|
||||||
|
throw new InvalidOperationException("StrUtil-Count3");
|
||||||
|
|
||||||
|
const string sU = "data:mytype;base64,";
|
||||||
|
if(!StrUtil.IsDataUri(sU))
|
||||||
|
throw new InvalidOperationException("StrUtil-DataUri1");
|
||||||
|
if(!StrUtil.IsDataUri(sU, "mytype"))
|
||||||
|
throw new InvalidOperationException("StrUtil-DataUri2");
|
||||||
|
if(StrUtil.IsDataUri(sU, "notmytype"))
|
||||||
|
throw new InvalidOperationException("StrUtil-DataUri3");
|
||||||
|
|
||||||
|
uint u = 0x7FFFFFFFU;
|
||||||
|
if(u.ToString(NumberFormatInfo.InvariantInfo) != "2147483647")
|
||||||
|
throw new InvalidOperationException("StrUtil-Inv1");
|
||||||
|
if(uint.MaxValue.ToString(NumberFormatInfo.InvariantInfo) !=
|
||||||
|
"4294967295")
|
||||||
|
throw new InvalidOperationException("StrUtil-Inv2");
|
||||||
|
if(long.MinValue.ToString(NumberFormatInfo.InvariantInfo) !=
|
||||||
|
"-9223372036854775808")
|
||||||
|
throw new InvalidOperationException("StrUtil-Inv3");
|
||||||
|
if(short.MinValue.ToString(NumberFormatInfo.InvariantInfo) !=
|
||||||
|
"-32768")
|
||||||
|
throw new InvalidOperationException("StrUtil-Inv4");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void TestUrlUtil()
|
private static void TestUrlUtil()
|
||||||
{
|
{
|
||||||
#if DEBUG && TODO
|
#if DEBUG
|
||||||
if(UrlUtil.GetHost(@"scheme://domain:port/path?query_string#fragment_id") !=
|
if(UrlUtil.GetHost(@"scheme://domain:port/path?query_string#fragment_id") !=
|
||||||
"domain")
|
"domain")
|
||||||
throw new InvalidOperationException("UrlUtil-H1");
|
throw new InvalidOperationException("UrlUtil-H1");
|
||||||
@@ -408,7 +519,7 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
if(UrlUtil.GetHost(@"s://u:p@d.tld:p/p?q#f") != "d.tld")
|
if(UrlUtil.GetHost(@"s://u:p@d.tld:p/p?q#f") != "d.tld")
|
||||||
throw new InvalidOperationException("UrlUtil-H7");
|
throw new InvalidOperationException("UrlUtil-H7");
|
||||||
|
|
||||||
if(NativeLib.IsUnix()) return;
|
//if(NativeLib.IsUnix()) return;
|
||||||
|
|
||||||
string strBase = "\\\\HOMESERVER\\Apps\\KeePass\\KeePass.exe";
|
string strBase = "\\\\HOMESERVER\\Apps\\KeePass\\KeePass.exe";
|
||||||
string strDoc = "\\\\HOMESERVER\\Documents\\KeePass\\NewDatabase.kdbx";
|
string strDoc = "\\\\HOMESERVER\\Documents\\KeePass\\NewDatabase.kdbx";
|
||||||
@@ -419,6 +530,13 @@ namespace ModernKeePassLib.Cryptography
|
|||||||
|
|
||||||
str = UrlUtil.MakeAbsolutePath(strBase, strRel);
|
str = UrlUtil.MakeAbsolutePath(strBase, strRel);
|
||||||
if(!str.Equals(strDoc)) throw new InvalidOperationException("UrlUtil-R2");
|
if(!str.Equals(strDoc)) throw new InvalidOperationException("UrlUtil-R2");
|
||||||
|
|
||||||
|
str = UrlUtil.GetQuotedAppPath(" \"Test\" \"%1\" ");
|
||||||
|
if(str != "Test") throw new InvalidOperationException("UrlUtil-Q1");
|
||||||
|
str = UrlUtil.GetQuotedAppPath("C:\\Program Files\\Test.exe");
|
||||||
|
if(str != "C:\\Program Files\\Test.exe") throw new InvalidOperationException("UrlUtil-Q2");
|
||||||
|
str = UrlUtil.GetQuotedAppPath("Reg.exe \"Test\" \"Test 2\"");
|
||||||
|
if(str != "Reg.exe \"Test\" \"Test 2\"") throw new InvalidOperationException("UrlUtil-Q3");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -39,18 +39,18 @@ namespace ModernKeePassLib.Interfaces
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date/time when the object was last accessed.
|
/// The date/time when the object was last modified.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DateTime LastAccessTime
|
DateTime LastModificationTime
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date/time when the object was last modified.
|
/// The date/time when the object was last accessed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DateTime LastModificationTime
|
DateTime LastAccessTime
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,16 +22,18 @@ using System.Text;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
using Windows.Security.Cryptography.Core;
|
using Windows.Security.Cryptography.Core;
|
||||||
|
using Windows.Security.ExchangeActiveSyncProvisioning;
|
||||||
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Native;
|
|
||||||
using ModernKeePassLib.Resources;
|
using ModernKeePassLib.Resources;
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.Security.Cryptography;
|
|
||||||
using Windows.Storage.Streams;
|
|
||||||
using ModernKeePassLib.Cryptography;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.Keys
|
namespace ModernKeePassLib.Keys
|
||||||
{
|
{
|
||||||
@@ -54,7 +56,7 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
public uint UserKeyCount
|
public uint UserKeyCount
|
||||||
{
|
{
|
||||||
get { return (uint)m_vUserKeys.Count; }
|
get { return (uint) m_vUserKeys.Count; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -89,7 +91,8 @@ namespace ModernKeePassLib.Keys
|
|||||||
/// <param name="pKey">User key to add.</param>
|
/// <param name="pKey">User key to add.</param>
|
||||||
public void AddUserKey(IUserKey pKey)
|
public void AddUserKey(IUserKey pKey)
|
||||||
{
|
{
|
||||||
Debug.Assert(pKey != null); if(pKey == null) throw new ArgumentNullException("pKey");
|
Debug.Assert(pKey != null);
|
||||||
|
if (pKey == null) throw new ArgumentNullException("pKey");
|
||||||
|
|
||||||
m_vUserKeys.Add(pKey);
|
m_vUserKeys.Add(pKey);
|
||||||
}
|
}
|
||||||
@@ -101,25 +104,23 @@ namespace ModernKeePassLib.Keys
|
|||||||
/// <returns>Returns <c>true</c> if the key was removed successfully.</returns>
|
/// <returns>Returns <c>true</c> if the key was removed successfully.</returns>
|
||||||
public bool RemoveUserKey(IUserKey pKey)
|
public bool RemoveUserKey(IUserKey pKey)
|
||||||
{
|
{
|
||||||
Debug.Assert(pKey != null); if(pKey == null) throw new ArgumentNullException("pKey");
|
Debug.Assert(pKey != null);
|
||||||
|
if (pKey == null) throw new ArgumentNullException("pKey");
|
||||||
|
|
||||||
Debug.Assert(m_vUserKeys.IndexOf(pKey) >= 0);
|
Debug.Assert(m_vUserKeys.IndexOf(pKey) >= 0);
|
||||||
return m_vUserKeys.Remove(pKey);
|
return m_vUserKeys.Remove(pKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#if !PCL && !KeePassRT /// <summary>
|
||||||
/// Test whether the composite key contains a specific type of
|
/// Test whether the composite key contains a specific type of
|
||||||
/// user keys (password, key file, ...). If at least one user
|
/// user keys (password, key file, ...). If at least one user
|
||||||
/// key of that type is present, the function returns <c>true</c>.
|
/// key of that type is present, the function returns <c>true</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tUserKeyType">User key type.</param>
|
/// <param name="tUserKeyType">User key type.</param>
|
||||||
/// <returns>Returns <c>true</c>, if the composite key contains
|
/// <returns>Returns <c>true</c>, if the composite key contains
|
||||||
/// a user key of the specified type.</returns>
|
/// a user key of the specified type.</returns>
|
||||||
public bool ContainsType(Type tUserKeyType)
|
public bool ContainsType(Type tUserKeyType)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return false;
|
|
||||||
#if TODO
|
|
||||||
Debug.Assert(tUserKeyType != null);
|
Debug.Assert(tUserKeyType != null);
|
||||||
if(tUserKeyType == null) throw new ArgumentNullException("tUserKeyType");
|
if(tUserKeyType == null) throw new ArgumentNullException("tUserKeyType");
|
||||||
|
|
||||||
@@ -130,7 +131,6 @@ namespace ModernKeePassLib.Keys
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -141,10 +141,6 @@ namespace ModernKeePassLib.Keys
|
|||||||
/// or <c>null</c> if no key of that type is found.</returns>
|
/// or <c>null</c> if no key of that type is found.</returns>
|
||||||
public IUserKey GetUserKey(Type tUserKeyType)
|
public IUserKey GetUserKey(Type tUserKeyType)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
|
|
||||||
Debug.Assert(tUserKeyType != null);
|
Debug.Assert(tUserKeyType != null);
|
||||||
if(tUserKeyType == null) throw new ArgumentNullException("tUserKeyType");
|
if(tUserKeyType == null) throw new ArgumentNullException("tUserKeyType");
|
||||||
|
|
||||||
@@ -155,8 +151,8 @@ namespace ModernKeePassLib.Keys
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the composite key from the supplied user key sources (password,
|
/// Creates the composite key from the supplied user key sources (password,
|
||||||
@@ -168,10 +164,10 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
// Concatenate user key data
|
// Concatenate user key data
|
||||||
MemoryStream ms = new MemoryStream();
|
MemoryStream ms = new MemoryStream();
|
||||||
foreach(IUserKey pKey in m_vUserKeys)
|
foreach (IUserKey pKey in m_vUserKeys)
|
||||||
{
|
{
|
||||||
ProtectedBinary b = pKey.KeyData;
|
ProtectedBinary b = pKey.KeyData;
|
||||||
if(b != null)
|
if (b != null)
|
||||||
{
|
{
|
||||||
byte[] pbKeyData = b.ReadData();
|
byte[] pbKeyData = b.ReadData();
|
||||||
ms.Write(pbKeyData, 0, pbKeyData.Length);
|
ms.Write(pbKeyData, 0, pbKeyData.Length);
|
||||||
@@ -179,15 +175,20 @@ namespace ModernKeePassLib.Keys
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] pbHash = SHA256Managed.Instance.ComputeHash(ms.ToArray());
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
var pbHash = sha256.HashData(ms.ToArray().AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
|
byte[] pbHash = sha256.ComputeHash(ms.ToArray());
|
||||||
|
#endif
|
||||||
|
ms.Dispose();
|
||||||
return pbHash;
|
return pbHash;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool EqualsValue(CompositeKey ckOther)
|
public bool EqualsValue(CompositeKey ckOther)
|
||||||
{
|
{
|
||||||
if(ckOther == null) throw new ArgumentNullException("ckOther");
|
if (ckOther == null) throw new ArgumentNullException("ckOther");
|
||||||
|
|
||||||
byte[] pbThis = CreateRawCompositeKey32();
|
byte[] pbThis = CreateRawCompositeKey32();
|
||||||
byte[] pbOther = ckOther.CreateRawCompositeKey32();
|
byte[] pbOther = ckOther.CreateRawCompositeKey32();
|
||||||
@@ -210,17 +211,23 @@ namespace ModernKeePassLib.Keys
|
|||||||
public ProtectedBinary GenerateKey32(byte[] pbKeySeed32, ulong uNumRounds)
|
public ProtectedBinary GenerateKey32(byte[] pbKeySeed32, ulong uNumRounds)
|
||||||
{
|
{
|
||||||
Debug.Assert(pbKeySeed32 != null);
|
Debug.Assert(pbKeySeed32 != null);
|
||||||
if(pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32");
|
if (pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32");
|
||||||
Debug.Assert(pbKeySeed32.Length == 32);
|
Debug.Assert(pbKeySeed32.Length == 32);
|
||||||
if(pbKeySeed32.Length != 32) throw new ArgumentException("pbKeySeed32");
|
if (pbKeySeed32.Length != 32) throw new ArgumentException("pbKeySeed32");
|
||||||
|
|
||||||
byte[] pbRaw32 = CreateRawCompositeKey32();
|
byte[] pbRaw32 = CreateRawCompositeKey32();
|
||||||
if((pbRaw32 == null) || (pbRaw32.Length != 32))
|
if ((pbRaw32 == null) || (pbRaw32.Length != 32))
|
||||||
{ Debug.Assert(false); return null; }
|
{
|
||||||
|
Debug.Assert(false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
byte[] pbTrf32 = TransformKey(pbRaw32, pbKeySeed32, uNumRounds);
|
byte[] pbTrf32 = TransformKey(pbRaw32, pbKeySeed32, uNumRounds);
|
||||||
if((pbTrf32 == null) || (pbTrf32.Length != 32))
|
if ((pbTrf32 == null) || (pbTrf32.Length != 32))
|
||||||
{ Debug.Assert(false); return null; }
|
{
|
||||||
|
Debug.Assert(false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
ProtectedBinary pbRet = new ProtectedBinary(true, pbTrf32);
|
ProtectedBinary pbRet = new ProtectedBinary(true, pbTrf32);
|
||||||
MemUtil.ZeroByteArray(pbTrf32);
|
MemUtil.ZeroByteArray(pbTrf32);
|
||||||
@@ -231,6 +238,7 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
private void ValidateUserKeys()
|
private void ValidateUserKeys()
|
||||||
{
|
{
|
||||||
|
#if !PCL
|
||||||
int nAccounts = 0;
|
int nAccounts = 0;
|
||||||
|
|
||||||
foreach(IUserKey uKey in m_vUserKeys)
|
foreach(IUserKey uKey in m_vUserKeys)
|
||||||
@@ -244,6 +252,7 @@ namespace ModernKeePassLib.Keys
|
|||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -258,85 +267,55 @@ namespace ModernKeePassLib.Keys
|
|||||||
private static byte[] TransformKey(byte[] pbOriginalKey32, byte[] pbKeySeed32,
|
private static byte[] TransformKey(byte[] pbOriginalKey32, byte[] pbKeySeed32,
|
||||||
ulong uNumRounds)
|
ulong uNumRounds)
|
||||||
{
|
{
|
||||||
|
|
||||||
Debug.Assert((pbOriginalKey32 != null) && (pbOriginalKey32.Length == 32));
|
Debug.Assert((pbOriginalKey32 != null) && (pbOriginalKey32.Length == 32));
|
||||||
if(pbOriginalKey32 == null) throw new ArgumentNullException("pbOriginalKey32");
|
if (pbOriginalKey32 == null) throw new ArgumentNullException("pbOriginalKey32");
|
||||||
if(pbOriginalKey32.Length != 32) throw new ArgumentException();
|
if (pbOriginalKey32.Length != 32) throw new ArgumentException();
|
||||||
|
|
||||||
Debug.Assert((pbKeySeed32 != null) && (pbKeySeed32.Length == 32));
|
Debug.Assert((pbKeySeed32 != null) && (pbKeySeed32.Length == 32));
|
||||||
if(pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32");
|
if (pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32");
|
||||||
if(pbKeySeed32.Length != 32) throw new ArgumentException();
|
if (pbKeySeed32.Length != 32) throw new ArgumentException();
|
||||||
|
|
||||||
byte[] pbNewKey = new byte[32];
|
byte[] pbNewKey = new byte[32];
|
||||||
Array.Copy(pbOriginalKey32, pbNewKey, pbNewKey.Length);
|
Array.Copy(pbOriginalKey32, pbNewKey, pbNewKey.Length);
|
||||||
|
|
||||||
if(TransformKeyManaged(pbNewKey, pbKeySeed32, uNumRounds) == false)
|
#if !PCL // Try to use the native library first
|
||||||
|
if(NativeLib.TransformKey256(pbNewKey, pbKeySeed32, uNumRounds))
|
||||||
|
return (new SHA256Managed()).ComputeHash(pbNewKey);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (TransformKeyManaged(pbNewKey, pbKeySeed32, uNumRounds) == false)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
byte[] transformedKey = SHA256Managed.Instance.ComputeHash(pbNewKey);
|
#if PCL
|
||||||
return (transformedKey);
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
return sha256.HashData(pbNewKey.AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
|
return sha256.ComputeHash(pbNewKey);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
|
public static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
|
||||||
ulong uNumRounds)
|
ulong uNumRounds)
|
||||||
{
|
{
|
||||||
|
#if KeePassRT
|
||||||
|
KeyParameter kp = new KeyParameter(pbKeySeed32);
|
||||||
|
AesEngine aes = new AesEngine();
|
||||||
|
aes.Init(true, kp);
|
||||||
|
|
||||||
|
for(ulong i = 0; i < uNumRounds; ++i)
|
||||||
|
{
|
||||||
|
aes.ProcessBlock(pbNewKey32, 0, pbNewKey32, 0);
|
||||||
|
aes.ProcessBlock(pbNewKey32, 16, pbNewKey32, 16);
|
||||||
|
}
|
||||||
|
#elif PCL
|
||||||
|
var aes = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcb);
|
||||||
|
var key = aes.CreateSymmetricKey(pbKeySeed32.AsBuffer());
|
||||||
|
//var iCrypt = CryptographicEngine.CreateEncryptor(key);
|
||||||
|
#else
|
||||||
byte[] pbIV = new byte[16];
|
byte[] pbIV = new byte[16];
|
||||||
Array.Clear(pbIV, 0, pbIV.Length);
|
Array.Clear(pbIV, 0, pbIV.Length);
|
||||||
|
|
||||||
String strAlgName = "AES_ECB"; // Algorithm name
|
|
||||||
|
|
||||||
IBuffer iv = null; // no IV used in ECB.
|
|
||||||
IBuffer buffMsg = CryptographicBuffer.CreateFromByteArray(pbNewKey32);
|
|
||||||
IBuffer keyMaterial = CryptographicBuffer.CreateFromByteArray(pbKeySeed32);
|
|
||||||
SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(strAlgName);
|
|
||||||
CryptographicKey key = objAlg.CreateSymmetricKey(keyMaterial);
|
|
||||||
|
|
||||||
for (ulong i = 0; i < uNumRounds; ++i)
|
|
||||||
{
|
|
||||||
buffMsg = CryptographicEngine.Encrypt(key, buffMsg, iv);
|
|
||||||
}
|
|
||||||
byte[] newKey32;
|
|
||||||
CryptographicBuffer.CopyToByteArray(buffMsg, out newKey32);
|
|
||||||
newKey32.CopyTo(pbNewKey32,0);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Benchmark the <c>TransformKey</c> method. Within
|
|
||||||
/// <paramref name="uMilliseconds"/> ms, random keys will be transformed
|
|
||||||
/// and the number of performed transformations are returned.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="uMilliseconds">Test duration in ms.</param>
|
|
||||||
/// <param name="uStep">Stepping.
|
|
||||||
/// <paramref name="uStep" /> should be a prime number. For fast processors
|
|
||||||
/// (PCs) a value of <c>3001</c> is recommended, for slower processors (PocketPC)
|
|
||||||
/// a value of <c>401</c> is recommended.</param>
|
|
||||||
/// <returns>Number of transformations performed in the specified
|
|
||||||
/// amount of time. Maximum value is <c>uint.MaxValue</c>.</returns>
|
|
||||||
public static ulong TransformKeyBenchmark(uint uMilliseconds, ulong uStep)
|
|
||||||
{
|
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return 0;
|
|
||||||
#if TODO
|
|
||||||
ulong uRounds;
|
|
||||||
|
|
||||||
// Try native method
|
|
||||||
if(NativeLib.TransformKeyBenchmark256(uMilliseconds, out uRounds))
|
|
||||||
return uRounds;
|
|
||||||
|
|
||||||
byte[] pbIV = new byte[16];
|
|
||||||
Array.Clear(pbIV, 0, pbIV.Length);
|
|
||||||
|
|
||||||
byte[] pbKey = new byte[32];
|
|
||||||
byte[] pbNewKey = new byte[32];
|
|
||||||
for(int i = 0; i < pbKey.Length; ++i)
|
|
||||||
{
|
|
||||||
pbKey[i] = (byte)i;
|
|
||||||
pbNewKey[i] = (byte)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
RijndaelManaged r = new RijndaelManaged();
|
RijndaelManaged r = new RijndaelManaged();
|
||||||
if(r.BlockSize != 128) // AES block size
|
if(r.BlockSize != 128) // AES block size
|
||||||
{
|
{
|
||||||
@@ -347,56 +326,40 @@ namespace ModernKeePassLib.Keys
|
|||||||
r.IV = pbIV;
|
r.IV = pbIV;
|
||||||
r.Mode = CipherMode.ECB;
|
r.Mode = CipherMode.ECB;
|
||||||
r.KeySize = 256;
|
r.KeySize = 256;
|
||||||
r.Key = pbKey;
|
r.Key = pbKeySeed32;
|
||||||
ICryptoTransform iCrypt = r.CreateEncryptor();
|
ICryptoTransform iCrypt = r.CreateEncryptor();
|
||||||
|
#endif
|
||||||
|
|
||||||
// !iCrypt.CanReuseTransform -- doesn't work with Mono
|
// !iCrypt.CanReuseTransform -- doesn't work with Mono
|
||||||
if((iCrypt == null) || (iCrypt.InputBlockSize != 16) ||
|
/*if ((iCrypt == null) || (iCrypt.InputBlockSize != 16) ||
|
||||||
(iCrypt.OutputBlockSize != 16))
|
(iCrypt.OutputBlockSize != 16))*/
|
||||||
|
if (aes.BlockLength != 16)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "Invalid ICryptoTransform.");
|
Debug.Assert(false, "Invalid ICryptoTransform.");
|
||||||
Debug.Assert(iCrypt.InputBlockSize == 16, "Invalid input block size!");
|
/*Debug.Assert((iCrypt.InputBlockSize == 16), "Invalid input block size!");
|
||||||
Debug.Assert(iCrypt.OutputBlockSize == 16, "Invalid output block size!");
|
Debug.Assert((iCrypt.OutputBlockSize == 16), "Invalid output block size!");*/
|
||||||
return PwDefs.DefaultKeyEncryptionRounds;
|
Debug.Assert(aes.BlockLength == 16, "Invalid input block size!");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime dtStart = DateTime.Now;
|
for (ulong i = 0; i < uNumRounds; ++i)
|
||||||
TimeSpan ts;
|
|
||||||
double dblReqMillis = uMilliseconds;
|
|
||||||
|
|
||||||
uRounds = 0;
|
|
||||||
while(true)
|
|
||||||
{
|
{
|
||||||
for(ulong j = 0; j < uStep; ++j)
|
/*iCrypt.TransformBlock(pbNewKey32, 0, 16, pbNewKey32, 0);
|
||||||
{
|
iCrypt.TransformBlock(pbNewKey32, 16, 16, pbNewKey32, 16);*/
|
||||||
iCrypt.TransformBlock(pbNewKey, 0, 16, pbNewKey, 0);
|
|
||||||
iCrypt.TransformBlock(pbNewKey, 16, 16, pbNewKey, 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uRounds += uStep;
|
return true;
|
||||||
if(uRounds < uStep) // Overflow check
|
|
||||||
{
|
|
||||||
uRounds = ulong.MaxValue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ts = DateTime.Now - dtStart;
|
|
||||||
if(ts.TotalMilliseconds > dblReqMillis) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return uRounds;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class InvalidCompositeKeyException : Exception
|
public sealed class InvalidCompositeKeyException : Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
public override string Message
|
public override string Message
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return "The composite key is invalid!" + Environment.NewLine + "Make sure the composite key is correct and try again."; // No translation needed here, the message will not be shown in the UI.
|
return KLRes.InvalidCompositeKey + Environment.NewLine
|
||||||
|
+ Environment.NewLine + KLRes.InvalidCompositeKeyHint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,8 +17,20 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Keys
|
namespace ModernKeePassLib.Keys
|
||||||
{
|
{
|
||||||
@@ -42,10 +54,6 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
public KcpCustomKey(string strName, byte[] pbKeyData, bool bPerformHash)
|
public KcpCustomKey(string strName, byte[] pbKeyData, bool bPerformHash)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return;
|
|
||||||
#if TODO
|
|
||||||
|
|
||||||
Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
|
Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
|
||||||
Debug.Assert(pbKeyData != null); if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");
|
Debug.Assert(pbKeyData != null); if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");
|
||||||
|
|
||||||
@@ -53,12 +61,16 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
if(bPerformHash)
|
if(bPerformHash)
|
||||||
{
|
{
|
||||||
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
var pbRaw = sha256.HashData(pbKeyData.AsBuffer());
|
||||||
|
#else
|
||||||
SHA256Managed sha256 = new SHA256Managed();
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
byte[] pbRaw = sha256.ComputeHash(pbKeyData);
|
byte[] pbRaw = sha256.ComputeHash(pbKeyData);
|
||||||
m_pbKey = new ProtectedBinary(true, pbRaw);
|
#endif
|
||||||
|
m_pbKey = new ProtectedBinary(true, pbRaw.ToArray());
|
||||||
}
|
}
|
||||||
else m_pbKey = new ProtectedBinary(true, pbKeyData);
|
else m_pbKey = new ProtectedBinary(true, pbKeyData);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void Clear()
|
// public void Clear()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,9 +17,27 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Security;
|
||||||
|
#if PCL
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
|
using ModernKeePassLib.Cryptography;
|
||||||
|
using ModernKeePassLib.Resources;
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
using ModernKeePassLib.Serialization;
|
using ModernKeePassLib.Serialization;
|
||||||
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Keys
|
namespace ModernKeePassLib.Keys
|
||||||
{
|
{
|
||||||
@@ -51,22 +69,47 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
public KcpKeyFile(string strKeyFile)
|
public KcpKeyFile(string strKeyFile)
|
||||||
{
|
{
|
||||||
Construct(IOConnectionInfo.FromPath(strKeyFile));
|
Construct(IOConnectionInfo.FromPath(strKeyFile), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KcpKeyFile(string strKeyFile, bool bThrowIfDbFile)
|
||||||
|
{
|
||||||
|
Construct(IOConnectionInfo.FromPath(strKeyFile), bThrowIfDbFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KcpKeyFile(IOConnectionInfo iocKeyFile)
|
public KcpKeyFile(IOConnectionInfo iocKeyFile)
|
||||||
{
|
{
|
||||||
Construct(iocKeyFile);
|
Construct(iocKeyFile, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Construct(IOConnectionInfo iocFile)
|
public KcpKeyFile(IOConnectionInfo iocKeyFile, bool bThrowIfDbFile)
|
||||||
|
{
|
||||||
|
Construct(iocKeyFile, bThrowIfDbFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Construct(IOConnectionInfo iocFile, bool bThrowIfDbFile)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return;
|
|
||||||
#if TODO
|
|
||||||
byte[] pbFileData = IOConnection.ReadFile(iocFile);
|
byte[] pbFileData = IOConnection.ReadFile(iocFile);
|
||||||
if(pbFileData == null) throw new FileNotFoundException();
|
if(pbFileData == null) throw new FileNotFoundException();
|
||||||
|
|
||||||
|
if(bThrowIfDbFile && (pbFileData.Length >= 8))
|
||||||
|
{
|
||||||
|
uint uSig1 = MemUtil.BytesToUInt32(MemUtil.Mid(pbFileData, 0, 4));
|
||||||
|
uint uSig2 = MemUtil.BytesToUInt32(MemUtil.Mid(pbFileData, 4, 4));
|
||||||
|
|
||||||
|
if(((uSig1 == KdbxFile.FileSignature1) &&
|
||||||
|
(uSig2 == KdbxFile.FileSignature2)) ||
|
||||||
|
((uSig1 == KdbxFile.FileSignaturePreRelease1) &&
|
||||||
|
(uSig2 == KdbxFile.FileSignaturePreRelease2)) ||
|
||||||
|
((uSig1 == KdbxFile.FileSignatureOld1) &&
|
||||||
|
(uSig2 == KdbxFile.FileSignatureOld2)))
|
||||||
|
#if KeePassLibSD
|
||||||
|
throw new Exception(KLRes.KeyFileDbSel);
|
||||||
|
#else
|
||||||
|
throw new InvalidDataException(KLRes.KeyFileDbSel);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
byte[] pbKey = LoadXmlKeyFile(pbFileData);
|
byte[] pbKey = LoadXmlKeyFile(pbFileData);
|
||||||
if(pbKey == null) pbKey = LoadKeyFile(pbFileData);
|
if(pbKey == null) pbKey = LoadKeyFile(pbFileData);
|
||||||
|
|
||||||
@@ -76,7 +119,6 @@ namespace ModernKeePassLib.Keys
|
|||||||
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
||||||
|
|
||||||
MemUtil.ZeroByteArray(pbKey);
|
MemUtil.ZeroByteArray(pbKey);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void Clear()
|
// public void Clear()
|
||||||
@@ -87,9 +129,6 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
private static byte[] LoadKeyFile(byte[] pbFileData)
|
private static byte[] LoadKeyFile(byte[] pbFileData)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
if(pbFileData == null) { Debug.Assert(false); return null; }
|
if(pbFileData == null) { Debug.Assert(false); return null; }
|
||||||
|
|
||||||
int iLength = pbFileData.Length;
|
int iLength = pbFileData.Length;
|
||||||
@@ -100,12 +139,16 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
if(pbKey == null)
|
if(pbKey == null)
|
||||||
{
|
{
|
||||||
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
pbKey = sha256.HashData(pbFileData.AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
SHA256Managed sha256 = new SHA256Managed();
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
pbKey = sha256.ComputeHash(pbFileData);
|
pbKey = sha256.ComputeHash(pbFileData);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return pbKey;
|
return pbKey;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] LoadBinaryKey32(byte[] pbFileData)
|
private static byte[] LoadBinaryKey32(byte[] pbFileData)
|
||||||
@@ -118,15 +161,12 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
private static byte[] LoadHexKey32(byte[] pbFileData)
|
private static byte[] LoadHexKey32(byte[] pbFileData)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
if(pbFileData == null) { Debug.Assert(false); return null; }
|
if(pbFileData == null) { Debug.Assert(false); return null; }
|
||||||
if(pbFileData.Length != 64) { Debug.Assert(false); return null; }
|
if(pbFileData.Length != 64) { Debug.Assert(false); return null; }
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string strHex = Encoding.ASCII.GetString(pbFileData, 0, 64);
|
string strHex = StrUtil.Utf8.GetString(pbFileData, 0, 64);
|
||||||
if(!StrUtil.IsHexString(strHex, true)) return null;
|
if(!StrUtil.IsHexString(strHex, true)) return null;
|
||||||
|
|
||||||
byte[] pbKey = MemUtil.HexStringToByteArray(strHex);
|
byte[] pbKey = MemUtil.HexStringToByteArray(strHex);
|
||||||
@@ -138,7 +178,6 @@ namespace ModernKeePassLib.Keys
|
|||||||
catch(Exception) { Debug.Assert(false); }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -152,9 +191,6 @@ namespace ModernKeePassLib.Keys
|
|||||||
/// <returns>Returns a <c>FileSaveResult</c> error code.</returns>
|
/// <returns>Returns a <c>FileSaveResult</c> error code.</returns>
|
||||||
public static void Create(string strFilePath, byte[] pbAdditionalEntropy)
|
public static void Create(string strFilePath, byte[] pbAdditionalEntropy)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return;
|
|
||||||
#if TODO
|
|
||||||
byte[] pbKey32 = CryptoRandom.Instance.GetRandomBytes(32);
|
byte[] pbKey32 = CryptoRandom.Instance.GetRandomBytes(32);
|
||||||
if(pbKey32 == null) throw new SecurityException();
|
if(pbKey32 == null) throw new SecurityException();
|
||||||
|
|
||||||
@@ -163,17 +199,22 @@ namespace ModernKeePassLib.Keys
|
|||||||
pbFinalKey32 = pbKey32;
|
pbFinalKey32 = pbKey32;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MemoryStream ms = new MemoryStream();
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
ms.Write(pbAdditionalEntropy, 0, pbAdditionalEntropy.Length);
|
ms.Write(pbAdditionalEntropy, 0, pbAdditionalEntropy.Length);
|
||||||
ms.Write(pbKey32, 0, 32);
|
ms.Write(pbKey32, 0, 32);
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
pbFinalKey32 = sha256.HashData(ms.GetWindowsRuntimeBuffer()).ToArray();
|
||||||
|
#else
|
||||||
SHA256Managed sha256 = new SHA256Managed();
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
pbFinalKey32 = sha256.ComputeHash(ms.ToArray());
|
pbFinalKey32 = sha256.ComputeHash(ms.ToArray());
|
||||||
ms.Close();
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateXmlKeyFile(strFilePath, pbFinalKey32);
|
CreateXmlKeyFile(strFilePath, pbFinalKey32);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -199,9 +240,6 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
private static byte[] LoadXmlKeyFile(byte[] pbFileData)
|
private static byte[] LoadXmlKeyFile(byte[] pbFileData)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
if(pbFileData == null) { Debug.Assert(false); return null; }
|
if(pbFileData == null) { Debug.Assert(false); return null; }
|
||||||
|
|
||||||
MemoryStream ms = new MemoryStream(pbFileData, false);
|
MemoryStream ms = new MemoryStream(pbFileData, false);
|
||||||
@@ -209,10 +247,38 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#if PCL
|
||||||
|
|
||||||
|
var doc = XDocument.Load(ms);
|
||||||
|
|
||||||
|
var el = doc.Root;
|
||||||
|
|
||||||
|
if((el == null) || !el.Name.LocalName.Equals(RootElementName))
|
||||||
|
return null;
|
||||||
|
if(el.DescendantNodes().Count() < 2)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
foreach(var xmlChild in el.Descendants())
|
||||||
|
{
|
||||||
|
if(xmlChild.Name == MetaElementName) { } // Ignore Meta
|
||||||
|
else if(xmlChild.Name == KeyElementName)
|
||||||
|
{
|
||||||
|
foreach(var xmlKeyChild in xmlChild.Descendants())
|
||||||
|
{
|
||||||
|
if(xmlKeyChild.Name == KeyDataElementName)
|
||||||
|
{
|
||||||
|
if(pbKeyData == null)
|
||||||
|
pbKeyData = Convert.FromBase64String(xmlKeyChild.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
doc.Load(ms);
|
doc.Load(ms);
|
||||||
|
|
||||||
XmlElement el = doc.DocumentElement;
|
XmlElement el = doc.DocumentElement;
|
||||||
|
|
||||||
if((el == null) || !el.Name.Equals(RootElementName)) return null;
|
if((el == null) || !el.Name.Equals(RootElementName)) return null;
|
||||||
if(el.ChildNodes.Count < 2) return null;
|
if(el.ChildNodes.Count < 2) return null;
|
||||||
|
|
||||||
@@ -231,26 +297,30 @@ namespace ModernKeePassLib.Keys
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch(Exception) { pbKeyData = null; }
|
catch(Exception) { pbKeyData = null; }
|
||||||
finally { ms.Close(); }
|
finally { ms.Dispose(); }
|
||||||
|
|
||||||
return pbKeyData;
|
return pbKeyData;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateXmlKeyFile(string strFile, byte[] pbKeyData)
|
private static void CreateXmlKeyFile(string strFile, byte[] pbKeyData)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return;
|
|
||||||
#if TODO
|
|
||||||
|
|
||||||
Debug.Assert(strFile != null);
|
Debug.Assert(strFile != null);
|
||||||
if(strFile == null) throw new ArgumentNullException("strFile");
|
if(strFile == null) throw new ArgumentNullException("strFile");
|
||||||
Debug.Assert(pbKeyData != null);
|
Debug.Assert(pbKeyData != null);
|
||||||
if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");
|
if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");
|
||||||
|
|
||||||
XmlTextWriter xtw = new XmlTextWriter(strFile, StrUtil.Utf8);
|
IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
|
||||||
|
Stream sOut = IOConnection.OpenWrite(ioc);
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
var settings = new XmlWriterSettings() { Encoding = StrUtil.Utf8 };
|
||||||
|
var xtw = XmlWriter.Create(sOut, settings);
|
||||||
|
#else
|
||||||
|
XmlTextWriter xtw = new XmlTextWriter(sOut, StrUtil.Utf8);
|
||||||
|
#endif
|
||||||
|
|
||||||
xtw.WriteStartDocument();
|
xtw.WriteStartDocument();
|
||||||
xtw.WriteWhitespace("\r\n");
|
xtw.WriteWhitespace("\r\n");
|
||||||
@@ -280,8 +350,9 @@ namespace ModernKeePassLib.Keys
|
|||||||
xtw.WriteEndElement(); // RootElementName
|
xtw.WriteEndElement(); // RootElementName
|
||||||
xtw.WriteWhitespace("\r\n");
|
xtw.WriteWhitespace("\r\n");
|
||||||
xtw.WriteEndDocument(); // End KeyFile
|
xtw.WriteEndDocument(); // End KeyFile
|
||||||
xtw.Close();
|
xtw.Dispose();
|
||||||
#endif
|
|
||||||
|
sOut.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,10 +18,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
using ModernKeePassLib.Cryptography;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.Keys
|
namespace ModernKeePassLib.Keys
|
||||||
{
|
{
|
||||||
@@ -66,11 +74,16 @@ namespace ModernKeePassLib.Keys
|
|||||||
Debug.Assert(pbPasswordUtf8 != null);
|
Debug.Assert(pbPasswordUtf8 != null);
|
||||||
if(pbPasswordUtf8 == null) throw new ArgumentNullException("pbPasswordUtf8");
|
if(pbPasswordUtf8 == null) throw new ArgumentNullException("pbPasswordUtf8");
|
||||||
|
|
||||||
byte[] pbRaw = SHA256Managed.Instance.ComputeHash(pbPasswordUtf8);
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
var pbRaw = sha256.HashData(pbPasswordUtf8.AsBuffer());
|
||||||
|
#else
|
||||||
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
|
byte[] pbRaw = sha256.ComputeHash(pbPasswordUtf8);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_psPassword = new ProtectedString(true, pbPasswordUtf8);
|
m_psPassword = new ProtectedString(true, pbPasswordUtf8);
|
||||||
m_pbKeyData = new ProtectedBinary(true, pbRaw);
|
m_pbKeyData = new ProtectedBinary(true, pbRaw.ToArray());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void Clear()
|
// public void Clear()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,8 +17,18 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Security;
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.DataProtection;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Windows.Storage.Streams;
|
||||||
|
using ModernKeePassLib.Cryptography;
|
||||||
|
using ModernKeePassLib.Resources;
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Keys
|
namespace ModernKeePassLib.Keys
|
||||||
{
|
{
|
||||||
@@ -52,14 +62,14 @@ namespace ModernKeePassLib.Keys
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public KcpUserAccount()
|
public KcpUserAccount()
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return;
|
|
||||||
#if TODO
|
|
||||||
// Test if ProtectedData is supported -- throws an exception
|
// Test if ProtectedData is supported -- throws an exception
|
||||||
// when running on an old system (Windows 98 / ME).
|
// when running on an old system (Windows 98 / ME).
|
||||||
byte[] pbDummyData = new byte[128];
|
byte[] pbDummyData = new byte[128];
|
||||||
ProtectedData.Protect(pbDummyData, m_pbEntropy,
|
|
||||||
DataProtectionScope.CurrentUser);
|
DataProtectionProvider provider = new DataProtectionProvider("Local=user");
|
||||||
|
provider.ProtectAsync(pbDummyData.AsBuffer()).GetResults();
|
||||||
|
/*ProtectedData.Protect(pbDummyData, m_pbEntropy,
|
||||||
|
DataProtectionScope.CurrentUser);*/
|
||||||
|
|
||||||
byte[] pbKey = LoadUserKey(false);
|
byte[] pbKey = LoadUserKey(false);
|
||||||
if(pbKey == null) pbKey = CreateUserKey();
|
if(pbKey == null) pbKey = CreateUserKey();
|
||||||
@@ -67,7 +77,6 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
||||||
Array.Clear(pbKey, 0, pbKey.Length);
|
Array.Clear(pbKey, 0, pbKey.Length);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void Clear()
|
// public void Clear()
|
||||||
@@ -77,42 +86,54 @@ namespace ModernKeePassLib.Keys
|
|||||||
|
|
||||||
private static string GetUserKeyFilePath(bool bCreate)
|
private static string GetUserKeyFilePath(bool bCreate)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
#if KeePassRT
|
||||||
return null;
|
string strUserDir = ApplicationData.Current.RoamingFolder.Path;
|
||||||
#if TODO
|
#else
|
||||||
|
/*string strUserDir = Environment.GetFolderPath(
|
||||||
string strUserDir = Environment.GetFolderPath(
|
Environment.SpecialFolder.ApplicationData);*/
|
||||||
Environment.SpecialFolder.ApplicationData);
|
var strUserDir = ApplicationData.Current.RoamingFolder.Path;
|
||||||
|
#endif
|
||||||
|
|
||||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||||
strUserDir += PwDefs.ShortProductName;
|
strUserDir += PwDefs.ShortProductName;
|
||||||
|
|
||||||
if(bCreate && !Directory.Exists(strUserDir))
|
// Folder is sure to exist
|
||||||
Directory.CreateDirectory(strUserDir);
|
/*if(bCreate && !Directory.Exists(strUserDir))
|
||||||
|
Directory.CreateDirectory(strUserDir);*/
|
||||||
|
|
||||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||||
return strUserDir + UserKeyFileName;
|
return strUserDir + UserKeyFileName;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] LoadUserKey(bool bShowWarning)
|
private static byte[] LoadUserKey(bool bShowWarning)
|
||||||
{
|
{
|
||||||
byte[] pbKey = null;
|
byte[] pbKey = null;
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if !KeePassLibSD
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string strFilePath = GetUserKeyFilePath(false);
|
string strFilePath = GetUserKeyFilePath(false);
|
||||||
byte[] pbProtectedKey = File.ReadAllBytes(strFilePath);
|
var pbProtectedKeyStream =
|
||||||
|
ApplicationData.Current.RoamingFolder.GetFileAsync(strFilePath).GetResults().
|
||||||
|
OpenAsync(FileAccessMode.Read).GetResults().AsStream();
|
||||||
|
using (var ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
ms.CopyTo(pbProtectedKeyStream);
|
||||||
|
var pbProtectedKey = ms.ToArray();
|
||||||
|
|
||||||
pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy,
|
//byte[] pbProtectedKey = File.ReadAllBytes(strFilePath);
|
||||||
DataProtectionScope.CurrentUser);
|
|
||||||
|
DataProtectionProvider provider = new DataProtectionProvider("Local=user");
|
||||||
|
pbKey = provider.UnprotectAsync(pbProtectedKey.AsBuffer()).GetResults().ToArray();
|
||||||
|
/*pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy,
|
||||||
|
DataProtectionScope.CurrentUser);*/
|
||||||
|
|
||||||
Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length);
|
Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Exception exLoad)
|
catch(Exception exLoad)
|
||||||
{
|
{
|
||||||
if(bShowWarning) MessageService.ShowWarning(exLoad);
|
//if(bShowWarning) MessageService.ShowWarning(exLoad);
|
||||||
|
|
||||||
pbKey = null;
|
pbKey = null;
|
||||||
}
|
}
|
||||||
@@ -125,16 +146,22 @@ namespace ModernKeePassLib.Keys
|
|||||||
{
|
{
|
||||||
byte[] pbKey = null;
|
byte[] pbKey = null;
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if !KeePassLibSD
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string strFilePath = GetUserKeyFilePath(true);
|
string strFilePath = GetUserKeyFilePath(true);
|
||||||
|
|
||||||
byte[] pbRandomKey = CryptoRandom.Instance.GetRandomBytes(64);
|
byte[] pbRandomKey = CryptoRandom.Instance.GetRandomBytes(64);
|
||||||
byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey,
|
|
||||||
m_pbEntropy, DataProtectionScope.CurrentUser);
|
|
||||||
|
|
||||||
File.WriteAllBytes(strFilePath, pbProtectedKey);
|
DataProtectionProvider provider = new DataProtectionProvider("Local=user");
|
||||||
|
var pbProtectedKey = provider.ProtectAsync(pbRandomKey.AsBuffer()).GetResults().ToArray();
|
||||||
|
/*byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey,
|
||||||
|
m_pbEntropy, DataProtectionScope.CurrentUser);*/
|
||||||
|
|
||||||
|
var file = ApplicationData.Current.RoamingFolder.CreateFileAsync(strFilePath).GetResults().
|
||||||
|
OpenAsync(FileAccessMode.ReadWrite).GetResults();
|
||||||
|
file.WriteAsync(pbProtectedKey.AsBuffer()).GetResults();
|
||||||
|
//File.WriteAllBytes(strFilePath, pbProtectedKey);
|
||||||
|
|
||||||
Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length);
|
Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length);
|
||||||
Array.Clear(pbRandomKey, 0, pbRandomKey.Length);
|
Array.Clear(pbRandomKey, 0, pbRandomKey.Length);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
Binary file not shown.
@@ -24,7 +24,7 @@
|
|||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
<DefineConstants>TRACE;DEBUG;NETSTANDARD1_2, KeePassWinRT</DefineConstants>
|
<DefineConstants>TRACE;DEBUG;NETSTANDARD1_2, PCL</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -126,7 +126,6 @@
|
|||||||
<Compile Include="Cryptography\PopularPasswords.cs" />
|
<Compile Include="Cryptography\PopularPasswords.cs" />
|
||||||
<Compile Include="Cryptography\QualityEstimation.cs" />
|
<Compile Include="Cryptography\QualityEstimation.cs" />
|
||||||
<Compile Include="Cryptography\SelfTest.cs" />
|
<Compile Include="Cryptography\SelfTest.cs" />
|
||||||
<Compile Include="Cryptography\SHA256Managed.cs" />
|
|
||||||
<Compile Include="DebugAssert.cs" />
|
<Compile Include="DebugAssert.cs" />
|
||||||
<Compile Include="Interfaces\IStructureItem.cs" />
|
<Compile Include="Interfaces\IStructureItem.cs" />
|
||||||
<Compile Include="Interfaces\IUIOperations.cs" />
|
<Compile Include="Interfaces\IUIOperations.cs" />
|
||||||
@@ -137,7 +136,6 @@
|
|||||||
<Compile Include="Keys\KeyValidator.cs" />
|
<Compile Include="Keys\KeyValidator.cs" />
|
||||||
<Compile Include="Keys\KeyValidatorPool.cs" />
|
<Compile Include="Keys\KeyValidatorPool.cs" />
|
||||||
<Compile Include="Keys\UserKeyType.cs" />
|
<Compile Include="Keys\UserKeyType.cs" />
|
||||||
<Compile Include="Native\NativeMethods.cs" />
|
|
||||||
<Compile Include="PwCustomIcon.cs" />
|
<Compile Include="PwCustomIcon.cs" />
|
||||||
<Compile Include="Resources\KLRes.Generated.cs" />
|
<Compile Include="Resources\KLRes.Generated.cs" />
|
||||||
<Compile Include="Resources\KSRes.Generated.cs" />
|
<Compile Include="Resources\KSRes.Generated.cs" />
|
||||||
@@ -162,32 +160,22 @@
|
|||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="PwEnums.cs" />
|
<Compile Include="PwEnums.cs" />
|
||||||
<Compile Include="Serialization\BinaryReaderEx.cs" />
|
<Compile Include="Serialization\BinaryReaderEx.cs" />
|
||||||
<Compile Include="Serialization\CryptoStream.cs" />
|
|
||||||
<Compile Include="Serialization\FileLock.cs" />
|
<Compile Include="Serialization\FileLock.cs" />
|
||||||
<Compile Include="Serialization\FileTransactionEx.cs" />
|
<Compile Include="Serialization\FileTransactionEx.cs" />
|
||||||
<Compile Include="Serialization\HashedBlockStream.cs" />
|
<Compile Include="Serialization\HashedBlockStream.cs" />
|
||||||
<Compile Include="Serialization\IOConnection.cs" />
|
<Compile Include="Serialization\IOConnection.cs" />
|
||||||
<Compile Include="Serialization\Kdb4File.cs" />
|
|
||||||
<Compile Include="Serialization\Kdb4File.Read.cs" />
|
|
||||||
<Compile Include="Serialization\Kdb4File.Read.Streamed.cs" />
|
|
||||||
<Compile Include="Serialization\Kdb4File.Write.cs" />
|
|
||||||
<Compile Include="Serialization\IOConnectionInfo.cs" />
|
<Compile Include="Serialization\IOConnectionInfo.cs" />
|
||||||
|
<Compile Include="Serialization\KdbxFile.cs" />
|
||||||
|
<Compile Include="Serialization\KdbxFile.Read.cs" />
|
||||||
|
<Compile Include="Serialization\KdbxFile.Read.Streamed.cs" />
|
||||||
|
<Compile Include="Serialization\KdbxFile.Write.cs" />
|
||||||
<Compile Include="Serialization\OldFormatException.cs" />
|
<Compile Include="Serialization\OldFormatException.cs" />
|
||||||
<Compile Include="Translation\KPControlCustomization.cs" />
|
|
||||||
<Compile Include="Translation\KPFormCustomization.cs" />
|
|
||||||
<Compile Include="Translation\KPStringTable.cs" />
|
|
||||||
<Compile Include="Translation\KPStringTableItem.cs" />
|
|
||||||
<Compile Include="Translation\KPTranslation.cs" />
|
|
||||||
<Compile Include="Translation\KPTranslationProperties.cs" />
|
|
||||||
<Compile Include="Utility\AppLogEx.cs" />
|
<Compile Include="Utility\AppLogEx.cs" />
|
||||||
<Compile Include="Utility\MemUtil.cs" />
|
<Compile Include="Utility\MemUtil.cs" />
|
||||||
<Compile Include="Utility\MessageService.cs" />
|
|
||||||
<Compile Include="Native\NativeLib.cs" />
|
|
||||||
<Compile Include="Cryptography\PasswordGenerator\PwGenerator.cs" />
|
<Compile Include="Cryptography\PasswordGenerator\PwGenerator.cs" />
|
||||||
<Compile Include="Utility\StrUtil.cs" />
|
<Compile Include="Utility\StrUtil.cs" />
|
||||||
<Compile Include="Utility\UrlUtil.cs" />
|
<Compile Include="Utility\UrlUtil.cs" />
|
||||||
<Compile Include="Utility\TimeUtil.cs" />
|
<Compile Include="Utility\TimeUtil.cs" />
|
||||||
<Compile Include="WinRTColor.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Libs\Windows.winmd" />
|
<None Include="Libs\Windows.winmd" />
|
||||||
@@ -201,6 +189,10 @@
|
|||||||
<HintPath>Libs\Windows.winmd</HintPath>
|
<HintPath>Libs\Windows.winmd</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Native\" />
|
||||||
|
<Folder Include="Translation\" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
2
ModernKeePassLib/ModernKeePassLib.csproj.DotSettings
Normal file
2
ModernKeePassLib/ModernKeePassLib.csproj.DotSettings
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp70</s:String></wpf:ResourceDictionary>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ProjectView>ProjectFiles</ProjectView>
|
<ProjectView>ShowAllFiles</ProjectView>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
70
ModernKeePassLib/Native/Native.PCL.cs
Normal file
70
ModernKeePassLib/Native/Native.PCL.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
using PlatformID = System.UInt32;
|
||||||
|
|
||||||
|
namespace KeePass2PCL.Native
|
||||||
|
{
|
||||||
|
internal static class NativeLib
|
||||||
|
{
|
||||||
|
public static ulong MonoVersion {
|
||||||
|
get { throw new NotImplementedException(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsUnix()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class NativeMethods
|
||||||
|
{
|
||||||
|
public static bool SupportsStrCmpNaturally {
|
||||||
|
get { throw new NotImplementedException(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int StrCmpNaturally (string s1, string s2)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum DataProtectionScope
|
||||||
|
{
|
||||||
|
CurrentUser,
|
||||||
|
LocalMachine
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class ProtectedData
|
||||||
|
{
|
||||||
|
public static byte[] Protect(byte[] userData, byte[] optionalEntropy, DataProtectionScope scope)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] Unprotect(byte[] userData, byte[] optionalEntropy, DataProtectionScope scope)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum MemoryProtectionScope
|
||||||
|
{
|
||||||
|
CrossProcess,
|
||||||
|
SameLogon,
|
||||||
|
SameProcess
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class ProtectedMemory
|
||||||
|
{
|
||||||
|
public static byte[] Protect(byte[] userData, MemoryProtectionScope scope)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] Unprotect(byte[] userData, MemoryProtectionScope scope)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,13 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Threading;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
@@ -44,6 +50,43 @@ namespace ModernKeePassLib.Native
|
|||||||
set { m_bAllowNative = value; }
|
set { m_bAllowNative = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ulong? m_ouMonoVersion = null;
|
||||||
|
public static ulong MonoVersion
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(m_ouMonoVersion.HasValue) return m_ouMonoVersion.Value;
|
||||||
|
|
||||||
|
ulong uVersion = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Type t = Type.GetType("Mono.Runtime");
|
||||||
|
if(t != null)
|
||||||
|
{
|
||||||
|
MethodInfo mi = t.GetMethod("GetDisplayName",
|
||||||
|
BindingFlags.NonPublic | BindingFlags.Static);
|
||||||
|
if(mi != null)
|
||||||
|
{
|
||||||
|
string strName = (mi.Invoke(null, null) as string);
|
||||||
|
if(!string.IsNullOrEmpty(strName))
|
||||||
|
{
|
||||||
|
Match m = Regex.Match(strName, "\\d+(\\.\\d+)+");
|
||||||
|
if(m.Success)
|
||||||
|
uVersion = StrUtil.ParseVersion(m.Value);
|
||||||
|
else { Debug.Assert(false); }
|
||||||
|
}
|
||||||
|
else { Debug.Assert(false); }
|
||||||
|
}
|
||||||
|
else { Debug.Assert(false); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
|
m_ouMonoVersion = uVersion;
|
||||||
|
return uVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determine if the native library is installed.
|
/// Determine if the native library is installed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -70,10 +113,6 @@ namespace ModernKeePassLib.Native
|
|||||||
{
|
{
|
||||||
if(m_bIsUnix.HasValue) return m_bIsUnix.Value;
|
if(m_bIsUnix.HasValue) return m_bIsUnix.Value;
|
||||||
|
|
||||||
#if KeePassWinRT
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
|
|
||||||
PlatformID p = GetPlatformID();
|
PlatformID p = GetPlatformID();
|
||||||
|
|
||||||
// Mono defines Unix as 128 in early .NET versions
|
// Mono defines Unix as 128 in early .NET versions
|
||||||
@@ -84,19 +123,20 @@ namespace ModernKeePassLib.Native
|
|||||||
m_bIsUnix = (((int)p == 4) || ((int)p == 6) || ((int)p == 128));
|
m_bIsUnix = (((int)p == 4) || ((int)p == 6) || ((int)p == 128));
|
||||||
#endif
|
#endif
|
||||||
return m_bIsUnix.Value;
|
return m_bIsUnix.Value;
|
||||||
#endif //KeePassWinRT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Bert : Not supported for the time being.
|
|
||||||
#if !KeePassWinRT
|
|
||||||
private static PlatformID? m_platID = null;
|
private static PlatformID? m_platID = null;
|
||||||
public static PlatformID GetPlatformID()
|
public static PlatformID GetPlatformID()
|
||||||
{
|
{
|
||||||
if(m_platID.HasValue) return m_platID.Value;
|
if(m_platID.HasValue) return m_platID.Value;
|
||||||
|
|
||||||
|
#if KeePassRT
|
||||||
|
m_platID = PlatformID.Win32NT;
|
||||||
|
#else
|
||||||
m_platID = Environment.OSVersion.Platform;
|
m_platID = Environment.OSVersion.Platform;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
// Mono returns PlatformID.Unix on Mac OS X, workaround this
|
// Mono returns PlatformID.Unix on Mac OS X, workaround this
|
||||||
if(m_platID.Value == PlatformID.Unix)
|
if(m_platID.Value == PlatformID.Unix)
|
||||||
{
|
{
|
||||||
@@ -108,11 +148,8 @@ namespace ModernKeePassLib.Native
|
|||||||
|
|
||||||
return m_platID.Value;
|
return m_platID.Value;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
// BERT Todo: Not supported for the moment.
|
|
||||||
#if !KeePassLibSD && TODO
|
|
||||||
public static string RunConsoleApp(string strAppPath, string strParams)
|
public static string RunConsoleApp(string strAppPath, string strParams)
|
||||||
{
|
{
|
||||||
return RunConsoleApp(strAppPath, strParams, null);
|
return RunConsoleApp(strAppPath, strParams, null);
|
||||||
@@ -120,10 +157,23 @@ namespace ModernKeePassLib.Native
|
|||||||
|
|
||||||
public static string RunConsoleApp(string strAppPath, string strParams,
|
public static string RunConsoleApp(string strAppPath, string strParams,
|
||||||
string strStdInput)
|
string strStdInput)
|
||||||
|
{
|
||||||
|
return RunConsoleApp(strAppPath, strParams, strStdInput,
|
||||||
|
(AppRunFlags.GetStdOutput | AppRunFlags.WaitForExit));
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate string RunProcessDelegate();
|
||||||
|
|
||||||
|
public static string RunConsoleApp(string strAppPath, string strParams,
|
||||||
|
string strStdInput, AppRunFlags f)
|
||||||
{
|
{
|
||||||
if(strAppPath == null) throw new ArgumentNullException("strAppPath");
|
if(strAppPath == null) throw new ArgumentNullException("strAppPath");
|
||||||
if(strAppPath.Length == 0) throw new ArgumentException("strAppPath");
|
if(strAppPath.Length == 0) throw new ArgumentException("strAppPath");
|
||||||
|
|
||||||
|
bool bStdOut = ((f & AppRunFlags.GetStdOutput) != AppRunFlags.None);
|
||||||
|
|
||||||
|
RunProcessDelegate fnRun = delegate()
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ProcessStartInfo psi = new ProcessStartInfo();
|
ProcessStartInfo psi = new ProcessStartInfo();
|
||||||
@@ -132,7 +182,7 @@ namespace ModernKeePassLib.Native
|
|||||||
psi.FileName = strAppPath;
|
psi.FileName = strAppPath;
|
||||||
psi.WindowStyle = ProcessWindowStyle.Hidden;
|
psi.WindowStyle = ProcessWindowStyle.Hidden;
|
||||||
psi.UseShellExecute = false;
|
psi.UseShellExecute = false;
|
||||||
psi.RedirectStandardOutput = true;
|
psi.RedirectStandardOutput = bStdOut;
|
||||||
|
|
||||||
if(strStdInput != null) psi.RedirectStandardInput = true;
|
if(strStdInput != null) psi.RedirectStandardInput = true;
|
||||||
|
|
||||||
@@ -142,18 +192,86 @@ namespace ModernKeePassLib.Native
|
|||||||
|
|
||||||
if(strStdInput != null)
|
if(strStdInput != null)
|
||||||
{
|
{
|
||||||
|
// Workaround for Mono Process StdIn BOM bug;
|
||||||
|
// https://sourceforge.net/p/keepass/bugs/1219/
|
||||||
|
EnsureNoBom(p.StandardInput);
|
||||||
|
|
||||||
p.StandardInput.Write(strStdInput);
|
p.StandardInput.Write(strStdInput);
|
||||||
p.StandardInput.Close();
|
p.StandardInput.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
string strOutput = p.StandardOutput.ReadToEnd();
|
string strOutput = string.Empty;
|
||||||
|
if(bStdOut) strOutput = p.StandardOutput.ReadToEnd();
|
||||||
|
|
||||||
|
if((f & AppRunFlags.WaitForExit) != AppRunFlags.None)
|
||||||
p.WaitForExit();
|
p.WaitForExit();
|
||||||
|
else if((f & AppRunFlags.GCKeepAlive) != AppRunFlags.None)
|
||||||
|
{
|
||||||
|
Thread th = new Thread(delegate()
|
||||||
|
{
|
||||||
|
try { p.WaitForExit(); }
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
});
|
||||||
|
th.Start();
|
||||||
|
}
|
||||||
|
|
||||||
return strOutput;
|
return strOutput;
|
||||||
}
|
}
|
||||||
catch(Exception) { Debug.Assert(false); }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
if((f & AppRunFlags.DoEvents) != AppRunFlags.None)
|
||||||
|
{
|
||||||
|
List<Form> lDisabledForms = new List<Form>();
|
||||||
|
if((f & AppRunFlags.DisableForms) != AppRunFlags.None)
|
||||||
|
{
|
||||||
|
foreach(Form form in Application.OpenForms)
|
||||||
|
{
|
||||||
|
if(!form.Enabled) continue;
|
||||||
|
|
||||||
|
lDisabledForms.Add(form);
|
||||||
|
form.Enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IAsyncResult ar = fnRun.BeginInvoke(null, null);
|
||||||
|
|
||||||
|
while(!ar.AsyncWaitHandle.WaitOne(0))
|
||||||
|
{
|
||||||
|
Application.DoEvents();
|
||||||
|
Thread.Sleep(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
string strRet = fnRun.EndInvoke(ar);
|
||||||
|
|
||||||
|
for(int i = lDisabledForms.Count - 1; i >= 0; --i)
|
||||||
|
lDisabledForms[i].Enabled = true;
|
||||||
|
|
||||||
|
return strRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fnRun();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsureNoBom(StreamWriter sw)
|
||||||
|
{
|
||||||
|
if(sw == null) { Debug.Assert(false); return; }
|
||||||
|
if(!NativeLib.IsUnix()) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Encoding enc = sw.Encoding;
|
||||||
|
if(enc == null) { Debug.Assert(false); return; }
|
||||||
|
byte[] pbBom = enc.GetPreamble();
|
||||||
|
if((pbBom == null) || (pbBom.Length == 0)) return;
|
||||||
|
|
||||||
|
FieldInfo fi = typeof(StreamWriter).GetField("preamble_done",
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
if(fi != null) fi.SetValue(sw, true);
|
||||||
|
}
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -172,12 +290,12 @@ namespace ModernKeePassLib.Native
|
|||||||
KeyValuePair<IntPtr, IntPtr> kvp = PrepareArrays256(pBuf256, pKey256);
|
KeyValuePair<IntPtr, IntPtr> kvp = PrepareArrays256(pBuf256, pKey256);
|
||||||
bool bResult = false;
|
bool bResult = false;
|
||||||
|
|
||||||
/*try
|
try
|
||||||
{
|
{
|
||||||
bResult = NativeMethods.TransformKey(kvp.Key, kvp.Value, uRounds);
|
bResult = NativeMethods.TransformKey(kvp.Key, kvp.Value, uRounds);
|
||||||
}
|
}
|
||||||
catch(Exception) { bResult = false; }
|
catch(Exception) { bResult = false; }
|
||||||
*/
|
|
||||||
if(bResult) GetBuffers256(kvp, pBuf256, pKey256);
|
if(bResult) GetBuffers256(kvp, pBuf256, pKey256);
|
||||||
|
|
||||||
NativeLib.FreeArrays(kvp);
|
NativeLib.FreeArrays(kvp);
|
||||||
@@ -196,8 +314,8 @@ namespace ModernKeePassLib.Native
|
|||||||
|
|
||||||
if(m_bAllowNative == false) return false;
|
if(m_bAllowNative == false) return false;
|
||||||
|
|
||||||
/*try { puRounds = NativeMethods.TransformKeyBenchmark(uTimeMs); }
|
try { puRounds = NativeMethods.TransformKeyBenchmark(uTimeMs); }
|
||||||
catch(Exception) { return false; }*/
|
catch(Exception) { return false; }
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
112
ModernKeePassLib/Native/NativeMethods.Unix.cs
Normal file
112
ModernKeePassLib/Native/NativeMethods.Unix.cs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
|
Copyright (C) 2003-2014 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
|
||||||
|
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.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace KeePass2PCL.Native
|
||||||
|
{
|
||||||
|
internal static partial class NativeMethods
|
||||||
|
{
|
||||||
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
private struct XClassHint
|
||||||
|
{
|
||||||
|
public IntPtr res_name;
|
||||||
|
public IntPtr res_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("libX11")]
|
||||||
|
private static extern int XSetClassHint(IntPtr display, IntPtr window, IntPtr class_hints);
|
||||||
|
|
||||||
|
private static Type m_tXplatUIX11 = null;
|
||||||
|
private static Type GetXplatUIX11Type(bool bThrowOnError)
|
||||||
|
{
|
||||||
|
if(m_tXplatUIX11 == null)
|
||||||
|
{
|
||||||
|
// CheckState is in System.Windows.Forms
|
||||||
|
string strTypeCS = typeof(CheckState).AssemblyQualifiedName;
|
||||||
|
string strTypeX11 = strTypeCS.Replace("CheckState", "XplatUIX11");
|
||||||
|
m_tXplatUIX11 = Type.GetType(strTypeX11, bThrowOnError, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_tXplatUIX11;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Type m_tHwnd = null;
|
||||||
|
private static Type GetHwndType(bool bThrowOnError)
|
||||||
|
{
|
||||||
|
if(m_tHwnd == null)
|
||||||
|
{
|
||||||
|
// CheckState is in System.Windows.Forms
|
||||||
|
string strTypeCS = typeof(CheckState).AssemblyQualifiedName;
|
||||||
|
string strTypeHwnd = strTypeCS.Replace("CheckState", "Hwnd");
|
||||||
|
m_tHwnd = Type.GetType(strTypeHwnd, bThrowOnError, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_tHwnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetWmClass(Form f, string strName, string strClass)
|
||||||
|
{
|
||||||
|
if(f == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
// The following crashes under Mac OS X (SIGSEGV in native code,
|
||||||
|
// not just an exception), thus skip it when we're on Mac OS X;
|
||||||
|
// https://sourceforge.net/projects/keepass/forums/forum/329221/topic/5860588
|
||||||
|
if(NativeLib.GetPlatformID() == PlatformID.MacOSX) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Type tXplatUIX11 = GetXplatUIX11Type(true);
|
||||||
|
FieldInfo fiDisplayHandle = tXplatUIX11.GetField("DisplayHandle",
|
||||||
|
BindingFlags.NonPublic | BindingFlags.Static);
|
||||||
|
IntPtr hDisplay = (IntPtr)fiDisplayHandle.GetValue(null);
|
||||||
|
|
||||||
|
Type tHwnd = GetHwndType(true);
|
||||||
|
MethodInfo miObjectFromHandle = tHwnd.GetMethod("ObjectFromHandle",
|
||||||
|
BindingFlags.Public | BindingFlags.Static);
|
||||||
|
object oHwnd = miObjectFromHandle.Invoke(null, new object[] { f.Handle });
|
||||||
|
|
||||||
|
FieldInfo fiWholeWindow = tHwnd.GetField("whole_window",
|
||||||
|
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
IntPtr hWindow = (IntPtr)fiWholeWindow.GetValue(oHwnd);
|
||||||
|
|
||||||
|
XClassHint xch = new XClassHint();
|
||||||
|
xch.res_name = Marshal.StringToCoTaskMemAnsi(strName ?? string.Empty);
|
||||||
|
xch.res_class = Marshal.StringToCoTaskMemAnsi(strClass ?? string.Empty);
|
||||||
|
IntPtr pXch = Marshal.AllocCoTaskMem(Marshal.SizeOf(xch));
|
||||||
|
Marshal.StructureToPtr(xch, pXch, false);
|
||||||
|
|
||||||
|
XSetClassHint(hDisplay, hWindow, pXch);
|
||||||
|
|
||||||
|
Marshal.FreeCoTaskMem(pXch);
|
||||||
|
Marshal.FreeCoTaskMem(xch.res_name);
|
||||||
|
Marshal.FreeCoTaskMem(xch.res_class);
|
||||||
|
}
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,13 +21,20 @@ using System;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.IO;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Native
|
namespace ModernKeePassLib.Native
|
||||||
{
|
{
|
||||||
internal static class NativeMethods
|
internal static partial class NativeMethods
|
||||||
{
|
{
|
||||||
internal const int MAX_PATH = 260;
|
internal const int MAX_PATH = 260;
|
||||||
|
|
||||||
|
// internal const uint TF_SFT_SHOWNORMAL = 0x00000001;
|
||||||
|
// internal const uint TF_SFT_HIDDEN = 0x00000008;
|
||||||
|
|
||||||
/* [DllImport("KeePassNtv32.dll", EntryPoint = "TransformKey")]
|
/* [DllImport("KeePassNtv32.dll", EntryPoint = "TransformKey")]
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
private static extern bool TransformKey32(IntPtr pBuf256,
|
private static extern bool TransformKey32(IntPtr pBuf256,
|
||||||
@@ -65,7 +72,7 @@ namespace ModernKeePassLib.Native
|
|||||||
else
|
else
|
||||||
return TransformKeyTimed32(pBuf256, pKey256, ref puRounds, uSeconds);
|
return TransformKeyTimed32(pBuf256, pKey256, ref puRounds, uSeconds);
|
||||||
} */
|
} */
|
||||||
/*
|
|
||||||
[DllImport("KeePassLibC32.dll", EntryPoint = "TransformKey256")]
|
[DllImport("KeePassLibC32.dll", EntryPoint = "TransformKey256")]
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
private static extern bool TransformKey32(IntPtr pBuf256,
|
private static extern bool TransformKey32(IntPtr pBuf256,
|
||||||
@@ -95,11 +102,25 @@ namespace ModernKeePassLib.Native
|
|||||||
{
|
{
|
||||||
if(Marshal.SizeOf(typeof(IntPtr)) == 8)
|
if(Marshal.SizeOf(typeof(IntPtr)) == 8)
|
||||||
return TransformKeyBenchmark64(uTimeMs);
|
return TransformKeyBenchmark64(uTimeMs);
|
||||||
else
|
|
||||||
return TransformKeyBenchmark32(uTimeMs);
|
return TransformKeyBenchmark32(uTimeMs);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
#if !KeePassLibSD && TODO
|
/* [DllImport("KeePassLibC32.dll", EntryPoint = "TF_ShowLangBar")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
private static extern bool TF_ShowLangBar32(UInt32 dwFlags);
|
||||||
|
|
||||||
|
[DllImport("KeePassLibC64.dll", EntryPoint = "TF_ShowLangBar")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
private static extern bool TF_ShowLangBar64(UInt32 dwFlags);
|
||||||
|
|
||||||
|
internal static bool TfShowLangBar(uint dwFlags)
|
||||||
|
{
|
||||||
|
if(Marshal.SizeOf(typeof(IntPtr)) == 8)
|
||||||
|
return TF_ShowLangBar64(dwFlags);
|
||||||
|
return TF_ShowLangBar32(dwFlags);
|
||||||
|
} */
|
||||||
|
|
||||||
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
[DllImport("ShlWApi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
[DllImport("ShlWApi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||||
internal static extern int StrCmpLogicalW(string x, string y);
|
internal static extern int StrCmpLogicalW(string x, string y);
|
||||||
|
|
||||||
@@ -114,7 +135,7 @@ namespace ModernKeePassLib.Native
|
|||||||
|
|
||||||
private static void TestNaturalComparisonsSupport()
|
private static void TestNaturalComparisonsSupport()
|
||||||
{
|
{
|
||||||
#if KeePassLibSD || !TODO
|
#if (KeePassLibSD || KeePassRT)
|
||||||
#warning No native natural comparisons supported.
|
#warning No native natural comparisons supported.
|
||||||
m_bSupportsLogicalCmp = false;
|
m_bSupportsLogicalCmp = false;
|
||||||
#else
|
#else
|
||||||
@@ -143,11 +164,36 @@ namespace ModernKeePassLib.Native
|
|||||||
if(m_bSupportsLogicalCmp.HasValue == false) TestNaturalComparisonsSupport();
|
if(m_bSupportsLogicalCmp.HasValue == false) TestNaturalComparisonsSupport();
|
||||||
if(m_bSupportsLogicalCmp.Value == false) return 0;
|
if(m_bSupportsLogicalCmp.Value == false) return 0;
|
||||||
|
|
||||||
#if KeePassLibSD || !TODO
|
#if (KeePassLibSD || KeePassRT)
|
||||||
#warning No native natural comparisons supported.
|
#warning No native natural comparisons supported.
|
||||||
return x.CompareTo(y);
|
return x.CompareTo(y);
|
||||||
#else
|
#else
|
||||||
return StrCmpLogicalW(x, y);
|
return StrCmpLogicalW(x, y);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GetUserRuntimeDir()
|
||||||
|
{
|
||||||
|
#if !KeePassLibSD
|
||||||
|
#if KeePassRT
|
||||||
|
string strRtDir = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
|
||||||
|
#else
|
||||||
|
string strRtDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR");
|
||||||
|
if(string.IsNullOrEmpty(strRtDir))
|
||||||
|
strRtDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||||
|
if(string.IsNullOrEmpty(strRtDir))
|
||||||
|
{
|
||||||
|
Debug.Assert(false);
|
||||||
|
return Path.GetTempPath(); // Not UrlUtil (otherwise cyclic)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
strRtDir = UrlUtil.EnsureTerminatingSeparator(strRtDir, false);
|
||||||
|
strRtDir += PwDefs.ShortProductName;
|
||||||
|
|
||||||
|
return strRtDir;
|
||||||
|
#else
|
||||||
|
return Path.GetTempPath();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,5 +39,5 @@ using System.Runtime.InteropServices;
|
|||||||
//[assembly: Guid("395f6eec-a1e0-4438-aa82-b75099348134")]
|
//[assembly: Guid("395f6eec-a1e0-4438-aa82-b75099348134")]
|
||||||
|
|
||||||
// Assembly version information
|
// Assembly version information
|
||||||
[assembly: AssemblyVersion("2.19.0.*")]
|
[assembly: AssemblyVersion("2.36.0.*")]
|
||||||
[assembly: AssemblyFileVersion("2.19.0.0")]
|
[assembly: AssemblyFileVersion("2.36.0.0")]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,10 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
//using System.Drawing;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Media.Imaging;
|
|
||||||
|
|
||||||
// Bert TODO: http://blog.tallcomponents.com/2012/06/windows-8-release-preview-back-to-earth.html
|
|
||||||
namespace ModernKeePassLib
|
namespace ModernKeePassLib
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -31,7 +29,7 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
private PwUuid m_pwUuid;
|
private PwUuid m_pwUuid;
|
||||||
private byte[] m_pbImageDataPng;
|
private byte[] m_pbImageDataPng;
|
||||||
private BitmapImage m_pCachedImage;
|
private Image m_pCachedImage;
|
||||||
|
|
||||||
public PwUuid Uuid
|
public PwUuid Uuid
|
||||||
{
|
{
|
||||||
@@ -43,7 +41,7 @@ namespace ModernKeePassLib
|
|||||||
get { return m_pbImageDataPng; }
|
get { return m_pbImageDataPng; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public BitmapImage Image
|
public Image Image
|
||||||
{
|
{
|
||||||
get { return m_pCachedImage; }
|
get { return m_pCachedImage; }
|
||||||
}
|
}
|
||||||
@@ -52,8 +50,8 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
Debug.Assert(pwUuid != null);
|
Debug.Assert(pwUuid != null);
|
||||||
if(pwUuid == null) throw new ArgumentNullException("pwUuid");
|
if(pwUuid == null) throw new ArgumentNullException("pwUuid");
|
||||||
Debug.Assert(pwUuid != PwUuid.Zero);
|
Debug.Assert(!pwUuid.Equals(PwUuid.Zero));
|
||||||
if(pwUuid == PwUuid.Zero) throw new ArgumentException("pwUuid == 0");
|
if(pwUuid.Equals(PwUuid.Zero)) throw new ArgumentException("pwUuid == 0");
|
||||||
|
|
||||||
Debug.Assert(pbImageDataPng != null);
|
Debug.Assert(pbImageDataPng != null);
|
||||||
if(pbImageDataPng == null) throw new ArgumentNullException("pbImageDataPng");
|
if(pbImageDataPng == null) throw new ArgumentNullException("pbImageDataPng");
|
||||||
@@ -61,10 +59,11 @@ namespace ModernKeePassLib
|
|||||||
m_pwUuid = pwUuid;
|
m_pwUuid = pwUuid;
|
||||||
m_pbImageDataPng = pbImageDataPng;
|
m_pbImageDataPng = pbImageDataPng;
|
||||||
|
|
||||||
#if !KeePassLibSD && false
|
#if !KeePassLibSD
|
||||||
MemoryStream ms = new MemoryStream(m_pbImageDataPng, false);
|
// MemoryStream ms = new MemoryStream(m_pbImageDataPng, false);
|
||||||
m_pCachedImage = Image.FromStream(ms);
|
// m_pCachedImage = Image.FromStream(ms);
|
||||||
ms.Close();
|
// ms.Close();
|
||||||
|
//m_pCachedImage = GfxUtil.LoadImage(m_pbImageDataPng);
|
||||||
#else
|
#else
|
||||||
m_pCachedImage = null;
|
m_pCachedImage = null;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,17 +19,18 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using Windows.UI;
|
||||||
using Windows.UI.Xaml.Media.Imaging;
|
using Windows.UI.Xaml.Controls;
|
||||||
//using System.Drawing;
|
|
||||||
|
|
||||||
using ModernKeePassLib.WinRTAdaptors;
|
|
||||||
using ModernKeePassLib.Collections;
|
using ModernKeePassLib.Collections;
|
||||||
|
using ModernKeePassLib.Cryptography;
|
||||||
using ModernKeePassLib.Cryptography.Cipher;
|
using ModernKeePassLib.Cryptography.Cipher;
|
||||||
using ModernKeePassLib.Delegates;
|
using ModernKeePassLib.Delegates;
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
using ModernKeePassLib.Keys;
|
using ModernKeePassLib.Keys;
|
||||||
|
using ModernKeePassLib.Resources;
|
||||||
|
using ModernKeePassLib.Security;
|
||||||
using ModernKeePassLib.Serialization;
|
using ModernKeePassLib.Serialization;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ namespace ModernKeePassLib
|
|||||||
private string m_strDefaultUserName = string.Empty;
|
private string m_strDefaultUserName = string.Empty;
|
||||||
private DateTime m_dtDefaultUserChanged = PwDefs.DtDefaultNow;
|
private DateTime m_dtDefaultUserChanged = PwDefs.DtDefaultNow;
|
||||||
private uint m_uMntncHistoryDays = 365;
|
private uint m_uMntncHistoryDays = 365;
|
||||||
private Color m_clr = Color.Empty;
|
private Color m_clr;
|
||||||
|
|
||||||
private DateTime m_dtKeyLastChanged = PwDefs.DtDefaultNow;
|
private DateTime m_dtKeyLastChanged = PwDefs.DtDefaultNow;
|
||||||
private long m_lKeyChangeRecDays = -1;
|
private long m_lKeyChangeRecDays = -1;
|
||||||
@@ -497,7 +498,7 @@ namespace ModernKeePassLib
|
|||||||
m_strDefaultUserName = string.Empty;
|
m_strDefaultUserName = string.Empty;
|
||||||
m_dtDefaultUserChanged = dtNow;
|
m_dtDefaultUserChanged = dtNow;
|
||||||
m_uMntncHistoryDays = 365;
|
m_uMntncHistoryDays = 365;
|
||||||
m_clr = Color.Empty;
|
m_clr = new Color();
|
||||||
|
|
||||||
m_dtKeyLastChanged = dtNow;
|
m_dtKeyLastChanged = dtNow;
|
||||||
m_lKeyChangeRecDays = -1;
|
m_lKeyChangeRecDays = -1;
|
||||||
@@ -561,10 +562,9 @@ namespace ModernKeePassLib
|
|||||||
/// <param name="ioSource">IO connection to load the database from.</param>
|
/// <param name="ioSource">IO connection to load the database from.</param>
|
||||||
/// <param name="pwKey">Key used to open the specified database.</param>
|
/// <param name="pwKey">Key used to open the specified database.</param>
|
||||||
/// <param name="slLogger">Logger, which gets all status messages.</param>
|
/// <param name="slLogger">Logger, which gets all status messages.</param>
|
||||||
public async Task Open(IOConnectionInfo ioSource, CompositeKey pwKey,
|
public void Open(IOConnectionInfo ioSource, CompositeKey pwKey,
|
||||||
IStatusLogger slLogger)
|
IStatusLogger slLogger)
|
||||||
{
|
{
|
||||||
|
|
||||||
Debug.Assert(ioSource != null);
|
Debug.Assert(ioSource != null);
|
||||||
if(ioSource == null) throw new ArgumentNullException("ioSource");
|
if(ioSource == null) throw new ArgumentNullException("ioSource");
|
||||||
Debug.Assert(pwKey != null);
|
Debug.Assert(pwKey != null);
|
||||||
@@ -582,17 +582,15 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
m_bModified = false;
|
m_bModified = false;
|
||||||
|
|
||||||
Kdb4File kdb4 = new Kdb4File(this);
|
KdbxFile kdbx = new KdbxFile(this);
|
||||||
kdb4.DetachBinaries = m_strDetachBins;
|
kdbx.DetachBinaries = m_strDetachBins;
|
||||||
|
|
||||||
IOConnection ioc = new IOConnection();
|
|
||||||
Stream s = await ioc.OpenRead(ioSource);
|
|
||||||
kdb4.Load(s, Kdb4Format.Default, slLogger);
|
|
||||||
|
|
||||||
|
Stream s = IOConnection.OpenRead(ioSource);
|
||||||
|
kdbx.Load(s, KdbxFormat.Default, slLogger);
|
||||||
s.Dispose();
|
s.Dispose();
|
||||||
|
|
||||||
m_pbHashOfLastIO = kdb4.HashOfFileOnDisk;
|
m_pbHashOfLastIO = kdbx.HashOfFileOnDisk;
|
||||||
m_pbHashOfFileOnDisk = kdb4.HashOfFileOnDisk;
|
m_pbHashOfFileOnDisk = kdbx.HashOfFileOnDisk;
|
||||||
Debug.Assert(m_pbHashOfFileOnDisk != null);
|
Debug.Assert(m_pbHashOfFileOnDisk != null);
|
||||||
|
|
||||||
m_bDatabaseOpened = true;
|
m_bDatabaseOpened = true;
|
||||||
@@ -610,7 +608,7 @@ namespace ModernKeePassLib
|
|||||||
/// it has been opened from.
|
/// it has been opened from.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="slLogger">Logger that recieves status information.</param>
|
/// <param name="slLogger">Logger that recieves status information.</param>
|
||||||
public async void Save(IStatusLogger slLogger)
|
public void Save(IStatusLogger slLogger)
|
||||||
{
|
{
|
||||||
Debug.Assert(ValidateUuidUniqueness());
|
Debug.Assert(ValidateUuidUniqueness());
|
||||||
|
|
||||||
@@ -620,10 +618,10 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
FileTransactionEx ft = new FileTransactionEx(m_ioSource,
|
FileTransactionEx ft = new FileTransactionEx(m_ioSource,
|
||||||
m_bUseFileTransactions);
|
m_bUseFileTransactions);
|
||||||
Stream s = await ft.OpenWrite();
|
Stream s = ft.OpenWrite();
|
||||||
|
|
||||||
Kdb4File kdb = new Kdb4File(this);
|
KdbxFile kdb = new KdbxFile(this);
|
||||||
kdb.Save(s, null, Kdb4Format.Default, slLogger);
|
kdb.Save(s, null, KdbxFormat.Default, slLogger);
|
||||||
|
|
||||||
ft.CommitWrite();
|
ft.CommitWrite();
|
||||||
|
|
||||||
@@ -631,8 +629,6 @@ namespace ModernKeePassLib
|
|||||||
m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk;
|
m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk;
|
||||||
Debug.Assert(m_pbHashOfFileOnDisk != null);
|
Debug.Assert(m_pbHashOfFileOnDisk != null);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{ }
|
|
||||||
finally { if(fl != null) fl.Dispose(); }
|
finally { if(fl != null) fl.Dispose(); }
|
||||||
|
|
||||||
m_bModified = false;
|
m_bModified = false;
|
||||||
@@ -688,15 +684,15 @@ namespace ModernKeePassLib
|
|||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MergeIn(PwDatabase pwSource, PwMergeMethod mm)
|
public void MergeIn(PwDatabase pdSource, PwMergeMethod mm)
|
||||||
{
|
{
|
||||||
MergeIn(pwSource, mm, null);
|
MergeIn(pdSource, mm, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Synchronize the current database with another one.
|
/// Synchronize the current database with another one.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pwSource">Input database to synchronize with. This input
|
/// <param name="pdSource">Input database to synchronize with. This input
|
||||||
/// database is used to update the current one, but is not modified! You
|
/// database is used to update the current one, but is not modified! You
|
||||||
/// must copy the current object if you want a second instance of the
|
/// must copy the current object if you want a second instance of the
|
||||||
/// synchronized database. The input database must not be seen as valid
|
/// synchronized database. The input database must not be seen as valid
|
||||||
@@ -704,27 +700,38 @@ namespace ModernKeePassLib
|
|||||||
/// <param name="mm">Merge method.</param>
|
/// <param name="mm">Merge method.</param>
|
||||||
/// <param name="slStatus">Logger to report status messages to.
|
/// <param name="slStatus">Logger to report status messages to.
|
||||||
/// May be <c>null</c>.</param>
|
/// May be <c>null</c>.</param>
|
||||||
public void MergeIn(PwDatabase pwSource, PwMergeMethod mm,
|
public void MergeIn(PwDatabase pdSource, PwMergeMethod mm,
|
||||||
IStatusLogger slStatus)
|
IStatusLogger slStatus)
|
||||||
{
|
{
|
||||||
if(pwSource == null) throw new ArgumentNullException("pwSource");
|
if(pdSource == null) throw new ArgumentNullException("pdSource");
|
||||||
|
|
||||||
PwGroup pgOrgStructure = m_pgRootGroup.CloneStructure();
|
PwGroup pgOrgStructure = m_pgRootGroup.CloneStructure();
|
||||||
PwGroup pgSrcStructure = pwSource.m_pgRootGroup.CloneStructure();
|
PwGroup pgSrcStructure = pdSource.m_pgRootGroup.CloneStructure();
|
||||||
|
|
||||||
if(mm == PwMergeMethod.CreateNewUuids)
|
if(mm == PwMergeMethod.CreateNewUuids)
|
||||||
pwSource.RootGroup.CreateNewItemUuids(true, true, true);
|
{
|
||||||
|
pdSource.RootGroup.CreateNewItemUuids(true, true, true);
|
||||||
|
pdSource.RootGroup.Uuid = new PwUuid(true);
|
||||||
|
}
|
||||||
|
|
||||||
GroupHandler gh = delegate(PwGroup pg)
|
GroupHandler gh = delegate(PwGroup pg)
|
||||||
{
|
{
|
||||||
if(pg == pwSource.m_pgRootGroup) return true;
|
// if(pg == pdSource.m_pgRootGroup) return true;
|
||||||
|
|
||||||
PwGroup pgLocal = m_pgRootGroup.FindGroup(pg.Uuid, true);
|
PwGroup pgLocal = m_pgRootGroup.FindGroup(pg.Uuid, true);
|
||||||
if(pgLocal == null)
|
if(pgLocal == null)
|
||||||
{
|
{
|
||||||
PwGroup pgSourceParent = pg.ParentGroup;
|
PwGroup pgSourceParent = pg.ParentGroup;
|
||||||
PwGroup pgLocalContainer;
|
PwGroup pgLocalContainer;
|
||||||
if(pgSourceParent == pwSource.m_pgRootGroup)
|
if(pgSourceParent == null)
|
||||||
|
{
|
||||||
|
// pg is the root group of pdSource, and no corresponding
|
||||||
|
// local group was found; create the group within the
|
||||||
|
// local root group
|
||||||
|
Debug.Assert(pg == pdSource.m_pgRootGroup);
|
||||||
|
pgLocalContainer = m_pgRootGroup;
|
||||||
|
}
|
||||||
|
else if(pgSourceParent == pdSource.m_pgRootGroup)
|
||||||
pgLocalContainer = m_pgRootGroup;
|
pgLocalContainer = m_pgRootGroup;
|
||||||
else
|
else
|
||||||
pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
|
pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
|
||||||
@@ -760,7 +767,7 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
PwGroup pgSourceParent = pe.ParentGroup;
|
PwGroup pgSourceParent = pe.ParentGroup;
|
||||||
PwGroup pgLocalContainer;
|
PwGroup pgLocalContainer;
|
||||||
if(pgSourceParent == pwSource.m_pgRootGroup)
|
if(pgSourceParent == pdSource.m_pgRootGroup)
|
||||||
pgLocalContainer = m_pgRootGroup;
|
pgLocalContainer = m_pgRootGroup;
|
||||||
else
|
else
|
||||||
pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
|
pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
|
||||||
@@ -783,12 +790,12 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
bool bOrgBackup = !bEquals;
|
bool bOrgBackup = !bEquals;
|
||||||
if(mm != PwMergeMethod.OverwriteExisting)
|
if(mm != PwMergeMethod.OverwriteExisting)
|
||||||
bOrgBackup &= (pe.LastModificationTime > peLocal.LastModificationTime);
|
bOrgBackup &= (TimeUtil.CompareLastMod(pe, peLocal, true) > 0);
|
||||||
bOrgBackup &= !pe.HasBackupOfData(peLocal, false, true);
|
bOrgBackup &= !pe.HasBackupOfData(peLocal, false, true);
|
||||||
if(bOrgBackup) peLocal.CreateBackup(null); // Maintain at end
|
if(bOrgBackup) peLocal.CreateBackup(null); // Maintain at end
|
||||||
|
|
||||||
bool bSrcBackup = !bEquals && (mm != PwMergeMethod.OverwriteExisting);
|
bool bSrcBackup = !bEquals && (mm != PwMergeMethod.OverwriteExisting);
|
||||||
bSrcBackup &= (peLocal.LastModificationTime > pe.LastModificationTime);
|
bSrcBackup &= (TimeUtil.CompareLastMod(peLocal, pe, true) > 0);
|
||||||
bSrcBackup &= !peLocal.HasBackupOfData(pe, false, true);
|
bSrcBackup &= !peLocal.HasBackupOfData(pe, false, true);
|
||||||
if(bSrcBackup) pe.CreateBackup(null); // Maintain at end
|
if(bSrcBackup) pe.CreateBackup(null); // Maintain at end
|
||||||
|
|
||||||
@@ -807,7 +814,8 @@ namespace ModernKeePassLib
|
|||||||
return ((slStatus != null) ? slStatus.ContinueWork() : true);
|
return ((slStatus != null) ? slStatus.ContinueWork() : true);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(!pwSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh))
|
gh(pdSource.RootGroup);
|
||||||
|
if(!pdSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh))
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
IStatusLogger slPrevStatus = m_slStatus;
|
IStatusLogger slPrevStatus = m_slStatus;
|
||||||
@@ -815,7 +823,7 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
if(mm == PwMergeMethod.Synchronize)
|
if(mm == PwMergeMethod.Synchronize)
|
||||||
{
|
{
|
||||||
ApplyDeletions(pwSource.m_vDeletedObjects, true);
|
ApplyDeletions(pdSource.m_vDeletedObjects, true);
|
||||||
ApplyDeletions(m_vDeletedObjects, false);
|
ApplyDeletions(m_vDeletedObjects, false);
|
||||||
|
|
||||||
PwObjectPool ppOrgGroups = PwObjectPool.FromGroupRecursive(
|
PwObjectPool ppOrgGroups = PwObjectPool.FromGroupRecursive(
|
||||||
@@ -836,18 +844,18 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
// Must be called *after* merging groups, because group UUIDs
|
// Must be called *after* merging groups, because group UUIDs
|
||||||
// are required for recycle bin and entry template UUIDs
|
// are required for recycle bin and entry template UUIDs
|
||||||
MergeInDbProperties(pwSource, mm);
|
MergeInDbProperties(pdSource, mm);
|
||||||
|
|
||||||
MergeInCustomIcons(pwSource);
|
MergeInCustomIcons(pdSource);
|
||||||
|
|
||||||
MaintainBackups();
|
MaintainBackups();
|
||||||
|
|
||||||
m_slStatus = slPrevStatus;
|
m_slStatus = slPrevStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MergeInCustomIcons(PwDatabase pwSource)
|
private void MergeInCustomIcons(PwDatabase pdSource)
|
||||||
{
|
{
|
||||||
foreach(PwCustomIcon pwci in pwSource.CustomIcons)
|
foreach(PwCustomIcon pwci in pdSource.CustomIcons)
|
||||||
{
|
{
|
||||||
if(GetCustomIconIndex(pwci.Uuid) >= 0) continue;
|
if(GetCustomIconIndex(pwci.Uuid) >= 0) continue;
|
||||||
|
|
||||||
@@ -856,10 +864,6 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Apply a list of deleted objects.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="listDelObjects">List of deleted objects.</param>
|
|
||||||
private void ApplyDeletions(PwObjectList<PwDeletedObject> listDelObjects,
|
private void ApplyDeletions(PwObjectList<PwDeletedObject> listDelObjects,
|
||||||
bool bCopyDeletionInfoToLocal)
|
bool bCopyDeletionInfoToLocal)
|
||||||
{
|
{
|
||||||
@@ -874,10 +878,13 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
foreach(PwDeletedObject pdo in listDelObjects)
|
foreach(PwDeletedObject pdo in listDelObjects)
|
||||||
{
|
{
|
||||||
if(pg.Uuid.EqualsValue(pdo.Uuid))
|
if(pg.Uuid.Equals(pdo.Uuid))
|
||||||
if(pg.LastModificationTime < pdo.DeletionTime)
|
{
|
||||||
|
if(TimeUtil.Compare(pg.LastModificationTime,
|
||||||
|
pdo.DeletionTime, true) < 0)
|
||||||
listGroupsToDelete.AddLast(pg);
|
listGroupsToDelete.AddLast(pg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ((m_slStatus != null) ? m_slStatus.ContinueWork() : true);
|
return ((m_slStatus != null) ? m_slStatus.ContinueWork() : true);
|
||||||
};
|
};
|
||||||
@@ -886,10 +893,13 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
foreach(PwDeletedObject pdo in listDelObjects)
|
foreach(PwDeletedObject pdo in listDelObjects)
|
||||||
{
|
{
|
||||||
if(pe.Uuid.EqualsValue(pdo.Uuid))
|
if(pe.Uuid.Equals(pdo.Uuid))
|
||||||
if(pe.LastModificationTime < pdo.DeletionTime)
|
{
|
||||||
|
if(TimeUtil.Compare(pe.LastModificationTime,
|
||||||
|
pdo.DeletionTime, true) < 0)
|
||||||
listEntriesToDelete.AddLast(pe);
|
listEntriesToDelete.AddLast(pe);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ((m_slStatus != null) ? m_slStatus.ContinueWork() : true);
|
return ((m_slStatus != null) ? m_slStatus.ContinueWork() : true);
|
||||||
};
|
};
|
||||||
@@ -909,7 +919,7 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
foreach(PwDeletedObject pdoLocal in m_vDeletedObjects)
|
foreach(PwDeletedObject pdoLocal in m_vDeletedObjects)
|
||||||
{
|
{
|
||||||
if(pdoNew.Uuid.EqualsValue(pdoLocal.Uuid))
|
if(pdoNew.Uuid.Equals(pdoLocal.Uuid))
|
||||||
{
|
{
|
||||||
bCopy = false;
|
bCopy = false;
|
||||||
|
|
||||||
@@ -942,8 +952,15 @@ namespace ModernKeePassLib
|
|||||||
if(ptSrc == null) continue;
|
if(ptSrc == null) continue;
|
||||||
|
|
||||||
PwGroup pgOrgParent = ptOrg.ParentGroup;
|
PwGroup pgOrgParent = ptOrg.ParentGroup;
|
||||||
|
// vGroups does not contain the root group, thus pgOrgParent
|
||||||
|
// should not be null
|
||||||
|
if(pgOrgParent == null) { Debug.Assert(false); continue; }
|
||||||
|
|
||||||
PwGroup pgSrcParent = ptSrc.ParentGroup;
|
PwGroup pgSrcParent = ptSrc.ParentGroup;
|
||||||
if(pgOrgParent.Uuid.EqualsValue(pgSrcParent.Uuid))
|
// pgSrcParent may be null (for the source root group)
|
||||||
|
if(pgSrcParent == null) continue;
|
||||||
|
|
||||||
|
if(pgOrgParent.Uuid.Equals(pgSrcParent.Uuid))
|
||||||
{
|
{
|
||||||
pg.LocationChanged = ((ptSrc.LocationChanged > ptOrg.LocationChanged) ?
|
pg.LocationChanged = ((ptSrc.LocationChanged > ptOrg.LocationChanged) ?
|
||||||
ptSrc.LocationChanged : ptOrg.LocationChanged);
|
ptSrc.LocationChanged : ptOrg.LocationChanged);
|
||||||
@@ -963,7 +980,7 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Assert(pg.ParentGroup.Uuid.EqualsValue(pgOrgParent.Uuid));
|
Debug.Assert(pg.ParentGroup.Uuid.Equals(pgOrgParent.Uuid));
|
||||||
Debug.Assert(pg.LocationChanged == ptOrg.LocationChanged);
|
Debug.Assert(pg.LocationChanged == ptOrg.LocationChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -989,7 +1006,7 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
PwGroup pgOrg = ptOrg.ParentGroup;
|
PwGroup pgOrg = ptOrg.ParentGroup;
|
||||||
PwGroup pgSrc = ptSrc.ParentGroup;
|
PwGroup pgSrc = ptSrc.ParentGroup;
|
||||||
if(pgOrg.Uuid.EqualsValue(pgSrc.Uuid))
|
if(pgOrg.Uuid.Equals(pgSrc.Uuid))
|
||||||
{
|
{
|
||||||
pe.LocationChanged = ((ptSrc.LocationChanged > ptOrg.LocationChanged) ?
|
pe.LocationChanged = ((ptSrc.LocationChanged > ptOrg.LocationChanged) ?
|
||||||
ptSrc.LocationChanged : ptOrg.LocationChanged);
|
ptSrc.LocationChanged : ptOrg.LocationChanged);
|
||||||
@@ -1007,7 +1024,7 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Assert(pe.ParentGroup.Uuid.EqualsValue(pgOrg.Uuid));
|
Debug.Assert(pe.ParentGroup.Uuid.Equals(pgOrg.Uuid));
|
||||||
Debug.Assert(pe.LocationChanged == ptOrg.LocationChanged);
|
Debug.Assert(pe.LocationChanged == ptOrg.LocationChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1084,7 +1101,7 @@ namespace ModernKeePassLib
|
|||||||
bool bAdded = false;
|
bool bAdded = false;
|
||||||
foreach(PwUuid puBefore in qRelBefore)
|
foreach(PwUuid puBefore in qRelBefore)
|
||||||
{
|
{
|
||||||
if(puBefore.EqualsValue(pt.Uuid))
|
if(puBefore.Equals(pt.Uuid))
|
||||||
{
|
{
|
||||||
qBefore.Enqueue(pt);
|
qBefore.Enqueue(pt);
|
||||||
bAdded = true;
|
bAdded = true;
|
||||||
@@ -1095,7 +1112,7 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
foreach(PwUuid puAfter in qRelAfter)
|
foreach(PwUuid puAfter in qRelAfter)
|
||||||
{
|
{
|
||||||
if(puAfter.EqualsValue(pt.Uuid))
|
if(puAfter.Equals(pt.Uuid))
|
||||||
{
|
{
|
||||||
qAfter.Enqueue(pt);
|
qAfter.Enqueue(pt);
|
||||||
bAdded = true;
|
bAdded = true;
|
||||||
@@ -1159,7 +1176,16 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
uPosMax = u;
|
uPosMax = u;
|
||||||
dtMax = ptOrg.LocationChanged; // No 'continue'
|
dtMax = ptOrg.LocationChanged; // No 'continue'
|
||||||
vNeighborSrc = ptOrg.ParentGroup.GetObjects(false, bEntries);
|
|
||||||
|
PwGroup pgParent = ptOrg.ParentGroup;
|
||||||
|
if(pgParent != null)
|
||||||
|
vNeighborSrc = pgParent.GetObjects(false, bEntries);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Assert(false); // Org root should be excluded
|
||||||
|
vNeighborSrc = new List<IStructureItem>();
|
||||||
|
vNeighborSrc.Add(ptOrg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IStructureItem ptSrc = pgSrcStructure.FindObject(pt.Uuid, true, bEntries);
|
// IStructureItem ptSrc = pgSrcStructure.FindObject(pt.Uuid, true, bEntries);
|
||||||
@@ -1168,7 +1194,16 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
uPosMax = u;
|
uPosMax = u;
|
||||||
dtMax = ptSrc.LocationChanged; // No 'continue'
|
dtMax = ptSrc.LocationChanged; // No 'continue'
|
||||||
vNeighborSrc = ptSrc.ParentGroup.GetObjects(false, bEntries);
|
|
||||||
|
PwGroup pgParent = ptSrc.ParentGroup;
|
||||||
|
if(pgParent != null)
|
||||||
|
vNeighborSrc = pgParent.GetObjects(false, bEntries);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// pgParent may be null (for the source root group)
|
||||||
|
vNeighborSrc = new List<IStructureItem>();
|
||||||
|
vNeighborSrc.Add(ptSrc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1190,7 +1225,7 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
PwUuid pw = vItems[i].Uuid;
|
PwUuid pw = vItems[i].Uuid;
|
||||||
|
|
||||||
if(pw.EqualsValue(pwPivot)) bBefore = false;
|
if(pw.Equals(pwPivot)) bBefore = false;
|
||||||
else if(bBefore) qBefore.Enqueue(pw);
|
else if(bBefore) qBefore.Enqueue(pw);
|
||||||
else qAfter.Enqueue(pw);
|
else qAfter.Enqueue(pw);
|
||||||
}
|
}
|
||||||
@@ -1226,8 +1261,8 @@ namespace ModernKeePassLib
|
|||||||
PwGroup pgSrcParent = ptSrc.ParentGroup;
|
PwGroup pgSrcParent = ptSrc.ParentGroup;
|
||||||
if(pgSrcParent == null) return true; // Root might be in tree
|
if(pgSrcParent == null) return true; // Root might be in tree
|
||||||
|
|
||||||
if(!ptFirst.ParentGroup.Uuid.EqualsValue(pgOrgParent.Uuid)) return true;
|
if(!ptFirst.ParentGroup.Uuid.Equals(pgOrgParent.Uuid)) return true;
|
||||||
if(!pgOrgParent.Uuid.EqualsValue(pgSrcParent.Uuid)) return true;
|
if(!pgOrgParent.Uuid.Equals(pgSrcParent.Uuid)) return true;
|
||||||
|
|
||||||
List<IStructureItem> lOrg = pgOrgParent.GetObjects(false, bEntries);
|
List<IStructureItem> lOrg = pgOrgParent.GetObjects(false, bEntries);
|
||||||
List<IStructureItem> lSrc = pgSrcParent.GetObjects(false, bEntries);
|
List<IStructureItem> lSrc = pgSrcParent.GetObjects(false, bEntries);
|
||||||
@@ -1239,8 +1274,8 @@ namespace ModernKeePassLib
|
|||||||
IStructureItem pt = vItems.GetAt(u);
|
IStructureItem pt = vItems.GetAt(u);
|
||||||
Debug.Assert(pt.ParentGroup == ptFirst.ParentGroup);
|
Debug.Assert(pt.ParentGroup == ptFirst.ParentGroup);
|
||||||
|
|
||||||
if(!pt.Uuid.EqualsValue(lOrg[(int)u].Uuid)) return true;
|
if(!pt.Uuid.Equals(lOrg[(int)u].Uuid)) return true;
|
||||||
if(!pt.Uuid.EqualsValue(lSrc[(int)u].Uuid)) return true;
|
if(!pt.Uuid.Equals(lSrc[(int)u].Uuid)) return true;
|
||||||
if(pt.LocationChanged != lOrg[(int)u].LocationChanged) return true;
|
if(pt.LocationChanged != lOrg[(int)u].LocationChanged) return true;
|
||||||
if(pt.LocationChanged != lSrc[(int)u].LocationChanged) return true;
|
if(pt.LocationChanged != lSrc[(int)u].LocationChanged) return true;
|
||||||
}
|
}
|
||||||
@@ -1248,41 +1283,41 @@ namespace ModernKeePassLib
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MergeInDbProperties(PwDatabase pwSource, PwMergeMethod mm)
|
private void MergeInDbProperties(PwDatabase pdSource, PwMergeMethod mm)
|
||||||
{
|
{
|
||||||
if(pwSource == null) { Debug.Assert(false); return; }
|
if(pdSource == null) { Debug.Assert(false); return; }
|
||||||
if((mm == PwMergeMethod.KeepExisting) || (mm == PwMergeMethod.None))
|
if((mm == PwMergeMethod.KeepExisting) || (mm == PwMergeMethod.None))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool bForce = (mm == PwMergeMethod.OverwriteExisting);
|
bool bForce = (mm == PwMergeMethod.OverwriteExisting);
|
||||||
|
|
||||||
if(bForce || (pwSource.m_dtNameChanged > m_dtNameChanged))
|
if(bForce || (pdSource.m_dtNameChanged > m_dtNameChanged))
|
||||||
{
|
{
|
||||||
m_strName = pwSource.m_strName;
|
m_strName = pdSource.m_strName;
|
||||||
m_dtNameChanged = pwSource.m_dtNameChanged;
|
m_dtNameChanged = pdSource.m_dtNameChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bForce || (pwSource.m_dtDescChanged > m_dtDescChanged))
|
if(bForce || (pdSource.m_dtDescChanged > m_dtDescChanged))
|
||||||
{
|
{
|
||||||
m_strDesc = pwSource.m_strDesc;
|
m_strDesc = pdSource.m_strDesc;
|
||||||
m_dtDescChanged = pwSource.m_dtDescChanged;
|
m_dtDescChanged = pdSource.m_dtDescChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bForce || (pwSource.m_dtDefaultUserChanged > m_dtDefaultUserChanged))
|
if(bForce || (pdSource.m_dtDefaultUserChanged > m_dtDefaultUserChanged))
|
||||||
{
|
{
|
||||||
m_strDefaultUserName = pwSource.m_strDefaultUserName;
|
m_strDefaultUserName = pdSource.m_strDefaultUserName;
|
||||||
m_dtDefaultUserChanged = pwSource.m_dtDefaultUserChanged;
|
m_dtDefaultUserChanged = pdSource.m_dtDefaultUserChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bForce) m_clr = pwSource.m_clr;
|
if(bForce) m_clr = pdSource.m_clr;
|
||||||
|
|
||||||
PwUuid pwPrefBin = m_pwRecycleBin, pwAltBin = pwSource.m_pwRecycleBin;
|
PwUuid pwPrefBin = m_pwRecycleBin, pwAltBin = pdSource.m_pwRecycleBin;
|
||||||
if(bForce || (pwSource.m_dtRecycleBinChanged > m_dtRecycleBinChanged))
|
if(bForce || (pdSource.m_dtRecycleBinChanged > m_dtRecycleBinChanged))
|
||||||
{
|
{
|
||||||
pwPrefBin = pwSource.m_pwRecycleBin;
|
pwPrefBin = pdSource.m_pwRecycleBin;
|
||||||
pwAltBin = m_pwRecycleBin;
|
pwAltBin = m_pwRecycleBin;
|
||||||
m_bUseRecycleBin = pwSource.m_bUseRecycleBin;
|
m_bUseRecycleBin = pdSource.m_bUseRecycleBin;
|
||||||
m_dtRecycleBinChanged = pwSource.m_dtRecycleBinChanged;
|
m_dtRecycleBinChanged = pdSource.m_dtRecycleBinChanged;
|
||||||
}
|
}
|
||||||
if(m_pgRootGroup.FindGroup(pwPrefBin, true) != null)
|
if(m_pgRootGroup.FindGroup(pwPrefBin, true) != null)
|
||||||
m_pwRecycleBin = pwPrefBin;
|
m_pwRecycleBin = pwPrefBin;
|
||||||
@@ -1290,12 +1325,12 @@ namespace ModernKeePassLib
|
|||||||
m_pwRecycleBin = pwAltBin;
|
m_pwRecycleBin = pwAltBin;
|
||||||
else m_pwRecycleBin = PwUuid.Zero; // Debug.Assert(false);
|
else m_pwRecycleBin = PwUuid.Zero; // Debug.Assert(false);
|
||||||
|
|
||||||
PwUuid pwPrefTmp = m_pwEntryTemplatesGroup, pwAltTmp = pwSource.m_pwEntryTemplatesGroup;
|
PwUuid pwPrefTmp = m_pwEntryTemplatesGroup, pwAltTmp = pdSource.m_pwEntryTemplatesGroup;
|
||||||
if(bForce || (pwSource.m_dtEntryTemplatesChanged > m_dtEntryTemplatesChanged))
|
if(bForce || (pdSource.m_dtEntryTemplatesChanged > m_dtEntryTemplatesChanged))
|
||||||
{
|
{
|
||||||
pwPrefTmp = pwSource.m_pwEntryTemplatesGroup;
|
pwPrefTmp = pdSource.m_pwEntryTemplatesGroup;
|
||||||
pwAltTmp = m_pwEntryTemplatesGroup;
|
pwAltTmp = m_pwEntryTemplatesGroup;
|
||||||
m_dtEntryTemplatesChanged = pwSource.m_dtEntryTemplatesChanged;
|
m_dtEntryTemplatesChanged = pdSource.m_dtEntryTemplatesChanged;
|
||||||
}
|
}
|
||||||
if(m_pgRootGroup.FindGroup(pwPrefTmp, true) != null)
|
if(m_pgRootGroup.FindGroup(pwPrefTmp, true) != null)
|
||||||
m_pwEntryTemplatesGroup = pwPrefTmp;
|
m_pwEntryTemplatesGroup = pwPrefTmp;
|
||||||
@@ -1307,10 +1342,7 @@ namespace ModernKeePassLib
|
|||||||
private void MergeEntryHistory(PwEntry pe, PwEntry peSource,
|
private void MergeEntryHistory(PwEntry pe, PwEntry peSource,
|
||||||
PwMergeMethod mm)
|
PwMergeMethod mm)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
if(!pe.Uuid.Equals(peSource.Uuid)) { Debug.Assert(false); return; }
|
||||||
return ;
|
|
||||||
#if TODO
|
|
||||||
if(!pe.Uuid.EqualsValue(peSource.Uuid)) { Debug.Assert(false); return; }
|
|
||||||
|
|
||||||
if(pe.History.UCount == peSource.History.UCount)
|
if(pe.History.UCount == peSource.History.UCount)
|
||||||
{
|
{
|
||||||
@@ -1330,31 +1362,35 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
if((m_slStatus != null) && !m_slStatus.ContinueWork()) return;
|
if((m_slStatus != null) && !m_slStatus.ContinueWork()) return;
|
||||||
|
|
||||||
SortedList<DateTime, PwEntry> list = new SortedList<DateTime, PwEntry>();
|
IDictionary<DateTime, PwEntry> dict =
|
||||||
|
#if KeePassLibSD
|
||||||
|
new SortedList<DateTime, PwEntry>();
|
||||||
|
#else
|
||||||
|
new SortedDictionary<DateTime, PwEntry>();
|
||||||
|
#endif
|
||||||
foreach(PwEntry peOrg in pe.History)
|
foreach(PwEntry peOrg in pe.History)
|
||||||
{
|
{
|
||||||
list[peOrg.LastModificationTime] = peOrg;
|
dict[peOrg.LastModificationTime] = peOrg;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(PwEntry peSrc in peSource.History)
|
foreach(PwEntry peSrc in peSource.History)
|
||||||
{
|
{
|
||||||
DateTime dt = peSrc.LastModificationTime;
|
DateTime dt = peSrc.LastModificationTime;
|
||||||
if(list.ContainsKey(dt))
|
if(dict.ContainsKey(dt))
|
||||||
{
|
{
|
||||||
if(mm == PwMergeMethod.OverwriteExisting)
|
if(mm == PwMergeMethod.OverwriteExisting)
|
||||||
list[dt] = peSrc.CloneDeep();
|
dict[dt] = peSrc.CloneDeep();
|
||||||
}
|
}
|
||||||
else list[dt] = peSrc.CloneDeep();
|
else dict[dt] = peSrc.CloneDeep();
|
||||||
}
|
}
|
||||||
|
|
||||||
pe.History.Clear();
|
pe.History.Clear();
|
||||||
foreach(KeyValuePair<DateTime, PwEntry> kvpCur in list)
|
foreach(KeyValuePair<DateTime, PwEntry> kvpCur in dict)
|
||||||
{
|
{
|
||||||
Debug.Assert(kvpCur.Value.Uuid.EqualsValue(pe.Uuid));
|
Debug.Assert(kvpCur.Value.Uuid.Equals(pe.Uuid));
|
||||||
Debug.Assert(kvpCur.Value.History.UCount == 0);
|
Debug.Assert(kvpCur.Value.History.UCount == 0);
|
||||||
pe.History.Add(kvpCur.Value);
|
pe.History.Add(kvpCur.Value);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MaintainBackups()
|
public bool MaintainBackups()
|
||||||
@@ -1378,12 +1414,12 @@ namespace ModernKeePassLib
|
|||||||
/// <param name="strFile">Source file.</param>
|
/// <param name="strFile">Source file.</param>
|
||||||
public void Synchronize(string strFile)
|
public void Synchronize(string strFile)
|
||||||
{
|
{
|
||||||
PwDatabase pwSource = new PwDatabase();
|
PwDatabase pdSource = new PwDatabase();
|
||||||
|
|
||||||
IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
|
IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
|
||||||
pwSource.Open(ioc, m_pwUserKey, null);
|
pdSource.Open(ioc, m_pwUserKey, null);
|
||||||
|
|
||||||
MergeIn(pwSource, PwMergeMethod.Synchronize);
|
MergeIn(pdSource, PwMergeMethod.Synchronize);
|
||||||
} */
|
} */
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1393,32 +1429,50 @@ namespace ModernKeePassLib
|
|||||||
/// <returns>Index of the icon.</returns>
|
/// <returns>Index of the icon.</returns>
|
||||||
public int GetCustomIconIndex(PwUuid pwIconId)
|
public int GetCustomIconIndex(PwUuid pwIconId)
|
||||||
{
|
{
|
||||||
int nIndex = 0;
|
for(int i = 0; i < m_vCustomIcons.Count; ++i)
|
||||||
|
|
||||||
foreach(PwCustomIcon pwci in m_vCustomIcons)
|
|
||||||
{
|
{
|
||||||
if(pwci.Uuid.EqualsValue(pwIconId))
|
PwCustomIcon pwci = m_vCustomIcons[i];
|
||||||
return nIndex;
|
if(pwci.Uuid.Equals(pwIconId))
|
||||||
|
return i;
|
||||||
++nIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug.Assert(false); // Do not assert
|
// Debug.Assert(false); // Do not assert
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetCustomIconIndex(byte[] pbPngData)
|
||||||
|
{
|
||||||
|
if(pbPngData == null) { Debug.Assert(false); return -1; }
|
||||||
|
|
||||||
|
for(int i = 0; i < m_vCustomIcons.Count; ++i)
|
||||||
|
{
|
||||||
|
PwCustomIcon pwci = m_vCustomIcons[i];
|
||||||
|
byte[] pbEx = pwci.ImageDataPng;
|
||||||
|
if(pbEx == null) { Debug.Assert(false); continue; }
|
||||||
|
|
||||||
|
if(MemUtil.ArraysEqual(pbEx, pbPngData))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a custom icon. This function can return <c>null</c>, if
|
/// Get a custom icon. This function can return <c>null</c>, if
|
||||||
/// no cached image of the icon is available.
|
/// no cached image of the icon is available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pwIconId">ID of the icon.</param>
|
/// <param name="pwIconId">ID of the icon.</param>
|
||||||
/// <returns>Image data.</returns>
|
/// <returns>Image data.</returns>
|
||||||
public BitmapImage GetCustomIcon(PwUuid pwIconId)
|
public Image GetCustomIcon(PwUuid pwIconId)
|
||||||
{
|
{
|
||||||
|
#if PCL
|
||||||
|
return null;
|
||||||
|
#else
|
||||||
int nIndex = GetCustomIconIndex(pwIconId);
|
int nIndex = GetCustomIconIndex(pwIconId);
|
||||||
|
|
||||||
if(nIndex >= 0) return m_vCustomIcons[nIndex].Image;
|
if(nIndex >= 0) return m_vCustomIcons[nIndex].Image;
|
||||||
else { Debug.Assert(false); return null; }
|
else { Debug.Assert(false); return null; }
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteCustomIcons(List<PwUuid> vUuidsToDelete)
|
public bool DeleteCustomIcons(List<PwUuid> vUuidsToDelete)
|
||||||
@@ -1430,11 +1484,11 @@ namespace ModernKeePassLib
|
|||||||
GroupHandler gh = delegate(PwGroup pg)
|
GroupHandler gh = delegate(PwGroup pg)
|
||||||
{
|
{
|
||||||
PwUuid uuidThis = pg.CustomIconUuid;
|
PwUuid uuidThis = pg.CustomIconUuid;
|
||||||
if(uuidThis.EqualsValue(PwUuid.Zero)) return true;
|
if(uuidThis.Equals(PwUuid.Zero)) return true;
|
||||||
|
|
||||||
foreach(PwUuid uuidDelete in vUuidsToDelete)
|
foreach(PwUuid uuidDelete in vUuidsToDelete)
|
||||||
{
|
{
|
||||||
if(uuidThis.EqualsValue(uuidDelete))
|
if(uuidThis.Equals(uuidDelete))
|
||||||
{
|
{
|
||||||
pg.CustomIconUuid = PwUuid.Zero;
|
pg.CustomIconUuid = PwUuid.Zero;
|
||||||
break;
|
break;
|
||||||
@@ -1469,11 +1523,11 @@ namespace ModernKeePassLib
|
|||||||
private static void RemoveCustomIconUuid(PwEntry pe, List<PwUuid> vToDelete)
|
private static void RemoveCustomIconUuid(PwEntry pe, List<PwUuid> vToDelete)
|
||||||
{
|
{
|
||||||
PwUuid uuidThis = pe.CustomIconUuid;
|
PwUuid uuidThis = pe.CustomIconUuid;
|
||||||
if(uuidThis.EqualsValue(PwUuid.Zero)) return;
|
if(uuidThis.Equals(PwUuid.Zero)) return;
|
||||||
|
|
||||||
foreach(PwUuid uuidDelete in vToDelete)
|
foreach(PwUuid uuidDelete in vToDelete)
|
||||||
{
|
{
|
||||||
if(uuidThis.EqualsValue(uuidDelete))
|
if(uuidThis.Equals(uuidDelete))
|
||||||
{
|
{
|
||||||
pe.CustomIconUuid = PwUuid.Zero;
|
pe.CustomIconUuid = PwUuid.Zero;
|
||||||
break;
|
break;
|
||||||
@@ -1493,7 +1547,7 @@ namespace ModernKeePassLib
|
|||||||
GroupHandler gh = delegate(PwGroup pg)
|
GroupHandler gh = delegate(PwGroup pg)
|
||||||
{
|
{
|
||||||
foreach(PwUuid u in l)
|
foreach(PwUuid u in l)
|
||||||
bAllUnique &= !pg.Uuid.EqualsValue(u);
|
bAllUnique &= !pg.Uuid.Equals(u);
|
||||||
l.Add(pg.Uuid);
|
l.Add(pg.Uuid);
|
||||||
return bAllUnique;
|
return bAllUnique;
|
||||||
};
|
};
|
||||||
@@ -1501,7 +1555,7 @@ namespace ModernKeePassLib
|
|||||||
EntryHandler eh = delegate(PwEntry pe)
|
EntryHandler eh = delegate(PwEntry pe)
|
||||||
{
|
{
|
||||||
foreach(PwUuid u in l)
|
foreach(PwUuid u in l)
|
||||||
bAllUnique &= !pe.Uuid.EqualsValue(u);
|
bAllUnique &= !pe.Uuid.Equals(u);
|
||||||
l.Add(pe.Uuid);
|
l.Add(pe.Uuid);
|
||||||
return bAllUnique;
|
return bAllUnique;
|
||||||
};
|
};
|
||||||
@@ -1599,7 +1653,7 @@ namespace ModernKeePassLib
|
|||||||
PwEntry peB = l.GetAt(j);
|
PwEntry peB = l.GetAt(j);
|
||||||
if(!DupEntriesEqual(peA, peB)) continue;
|
if(!DupEntriesEqual(peA, peB)) continue;
|
||||||
|
|
||||||
bool bDeleteA = (peA.LastModificationTime <= peB.LastModificationTime);
|
bool bDeleteA = (TimeUtil.CompareLastMod(peA, peB, true) <= 0);
|
||||||
if(pgRecycleBin != null)
|
if(pgRecycleBin != null)
|
||||||
{
|
{
|
||||||
bool bAInBin = peA.IsContainedIn(pgRecycleBin);
|
bool bAInBin = peA.IsContainedIn(pgRecycleBin);
|
||||||
@@ -1638,10 +1692,6 @@ namespace ModernKeePassLib
|
|||||||
private static List<string> m_lStdFields = null;
|
private static List<string> m_lStdFields = null;
|
||||||
private static bool DupEntriesEqual(PwEntry a, PwEntry b)
|
private static bool DupEntriesEqual(PwEntry a, PwEntry b)
|
||||||
{
|
{
|
||||||
|
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return true;
|
|
||||||
#if TODO
|
|
||||||
if(m_lStdFields == null) m_lStdFields = PwDefs.GetStandardFields();
|
if(m_lStdFields == null) m_lStdFields = PwDefs.GetStandardFields();
|
||||||
|
|
||||||
foreach(string strStdKey in m_lStdFields)
|
foreach(string strStdKey in m_lStdFields)
|
||||||
@@ -1689,7 +1739,6 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint DeleteEmptyGroups()
|
public uint DeleteEmptyGroups()
|
||||||
@@ -1721,11 +1770,11 @@ namespace ModernKeePassLib
|
|||||||
GroupHandler gh = delegate(PwGroup pg)
|
GroupHandler gh = delegate(PwGroup pg)
|
||||||
{
|
{
|
||||||
PwUuid pwUuid = pg.CustomIconUuid;
|
PwUuid pwUuid = pg.CustomIconUuid;
|
||||||
if((pwUuid == null) || pwUuid.EqualsValue(PwUuid.Zero)) return true;
|
if((pwUuid == null) || pwUuid.Equals(PwUuid.Zero)) return true;
|
||||||
|
|
||||||
for(int i = 0; i < lToDelete.Count; ++i)
|
for(int i = 0; i < lToDelete.Count; ++i)
|
||||||
{
|
{
|
||||||
if(lToDelete[i].EqualsValue(pwUuid))
|
if(lToDelete[i].Equals(pwUuid))
|
||||||
{
|
{
|
||||||
lToDelete.RemoveAt(i);
|
lToDelete.RemoveAt(i);
|
||||||
break;
|
break;
|
||||||
@@ -1738,11 +1787,11 @@ namespace ModernKeePassLib
|
|||||||
EntryHandler eh = delegate(PwEntry pe)
|
EntryHandler eh = delegate(PwEntry pe)
|
||||||
{
|
{
|
||||||
PwUuid pwUuid = pe.CustomIconUuid;
|
PwUuid pwUuid = pe.CustomIconUuid;
|
||||||
if((pwUuid == null) || pwUuid.EqualsValue(PwUuid.Zero)) return true;
|
if((pwUuid == null) || pwUuid.Equals(PwUuid.Zero)) return true;
|
||||||
|
|
||||||
for(int i = 0; i < lToDelete.Count; ++i)
|
for(int i = 0; i < lToDelete.Count; ++i)
|
||||||
{
|
{
|
||||||
if(lToDelete[i].EqualsValue(pwUuid))
|
if(lToDelete[i].Equals(pwUuid))
|
||||||
{
|
{
|
||||||
lToDelete.RemoveAt(i);
|
lToDelete.RemoveAt(i);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -25,6 +25,7 @@ using System.Diagnostics;
|
|||||||
|
|
||||||
using ModernKeePassLib.Delegates;
|
using ModernKeePassLib.Delegates;
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
|
using ModernKeePassLib.Serialization;
|
||||||
|
|
||||||
namespace ModernKeePassLib
|
namespace ModernKeePassLib
|
||||||
{
|
{
|
||||||
@@ -44,6 +45,9 @@ namespace ModernKeePassLib
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const string ShortProductName = "KeePass";
|
public const string ShortProductName = "KeePass";
|
||||||
|
|
||||||
|
internal const string UnixName = "keepass2";
|
||||||
|
internal const string ResClass = "KeePass2"; // With initial capital
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version, encoded as 32-bit unsigned integer.
|
/// Version, encoded as 32-bit unsigned integer.
|
||||||
/// 2.00 = 0x02000000, 2.01 = 0x02000100, ..., 2.18 = 0x02010800.
|
/// 2.00 = 0x02000000, 2.01 = 0x02000100, ..., 2.18 = 0x02010800.
|
||||||
@@ -51,20 +55,20 @@ namespace ModernKeePassLib
|
|||||||
/// e.g. 2.19 = 0x02130000.
|
/// e.g. 2.19 = 0x02130000.
|
||||||
/// It is highly recommended to use <c>FileVersion64</c> instead.
|
/// It is highly recommended to use <c>FileVersion64</c> instead.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint Version32 = 0x02130000;
|
public const uint Version32 = 0x021C0000;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version, encoded as 64-bit unsigned integer
|
/// Version, encoded as 64-bit unsigned integer
|
||||||
/// (component-wise, 16 bits per component).
|
/// (component-wise, 16 bits per component).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const ulong FileVersion64 = 0x0002001300000000UL;
|
public const ulong FileVersion64 = 0x0002001C00000000UL;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version, encoded as string.
|
/// Version, encoded as string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string VersionString = "2.19";
|
public const string VersionString = "2.28";
|
||||||
|
|
||||||
public const string Copyright = @"Copyright <EFBFBD> 2003-2012 Dominik Reichl";
|
public const string Copyright = @"Copyright © 2003-2014 Dominik Reichl";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Product website URL. Terminated by a forward slash.
|
/// Product website URL. Terminated by a forward slash.
|
||||||
@@ -216,7 +220,7 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable 1591 // Missing XML comments warning
|
// #pragma warning disable 1591 // Missing XML comments warning
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Search parameters for group and entry searches.
|
/// Search parameters for group and entry searches.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -314,10 +318,11 @@ namespace ModernKeePassLib
|
|||||||
set { m_bSearchInTags = value; }
|
set { m_bSearchInTags = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PCL || KeePassRT
|
||||||
//Bert TODO: Check if using CurrentCultureIgnoreCase makes sense.
|
private StringComparison m_scType = StringComparison.OrdinalIgnoreCase;
|
||||||
private StringComparison m_scType = StringComparison.CurrentCultureIgnoreCase;
|
#else
|
||||||
//private StringComparison m_scType = StringComparison.InvariantCultureIgnoreCase;
|
private StringComparison m_scType = StringComparison.InvariantCultureIgnoreCase;
|
||||||
|
#endif
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// String comparison type. Specifies the condition when the specified
|
/// String comparison type. Specifies the condition when the specified
|
||||||
/// text matches a group/entry string.
|
/// text matches a group/entry string.
|
||||||
@@ -405,9 +410,9 @@ namespace ModernKeePassLib
|
|||||||
return (SearchParameters)this.MemberwiseClone();
|
return (SearchParameters)this.MemberwiseClone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma warning restore 1591 // Missing XML comments warning
|
// #pragma warning restore 1591 // Missing XML comments warning
|
||||||
|
|
||||||
#pragma warning disable 1591 // Missing XML comments warning
|
// #pragma warning disable 1591 // Missing XML comments warning
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Memory protection configuration structure (for default fields).
|
/// Memory protection configuration structure (for default fields).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -437,7 +442,7 @@ namespace ModernKeePassLib
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma warning restore 1591 // Missing XML comments warning
|
// #pragma warning restore 1591 // Missing XML comments warning
|
||||||
|
|
||||||
public sealed class ObjectTouchedEventArgs : EventArgs
|
public sealed class ObjectTouchedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
@@ -458,4 +463,24 @@ namespace ModernKeePassLib
|
|||||||
m_bParentsTouched = bParentsTouched;
|
m_bParentsTouched = bParentsTouched;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class IOAccessEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
private IOConnectionInfo m_ioc;
|
||||||
|
public IOConnectionInfo IOConnectionInfo { get { return m_ioc; } }
|
||||||
|
|
||||||
|
private IOConnectionInfo m_ioc2;
|
||||||
|
public IOConnectionInfo IOConnectionInfo2 { get { return m_ioc2; } }
|
||||||
|
|
||||||
|
private IOAccessType m_t;
|
||||||
|
public IOAccessType Type { get { return m_t; } }
|
||||||
|
|
||||||
|
public IOAccessEventArgs(IOConnectionInfo ioc, IOConnectionInfo ioc2,
|
||||||
|
IOAccessType t)
|
||||||
|
{
|
||||||
|
m_ioc = ioc;
|
||||||
|
m_ioc2 = ioc2;
|
||||||
|
m_t = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Xml;
|
||||||
|
using Windows.UI;
|
||||||
using ModernKeePassLib.Collections;
|
using ModernKeePassLib.Collections;
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
@@ -46,9 +48,8 @@ namespace ModernKeePassLib
|
|||||||
private PwIcon m_pwIcon = PwIcon.Key;
|
private PwIcon m_pwIcon = PwIcon.Key;
|
||||||
private PwUuid m_pwCustomIconID = PwUuid.Zero;
|
private PwUuid m_pwCustomIconID = PwUuid.Zero;
|
||||||
|
|
||||||
private WinRTAdaptors.Color m_clrForeground = WinRTAdaptors.Color.Empty;
|
private Color m_clrForeground;
|
||||||
private WinRTAdaptors.Color m_clrBackground = WinRTAdaptors.Color.Empty;
|
private Color m_clrBackground;
|
||||||
|
|
||||||
|
|
||||||
private DateTime m_tCreation = PwDefs.DtDefaultNow;
|
private DateTime m_tCreation = PwDefs.DtDefaultNow;
|
||||||
private DateTime m_tLastMod = PwDefs.DtDefaultNow;
|
private DateTime m_tLastMod = PwDefs.DtDefaultNow;
|
||||||
@@ -81,7 +82,7 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
get { return m_pParentGroup; }
|
get { return m_pParentGroup; }
|
||||||
|
|
||||||
/// Plugins: use <c>PwGroup.AddEntry</c> instead.
|
// Plugins: use <c>PwGroup.AddEntry</c> instead.
|
||||||
internal set { m_pParentGroup = value; }
|
internal set { m_pParentGroup = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +174,7 @@ namespace ModernKeePassLib
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get or set the foreground color of this entry.
|
/// Get or set the foreground color of this entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public WinRTAdaptors.Color ForegroundColor
|
public Color ForegroundColor
|
||||||
{
|
{
|
||||||
get { return m_clrForeground; }
|
get { return m_clrForeground; }
|
||||||
set { m_clrForeground = value; }
|
set { m_clrForeground = value; }
|
||||||
@@ -182,7 +183,7 @@ namespace ModernKeePassLib
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get or set the background color of this entry.
|
/// Get or set the background color of this entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public WinRTAdaptors.Color BackgroundColor
|
public Color BackgroundColor
|
||||||
{
|
{
|
||||||
get { return m_clrBackground; }
|
get { return m_clrBackground; }
|
||||||
set { m_clrBackground = value; }
|
set { m_clrBackground = value; }
|
||||||
@@ -197,15 +198,6 @@ namespace ModernKeePassLib
|
|||||||
set { m_tCreation = value; }
|
set { m_tCreation = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The date/time when this entry was last accessed (read).
|
|
||||||
/// </summary>
|
|
||||||
public DateTime LastAccessTime
|
|
||||||
{
|
|
||||||
get { return m_tLastAccess; }
|
|
||||||
set { m_tLastAccess = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date/time when this entry was last modified.
|
/// The date/time when this entry was last modified.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -215,6 +207,15 @@ namespace ModernKeePassLib
|
|||||||
set { m_tLastMod = value; }
|
set { m_tLastMod = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The date/time when this entry was last accessed (read).
|
||||||
|
/// </summary>
|
||||||
|
public DateTime LastAccessTime
|
||||||
|
{
|
||||||
|
get { return m_tLastAccess; }
|
||||||
|
set { m_tLastAccess = value; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date/time when this entry expires. Use the <c>Expires</c> property
|
/// The date/time when this entry expires. Use the <c>Expires</c> property
|
||||||
/// to specify if the entry does actually expire or not.
|
/// to specify if the entry does actually expire or not.
|
||||||
@@ -402,10 +403,6 @@ namespace ModernKeePassLib
|
|||||||
public bool EqualsEntry(PwEntry pe, PwCompareOptions pwOpt,
|
public bool EqualsEntry(PwEntry pe, PwCompareOptions pwOpt,
|
||||||
MemProtCmpMode mpCmpStr)
|
MemProtCmpMode mpCmpStr)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return false;
|
|
||||||
#if TODO
|
|
||||||
|
|
||||||
if(pe == null) { Debug.Assert(false); return false; }
|
if(pe == null) { Debug.Assert(false); return false; }
|
||||||
|
|
||||||
bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) !=
|
bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) !=
|
||||||
@@ -415,7 +412,7 @@ namespace ModernKeePassLib
|
|||||||
bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) !=
|
bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) !=
|
||||||
PwCompareOptions.None);
|
PwCompareOptions.None);
|
||||||
|
|
||||||
if(!m_uuid.EqualsValue(pe.m_uuid)) return false;
|
if(!m_uuid.Equals(pe.m_uuid)) return false;
|
||||||
if((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None)
|
if((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None)
|
||||||
{
|
{
|
||||||
if(m_pParentGroup != pe.m_pParentGroup) return false;
|
if(m_pParentGroup != pe.m_pParentGroup) return false;
|
||||||
@@ -458,7 +455,7 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(m_pwIcon != pe.m_pwIcon) return false;
|
if(m_pwIcon != pe.m_pwIcon) return false;
|
||||||
if(!m_pwCustomIconID.EqualsValue(pe.m_pwCustomIconID)) return false;
|
if(!m_pwCustomIconID.Equals(pe.m_pwCustomIconID)) return false;
|
||||||
|
|
||||||
if(m_clrForeground != pe.m_clrForeground) return false;
|
if(m_clrForeground != pe.m_clrForeground) return false;
|
||||||
if(m_clrBackground != pe.m_clrBackground) return false;
|
if(m_clrBackground != pe.m_clrBackground) return false;
|
||||||
@@ -479,7 +476,6 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -497,10 +493,12 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
Debug.Assert(peTemplate != null); if(peTemplate == null) throw new ArgumentNullException("peTemplate");
|
Debug.Assert(peTemplate != null); if(peTemplate == null) throw new ArgumentNullException("peTemplate");
|
||||||
|
|
||||||
if(bOnlyIfNewer && (peTemplate.m_tLastMod < m_tLastMod)) return;
|
if(bOnlyIfNewer && (TimeUtil.Compare(peTemplate.m_tLastMod, m_tLastMod,
|
||||||
|
true) < 0))
|
||||||
|
return;
|
||||||
|
|
||||||
// Template UUID should be the same as the current one
|
// Template UUID should be the same as the current one
|
||||||
Debug.Assert(m_uuid.EqualsValue(peTemplate.m_uuid));
|
Debug.Assert(m_uuid.Equals(peTemplate.m_uuid));
|
||||||
m_uuid = peTemplate.m_uuid;
|
m_uuid = peTemplate.m_uuid;
|
||||||
|
|
||||||
if(bAssignLocationChanged)
|
if(bAssignLocationChanged)
|
||||||
@@ -695,7 +693,7 @@ namespace ModernKeePassLib
|
|||||||
for(uint u = 0; u < m_listHistory.UCount; ++u)
|
for(uint u = 0; u < m_listHistory.UCount; ++u)
|
||||||
{
|
{
|
||||||
PwEntry pe = m_listHistory.GetAt(u);
|
PwEntry pe = m_listHistory.GetAt(u);
|
||||||
if(pe.LastModificationTime < dtMin)
|
if(TimeUtil.Compare(pe.LastModificationTime, dtMin, true) < 0)
|
||||||
{
|
{
|
||||||
idxRemove = u;
|
idxRemove = u;
|
||||||
dtMin = pe.LastModificationTime;
|
dtMin = pe.LastModificationTime;
|
||||||
@@ -847,6 +845,24 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetCreatedNow()
|
||||||
|
{
|
||||||
|
DateTime dt = DateTime.Now;
|
||||||
|
|
||||||
|
m_tCreation = dt;
|
||||||
|
m_tLastAccess = dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PwEntry Duplicate()
|
||||||
|
{
|
||||||
|
PwEntry pe = CloneDeep();
|
||||||
|
|
||||||
|
pe.SetUuid(new PwUuid(true), true);
|
||||||
|
pe.SetCreatedNow();
|
||||||
|
|
||||||
|
return pe;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class PwEntryComparer : IComparer<PwEntry>
|
public sealed class PwEntryComparer : IComparer<PwEntry>
|
||||||
@@ -867,13 +883,15 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
public int Compare(PwEntry a, PwEntry b)
|
public int Compare(PwEntry a, PwEntry b)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return 0;
|
|
||||||
#if TODO
|
|
||||||
string strA = a.Strings.ReadSafe(m_strFieldName);
|
string strA = a.Strings.ReadSafe(m_strFieldName);
|
||||||
string strB = b.Strings.ReadSafe(m_strFieldName);
|
string strB = b.Strings.ReadSafe(m_strFieldName);
|
||||||
|
|
||||||
if(m_bCompareNaturally) return StrUtil.CompareNaturally(strA, strB);
|
if(m_bCompareNaturally) return StrUtil.CompareNaturally(strA, strB);
|
||||||
|
|
||||||
|
#if PCL || KeePassRT
|
||||||
|
return string.Compare(strA, strB, m_bCaseInsensitive ?
|
||||||
|
StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture);
|
||||||
|
#else
|
||||||
return string.Compare(strA, strB, m_bCaseInsensitive);
|
return string.Compare(strA, strB, m_bCaseInsensitive);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -65,6 +65,8 @@ namespace ModernKeePassLib
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum PwMergeMethod
|
public enum PwMergeMethod
|
||||||
{
|
{
|
||||||
|
// Do not change the explicitly assigned values, otherwise
|
||||||
|
// serialization (e.g. of Ecas triggers) breaks
|
||||||
None = 0,
|
None = 0,
|
||||||
OverwriteExisting = 1,
|
OverwriteExisting = 1,
|
||||||
KeepExisting = 2,
|
KeepExisting = 2,
|
||||||
@@ -202,6 +204,67 @@ namespace ModernKeePassLib
|
|||||||
IgnoreHistory = 0x10,
|
IgnoreHistory = 0x10,
|
||||||
IgnoreLastBackup = 0x20,
|
IgnoreLastBackup = 0x20,
|
||||||
|
|
||||||
|
// For groups:
|
||||||
|
PropertiesOnly = 0x40,
|
||||||
|
|
||||||
IgnoreTimes = (IgnoreLastAccess | IgnoreLastMod)
|
IgnoreTimes = (IgnoreLastAccess | IgnoreLastMod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum IOAccessType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The IO connection is being opened for reading.
|
||||||
|
/// </summary>
|
||||||
|
Read = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The IO connection is being opened for writing.
|
||||||
|
/// </summary>
|
||||||
|
Write = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The IO 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.
|
||||||
|
/// </summary>
|
||||||
|
Delete = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The IO connection is being opened for renaming/moving a file/object.
|
||||||
|
/// </summary>
|
||||||
|
Move = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
// public enum PwLogicalOp
|
||||||
|
// {
|
||||||
|
// None = 0,
|
||||||
|
// Or = 1,
|
||||||
|
// And = 2,
|
||||||
|
// NOr = 3,
|
||||||
|
// NAnd = 4
|
||||||
|
// }
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum AppRunFlags
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
GetStdOutput = 1,
|
||||||
|
WaitForExit = 2,
|
||||||
|
|
||||||
|
// This flag prevents any handles being garbage-collected
|
||||||
|
// before the started process has terminated, without
|
||||||
|
// blocking the current thread;
|
||||||
|
// https://sourceforge.net/p/keepass/patches/84/
|
||||||
|
GCKeepAlive = 4,
|
||||||
|
|
||||||
|
// https://sourceforge.net/p/keepass/patches/85/
|
||||||
|
DoEvents = 8,
|
||||||
|
DisableForms = 16
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -137,7 +137,7 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
get { return m_pParentGroup; }
|
get { return m_pParentGroup; }
|
||||||
|
|
||||||
/// Plugins: use <c>PwGroup.AddGroup</c> instead.
|
// Plugins: use <c>PwGroup.AddGroup</c> instead.
|
||||||
internal set { Debug.Assert(value != this); m_pParentGroup = value; }
|
internal set { Debug.Assert(value != this); m_pParentGroup = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,9 +352,9 @@ namespace ModernKeePassLib
|
|||||||
pg.m_pwCustomIconID = m_pwCustomIconID;
|
pg.m_pwCustomIconID = m_pwCustomIconID;
|
||||||
|
|
||||||
pg.m_tCreation = m_tCreation;
|
pg.m_tCreation = m_tCreation;
|
||||||
pg.m_tExpire = m_tExpire;
|
|
||||||
pg.m_tLastAccess = m_tLastAccess;
|
|
||||||
pg.m_tLastMod = m_tLastMod;
|
pg.m_tLastMod = m_tLastMod;
|
||||||
|
pg.m_tLastAccess = m_tLastAccess;
|
||||||
|
pg.m_tExpire = m_tExpire;
|
||||||
pg.m_bExpires = m_bExpires;
|
pg.m_bExpires = m_bExpires;
|
||||||
pg.m_uUsageCount = m_uUsageCount;
|
pg.m_uUsageCount = m_uUsageCount;
|
||||||
|
|
||||||
@@ -363,6 +363,9 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
pg.m_strDefaultAutoTypeSequence = m_strDefaultAutoTypeSequence;
|
pg.m_strDefaultAutoTypeSequence = m_strDefaultAutoTypeSequence;
|
||||||
|
|
||||||
|
pg.m_bEnableAutoType = m_bEnableAutoType;
|
||||||
|
pg.m_bEnableSearching = m_bEnableSearching;
|
||||||
|
|
||||||
pg.m_pwLastTopVisibleEntry = m_pwLastTopVisibleEntry;
|
pg.m_pwLastTopVisibleEntry = m_pwLastTopVisibleEntry;
|
||||||
|
|
||||||
return pg;
|
return pg;
|
||||||
@@ -385,6 +388,76 @@ namespace ModernKeePassLib
|
|||||||
return pg;
|
return pg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool EqualsGroup(PwGroup pg, PwCompareOptions pwOpt,
|
||||||
|
MemProtCmpMode mpCmpStr)
|
||||||
|
{
|
||||||
|
if(pg == null) { Debug.Assert(false); return false; }
|
||||||
|
|
||||||
|
bool bIgnoreLastAccess = ((pwOpt & PwCompareOptions.IgnoreLastAccess) !=
|
||||||
|
PwCompareOptions.None);
|
||||||
|
bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) !=
|
||||||
|
PwCompareOptions.None);
|
||||||
|
|
||||||
|
if(!m_uuid.Equals(pg.m_uuid)) return false;
|
||||||
|
if((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None)
|
||||||
|
{
|
||||||
|
if(m_pParentGroup != pg.m_pParentGroup) return false;
|
||||||
|
if(!bIgnoreLastMod && (m_tParentGroupLastMod != pg.m_tParentGroupLastMod))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_strName != pg.m_strName) return false;
|
||||||
|
if(m_strNotes != pg.m_strNotes) return false;
|
||||||
|
|
||||||
|
if(m_pwIcon != pg.m_pwIcon) return false;
|
||||||
|
if(!m_pwCustomIconID.Equals(pg.m_pwCustomIconID)) return false;
|
||||||
|
|
||||||
|
if(m_tCreation != pg.m_tCreation) return false;
|
||||||
|
if(!bIgnoreLastMod && (m_tLastMod != pg.m_tLastMod)) return false;
|
||||||
|
if(!bIgnoreLastAccess && (m_tLastAccess != pg.m_tLastAccess)) return false;
|
||||||
|
if(m_tExpire != pg.m_tExpire) return false;
|
||||||
|
if(m_bExpires != pg.m_bExpires) return false;
|
||||||
|
if(!bIgnoreLastAccess && (m_uUsageCount != pg.m_uUsageCount)) return false;
|
||||||
|
|
||||||
|
// if(m_bIsExpanded != pg.m_bIsExpanded) return false;
|
||||||
|
|
||||||
|
if(m_strDefaultAutoTypeSequence != pg.m_strDefaultAutoTypeSequence) return false;
|
||||||
|
|
||||||
|
if(m_bEnableAutoType.HasValue != pg.m_bEnableAutoType.HasValue) return false;
|
||||||
|
if(m_bEnableAutoType.HasValue)
|
||||||
|
{
|
||||||
|
if(m_bEnableAutoType.Value != pg.m_bEnableAutoType.Value) return false;
|
||||||
|
}
|
||||||
|
if(m_bEnableSearching.HasValue != pg.m_bEnableSearching.HasValue) return false;
|
||||||
|
if(m_bEnableSearching.HasValue)
|
||||||
|
{
|
||||||
|
if(m_bEnableSearching.Value != pg.m_bEnableSearching.Value) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!m_pwLastTopVisibleEntry.Equals(pg.m_pwLastTopVisibleEntry)) return false;
|
||||||
|
|
||||||
|
if((pwOpt & PwCompareOptions.PropertiesOnly) == PwCompareOptions.None)
|
||||||
|
{
|
||||||
|
if(m_listEntries.UCount != pg.m_listEntries.UCount) return false;
|
||||||
|
for(uint u = 0; u < m_listEntries.UCount; ++u)
|
||||||
|
{
|
||||||
|
PwEntry peA = m_listEntries.GetAt(u);
|
||||||
|
PwEntry peB = pg.m_listEntries.GetAt(u);
|
||||||
|
if(!peA.EqualsEntry(peB, pwOpt, mpCmpStr)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_listGroups.UCount != pg.m_listGroups.UCount) return false;
|
||||||
|
for(uint u = 0; u < m_listGroups.UCount; ++u)
|
||||||
|
{
|
||||||
|
PwGroup pgA = m_listGroups.GetAt(u);
|
||||||
|
PwGroup pgB = pg.m_listGroups.GetAt(u);
|
||||||
|
if(!pgA.EqualsGroup(pgB, pwOpt, mpCmpStr)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Assign properties to the current group based on a template group.
|
/// Assign properties to the current group based on a template group.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -398,10 +471,12 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
Debug.Assert(pgTemplate != null); if(pgTemplate == null) throw new ArgumentNullException("pgTemplate");
|
Debug.Assert(pgTemplate != null); if(pgTemplate == null) throw new ArgumentNullException("pgTemplate");
|
||||||
|
|
||||||
if(bOnlyIfNewer && (pgTemplate.m_tLastMod < m_tLastMod)) return;
|
if(bOnlyIfNewer && (TimeUtil.Compare(pgTemplate.m_tLastMod, m_tLastMod,
|
||||||
|
true) < 0))
|
||||||
|
return;
|
||||||
|
|
||||||
// Template UUID should be the same as the current one
|
// Template UUID should be the same as the current one
|
||||||
Debug.Assert(m_uuid.EqualsValue(pgTemplate.m_uuid));
|
Debug.Assert(m_uuid.Equals(pgTemplate.m_uuid));
|
||||||
m_uuid = pgTemplate.m_uuid;
|
m_uuid = pgTemplate.m_uuid;
|
||||||
|
|
||||||
if(bAssignLocationChanged)
|
if(bAssignLocationChanged)
|
||||||
@@ -422,6 +497,9 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
m_strDefaultAutoTypeSequence = pgTemplate.m_strDefaultAutoTypeSequence;
|
m_strDefaultAutoTypeSequence = pgTemplate.m_strDefaultAutoTypeSequence;
|
||||||
|
|
||||||
|
m_bEnableAutoType = pgTemplate.m_bEnableAutoType;
|
||||||
|
m_bEnableSearching = pgTemplate.m_bEnableSearching;
|
||||||
|
|
||||||
m_pwLastTopVisibleEntry = pgTemplate.m_pwLastTopVisibleEntry;
|
m_pwLastTopVisibleEntry = pgTemplate.m_pwLastTopVisibleEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,8 +651,6 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pack all groups into one flat linked list of references (recursively).
|
/// Pack all groups into one flat linked list of references (recursively).
|
||||||
/// Temporary IDs (<c>TemporaryID</c> field) and levels (<c>TemporaryLevel</c>)
|
|
||||||
/// are assigned automatically.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Flat list of all groups.</returns>
|
/// <returns>Flat list of all groups.</returns>
|
||||||
public LinkedList<PwGroup> GetFlatGroupList()
|
public LinkedList<PwGroup> GetFlatGroupList()
|
||||||
@@ -671,6 +747,7 @@ namespace ModernKeePassLib
|
|||||||
/// <param name="sp">Specifies the search method.</param>
|
/// <param name="sp">Specifies the search method.</param>
|
||||||
/// <param name="listStorage">Entry list in which the search results will
|
/// <param name="listStorage">Entry list in which the search results will
|
||||||
/// be stored.</param>
|
/// be stored.</param>
|
||||||
|
/// <param name="slStatus">Optional status reporting object.</param>
|
||||||
public void SearchEntries(SearchParameters sp, PwObjectList<PwEntry> listStorage,
|
public void SearchEntries(SearchParameters sp, PwObjectList<PwEntry> listStorage,
|
||||||
IStatusLogger slStatus)
|
IStatusLogger slStatus)
|
||||||
{
|
{
|
||||||
@@ -743,9 +820,6 @@ namespace ModernKeePassLib
|
|||||||
PwObjectList<PwEntry> listStorage, IStatusLogger slStatus,
|
PwObjectList<PwEntry> listStorage, IStatusLogger slStatus,
|
||||||
ref ulong uCurEntries, ulong uTotalEntries)
|
ref ulong uCurEntries, ulong uTotalEntries)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return false;
|
|
||||||
#if TODO
|
|
||||||
SearchParameters sp = spIn.Clone();
|
SearchParameters sp = spIn.Clone();
|
||||||
if(sp.SearchString == null) { Debug.Assert(false); return true; }
|
if(sp.SearchString == null) { Debug.Assert(false); return true; }
|
||||||
sp.SearchString = sp.SearchString.Trim();
|
sp.SearchString = sp.SearchString.Trim();
|
||||||
@@ -767,9 +841,15 @@ namespace ModernKeePassLib
|
|||||||
Regex rx = null;
|
Regex rx = null;
|
||||||
if(sp.RegularExpression)
|
if(sp.RegularExpression)
|
||||||
{
|
{
|
||||||
|
#if PCL || KeePassRT
|
||||||
|
RegexOptions ro = RegexOptions.None;
|
||||||
|
#else
|
||||||
RegexOptions ro = RegexOptions.Compiled;
|
RegexOptions ro = RegexOptions.Compiled;
|
||||||
|
#endif
|
||||||
if((sp.ComparisonMode == StringComparison.CurrentCultureIgnoreCase) ||
|
if((sp.ComparisonMode == StringComparison.CurrentCultureIgnoreCase) ||
|
||||||
|
#if !PCL && !KeePassRT
|
||||||
(sp.ComparisonMode == StringComparison.InvariantCultureIgnoreCase) ||
|
(sp.ComparisonMode == StringComparison.InvariantCultureIgnoreCase) ||
|
||||||
|
#endif
|
||||||
(sp.ComparisonMode == StringComparison.OrdinalIgnoreCase))
|
(sp.ComparisonMode == StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
ro |= RegexOptions.IgnoreCase;
|
ro |= RegexOptions.IgnoreCase;
|
||||||
@@ -880,7 +960,6 @@ namespace ModernKeePassLib
|
|||||||
if(!PreOrderTraverseTree(null, eh)) return false;
|
if(!PreOrderTraverseTree(null, eh)) return false;
|
||||||
uCurEntries = uLocalCurEntries;
|
uCurEntries = uLocalCurEntries;
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SearchEvalAdd(SearchParameters sp, string strDataField,
|
private static void SearchEvalAdd(SearchParameters sp, string strDataField,
|
||||||
@@ -942,6 +1021,30 @@ namespace ModernKeePassLib
|
|||||||
return vTags;
|
return vTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !KeePassLibSD
|
||||||
|
public IDictionary<string, uint> BuildEntryTagsDict(bool bSort)
|
||||||
|
{
|
||||||
|
IDictionary<string, uint> d;
|
||||||
|
if(!bSort) d = new Dictionary<string, uint>(StrUtil.CaseIgnoreComparer);
|
||||||
|
else d = new SortedDictionary<string, uint>(StrUtil.CaseIgnoreComparer);
|
||||||
|
|
||||||
|
EntryHandler eh = delegate(PwEntry pe)
|
||||||
|
{
|
||||||
|
foreach(string strTag in pe.Tags)
|
||||||
|
{
|
||||||
|
uint u;
|
||||||
|
if(d.TryGetValue(strTag, out u)) d[strTag] = u + 1;
|
||||||
|
else d[strTag] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
TraverseTree(TraversalMethod.PreOrder, null, eh);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public void FindEntriesByTag(string strTag, PwObjectList<PwEntry> listStorage,
|
public void FindEntriesByTag(string strTag, PwObjectList<PwEntry> listStorage,
|
||||||
bool bSearchRecursive)
|
bool bSearchRecursive)
|
||||||
{
|
{
|
||||||
@@ -976,7 +1079,7 @@ namespace ModernKeePassLib
|
|||||||
public PwGroup FindGroup(PwUuid uuid, bool bSearchRecursive)
|
public PwGroup FindGroup(PwUuid uuid, bool bSearchRecursive)
|
||||||
{
|
{
|
||||||
// Do not assert on PwUuid.Zero
|
// Do not assert on PwUuid.Zero
|
||||||
if(m_uuid.EqualsValue(uuid)) return this;
|
if(m_uuid.Equals(uuid)) return this;
|
||||||
|
|
||||||
if(bSearchRecursive)
|
if(bSearchRecursive)
|
||||||
{
|
{
|
||||||
@@ -991,7 +1094,7 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
foreach(PwGroup pg in m_listGroups)
|
foreach(PwGroup pg in m_listGroups)
|
||||||
{
|
{
|
||||||
if(pg.m_uuid.EqualsValue(uuid))
|
if(pg.m_uuid.Equals(uuid))
|
||||||
return pg;
|
return pg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1055,7 +1158,7 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
foreach(PwEntry pe in m_listEntries)
|
foreach(PwEntry pe in m_listEntries)
|
||||||
{
|
{
|
||||||
if(pe.Uuid.EqualsValue(uuid)) return pe;
|
if(pe.Uuid.Equals(uuid)) return pe;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bSearchRecursive)
|
if(bSearchRecursive)
|
||||||
@@ -1085,6 +1188,8 @@ namespace ModernKeePassLib
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="strSeparator">String that separates the group
|
/// <param name="strSeparator">String that separates the group
|
||||||
/// names.</param>
|
/// names.</param>
|
||||||
|
/// <param name="bIncludeTopMostGroup">Specifies whether the returned
|
||||||
|
/// path starts with the topmost group.</param>
|
||||||
/// <returns>Full path of the group.</returns>
|
/// <returns>Full path of the group.</returns>
|
||||||
public string GetFullPath(string strSeparator, bool bIncludeTopMostGroup)
|
public string GetFullPath(string strSeparator, bool bIncludeTopMostGroup)
|
||||||
{
|
{
|
||||||
@@ -1155,6 +1260,7 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !KeePassLibSD
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find/create a subtree of groups.
|
/// Find/create a subtree of groups.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1168,11 +1274,23 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
public PwGroup FindCreateSubTree(string strTree, char[] vSeparators,
|
public PwGroup FindCreateSubTree(string strTree, char[] vSeparators,
|
||||||
bool bAllowCreate)
|
bool bAllowCreate)
|
||||||
|
{
|
||||||
|
if(vSeparators == null) { Debug.Assert(false); vSeparators = new char[0]; }
|
||||||
|
|
||||||
|
string[] v = new string[vSeparators.Length];
|
||||||
|
for(int i = 0; i < vSeparators.Length; ++i)
|
||||||
|
v[i] = new string(vSeparators[i], 1);
|
||||||
|
|
||||||
|
return FindCreateSubTree(strTree, v, bAllowCreate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PwGroup FindCreateSubTree(string strTree, string[] vSeparators,
|
||||||
|
bool bAllowCreate)
|
||||||
{
|
{
|
||||||
Debug.Assert(strTree != null); if(strTree == null) return this;
|
Debug.Assert(strTree != null); if(strTree == null) return this;
|
||||||
if(strTree.Length == 0) return this;
|
if(strTree.Length == 0) return this;
|
||||||
|
|
||||||
string[] vGroups = strTree.Split(vSeparators);
|
string[] vGroups = strTree.Split(vSeparators, StringSplitOptions.None);
|
||||||
if((vGroups == null) || (vGroups.Length == 0)) return this;
|
if((vGroups == null) || (vGroups.Length == 0)) return this;
|
||||||
|
|
||||||
PwGroup pgContainer = this;
|
PwGroup pgContainer = this;
|
||||||
@@ -1203,6 +1321,7 @@ namespace ModernKeePassLib
|
|||||||
|
|
||||||
return pgContainer;
|
return pgContainer;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the level of the group (i.e. the number of parent groups).
|
/// Get the level of the group (i.e. the number of parent groups).
|
||||||
@@ -1426,6 +1545,69 @@ namespace ModernKeePassLib
|
|||||||
}
|
}
|
||||||
m_listGroups.Clear();
|
m_listGroups.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal List<PwGroup> GetTopSearchSkippedGroups()
|
||||||
|
{
|
||||||
|
List<PwGroup> l = new List<PwGroup>();
|
||||||
|
|
||||||
|
if(!GetSearchingEnabledInherited()) l.Add(this);
|
||||||
|
else GetTopSearchSkippedGroupsRec(l);
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetTopSearchSkippedGroupsRec(List<PwGroup> l)
|
||||||
|
{
|
||||||
|
if(m_bEnableSearching.HasValue && !m_bEnableSearching.Value)
|
||||||
|
{
|
||||||
|
l.Add(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else { Debug.Assert(GetSearchingEnabledInherited()); }
|
||||||
|
|
||||||
|
foreach(PwGroup pgSub in m_listGroups)
|
||||||
|
pgSub.GetTopSearchSkippedGroupsRec(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCreatedNow(bool bRecursive)
|
||||||
|
{
|
||||||
|
DateTime dt = DateTime.Now;
|
||||||
|
|
||||||
|
m_tCreation = dt;
|
||||||
|
m_tLastAccess = dt;
|
||||||
|
|
||||||
|
if(!bRecursive) return;
|
||||||
|
|
||||||
|
GroupHandler gh = delegate(PwGroup pg)
|
||||||
|
{
|
||||||
|
pg.m_tCreation = dt;
|
||||||
|
pg.m_tLastAccess = dt;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
EntryHandler eh = delegate(PwEntry pe)
|
||||||
|
{
|
||||||
|
pe.CreationTime = dt;
|
||||||
|
pe.LastAccessTime = dt;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
TraverseTree(TraversalMethod.PreOrder, gh, eh);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PwGroup Duplicate()
|
||||||
|
{
|
||||||
|
PwGroup pg = CloneDeep();
|
||||||
|
|
||||||
|
pg.Uuid = new PwUuid(true);
|
||||||
|
pg.CreateNewItemUuids(true, true, true);
|
||||||
|
|
||||||
|
pg.SetCreatedNow(true);
|
||||||
|
|
||||||
|
pg.TakeOwnership(true, true, true);
|
||||||
|
|
||||||
|
return pg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class PwGroupComparer : IComparer<PwGroup>
|
public sealed class PwGroupComparer : IComparer<PwGroup>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
@@ -27,10 +28,10 @@ namespace ModernKeePassLib
|
|||||||
{
|
{
|
||||||
// [ImmutableObject(true)]
|
// [ImmutableObject(true)]
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an UUID of a password entry or group. Once created, <c>PwUuid</c>
|
/// Represents an UUID of a password entry or group. Once created,
|
||||||
/// objects aren't modifyable anymore (immutable).
|
/// <c>PwUuid</c> objects aren't modifyable anymore (immutable).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class PwUuid
|
public sealed class PwUuid : IComparable<PwUuid>, IEquatable<PwUuid>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Standard size in bytes of a UUID.
|
/// Standard size in bytes of a UUID.
|
||||||
@@ -40,9 +41,9 @@ namespace ModernKeePassLib
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Zero UUID (all bytes are zero).
|
/// Zero UUID (all bytes are zero).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly PwUuid Zero = new PwUuid();
|
public static readonly PwUuid Zero = new PwUuid(false);
|
||||||
|
|
||||||
private byte[] m_pbUuid = new byte[UuidSize];
|
private byte[] m_pbUuid = null; // Never null after constructor
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the 16 UUID bytes.
|
/// Get the 16 UUID bytes.
|
||||||
@@ -52,14 +53,6 @@ namespace ModernKeePassLib
|
|||||||
get { return m_pbUuid; }
|
get { return m_pbUuid; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Construct a new UUID object. Its value is initialized to zero.
|
|
||||||
/// </summary>
|
|
||||||
private PwUuid()
|
|
||||||
{
|
|
||||||
SetZero();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Construct a new UUID object.
|
/// Construct a new UUID object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -88,38 +81,95 @@ namespace ModernKeePassLib
|
|||||||
/// otherwise it returns <c>false</c>.</returns>
|
/// otherwise it returns <c>false</c>.</returns>
|
||||||
private void CreateNew()
|
private void CreateNew()
|
||||||
{
|
{
|
||||||
|
Debug.Assert(m_pbUuid == null); // Only call from constructor
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
m_pbUuid = Guid.NewGuid().ToByteArray();
|
m_pbUuid = Guid.NewGuid().ToByteArray();
|
||||||
|
|
||||||
if((m_pbUuid == null) || (m_pbUuid.Length != UuidSize))
|
if((m_pbUuid == null) || (m_pbUuid.Length != (int)UuidSize))
|
||||||
|
{
|
||||||
|
Debug.Assert(false);
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
// Zero is a reserved value -- do not generate Zero
|
// Zero is a reserved value -- do not generate Zero
|
||||||
if(this.EqualsValue(PwUuid.Zero) == false)
|
if(!Equals(PwUuid.Zero)) break;
|
||||||
break;
|
Debug.Assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void SetValue(byte[] uuidBytes)
|
||||||
/// Compare this UUID with another.
|
{
|
||||||
/// </summary>
|
Debug.Assert((uuidBytes != null) && (uuidBytes.Length == (int)UuidSize));
|
||||||
/// <param name="uuid">Second UUID object.</param>
|
if(uuidBytes == null) throw new ArgumentNullException("uuidBytes");
|
||||||
/// <returns>Returns <c>true</c> if both PwUuid object contain the same
|
if(uuidBytes.Length != (int)UuidSize) throw new ArgumentException();
|
||||||
/// value, otherwise <c>false</c> is returned.</returns>
|
|
||||||
|
Debug.Assert(m_pbUuid == null); // Only call from constructor
|
||||||
|
m_pbUuid = new byte[UuidSize];
|
||||||
|
|
||||||
|
Array.Copy(uuidBytes, m_pbUuid, (int)UuidSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetZero()
|
||||||
|
{
|
||||||
|
Debug.Assert(m_pbUuid == null); // Only call from constructor
|
||||||
|
m_pbUuid = new byte[UuidSize];
|
||||||
|
|
||||||
|
// Array.Clear(m_pbUuid, 0, (int)UuidSize);
|
||||||
|
#if DEBUG
|
||||||
|
List<byte> l = new List<byte>(m_pbUuid);
|
||||||
|
Debug.Assert(l.TrueForAll(bt => (bt == 0)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
public bool EqualsValue(PwUuid uuid)
|
public bool EqualsValue(PwUuid uuid)
|
||||||
{
|
{
|
||||||
Debug.Assert(uuid != null);
|
return Equals(uuid);
|
||||||
if(uuid == null) throw new ArgumentNullException("uuid");
|
}
|
||||||
|
|
||||||
for(int i = 0; i < UuidSize; ++i)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
if(m_pbUuid[i] != uuid.m_pbUuid[i]) return false;
|
return Equals(obj as PwUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(PwUuid other)
|
||||||
|
{
|
||||||
|
if(other == null) { Debug.Assert(false); return false; }
|
||||||
|
|
||||||
|
for(int i = 0; i < (int)UuidSize; ++i)
|
||||||
|
{
|
||||||
|
if(m_pbUuid[i] != other.m_pbUuid[i]) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int m_h = 0;
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
if(m_h == 0)
|
||||||
|
m_h = (int)MemUtil.Hash32(m_pbUuid, 0, m_pbUuid.Length);
|
||||||
|
return m_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareTo(PwUuid other)
|
||||||
|
{
|
||||||
|
if(other == null)
|
||||||
|
{
|
||||||
|
Debug.Assert(false);
|
||||||
|
throw new ArgumentNullException("other");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < (int)UuidSize; ++i)
|
||||||
|
{
|
||||||
|
if(m_pbUuid[i] < other.m_pbUuid[i]) return -1;
|
||||||
|
if(m_pbUuid[i] > other.m_pbUuid[i]) return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert the UUID to its string representation.
|
/// Convert the UUID to its string representation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -129,29 +179,15 @@ namespace ModernKeePassLib
|
|||||||
return MemUtil.ByteArrayToHexString(m_pbUuid);
|
return MemUtil.ByteArrayToHexString(m_pbUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#if DEBUG
|
||||||
/// Set the UUID value. The input parameter will not be modified.
|
public override string ToString()
|
||||||
/// </summary>
|
|
||||||
/// <param name="uuidBytes">UUID bytes. The byte array must contain
|
|
||||||
/// exactly <c>UUIDSize</c> bytes, otherwise the function will fail.</param>
|
|
||||||
private void SetValue(byte[] uuidBytes)
|
|
||||||
{
|
{
|
||||||
Debug.Assert((uuidBytes != null) && (uuidBytes.Length == UuidSize));
|
return ToHexString();
|
||||||
if(uuidBytes == null) throw new ArgumentNullException("uuidBytes");
|
}
|
||||||
if(uuidBytes.Length != UuidSize) throw new ArgumentException();
|
#endif
|
||||||
|
|
||||||
Array.Copy(uuidBytes, m_pbUuid, (int)UuidSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the UUID value to zero.
|
|
||||||
/// </summary>
|
|
||||||
private void SetZero()
|
|
||||||
{
|
|
||||||
Array.Clear(m_pbUuid, 0, (int)UuidSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
public sealed class PwUuidComparable : IComparable<PwUuidComparable>
|
public sealed class PwUuidComparable : IComparable<PwUuidComparable>
|
||||||
{
|
{
|
||||||
private byte[] m_pbUuid = new byte[PwUuid.UuidSize];
|
private byte[] m_pbUuid = new byte[PwUuid.UuidSize];
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ namespace ModernKeePassLib.Resources
|
|||||||
m_strInvalidCompositeKeyHint = TryGetEx(dictNew, "InvalidCompositeKeyHint", m_strInvalidCompositeKeyHint);
|
m_strInvalidCompositeKeyHint = TryGetEx(dictNew, "InvalidCompositeKeyHint", m_strInvalidCompositeKeyHint);
|
||||||
m_strInvalidDataWhileDecoding = TryGetEx(dictNew, "InvalidDataWhileDecoding", m_strInvalidDataWhileDecoding);
|
m_strInvalidDataWhileDecoding = TryGetEx(dictNew, "InvalidDataWhileDecoding", m_strInvalidDataWhileDecoding);
|
||||||
m_strKeePass1xHint = TryGetEx(dictNew, "KeePass1xHint", m_strKeePass1xHint);
|
m_strKeePass1xHint = TryGetEx(dictNew, "KeePass1xHint", m_strKeePass1xHint);
|
||||||
|
m_strKeyFileDbSel = TryGetEx(dictNew, "KeyFileDbSel", m_strKeyFileDbSel);
|
||||||
m_strMasterSeedLengthInvalid = TryGetEx(dictNew, "MasterSeedLengthInvalid", m_strMasterSeedLengthInvalid);
|
m_strMasterSeedLengthInvalid = TryGetEx(dictNew, "MasterSeedLengthInvalid", m_strMasterSeedLengthInvalid);
|
||||||
m_strOldFormat = TryGetEx(dictNew, "OldFormat", m_strOldFormat);
|
m_strOldFormat = TryGetEx(dictNew, "OldFormat", m_strOldFormat);
|
||||||
m_strTryAgainSecs = TryGetEx(dictNew, "TryAgainSecs", m_strTryAgainSecs);
|
m_strTryAgainSecs = TryGetEx(dictNew, "TryAgainSecs", m_strTryAgainSecs);
|
||||||
@@ -78,6 +79,7 @@ namespace ModernKeePassLib.Resources
|
|||||||
"InvalidCompositeKeyHint",
|
"InvalidCompositeKeyHint",
|
||||||
"InvalidDataWhileDecoding",
|
"InvalidDataWhileDecoding",
|
||||||
"KeePass1xHint",
|
"KeePass1xHint",
|
||||||
|
"KeyFileDbSel",
|
||||||
"MasterSeedLengthInvalid",
|
"MasterSeedLengthInvalid",
|
||||||
"OldFormat",
|
"OldFormat",
|
||||||
"TryAgainSecs",
|
"TryAgainSecs",
|
||||||
@@ -201,10 +203,10 @@ namespace ModernKeePassLib.Resources
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static string m_strFileSaveCorruptionWarning =
|
private static string m_strFileSaveCorruptionWarning =
|
||||||
@"The target file might be in a corrupted state. Please try saving again, and if that fails, save the database to a different location.";
|
@"The target file might be corrupted. Please try saving again. If that fails, save the database to a different location.";
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Look up a localized string similar to
|
/// Look up a localized string similar to
|
||||||
/// 'The target file might be in a corrupted state. Please try saving again, and if that fails, save the database to a different location.'.
|
/// 'The target file might be corrupted. Please try saving again. If that fails, save the database to a different location.'.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string FileSaveCorruptionWarning
|
public static string FileSaveCorruptionWarning
|
||||||
{
|
{
|
||||||
@@ -332,6 +334,17 @@ namespace ModernKeePassLib.Resources
|
|||||||
get { return m_strKeePass1xHint; }
|
get { return m_strKeePass1xHint; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string m_strKeyFileDbSel =
|
||||||
|
@"Database files cannot be used as key files.";
|
||||||
|
/// <summary>
|
||||||
|
/// Look up a localized string similar to
|
||||||
|
/// 'Database files cannot be used as key files.'.
|
||||||
|
/// </summary>
|
||||||
|
public static string KeyFileDbSel
|
||||||
|
{
|
||||||
|
get { return m_strKeyFileDbSel; }
|
||||||
|
}
|
||||||
|
|
||||||
private static string m_strMasterSeedLengthInvalid =
|
private static string m_strMasterSeedLengthInvalid =
|
||||||
@"The length of the master key seed is invalid!";
|
@"The length of the master key seed is invalid!";
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,21 +18,30 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
using ModernKeePassLib.Utility;
|
|
||||||
using ModernKeePassLib.Cryptography;
|
using ModernKeePassLib.Cryptography;
|
||||||
using Windows.Security.Cryptography;
|
using ModernKeePassLib.Cryptography.Cipher;
|
||||||
using Windows.Security.Cryptography.DataProtection;
|
using ModernKeePassLib.Utility;
|
||||||
using Windows.Storage.Streams;
|
|
||||||
|
|
||||||
|
|
||||||
#if KeePassLibSD
|
#if KeePassLibSD
|
||||||
using ModernKeePassLibSD;
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ModernKeePassLib.Security
|
namespace ModernKeePassLib.Security
|
||||||
{
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum PbCryptFlags
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Encrypt = 1,
|
||||||
|
Decrypt = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void PbCryptDelegate(byte[] pbData, PbCryptFlags cf,
|
||||||
|
long lID);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a protected binary, i.e. a byte array that is encrypted
|
/// Represents a protected binary, i.e. a byte array that is encrypted
|
||||||
/// in memory. A <c>ProtectedBinary</c> object is immutable and
|
/// in memory. A <c>ProtectedBinary</c> object is immutable and
|
||||||
@@ -40,51 +49,117 @@ namespace ModernKeePassLib.Security
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class ProtectedBinary : IEquatable<ProtectedBinary>
|
public sealed class ProtectedBinary : IEquatable<ProtectedBinary>
|
||||||
{
|
{
|
||||||
private static bool m_bProtectionSupported;
|
private const int BlockSize = 16;
|
||||||
private IBuffer m_pbDataCrypted;
|
|
||||||
private DataProtectionProvider m_pProvider;
|
|
||||||
private bool m_bProtected;
|
|
||||||
|
|
||||||
|
private static PbCryptDelegate g_fExtCrypt = null;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A flag specifying whether the <c>ProtectedBinary</c> object has
|
/// A plugin can provide a custom memory protection method
|
||||||
/// turned on in-memory protection or not.
|
/// by assigning a non-null delegate to this property.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsProtected
|
public static PbCryptDelegate ExtCrypt
|
||||||
|
{
|
||||||
|
get { return g_fExtCrypt; }
|
||||||
|
set { g_fExtCrypt = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local copy of the delegate that was used for encryption,
|
||||||
|
// in order to allow correct decryption even when the global
|
||||||
|
// delegate changes
|
||||||
|
private PbCryptDelegate m_fExtCrypt = null;
|
||||||
|
|
||||||
|
private enum PbMemProt
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
ProtectedMemory,
|
||||||
|
Salsa20,
|
||||||
|
ExtCrypt
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtectedMemory is supported only on Windows 2000 SP3 and higher
|
||||||
|
#if !KeePassLibSD
|
||||||
|
private static bool? g_bProtectedMemorySupported = null;
|
||||||
|
#endif
|
||||||
|
private static bool ProtectedMemorySupported
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
#if KeePassLibSD
|
||||||
return false;
|
return false;
|
||||||
#if TODO
|
#elif PCL
|
||||||
return m_bProtected;
|
return false;
|
||||||
|
#else
|
||||||
|
bool? ob = g_bProtectedMemorySupported;
|
||||||
|
if(ob.HasValue) return ob.Value;
|
||||||
|
|
||||||
|
// Mono does not implement any encryption for ProtectedMemory;
|
||||||
|
// https://sourceforge.net/p/keepass/feature-requests/1907/
|
||||||
|
/*if(NativeLib.IsUnix())
|
||||||
|
{
|
||||||
|
g_bProtectedMemorySupported = false;
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
ob = false;
|
||||||
|
try // Test whether ProtectedMemory is supported
|
||||||
|
{
|
||||||
|
// BlockSize * 3 in order to test encryption for multiple
|
||||||
|
// blocks, but not introduce a power of 2 as factor
|
||||||
|
byte[] pb = new byte[ProtectedBinary.BlockSize * 3];
|
||||||
|
for(int i = 0; i < pb.Length; ++i) pb[i] = (byte)i;
|
||||||
|
|
||||||
|
ProtectedMemory.Protect(pb, MemoryProtectionScope.SameProcess);
|
||||||
|
|
||||||
|
for(int i = 0; i < pb.Length; ++i)
|
||||||
|
{
|
||||||
|
if(pb[i] != (byte)i) { ob = true; break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception) { } // Windows 98 / ME
|
||||||
|
|
||||||
|
g_bProtectedMemorySupported = ob;
|
||||||
|
return ob.Value;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long g_lCurID = 0;
|
||||||
|
private long m_lID;
|
||||||
|
|
||||||
|
private byte[] m_pbData; // Never null
|
||||||
|
|
||||||
|
// The real length of the data; this value can be different from
|
||||||
|
// m_pbData.Length, as the length of m_pbData always is a multiple
|
||||||
|
// of BlockSize (required for ProtectedMemory)
|
||||||
|
private uint m_uDataLen;
|
||||||
|
|
||||||
|
private bool m_bProtected; // Protection requested by the caller
|
||||||
|
|
||||||
|
private PbMemProt m_mp = PbMemProt.None; // Actual protection
|
||||||
|
|
||||||
|
private object m_objSync = new object();
|
||||||
|
|
||||||
|
private static byte[] g_pbKey32 = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A flag specifying whether the <c>ProtectedBinary</c> object has
|
||||||
|
/// turned on memory protection or not.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsProtected
|
||||||
|
{
|
||||||
|
get { return m_bProtected; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Length of the stored data.
|
/// Length of the stored data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Length
|
public uint Length
|
||||||
{
|
{
|
||||||
get
|
get { return m_uDataLen; }
|
||||||
{
|
|
||||||
|
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return 0;
|
|
||||||
#if TODO
|
|
||||||
return m_uDataLen;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ProtectedBinary()
|
|
||||||
{
|
|
||||||
m_bProtectionSupported = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Construct a new, empty protected binary data object. Protection
|
/// Construct a new, empty protected binary data object.
|
||||||
/// is disabled.
|
/// Protection is disabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ProtectedBinary()
|
public ProtectedBinary()
|
||||||
{
|
{
|
||||||
@@ -113,11 +188,10 @@ namespace ModernKeePassLib.Security
|
|||||||
/// <param name="bEnableProtection">Enable protection or not.</param>
|
/// <param name="bEnableProtection">Enable protection or not.</param>
|
||||||
/// <param name="xbProtected"><c>XorredBuffer</c> object used to
|
/// <param name="xbProtected"><c>XorredBuffer</c> object used to
|
||||||
/// initialize the <c>ProtectedBinary</c> object.</param>
|
/// initialize the <c>ProtectedBinary</c> object.</param>
|
||||||
/// <exception cref="System.ArgumentNullException">Thrown if the input
|
|
||||||
/// parameter is <c>null</c>.</exception>
|
|
||||||
public ProtectedBinary(bool bEnableProtection, XorredBuffer xbProtected)
|
public ProtectedBinary(bool bEnableProtection, XorredBuffer xbProtected)
|
||||||
{
|
{
|
||||||
Debug.Assert(xbProtected != null); if (xbProtected == null) throw new ArgumentNullException("xbProtected");
|
Debug.Assert(xbProtected != null);
|
||||||
|
if(xbProtected == null) throw new ArgumentNullException("xbProtected");
|
||||||
|
|
||||||
byte[] pb = xbProtected.ReadPlainText();
|
byte[] pb = xbProtected.ReadPlainText();
|
||||||
Init(bEnableProtection, pb);
|
Init(bEnableProtection, pb);
|
||||||
@@ -126,23 +200,92 @@ namespace ModernKeePassLib.Security
|
|||||||
|
|
||||||
private void Init(bool bEnableProtection, byte[] pbData)
|
private void Init(bool bEnableProtection, byte[] pbData)
|
||||||
{
|
{
|
||||||
String strDescriptor = "LOCAL=user";
|
if(pbData == null) throw new ArgumentNullException("pbData");
|
||||||
m_pProvider = new DataProtectionProvider(strDescriptor);
|
|
||||||
|
|
||||||
EncryptAsync(bEnableProtection, pbData);
|
#if KeePassLibSD
|
||||||
|
m_lID = ++g_lCurID;
|
||||||
|
#else
|
||||||
|
m_lID = Interlocked.Increment(ref g_lCurID);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_bProtected = bEnableProtection;
|
||||||
|
m_uDataLen = (uint)pbData.Length;
|
||||||
|
|
||||||
|
const int bs = ProtectedBinary.BlockSize;
|
||||||
|
int nBlocks = (int)m_uDataLen / bs;
|
||||||
|
if((nBlocks * bs) < (int)m_uDataLen) ++nBlocks;
|
||||||
|
Debug.Assert((nBlocks * bs) >= (int)m_uDataLen);
|
||||||
|
|
||||||
|
m_pbData = new byte[nBlocks * bs];
|
||||||
|
Array.Copy(pbData, m_pbData, (int)m_uDataLen);
|
||||||
|
|
||||||
|
Encrypt();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EncryptAsync(bool bEnableProtection, byte[] pbData)
|
private void Encrypt()
|
||||||
{
|
{
|
||||||
IBuffer dataUncrypted = CryptographicBuffer.CreateFromByteArray(pbData);
|
Debug.Assert(m_mp == PbMemProt.None);
|
||||||
|
|
||||||
Task<IBuffer> task = m_pProvider.ProtectAsync(dataUncrypted).AsTask<IBuffer>();
|
// Nothing to do if caller didn't request protection
|
||||||
task.Wait();
|
if(!m_bProtected) return;
|
||||||
|
|
||||||
m_pbDataCrypted = task.Result;
|
// ProtectedMemory.Protect throws for data size == 0
|
||||||
// TODO: Here the dataUncrypted buffer should be cleared. Now just count on GarbageCollection to destroy.
|
if(m_pbData.Length == 0) return;
|
||||||
|
|
||||||
|
PbCryptDelegate f = g_fExtCrypt;
|
||||||
|
if(f != null)
|
||||||
|
{
|
||||||
|
f(m_pbData, PbCryptFlags.Encrypt, m_lID);
|
||||||
|
|
||||||
|
m_fExtCrypt = f;
|
||||||
|
m_mp = PbMemProt.ExtCrypt;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !PCL
|
||||||
|
if(ProtectedBinary.ProtectedMemorySupported)
|
||||||
|
{
|
||||||
|
ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess);
|
||||||
|
|
||||||
|
m_mp = PbMemProt.ProtectedMemory;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
byte[] pbKey32 = g_pbKey32;
|
||||||
|
if(pbKey32 == null)
|
||||||
|
{
|
||||||
|
pbKey32 = CryptoRandom.Instance.GetRandomBytes(32);
|
||||||
|
|
||||||
|
byte[] pbUpd = Interlocked.Exchange<byte[]>(ref g_pbKey32, pbKey32);
|
||||||
|
if(pbUpd != null) pbKey32 = pbUpd;
|
||||||
|
}
|
||||||
|
|
||||||
|
Salsa20Cipher s = new Salsa20Cipher(pbKey32,
|
||||||
|
BitConverter.GetBytes(m_lID));
|
||||||
|
s.Encrypt(m_pbData, m_pbData.Length, true);
|
||||||
|
s.Dispose();
|
||||||
|
m_mp = PbMemProt.Salsa20;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Decrypt()
|
||||||
|
{
|
||||||
|
if(m_pbData.Length == 0) return;
|
||||||
|
#if !PCL
|
||||||
|
if(m_mp == PbMemProt.ProtectedMemory)
|
||||||
|
ProtectedMemory.Unprotect(m_pbData, MemoryProtectionScope.SameProcess);
|
||||||
|
#endif
|
||||||
|
else if(m_mp == PbMemProt.Salsa20)
|
||||||
|
{
|
||||||
|
Salsa20Cipher s = new Salsa20Cipher(g_pbKey32,
|
||||||
|
BitConverter.GetBytes(m_lID));
|
||||||
|
s.Encrypt(m_pbData, m_pbData.Length, true);
|
||||||
|
s.Dispose();
|
||||||
|
}
|
||||||
|
else if(m_mp == PbMemProt.ExtCrypt)
|
||||||
|
m_fExtCrypt(m_pbData, PbCryptFlags.Decrypt, m_lID);
|
||||||
|
else { Debug.Assert(m_mp == PbMemProt.None); }
|
||||||
|
|
||||||
|
m_mp = PbMemProt.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -155,18 +298,18 @@ namespace ModernKeePassLib.Security
|
|||||||
/// protected data and can therefore be cleared safely.</returns>
|
/// protected data and can therefore be cleared safely.</returns>
|
||||||
public byte[] ReadData()
|
public byte[] ReadData()
|
||||||
{
|
{
|
||||||
if (m_pbDataCrypted == null) return new byte[0];
|
if(m_uDataLen == 0) return new byte[0];
|
||||||
|
|
||||||
// Decrypt the protected message specified on input.
|
byte[] pbReturn = new byte[m_uDataLen];
|
||||||
|
|
||||||
Task<IBuffer> task = m_pProvider.UnprotectAsync(m_pbDataCrypted).AsTask<IBuffer>();
|
lock(m_objSync)
|
||||||
task.Wait();
|
{
|
||||||
|
Decrypt();
|
||||||
IBuffer buffUnprotected = task.Result;
|
Array.Copy(m_pbData, pbReturn, (int)m_uDataLen);
|
||||||
byte[] strClearText;
|
Encrypt();
|
||||||
CryptographicBuffer.CopyToByteArray(buffUnprotected, out strClearText);
|
}
|
||||||
return strClearText;
|
|
||||||
|
|
||||||
|
return pbReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -174,14 +317,8 @@ namespace ModernKeePassLib.Security
|
|||||||
/// of bytes generated by a random stream.
|
/// of bytes generated by a random stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="crsRandomSource">Random number source.</param>
|
/// <param name="crsRandomSource">Random number source.</param>
|
||||||
/// <returns>Protected data.</returns>
|
|
||||||
/// <exception cref="System.ArgumentNullException">Thrown if the input
|
|
||||||
/// parameter is <c>null</c>.</exception>
|
|
||||||
public byte[] ReadXorredData(CryptoRandomStream crsRandomSource)
|
public byte[] ReadXorredData(CryptoRandomStream crsRandomSource)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
Debug.Assert(crsRandomSource != null);
|
Debug.Assert(crsRandomSource != null);
|
||||||
if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource");
|
if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource");
|
||||||
|
|
||||||
@@ -189,20 +326,19 @@ namespace ModernKeePassLib.Security
|
|||||||
uint uLen = (uint)pbData.Length;
|
uint uLen = (uint)pbData.Length;
|
||||||
|
|
||||||
byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
|
byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
|
||||||
Debug.Assert(randomPad.Length == uLen);
|
Debug.Assert(randomPad.Length == pbData.Length);
|
||||||
|
|
||||||
for(uint i = 0; i < uLen; ++i)
|
for(uint i = 0; i < uLen; ++i)
|
||||||
pbData[i] ^= randomPad[i];
|
pbData[i] ^= randomPad[i];
|
||||||
|
|
||||||
return pbData;
|
return pbData;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int? m_hash = null;
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
if(m_hash.HasValue) return m_hash.Value;
|
||||||
return 0;
|
|
||||||
#if TODO
|
|
||||||
int h = (m_bProtected ? 0x7B11D289 : 0);
|
int h = (m_bProtected ? 0x7B11D289 : 0);
|
||||||
|
|
||||||
byte[] pb = ReadData();
|
byte[] pb = ReadData();
|
||||||
@@ -213,8 +349,8 @@ namespace ModernKeePassLib.Security
|
|||||||
}
|
}
|
||||||
MemUtil.ZeroByteArray(pb);
|
MemUtil.ZeroByteArray(pb);
|
||||||
|
|
||||||
|
m_hash = h;
|
||||||
return h;
|
return h;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
@@ -224,9 +360,6 @@ namespace ModernKeePassLib.Security
|
|||||||
|
|
||||||
public bool Equals(ProtectedBinary other)
|
public bool Equals(ProtectedBinary other)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return false;
|
|
||||||
#if TODO
|
|
||||||
if(other == null) return false; // No assert
|
if(other == null) return false; // No assert
|
||||||
|
|
||||||
if(m_bProtected != other.m_bProtected) return false;
|
if(m_bProtected != other.m_bProtected) return false;
|
||||||
@@ -243,7 +376,6 @@ namespace ModernKeePassLib.Security
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return bEq;
|
return bEq;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,10 +23,9 @@ using System.Diagnostics;
|
|||||||
|
|
||||||
using ModernKeePassLib.Cryptography;
|
using ModernKeePassLib.Cryptography;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
#if KeePassLibSD
|
#if KeePassLibSD
|
||||||
using ModernKeePassLibSD;
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SecureString objects are limited to 65536 characters, don't use
|
// SecureString objects are limited to 65536 characters, don't use
|
||||||
@@ -48,7 +47,7 @@ namespace ModernKeePassLib.Security
|
|||||||
|
|
||||||
private bool m_bIsProtected;
|
private bool m_bIsProtected;
|
||||||
|
|
||||||
private static ProtectedString m_psEmpty = new ProtectedString();
|
private static readonly ProtectedString m_psEmpty = new ProtectedString();
|
||||||
public static ProtectedString Empty
|
public static ProtectedString Empty
|
||||||
{
|
{
|
||||||
get { return m_psEmpty; }
|
get { return m_psEmpty; }
|
||||||
@@ -56,7 +55,7 @@ namespace ModernKeePassLib.Security
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A flag specifying whether the <c>ProtectedString</c> object
|
/// A flag specifying whether the <c>ProtectedString</c> object
|
||||||
/// has turned on in-memory protection or not.
|
/// has turned on memory protection or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsProtected
|
public bool IsProtected
|
||||||
{
|
{
|
||||||
@@ -80,10 +79,6 @@ namespace ModernKeePassLib.Security
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return 0;
|
|
||||||
#if TODO
|
|
||||||
if(m_nCachedLength >= 0) return m_nCachedLength;
|
if(m_nCachedLength >= 0) return m_nCachedLength;
|
||||||
|
|
||||||
ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
|
ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
|
||||||
@@ -100,7 +95,6 @@ namespace ModernKeePassLib.Security
|
|||||||
}
|
}
|
||||||
|
|
||||||
return m_nCachedLength;
|
return m_nCachedLength;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,10 +112,9 @@ namespace ModernKeePassLib.Security
|
|||||||
/// to the value supplied in the parameters.
|
/// to the value supplied in the parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bEnableProtection">If this parameter is <c>true</c>,
|
/// <param name="bEnableProtection">If this parameter is <c>true</c>,
|
||||||
/// the string will be protected in-memory (encrypted). If it
|
/// the string will be protected in memory (encrypted). If it
|
||||||
/// is <c>false</c>, the string will be stored as plain-text.</param>
|
/// is <c>false</c>, the string will be stored as plain-text.</param>
|
||||||
/// <param name="strValue">The initial string value. This
|
/// <param name="strValue">The initial string value.</param>
|
||||||
/// parameter won't be modified.</param>
|
|
||||||
public ProtectedString(bool bEnableProtection, string strValue)
|
public ProtectedString(bool bEnableProtection, string strValue)
|
||||||
{
|
{
|
||||||
Init(bEnableProtection, strValue);
|
Init(bEnableProtection, strValue);
|
||||||
@@ -132,7 +125,7 @@ namespace ModernKeePassLib.Security
|
|||||||
/// to the value supplied in the parameters (UTF-8 encoded string).
|
/// to the value supplied in the parameters (UTF-8 encoded string).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bEnableProtection">If this parameter is <c>true</c>,
|
/// <param name="bEnableProtection">If this parameter is <c>true</c>,
|
||||||
/// the string will be protected in-memory (encrypted). If it
|
/// the string will be protected in memory (encrypted). If it
|
||||||
/// is <c>false</c>, the string will be stored as plain-text.</param>
|
/// is <c>false</c>, the string will be stored as plain-text.</param>
|
||||||
/// <param name="vUtf8Value">The initial string value, encoded as
|
/// <param name="vUtf8Value">The initial string value, encoded as
|
||||||
/// UTF-8 byte array. This parameter won't be modified; the caller
|
/// UTF-8 byte array. This parameter won't be modified; the caller
|
||||||
@@ -150,10 +143,9 @@ namespace ModernKeePassLib.Security
|
|||||||
/// <param name="xbProtected"><c>XorredBuffer</c> object containing the
|
/// <param name="xbProtected"><c>XorredBuffer</c> object containing the
|
||||||
/// string in UTF-8 representation. The UTF-8 string must not
|
/// string in UTF-8 representation. The UTF-8 string must not
|
||||||
/// be <c>null</c>-terminated.</param>
|
/// be <c>null</c>-terminated.</param>
|
||||||
/// <exception cref="System.ArgumentNullException">Thrown if the input
|
|
||||||
/// parameter is <c>null</c>.</exception>
|
|
||||||
public ProtectedString(bool bEnableProtection, XorredBuffer xbProtected)
|
public ProtectedString(bool bEnableProtection, XorredBuffer xbProtected)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(xbProtected != null);
|
||||||
if(xbProtected == null) throw new ArgumentNullException("xbProtected");
|
if(xbProtected == null) throw new ArgumentNullException("xbProtected");
|
||||||
|
|
||||||
byte[] pb = xbProtected.ReadPlainText();
|
byte[] pb = xbProtected.ReadPlainText();
|
||||||
@@ -196,7 +188,6 @@ namespace ModernKeePassLib.Security
|
|||||||
if(m_strPlainText != null) return m_strPlainText;
|
if(m_strPlainText != null) return m_strPlainText;
|
||||||
|
|
||||||
byte[] pb = ReadUtf8();
|
byte[] pb = ReadUtf8();
|
||||||
|
|
||||||
string str = ((pb.Length == 0) ? string.Empty :
|
string str = ((pb.Length == 0) ? string.Empty :
|
||||||
StrUtil.Utf8.GetString(pb, 0, pb.Length));
|
StrUtil.Utf8.GetString(pb, 0, pb.Length));
|
||||||
// No need to clear pb
|
// No need to clear pb
|
||||||
@@ -218,11 +209,7 @@ namespace ModernKeePassLib.Security
|
|||||||
public byte[] ReadUtf8()
|
public byte[] ReadUtf8()
|
||||||
{
|
{
|
||||||
ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
|
ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
|
||||||
|
if(pBin != null) return pBin.ReadData();
|
||||||
if (pBin != null)
|
|
||||||
{
|
|
||||||
return pBin.ReadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
return StrUtil.Utf8.GetBytes(m_strPlainText);
|
return StrUtil.Utf8.GetBytes(m_strPlainText);
|
||||||
}
|
}
|
||||||
@@ -233,8 +220,6 @@ namespace ModernKeePassLib.Security
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="crsRandomSource">Random number source.</param>
|
/// <param name="crsRandomSource">Random number source.</param>
|
||||||
/// <returns>Protected string.</returns>
|
/// <returns>Protected string.</returns>
|
||||||
/// <exception cref="System.ArgumentNullException">Thrown if the input
|
|
||||||
/// parameter is <c>null</c>.</exception>
|
|
||||||
public byte[] ReadXorredString(CryptoRandomStream crsRandomSource)
|
public byte[] ReadXorredString(CryptoRandomStream crsRandomSource)
|
||||||
{
|
{
|
||||||
Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource");
|
Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource");
|
||||||
@@ -243,7 +228,7 @@ namespace ModernKeePassLib.Security
|
|||||||
uint uLen = (uint)pbData.Length;
|
uint uLen = (uint)pbData.Length;
|
||||||
|
|
||||||
byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
|
byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
|
||||||
Debug.Assert(randomPad.Length == uLen);
|
Debug.Assert(randomPad.Length == pbData.Length);
|
||||||
|
|
||||||
for(uint i = 0; i < uLen; ++i)
|
for(uint i = 0; i < uLen; ++i)
|
||||||
pbData[i] ^= randomPad[i];
|
pbData[i] ^= randomPad[i];
|
||||||
@@ -260,5 +245,100 @@ namespace ModernKeePassLib.Security
|
|||||||
MemUtil.ZeroByteArray(pb);
|
MemUtil.ZeroByteArray(pb);
|
||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProtectedString Insert(int iStart, string strInsert)
|
||||||
|
{
|
||||||
|
if(iStart < 0) throw new ArgumentOutOfRangeException("iStart");
|
||||||
|
if(strInsert == null) throw new ArgumentNullException("strInsert");
|
||||||
|
if(strInsert.Length == 0) return this;
|
||||||
|
|
||||||
|
// Only operate directly with strings when m_bIsProtected is
|
||||||
|
// false, not in the case of non-null m_strPlainText, because
|
||||||
|
// the operation creates a new sequence in memory
|
||||||
|
if(!m_bIsProtected)
|
||||||
|
return new ProtectedString(false, ReadString().Insert(
|
||||||
|
iStart, strInsert));
|
||||||
|
|
||||||
|
UTF8Encoding utf8 = StrUtil.Utf8;
|
||||||
|
|
||||||
|
byte[] pb = ReadUtf8();
|
||||||
|
char[] v = utf8.GetChars(pb);
|
||||||
|
char[] vNew;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(iStart > v.Length)
|
||||||
|
throw new ArgumentOutOfRangeException("iStart");
|
||||||
|
|
||||||
|
char[] vIns = strInsert.ToCharArray();
|
||||||
|
|
||||||
|
vNew = new char[v.Length + vIns.Length];
|
||||||
|
Array.Copy(v, 0, vNew, 0, iStart);
|
||||||
|
Array.Copy(vIns, 0, vNew, iStart, vIns.Length);
|
||||||
|
Array.Copy(v, iStart, vNew, iStart + vIns.Length,
|
||||||
|
v.Length - iStart);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Array.Clear(v, 0, v.Length);
|
||||||
|
MemUtil.ZeroByteArray(pb);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] pbNew = utf8.GetBytes(vNew);
|
||||||
|
ProtectedString ps = new ProtectedString(m_bIsProtected, pbNew);
|
||||||
|
|
||||||
|
Debug.Assert(utf8.GetString(pbNew, 0, pbNew.Length) ==
|
||||||
|
ReadString().Insert(iStart, strInsert));
|
||||||
|
|
||||||
|
Array.Clear(vNew, 0, vNew.Length);
|
||||||
|
MemUtil.ZeroByteArray(pbNew);
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtectedString Remove(int iStart, int nCount)
|
||||||
|
{
|
||||||
|
if(iStart < 0) throw new ArgumentOutOfRangeException("iStart");
|
||||||
|
if(nCount < 0) throw new ArgumentOutOfRangeException("nCount");
|
||||||
|
if(nCount == 0) return this;
|
||||||
|
|
||||||
|
// Only operate directly with strings when m_bIsProtected is
|
||||||
|
// false, not in the case of non-null m_strPlainText, because
|
||||||
|
// the operation creates a new sequence in memory
|
||||||
|
if(!m_bIsProtected)
|
||||||
|
return new ProtectedString(false, ReadString().Remove(
|
||||||
|
iStart, nCount));
|
||||||
|
|
||||||
|
UTF8Encoding utf8 = StrUtil.Utf8;
|
||||||
|
|
||||||
|
byte[] pb = ReadUtf8();
|
||||||
|
char[] v = utf8.GetChars(pb);
|
||||||
|
char[] vNew;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if((iStart + nCount) > v.Length)
|
||||||
|
throw new ArgumentException("iStart + nCount");
|
||||||
|
|
||||||
|
vNew = new char[v.Length - nCount];
|
||||||
|
Array.Copy(v, 0, vNew, 0, iStart);
|
||||||
|
Array.Copy(v, iStart + nCount, vNew, iStart, v.Length -
|
||||||
|
(iStart + nCount));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Array.Clear(v, 0, v.Length);
|
||||||
|
MemUtil.ZeroByteArray(pb);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] pbNew = utf8.GetBytes(vNew);
|
||||||
|
ProtectedString ps = new ProtectedString(m_bIsProtected, pbNew);
|
||||||
|
|
||||||
|
Debug.Assert(utf8.GetString(pbNew, 0, pbNew.Length) ==
|
||||||
|
ReadString().Remove(iStart, nCount));
|
||||||
|
|
||||||
|
Array.Clear(vNew, 0, vNew.Length);
|
||||||
|
MemUtil.ZeroByteArray(pbNew);
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,42 +22,74 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Serialization
|
namespace ModernKeePassLib.Serialization
|
||||||
{
|
{
|
||||||
public sealed class BinaryReaderEx : BinaryReader
|
public sealed class BinaryReaderEx
|
||||||
{
|
{
|
||||||
private string m_strReadExcp = null;
|
private Stream m_s;
|
||||||
|
// private Encoding m_enc; // See constructor
|
||||||
|
|
||||||
|
private string m_strReadExcp;
|
||||||
public string ReadExceptionText
|
public string ReadExceptionText
|
||||||
{
|
{
|
||||||
get { return m_strReadExcp; }
|
get { return m_strReadExcp; }
|
||||||
set { m_strReadExcp = value; }
|
set { m_strReadExcp = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryReaderEx(Stream input, Encoding encoding,
|
private Stream m_sCopyTo = null;
|
||||||
string strReadExceptionText) :
|
/// <summary>
|
||||||
base(input, encoding)
|
/// If this property is set to a non-null stream, all data that
|
||||||
|
/// is read from the input stream is automatically written to
|
||||||
|
/// the copy stream (before returning the read data).
|
||||||
|
/// </summary>
|
||||||
|
public Stream CopyDataTo
|
||||||
{
|
{
|
||||||
|
get { return m_sCopyTo; }
|
||||||
|
set { m_sCopyTo = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BinaryReaderEx(Stream input, Encoding encoding,
|
||||||
|
string strReadExceptionText)
|
||||||
|
{
|
||||||
|
if(input == null)
|
||||||
|
throw new ArgumentNullException("input");
|
||||||
|
|
||||||
|
m_s = input;
|
||||||
|
// m_enc = encoding; // Not used yet
|
||||||
m_strReadExcp = strReadExceptionText;
|
m_strReadExcp = strReadExceptionText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadBytes(int count)
|
public byte[] ReadBytes(int nCount)
|
||||||
{
|
{
|
||||||
/*try
|
try
|
||||||
{*/
|
|
||||||
byte[] pb = base.ReadBytes(count);
|
|
||||||
if((pb == null) || (pb.Length != count))
|
|
||||||
{
|
{
|
||||||
if(m_strReadExcp != null) throw new IOException(m_strReadExcp);
|
byte[] pb = MemUtil.Read(m_s, nCount);
|
||||||
else throw new EndOfStreamException();
|
if((pb == null) || (pb.Length != nCount))
|
||||||
|
{
|
||||||
|
if(m_strReadExcp != null)
|
||||||
|
throw new IOException(m_strReadExcp);
|
||||||
|
else
|
||||||
|
throw new EndOfStreamException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_sCopyTo != null)
|
||||||
|
m_sCopyTo.Write(pb, 0, pb.Length);
|
||||||
return pb;
|
return pb;
|
||||||
/*}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception)
|
||||||
{
|
{
|
||||||
if(m_strReadExcp != null) throw new IOException(m_strReadExcp);
|
if(m_strReadExcp != null)
|
||||||
|
throw new IOException(m_strReadExcp);
|
||||||
else throw;
|
else throw;
|
||||||
}*/
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte ReadByte()
|
||||||
|
{
|
||||||
|
byte[] pb = ReadBytes(1);
|
||||||
|
return pb[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Windows.Security.Cryptography;
|
|
||||||
using Windows.Security.Cryptography.Core;
|
|
||||||
using Windows.Storage.Streams;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.Serialization
|
|
||||||
{
|
|
||||||
// An adaptor function to provide a stream interface from an IBuffer.
|
|
||||||
|
|
||||||
class CryptoStream : Stream
|
|
||||||
{
|
|
||||||
|
|
||||||
private int m_blockSize = 16 ;
|
|
||||||
private byte[] m_decoded;
|
|
||||||
private IEnumerator<byte> m_enumerator = null;
|
|
||||||
|
|
||||||
public CryptoStream(Stream s, String strAlgName, bool bEncrypt, byte[] pbKey, byte[] pbIV)
|
|
||||||
{
|
|
||||||
IBuffer iv = CryptographicBuffer.CreateFromByteArray(pbIV);
|
|
||||||
SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(strAlgName);
|
|
||||||
CryptographicKey key = objAlg.CreateSymmetricKey( CryptographicBuffer.CreateFromByteArray(pbKey) );
|
|
||||||
if (bEncrypt)
|
|
||||||
{
|
|
||||||
Debug.Assert(false, "Not implemented yet");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// For the time being, WinRT CryptographicEngine doesn't support stream decoding. Bummer.
|
|
||||||
// Copy the file to a memory buffer, then decode all at once.
|
|
||||||
|
|
||||||
|
|
||||||
byte[] block = new byte[s.Length]; // We are not at the beginning of the stream
|
|
||||||
// There is always less than s.Lenght bytes remaining to be read.
|
|
||||||
int readItemCount = s.Read(block, 0, (int) s.Length);
|
|
||||||
Array.Resize(ref block, readItemCount);
|
|
||||||
|
|
||||||
IBuffer input = CryptographicBuffer.CreateFromByteArray(block);
|
|
||||||
IBuffer decoded = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
decoded = CryptographicEngine.Decrypt(key, input, iv);
|
|
||||||
} catch (System.Exception)
|
|
||||||
{
|
|
||||||
throw new Keys.InvalidCompositeKeyException();
|
|
||||||
}
|
|
||||||
CryptographicBuffer.CopyToByteArray(decoded, out m_decoded);
|
|
||||||
m_enumerator = m_decoded.AsEnumerable().GetEnumerator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override bool CanRead { get { return true; } }
|
|
||||||
public override bool CanSeek { get { return false; } }
|
|
||||||
public override bool CanTimeout { get { return false; } }
|
|
||||||
public override bool CanWrite { get { return false; } }
|
|
||||||
public override long Length
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
throw new System.NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Position {
|
|
||||||
get
|
|
||||||
{
|
|
||||||
throw new System.NotSupportedException();
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
throw new System.NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void Flush()
|
|
||||||
{
|
|
||||||
Debug.Assert(false, "Not yet implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override int Read(byte[] buffer, int offset, int count)
|
|
||||||
{
|
|
||||||
// Exceptions:
|
|
||||||
// System.ArgumentException:
|
|
||||||
// The sum of offset and count is larger than the buffer length.
|
|
||||||
//
|
|
||||||
// System.ArgumentNullException:
|
|
||||||
// buffer is null.
|
|
||||||
//
|
|
||||||
// System.ArgumentOutOfRangeException:
|
|
||||||
// offset or count is negative.
|
|
||||||
//
|
|
||||||
// System.IO.IOException:
|
|
||||||
// An I/O error occurs.
|
|
||||||
//
|
|
||||||
// System.NotSupportedException:
|
|
||||||
// The stream does not support reading.
|
|
||||||
//
|
|
||||||
// System.ObjectDisposedException:
|
|
||||||
// Methods were called after the stream was closed.
|
|
||||||
|
|
||||||
if ((count <0) || (offset <0))
|
|
||||||
throw new System.ArgumentOutOfRangeException();
|
|
||||||
if (buffer == null)
|
|
||||||
throw new System.ArgumentNullException();
|
|
||||||
if (m_enumerator == null)
|
|
||||||
throw new System.ArgumentNullException();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
if (!m_enumerator.MoveNext())
|
|
||||||
return i;
|
|
||||||
buffer[i + offset] = m_enumerator.Current;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Seek(long offset, SeekOrigin origin)
|
|
||||||
{
|
|
||||||
throw new System.NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetLength(long value)
|
|
||||||
{
|
|
||||||
throw new System.NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Write(byte[] buffer, int offset, int count)
|
|
||||||
{
|
|
||||||
throw new System.NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,7 +21,11 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
#if PCL
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
#else
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
#endif
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
using ModernKeePassLib.Cryptography;
|
using ModernKeePassLib.Cryptography;
|
||||||
@@ -41,28 +45,24 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
public FileLockException(string strBaseFile, string strUser)
|
public FileLockException(string strBaseFile, string strUser)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "Not yet implemented");
|
|
||||||
return;
|
|
||||||
#if TODO
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(strBaseFile))
|
if(!string.IsNullOrEmpty(strBaseFile))
|
||||||
{
|
{
|
||||||
sb.Append(strBaseFile);
|
sb.Append(strBaseFile);
|
||||||
sb.Append(MessageService.NewParagraph);
|
sb.Append(Environment.NewLine + Environment.NewLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.Append(KLRes.FileLockedWrite);
|
sb.Append(KLRes.FileLockedWrite);
|
||||||
sb.Append(MessageService.NewLine);
|
sb.Append(Environment.NewLine);
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(strUser)) sb.Append(strUser);
|
if(!string.IsNullOrEmpty(strUser)) sb.Append(strUser);
|
||||||
else sb.Append("?");
|
else sb.Append("?");
|
||||||
|
|
||||||
sb.Append(MessageService.NewParagraph);
|
sb.Append(Environment.NewLine + Environment.NewLine);
|
||||||
sb.Append(KLRes.TryAgainSecs);
|
sb.Append(KLRes.TryAgainSecs);
|
||||||
|
|
||||||
m_strMsg = sb.ToString();
|
m_strMsg = sb.ToString();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,9 +124,6 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
public static LockFileInfo Load(IOConnectionInfo iocLockFile)
|
public static LockFileInfo Load(IOConnectionInfo iocLockFile)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
Stream s = null;
|
Stream s = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -134,7 +131,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
if(s == null) return null;
|
if(s == null) return null;
|
||||||
StreamReader sr = new StreamReader(s, StrUtil.Utf8);
|
StreamReader sr = new StreamReader(s, StrUtil.Utf8);
|
||||||
string str = sr.ReadToEnd();
|
string str = sr.ReadToEnd();
|
||||||
sr.Close();
|
sr.Dispose();
|
||||||
if(str == null) { Debug.Assert(false); return null; }
|
if(str == null) { Debug.Assert(false); return null; }
|
||||||
|
|
||||||
str = StrUtil.NormalizeNewLines(str, false);
|
str = StrUtil.NormalizeNewLines(str, false);
|
||||||
@@ -146,18 +143,14 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
catch(FileNotFoundException) { }
|
catch(FileNotFoundException) { }
|
||||||
catch(Exception) { Debug.Assert(false); }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
finally { if(s != null) s.Close(); }
|
finally { if(s != null) s.Dispose(); }
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Throws on error
|
// Throws on error
|
||||||
public static LockFileInfo Create(IOConnectionInfo iocLockFile)
|
public static LockFileInfo Create(IOConnectionInfo iocLockFile)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
LockFileInfo lfi;
|
LockFileInfo lfi;
|
||||||
Stream s = null;
|
Stream s = null;
|
||||||
try
|
try
|
||||||
@@ -165,7 +158,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
byte[] pbID = CryptoRandom.Instance.GetRandomBytes(16);
|
byte[] pbID = CryptoRandom.Instance.GetRandomBytes(16);
|
||||||
string strTime = TimeUtil.SerializeUtc(DateTime.Now);
|
string strTime = TimeUtil.SerializeUtc(DateTime.Now);
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
lfi = new LockFileInfo(Convert.ToBase64String(pbID), strTime,
|
lfi = new LockFileInfo(Convert.ToBase64String(pbID), strTime,
|
||||||
Environment.UserName, Environment.MachineName,
|
Environment.UserName, Environment.MachineName,
|
||||||
Environment.UserDomainName);
|
Environment.UserDomainName);
|
||||||
@@ -175,7 +168,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
#if !KeePassLibSD && TODO
|
#if !KeePassLibSD
|
||||||
sb.AppendLine(LockFileHeader);
|
sb.AppendLine(LockFileHeader);
|
||||||
sb.AppendLine(lfi.ID);
|
sb.AppendLine(lfi.ID);
|
||||||
sb.AppendLine(strTime);
|
sb.AppendLine(strTime);
|
||||||
@@ -197,18 +190,14 @@ namespace ModernKeePassLib.Serialization
|
|||||||
if(s == null) throw new IOException(iocLockFile.GetDisplayName());
|
if(s == null) throw new IOException(iocLockFile.GetDisplayName());
|
||||||
s.Write(pbFile, 0, pbFile.Length);
|
s.Write(pbFile, 0, pbFile.Length);
|
||||||
}
|
}
|
||||||
finally { if(s != null) s.Close(); }
|
finally { if(s != null) s.Dispose(); }
|
||||||
|
|
||||||
return lfi;
|
return lfi;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileLock(IOConnectionInfo iocBaseFile)
|
public FileLock(IOConnectionInfo iocBaseFile)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return ;
|
|
||||||
#if TODO
|
|
||||||
if(iocBaseFile == null) throw new ArgumentNullException("strBaseFile");
|
if(iocBaseFile == null) throw new ArgumentNullException("strBaseFile");
|
||||||
|
|
||||||
m_iocLockFile = iocBaseFile.CloneDeep();
|
m_iocLockFile = iocBaseFile.CloneDeep();
|
||||||
@@ -223,7 +212,6 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
|
|
||||||
LockFileInfo.Create(m_iocLockFile);
|
LockFileInfo.Create(m_iocLockFile);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~FileLock()
|
~FileLock()
|
||||||
@@ -239,9 +227,6 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
private void Dispose(bool bDisposing)
|
private void Dispose(bool bDisposing)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return ;
|
|
||||||
#if TODO
|
|
||||||
if(m_iocLockFile == null) return;
|
if(m_iocLockFile == null) return;
|
||||||
|
|
||||||
bool bFileDeleted = false;
|
bool bFileDeleted = false;
|
||||||
@@ -258,14 +243,18 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
if(bFileDeleted) break;
|
if(bFileDeleted) break;
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
if(bDisposing)
|
||||||
|
Task.Delay(50).Wait();
|
||||||
|
#else
|
||||||
if(bDisposing) Thread.Sleep(50);
|
if(bDisposing) Thread.Sleep(50);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bDisposing && !bFileDeleted)
|
if(bDisposing && !bFileDeleted)
|
||||||
IOConnection.DeleteFile(m_iocLockFile); // Possibly with exception
|
IOConnection.DeleteFile(m_iocLockFile); // Possibly with exception
|
||||||
|
|
||||||
m_iocLockFile = null;
|
m_iocLockFile = null;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// private bool OwnLockFile()
|
// private bool OwnLockFile()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,13 +22,8 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
// Bert TODO: For now, remove the accesscontrol from this class.
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
// In WinRT, the security of file has changed, and something could potentially be done
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364399%28v=vs.85%29.aspx
|
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -63,6 +58,16 @@ namespace ModernKeePassLib.Serialization
|
|||||||
m_bTransacted = bTransacted;
|
m_bTransacted = bTransacted;
|
||||||
m_iocBase = iocBaseFile.CloneDeep();
|
m_iocBase = iocBaseFile.CloneDeep();
|
||||||
|
|
||||||
|
// ModernKeePassLib is currently targeting .NET 4.5
|
||||||
|
#if !PCL
|
||||||
|
// Prevent transactions for FTP URLs under .NET 4.0 in order to
|
||||||
|
// avoid/workaround .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
|
||||||
|
if(m_iocBase.Path.StartsWith("ftp:", StrUtil.CaseIgnoreCmp) &&
|
||||||
|
(Environment.Version.Major >= 4) && !NativeLib.IsUnix())
|
||||||
|
m_bTransacted = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(m_bTransacted)
|
if(m_bTransacted)
|
||||||
{
|
{
|
||||||
m_iocTemp = m_iocBase.CloneDeep();
|
m_iocTemp = m_iocBase.CloneDeep();
|
||||||
@@ -71,7 +76,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
else m_iocTemp = m_iocBase;
|
else m_iocTemp = m_iocBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Stream> OpenWrite()
|
public Stream OpenWrite()
|
||||||
{
|
{
|
||||||
if(!m_bTransacted) m_bMadeUnhidden = UrlUtil.UnhideFile(m_iocTemp.Path);
|
if(!m_bTransacted) m_bMadeUnhidden = UrlUtil.UnhideFile(m_iocTemp.Path);
|
||||||
else // m_bTransacted
|
else // m_bTransacted
|
||||||
@@ -80,7 +85,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
catch(Exception) { }
|
catch(Exception) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
return await IOConnection.OpenWrite(m_iocTemp);
|
return IOConnection.OpenWrite(m_iocTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CommitWrite()
|
public void CommitWrite()
|
||||||
@@ -96,14 +101,14 @@ namespace ModernKeePassLib.Serialization
|
|||||||
{
|
{
|
||||||
bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);
|
bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
FileSecurity bkSecurity = null;
|
FileSecurity bkSecurity = null;
|
||||||
bool bEfsEncrypted = false;
|
bool bEfsEncrypted = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(IOConnection.FileExists(m_iocBase))
|
if(IOConnection.FileExists(m_iocBase))
|
||||||
{
|
{
|
||||||
#if !KeePassLibSD && TODO
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
if(m_iocBase.IsLocalFile())
|
if(m_iocBase.IsLocalFile())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -125,7 +130,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
IOConnection.RenameFile(m_iocTemp, m_iocBase);
|
IOConnection.RenameFile(m_iocTemp, m_iocBase);
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
if(m_iocBase.IsLocalFile())
|
if(m_iocBase.IsLocalFile())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,14 +19,19 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
#if PCL
|
||||||
|
using System.Linq;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
using ModernKeePassLib.Native;
|
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
using ModernKeePassLib.Cryptography;
|
|
||||||
|
|
||||||
#if KeePassLibSD
|
#if KeePassLibSD
|
||||||
using ModernKeePassLibSD;
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ModernKeePassLib.Serialization
|
namespace ModernKeePassLib.Serialization
|
||||||
@@ -93,12 +98,13 @@ namespace ModernKeePassLib.Serialization
|
|||||||
private void Initialize(Stream sBaseStream, bool bWriting, int nBufferSize,
|
private void Initialize(Stream sBaseStream, bool bWriting, int nBufferSize,
|
||||||
bool bVerify)
|
bool bVerify)
|
||||||
{
|
{
|
||||||
if(sBaseStream == null) throw new ArgumentNullException("sBaseStream");
|
if (sBaseStream == null) throw new ArgumentNullException(nameof(sBaseStream));
|
||||||
if(nBufferSize < 0) throw new ArgumentOutOfRangeException("nBufferSize");
|
|
||||||
|
|
||||||
if(nBufferSize == 0) nBufferSize = m_nDefaultBufferSize;
|
|
||||||
|
|
||||||
m_sBaseStream = sBaseStream;
|
m_sBaseStream = sBaseStream;
|
||||||
|
if (nBufferSize < 0)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(nBufferSize));
|
||||||
|
|
||||||
|
if(nBufferSize == 0)
|
||||||
|
nBufferSize = m_nDefaultBufferSize;
|
||||||
m_bWriting = bWriting;
|
m_bWriting = bWriting;
|
||||||
m_bVerify = bVerify;
|
m_bVerify = bVerify;
|
||||||
|
|
||||||
@@ -128,14 +134,20 @@ namespace ModernKeePassLib.Serialization
|
|||||||
if(m_bWriting) m_bwOutput.Flush();
|
if(m_bWriting) m_bwOutput.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TODO
|
#if PCL || KeePassRT
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if(!disposing) return;
|
||||||
|
#else
|
||||||
public override void Close()
|
public override void Close()
|
||||||
{
|
{
|
||||||
|
#endif
|
||||||
if(m_sBaseStream != null)
|
if(m_sBaseStream != null)
|
||||||
{
|
{
|
||||||
if(m_bWriting == false) // Reading mode
|
if(m_bWriting == false) // Reading mode
|
||||||
{
|
{
|
||||||
m_brInput.Close();
|
try { m_brInput.Dispose(); } catch { }
|
||||||
|
|
||||||
m_brInput = null;
|
m_brInput = null;
|
||||||
}
|
}
|
||||||
else // Writing mode
|
else // Writing mode
|
||||||
@@ -149,15 +161,14 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
|
|
||||||
Flush();
|
Flush();
|
||||||
m_bwOutput.Close();
|
m_bwOutput.Dispose();
|
||||||
m_bwOutput = null;
|
m_bwOutput = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sBaseStream.Close();
|
try { m_sBaseStream.Dispose(); } catch { }
|
||||||
m_sBaseStream = null;
|
m_sBaseStream = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
public override long Seek(long lOffset, SeekOrigin soOrigin)
|
public override long Seek(long lOffset, SeekOrigin soOrigin)
|
||||||
{
|
{
|
||||||
@@ -210,11 +221,11 @@ namespace ModernKeePassLib.Serialization
|
|||||||
throw new InvalidDataException();
|
throw new InvalidDataException();
|
||||||
|
|
||||||
int nBufferSize = 0;
|
int nBufferSize = 0;
|
||||||
try { nBufferSize = m_brInput.ReadInt32(); }
|
/*try {*/ nBufferSize = m_brInput.ReadInt32(); /*}
|
||||||
catch(NullReferenceException) // Mono bug workaround (LaunchPad 783268)
|
catch(NullReferenceException) // Mono bug workaround (LaunchPad 783268)
|
||||||
{
|
{
|
||||||
if(!NativeLib.IsUnix()) throw;
|
if(!NativeLib.IsUnix()) throw;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if(nBufferSize < 0)
|
if(nBufferSize < 0)
|
||||||
throw new InvalidDataException();
|
throw new InvalidDataException();
|
||||||
@@ -238,7 +249,13 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
if(m_bVerify)
|
if(m_bVerify)
|
||||||
{
|
{
|
||||||
byte[] pbComputedHash = SHA256Managed.Instance.ComputeHash(m_pbBuffer);
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
var pbComputedHash = sha256.HashData(m_pbBuffer.AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
|
byte[] pbComputedHash = sha256.ComputeHash(m_pbBuffer);
|
||||||
|
#endif
|
||||||
if((pbComputedHash == null) || (pbComputedHash.Length != 32))
|
if((pbComputedHash == null) || (pbComputedHash.Length != 32))
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
@@ -249,7 +266,6 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,14 +291,16 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
private void WriteHashedBlock()
|
private void WriteHashedBlock()
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return ;
|
|
||||||
#if TODO
|
|
||||||
m_bwOutput.Write(m_uBufferIndex);
|
m_bwOutput.Write(m_uBufferIndex);
|
||||||
++m_uBufferIndex;
|
++m_uBufferIndex;
|
||||||
|
|
||||||
if(m_nBufferPos > 0)
|
if(m_nBufferPos > 0)
|
||||||
{
|
{
|
||||||
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
var pbHash = sha256.HashData(m_pbBuffer.Where((x, i) => i < m_nBufferPos).ToArray().AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
|
||||||
SHA256Managed sha256 = new SHA256Managed();
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
@@ -297,6 +315,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
Array.Copy(m_pbBuffer, 0, pbData, 0, m_nBufferPos);
|
Array.Copy(m_pbBuffer, 0, pbData, 0, m_nBufferPos);
|
||||||
pbHash = sha256.ComputeHash(pbData);
|
pbHash = sha256.ComputeHash(pbData);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_bwOutput.Write(pbHash);
|
m_bwOutput.Write(pbHash);
|
||||||
@@ -315,7 +335,6 @@ namespace ModernKeePassLib.Serialization
|
|||||||
m_bwOutput.Write(m_pbBuffer, 0, m_nBufferPos);
|
m_bwOutput.Write(m_pbBuffer, 0, m_nBufferPos);
|
||||||
|
|
||||||
m_nBufferPos = 0;
|
m_nBufferPos = 0;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
@@ -18,27 +19,32 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
using Windows.Storage.Streams;
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
using Windows.Storage;
|
|
||||||
// BERT TODO: For the time being, the web functionality is not available for WinRT
|
|
||||||
|
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
|
||||||
using System.Net.Cache;
|
using System.Net.Cache;
|
||||||
using System.Net.Security;
|
using System.Net.Security;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !PCL && !KeePassRT
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
using Windows.Storage;
|
||||||
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Serialization
|
namespace ModernKeePassLib.Serialization
|
||||||
{
|
{
|
||||||
#if !KeePassLibSD && false
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
public sealed class IOWebClient : HttpClient
|
internal sealed class IOWebClient : WebClient
|
||||||
{
|
{
|
||||||
protected override WebRequest GetWebRequest(Uri address)
|
protected override WebRequest GetWebRequest(Uri address)
|
||||||
{
|
{
|
||||||
@@ -49,14 +55,192 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public class IOConnection
|
#if !PCL
|
||||||
|
internal abstract class WrapperStream : Stream
|
||||||
{
|
{
|
||||||
#if !KeePassLibSD && TODO
|
private readonly Stream m_s;
|
||||||
|
protected Stream BaseStream
|
||||||
|
{
|
||||||
|
get { return m_s; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanRead
|
||||||
|
{
|
||||||
|
get { return m_s.CanRead; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanSeek
|
||||||
|
{
|
||||||
|
get { return m_s.CanSeek; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanTimeout
|
||||||
|
{
|
||||||
|
get { return m_s.CanTimeout; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWrite
|
||||||
|
{
|
||||||
|
get { return m_s.CanWrite; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Length
|
||||||
|
{
|
||||||
|
get { return m_s.Length; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Position
|
||||||
|
{
|
||||||
|
get { return m_s.Position; }
|
||||||
|
set { m_s.Position = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int ReadTimeout
|
||||||
|
{
|
||||||
|
get { return m_s.ReadTimeout; }
|
||||||
|
set { m_s.ReadTimeout = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int WriteTimeout
|
||||||
|
{
|
||||||
|
get { return m_s.WriteTimeout; }
|
||||||
|
set { m_s.WriteTimeout = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrapperStream(Stream sBase) : base()
|
||||||
|
{
|
||||||
|
if(sBase == null) throw new ArgumentNullException("sBase");
|
||||||
|
|
||||||
|
m_s = sBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IAsyncResult BeginRead(byte[] buffer, int offset,
|
||||||
|
int count, AsyncCallback callback, object state)
|
||||||
|
{
|
||||||
|
return m_s.BeginRead(buffer, offset, count, callback, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IAsyncResult BeginWrite(byte[] buffer, int offset,
|
||||||
|
int count, AsyncCallback callback, object state)
|
||||||
|
{
|
||||||
|
return BeginWrite(buffer, offset, count, callback, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Close()
|
||||||
|
{
|
||||||
|
m_s.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int EndRead(IAsyncResult asyncResult)
|
||||||
|
{
|
||||||
|
return m_s.EndRead(asyncResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EndWrite(IAsyncResult asyncResult)
|
||||||
|
{
|
||||||
|
m_s.EndWrite(asyncResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
m_s.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
return m_s.Read(buffer, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int ReadByte()
|
||||||
|
{
|
||||||
|
return m_s.ReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
return m_s.Seek(offset, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
m_s.SetLength(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
m_s.Write(buffer, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteByte(byte value)
|
||||||
|
{
|
||||||
|
m_s.WriteByte(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class IocStream : WrapperStream
|
||||||
|
{
|
||||||
|
private readonly bool m_bWrite; // Initially opened for writing
|
||||||
|
|
||||||
|
public IocStream(Stream sBase) : base(sBase)
|
||||||
|
{
|
||||||
|
m_bWrite = sBase.CanWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Close()
|
||||||
|
{
|
||||||
|
base.Close();
|
||||||
|
|
||||||
|
if(MonoWorkarounds.IsRequired(10163) && m_bWrite)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Stream s = this.BaseStream;
|
||||||
|
Type t = s.GetType();
|
||||||
|
if(t.Name == "WebConnectionStream")
|
||||||
|
{
|
||||||
|
PropertyInfo pi = t.GetProperty("Request",
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
if(pi != null)
|
||||||
|
{
|
||||||
|
WebRequest wr = (pi.GetValue(s, null) as WebRequest);
|
||||||
|
if(wr != null)
|
||||||
|
IOConnection.DisposeResponse(wr.GetResponse(), false);
|
||||||
|
else { Debug.Assert(false); }
|
||||||
|
}
|
||||||
|
else { Debug.Assert(false); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream WrapIfRequired(Stream s)
|
||||||
|
{
|
||||||
|
if(s == null) { Debug.Assert(false); return null; }
|
||||||
|
|
||||||
|
if(MonoWorkarounds.IsRequired(10163) && s.CanWrite)
|
||||||
|
return new IocStream(s);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public static class IOConnection
|
||||||
|
{
|
||||||
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
private static ProxyServerType m_pstProxyType = ProxyServerType.System;
|
private static ProxyServerType m_pstProxyType = ProxyServerType.System;
|
||||||
private static string m_strProxyAddr = string.Empty;
|
private static string m_strProxyAddr = string.Empty;
|
||||||
private static string m_strProxyPort = string.Empty;
|
private static string m_strProxyPort = string.Empty;
|
||||||
private static string m_strProxyUserName = string.Empty;
|
private static string m_strProxyUserName = string.Empty;
|
||||||
private static string m_strProxyPassword = string.Empty;
|
private static string m_strProxyPassword = string.Empty;
|
||||||
|
|
||||||
|
private static bool m_bSslCertsAcceptInvalid = false;
|
||||||
|
internal static bool SslCertsAcceptInvalid
|
||||||
|
{
|
||||||
|
// get { return m_bSslCertsAcceptInvalid; }
|
||||||
|
set { m_bSslCertsAcceptInvalid = value; }
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Web request methods
|
// Web request methods
|
||||||
@@ -66,16 +250,18 @@ namespace ModernKeePassLib.Serialization
|
|||||||
// Web request headers
|
// Web request headers
|
||||||
public const string WrhMoveFileTo = "MoveFileTo";
|
public const string WrhMoveFileTo = "MoveFileTo";
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
public static event EventHandler<IOAccessEventArgs> IOAccessPre;
|
||||||
|
|
||||||
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
// Allow self-signed certificates, expired certificates, etc.
|
// Allow self-signed certificates, expired certificates, etc.
|
||||||
private static bool ValidateServerCertificate(object sender,
|
private static bool AcceptCertificate(object sender,
|
||||||
X509Certificate certificate, X509Chain chain,
|
X509Certificate certificate, X509Chain chain,
|
||||||
SslPolicyErrors sslPolicyErrors)
|
SslPolicyErrors sslPolicyErrors)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetProxy(ProxyServerType pst, string strAddr,
|
internal static void SetProxy(ProxyServerType pst, string strAddr,
|
||||||
string strPort, string strUserName, string strPassword)
|
string strPort, string strUserName, string strPassword)
|
||||||
{
|
{
|
||||||
m_pstProxyType = pst;
|
m_pstProxyType = pst;
|
||||||
@@ -185,12 +371,27 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
private static void PrepareWebAccess()
|
private static void PrepareWebAccess()
|
||||||
{
|
{
|
||||||
|
if(m_bSslCertsAcceptInvalid)
|
||||||
ServicePointManager.ServerCertificateValidationCallback =
|
ServicePointManager.ServerCertificateValidationCallback =
|
||||||
ValidateServerCertificate;
|
IOConnection.AcceptCertificate;
|
||||||
|
else
|
||||||
|
ServicePointManager.ServerCertificateValidationCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IOWebClient CreateWebClient(IOConnectionInfo ioc)
|
||||||
|
{
|
||||||
|
PrepareWebAccess();
|
||||||
|
|
||||||
|
IOWebClient wc = new IOWebClient();
|
||||||
|
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
|
||||||
|
wc.Credentials = new NetworkCredential("anonymous", string.Empty);
|
||||||
|
|
||||||
|
return wc;
|
||||||
|
}
|
||||||
|
|
||||||
private static WebRequest CreateWebRequest(IOConnectionInfo ioc)
|
private static WebRequest CreateWebRequest(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
@@ -206,122 +407,124 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
private async Task<Stream> OpenReadHttp(IOConnectionInfo ioc)
|
public static Stream OpenRead(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
|
RaiseIOAccessPreEvent(ioc, IOAccessType.Read);
|
||||||
|
|
||||||
// TODO: Configure the httpClient
|
|
||||||
// PrepareWebAccess();
|
|
||||||
// ConfigureWebClient(wc);
|
|
||||||
|
|
||||||
HttpClient hc = new HttpClient();
|
|
||||||
HttpResponseMessage response = await hc.GetAsync(ioc.Path);
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
|
|
||||||
// Read content into buffer
|
|
||||||
// Not the most efficient thing to do,
|
|
||||||
// but simplifies our life by allowing to use stream.length later on.
|
|
||||||
await response.Content.LoadIntoBufferAsync();
|
|
||||||
return await response.Content.ReadAsStreamAsync();
|
|
||||||
#if false
|
|
||||||
if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
|
|
||||||
wc.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
|
|
||||||
else if(NativeLib.IsUnix()) // Mono requires credentials
|
|
||||||
wc.Credentials = new NetworkCredential("anonymous", string.Empty);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<Stream> OpenRead(IOConnectionInfo ioc)
|
|
||||||
{
|
|
||||||
if(StrUtil.IsDataUri(ioc.Path))
|
if(StrUtil.IsDataUri(ioc.Path))
|
||||||
{
|
{
|
||||||
byte[] pbData = StrUtil.DataUriToData(ioc.Path);
|
byte[] pbData = StrUtil.DataUriToData(ioc.Path);
|
||||||
if(pbData != null) return new MemoryStream(pbData, false);
|
if(pbData != null) return new MemoryStream(pbData, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ioc.IsLocalFile()) return await OpenReadLocal(ioc);
|
if(ioc.IsLocalFile()) return OpenReadLocal(ioc);
|
||||||
|
|
||||||
|
return IocStream.WrapIfRequired(CreateWebClient(ioc).OpenRead(
|
||||||
return await OpenReadHttp(ioc);
|
new Uri(ioc.Path)));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
public static Stream OpenRead(IOConnectionInfo ioc)
|
||||||
private async Task<Stream> OpenReadLocal(IOConnectionInfo ioc)
|
|
||||||
{
|
{
|
||||||
try
|
RaiseIOAccessPreEvent(ioc, IOAccessType.Read);
|
||||||
{
|
|
||||||
IRandomAccessStream stream = await ioc.StorageFile.OpenAsync(FileAccessMode.Read);
|
return OpenReadLocal(ioc);
|
||||||
return stream.AsStream();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
#endif
|
||||||
|
|
||||||
|
private static Stream OpenReadLocal(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, ex.Message);
|
#if PCL
|
||||||
return null;
|
/*var file = FileSystem.Current.GetFileFromPathAsync(ioc.Path).Result;
|
||||||
}
|
return file.OpenAsync(PCLStorage.FileAccess.Read).Result;*/
|
||||||
|
return ioc.StorageFile.OpenAsync(FileAccessMode.Read).GetResults().AsStream();
|
||||||
|
#else
|
||||||
|
return new FileStream(ioc.Path, FileMode.Open, FileAccess.Read,
|
||||||
|
FileShare.Read);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
public static Stream OpenWrite(IOConnectionInfo ioc)
|
public static Stream OpenWrite(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
if(ioc == null) { Debug.Assert(false); return null; }
|
if(ioc == null) { Debug.Assert(false); return null; }
|
||||||
|
|
||||||
|
RaiseIOAccessPreEvent(ioc, IOAccessType.Write);
|
||||||
|
|
||||||
if(ioc.IsLocalFile()) return OpenWriteLocal(ioc);
|
if(ioc.IsLocalFile()) return OpenWriteLocal(ioc);
|
||||||
|
|
||||||
Uri uri = new Uri(ioc.Path);
|
Uri uri = new Uri(ioc.Path);
|
||||||
|
Stream s;
|
||||||
|
|
||||||
// Mono does not set HttpWebRequest.Method to POST for writes,
|
// Mono does not set HttpWebRequest.Method to POST for writes,
|
||||||
// so one needs to set the method to PUT explicitly
|
// so one needs to set the method to PUT explicitly
|
||||||
if(NativeLib.IsUnix() && (uri.Scheme.Equals(Uri.UriSchemeHttp,
|
if(NativeLib.IsUnix() && (uri.Scheme.Equals(Uri.UriSchemeHttp,
|
||||||
StrUtil.CaseIgnoreCmp) || uri.Scheme.Equals(Uri.UriSchemeHttps,
|
StrUtil.CaseIgnoreCmp) || uri.Scheme.Equals(Uri.UriSchemeHttps,
|
||||||
StrUtil.CaseIgnoreCmp)))
|
StrUtil.CaseIgnoreCmp)))
|
||||||
return CreateWebClient(ioc).OpenWrite(uri, WebRequestMethods.Http.Put);
|
s = CreateWebClient(ioc).OpenWrite(uri, WebRequestMethods.Http.Put);
|
||||||
|
else s = CreateWebClient(ioc).OpenWrite(uri);
|
||||||
|
|
||||||
return CreateWebClient(ioc).OpenWrite(uri);
|
return IocStream.WrapIfRequired(s);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
public static async Task<Stream> OpenWrite(IOConnectionInfo ioc)
|
public static Stream OpenWrite(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
return await OpenWriteLocal(ioc);
|
RaiseIOAccessPreEvent(ioc, IOAccessType.Write);
|
||||||
|
|
||||||
|
return OpenWriteLocal(ioc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private static async Task<Stream> OpenWriteLocal(IOConnectionInfo ioc)
|
private static Stream OpenWriteLocal(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
try
|
#if PCL
|
||||||
{
|
return ioc.StorageFile.OpenAsync(FileAccessMode.ReadWrite).GetResults().AsStream();
|
||||||
IRandomAccessStream stream = await ioc.StorageFile.OpenAsync(FileAccessMode.ReadWrite);
|
/*var file = FileSystem.Current.GetFileFromPathAsync(ioc.Path).Result;
|
||||||
return stream.AsStream();
|
return file.OpenAsync(FileAccess.ReadAndWrite).Result;*/
|
||||||
}
|
#else
|
||||||
catch (Exception ex)
|
return new FileStream(ioc.Path, FileMode.Create, FileAccess.Write,
|
||||||
{
|
FileShare.None);
|
||||||
Debug.Assert(false, ex.Message);
|
#endif
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool FileExists(IOConnectionInfo ioc)
|
public static bool FileExists(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
//return FileExists(ioc, false);
|
return FileExists(ioc, false);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public static bool FileExists(IOConnectionInfo ioc, bool bThrowErrors)
|
public static bool FileExists(IOConnectionInfo ioc, bool bThrowErrors)
|
||||||
{
|
{
|
||||||
if(ioc == null) { Debug.Assert(false); return false; }
|
if(ioc == null) { Debug.Assert(false); return false; }
|
||||||
|
|
||||||
if(ioc.IsLocalFile()) return ioc.StorageFile.IsAvailable;
|
RaiseIOAccessPreEvent(ioc, IOAccessType.Exists);
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
if(ioc.IsLocalFile())
|
||||||
|
return ioc.StorageFile.IsAvailable;
|
||||||
|
#else
|
||||||
|
if(ioc.IsLocalFile()) return File.Exists(ioc.Path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
|
if(ioc.Path.StartsWith("ftp://", StrUtil.CaseIgnoreCmp))
|
||||||
|
{
|
||||||
|
bool b = SendCommand(ioc, WebRequestMethods.Ftp.GetDateTimestamp);
|
||||||
|
if(!b && bThrowErrors) throw new InvalidOperationException();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Stream s = OpenRead(ioc);
|
Stream s = OpenRead(ioc);
|
||||||
if(s == null) throw new FileNotFoundException();
|
if(s == null) throw new FileNotFoundException();
|
||||||
|
|
||||||
// For FTP clients we called RETR to get the file, but we never
|
try { s.ReadByte(); }
|
||||||
// followed-up and downloaded the file; close may produce a
|
catch(Exception) { }
|
||||||
// 550 error -- that's okay
|
|
||||||
try { s.Close(); }
|
// We didn't download the file completely; close may throw
|
||||||
|
// an exception -- that's okay
|
||||||
|
try { s.Dispose(); }
|
||||||
catch(Exception) { }
|
catch(Exception) { }
|
||||||
}
|
}
|
||||||
catch(Exception)
|
catch(Exception)
|
||||||
@@ -331,19 +534,29 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}*/
|
|
||||||
|
|
||||||
public static async void DeleteFile(IOConnectionInfo ioc)
|
|
||||||
{
|
|
||||||
if(ioc.IsLocalFile()) { await ioc.StorageFile.DeleteAsync(StorageDeleteOption.Default);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
public static void DeleteFile(IOConnectionInfo ioc)
|
||||||
|
{
|
||||||
|
RaiseIOAccessPreEvent(ioc, IOAccessType.Delete);
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
if(ioc.IsLocalFile()) {
|
||||||
|
/*var file = FileSystem.Current.GetFileFromPathAsync(ioc.Path).Result;
|
||||||
|
file.DeleteAsync().RunSynchronously();*/
|
||||||
|
ioc.StorageFile.DeleteAsync(StorageDeleteOption.Default).GetResults();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if(ioc.IsLocalFile()) { File.Delete(ioc.Path); return; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
WebRequest req = CreateWebRequest(ioc);
|
WebRequest req = CreateWebRequest(ioc);
|
||||||
if(req != null)
|
if(req != null)
|
||||||
{
|
{
|
||||||
if(req is HttpWebRequest) req.Method = "DELETE";
|
if(req is HttpWebRequest) req.Method = "DELETE";
|
||||||
else if(req is FtpWebRequest) req.Method = WebRequestMethods.Ftp.DeleteFile;
|
else if(req is FtpWebRequest)
|
||||||
|
req.Method = WebRequestMethods.Ftp.DeleteFile;
|
||||||
else if(req is FileWebRequest)
|
else if(req is FileWebRequest)
|
||||||
{
|
{
|
||||||
File.Delete(UrlUtil.FileUrlToPath(ioc.Path));
|
File.Delete(UrlUtil.FileUrlToPath(ioc.Path));
|
||||||
@@ -365,11 +578,22 @@ namespace ModernKeePassLib.Serialization
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="iocFrom">Source file path.</param>
|
/// <param name="iocFrom">Source file path.</param>
|
||||||
/// <param name="iocTo">Target file path.</param>
|
/// <param name="iocTo">Target file path.</param>
|
||||||
public static async void RenameFile(IOConnectionInfo iocFrom, IOConnectionInfo iocTo)
|
public static void RenameFile(IOConnectionInfo iocFrom, IOConnectionInfo iocTo)
|
||||||
{
|
{
|
||||||
if(iocFrom.IsLocalFile()) { await iocTo.StorageFile.RenameAsync(iocTo.Path, NameCollisionOption.GenerateUniqueName); }
|
RaiseIOAccessPreEvent(iocFrom, iocTo, IOAccessType.Move);
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if PCL
|
||||||
|
if(iocFrom.IsLocalFile()) {
|
||||||
|
/*var file = FileSystem.Current.GetFileFromPathAsync(iocFrom.Path).Result;
|
||||||
|
file.MoveAsync(iocTo.Path).RunSynchronously();*/
|
||||||
|
iocFrom.StorageFile.RenameAsync(iocTo.Path).GetResults();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if(iocFrom.IsLocalFile()) { File.Move(iocFrom.Path, iocTo.Path); return; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
WebRequest req = CreateWebRequest(iocFrom);
|
WebRequest req = CreateWebRequest(iocFrom);
|
||||||
if(req != null)
|
if(req != null)
|
||||||
{
|
{
|
||||||
@@ -381,7 +605,13 @@ namespace ModernKeePassLib.Serialization
|
|||||||
else if(req is FtpWebRequest)
|
else if(req is FtpWebRequest)
|
||||||
{
|
{
|
||||||
req.Method = WebRequestMethods.Ftp.Rename;
|
req.Method = WebRequestMethods.Ftp.Rename;
|
||||||
((FtpWebRequest)req).RenameTo = UrlUtil.GetFileName(iocTo.Path);
|
string strTo = UrlUtil.GetFileName(iocTo.Path);
|
||||||
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
else if(req is FileWebRequest)
|
else if(req is FileWebRequest)
|
||||||
{
|
{
|
||||||
@@ -412,11 +642,23 @@ namespace ModernKeePassLib.Serialization
|
|||||||
// DeleteFile(iocFrom);
|
// DeleteFile(iocFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DisposeResponse(WebResponse wr, bool bGetStream)
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
|
private static bool SendCommand(IOConnectionInfo ioc, string strMethod)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WebRequest req = CreateWebRequest(ioc);
|
||||||
|
req.Method = strMethod;
|
||||||
|
DisposeResponse(req.GetResponse(), true);
|
||||||
|
}
|
||||||
|
catch(Exception) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
internal static void DisposeResponse(WebResponse wr, bool bGetStream)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "Not implemented yet");
|
|
||||||
return;
|
|
||||||
#if TODO
|
|
||||||
if(wr == null) return;
|
if(wr == null) return;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -424,12 +666,12 @@ namespace ModernKeePassLib.Serialization
|
|||||||
if(bGetStream)
|
if(bGetStream)
|
||||||
{
|
{
|
||||||
Stream s = wr.GetResponseStream();
|
Stream s = wr.GetResponseStream();
|
||||||
if(s != null) s.Close();
|
if(s != null) s.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception) { Debug.Assert(false); }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
try { wr.Close(); }
|
try { wr.Dispose(); }
|
||||||
catch(Exception) { Debug.Assert(false); }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,12 +692,30 @@ namespace ModernKeePassLib.Serialization
|
|||||||
catch(Exception) { }
|
catch(Exception) { }
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if(sIn != null) sIn.Close();
|
if(sIn != null) sIn.Dispose();
|
||||||
if(ms != null) ms.Close();
|
if(ms != null) ms.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
private static void RaiseIOAccessPreEvent(IOConnectionInfo ioc, IOAccessType t)
|
||||||
|
{
|
||||||
|
RaiseIOAccessPreEvent(ioc, null, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RaiseIOAccessPreEvent(IOConnectionInfo ioc,
|
||||||
|
IOConnectionInfo ioc2, IOAccessType t)
|
||||||
|
{
|
||||||
|
if(ioc == null) { Debug.Assert(false); return; }
|
||||||
|
// ioc2 may be null
|
||||||
|
|
||||||
|
if(IOConnection.IOAccessPre != null)
|
||||||
|
{
|
||||||
|
IOConnectionInfo ioc2Lcl = ((ioc2 != null) ? ioc2.CloneDeep() : null);
|
||||||
|
IOAccessEventArgs e = new IOAccessEventArgs(ioc.CloneDeep(), ioc2Lcl, t);
|
||||||
|
IOConnection.IOAccessPre(null, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,11 +23,15 @@ using System.Text;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Xml.Serialization;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
using Windows.Storage;
|
||||||
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
using Windows.Storage;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.Serialization
|
namespace ModernKeePassLib.Serialization
|
||||||
{
|
{
|
||||||
@@ -122,6 +126,14 @@ namespace ModernKeePassLib.Serialization
|
|||||||
set { m_ioCredSaveMode = value; }
|
set { m_ioCredSaveMode = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool m_bComplete = false;
|
||||||
|
[XmlIgnore]
|
||||||
|
public bool IsComplete // Credentials etc. fully specified
|
||||||
|
{
|
||||||
|
get { return m_bComplete; }
|
||||||
|
set { m_bComplete = value; }
|
||||||
|
}
|
||||||
|
|
||||||
/* public IOFileFormatHint FileFormatHint
|
/* public IOFileFormatHint FileFormatHint
|
||||||
{
|
{
|
||||||
get { return m_ioHint; }
|
get { return m_ioHint; }
|
||||||
@@ -133,11 +145,17 @@ namespace ModernKeePassLib.Serialization
|
|||||||
return (IOConnectionInfo)this.MemberwiseClone();
|
return (IOConnectionInfo)this.MemberwiseClone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG // For debugger display only
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return GetDisplayName();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serialize the current connection info to a string. Credentials
|
/// Serialize the current connection info to a string. Credentials
|
||||||
/// are only serialized if the <c>SaveCredentials</c> property
|
/// are serialized based on the <c>CredSaveMode</c> property.
|
||||||
/// is <c>true</c>.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="iocToCompile">Input object to be serialized.</param>
|
/// <param name="iocToCompile">Input object to be serialized.</param>
|
||||||
/// <returns>Serialized object as string.</returns>
|
/// <returns>Serialized object as string.</returns>
|
||||||
@@ -149,31 +167,9 @@ namespace ModernKeePassLib.Serialization
|
|||||||
string strUrl = iocToCompile.Path;
|
string strUrl = iocToCompile.Path;
|
||||||
string strUser = TransformUnreadable(iocToCompile.UserName, true);
|
string strUser = TransformUnreadable(iocToCompile.UserName, true);
|
||||||
string strPassword = TransformUnreadable(iocToCompile.Password, true);
|
string strPassword = TransformUnreadable(iocToCompile.Password, true);
|
||||||
string strAll = strUrl + strUser + strPassword;
|
|
||||||
char chSep = char.MinValue;
|
|
||||||
|
|
||||||
char[] vPrefSeps = new char[]{ '@', '#', '!', '$', '*' };
|
|
||||||
foreach(char ch in vPrefSeps)
|
|
||||||
{
|
|
||||||
if(strAll.IndexOf(ch) < 0)
|
|
||||||
{
|
|
||||||
chSep = ch;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(chSep == char.MinValue)
|
|
||||||
{
|
|
||||||
for(char chEnum = '!'; chEnum < char.MaxValue; ++chEnum)
|
|
||||||
{
|
|
||||||
if(strAll.IndexOf(chEnum) < 0)
|
|
||||||
{
|
|
||||||
chSep = chEnum;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
string strAll = strUrl + strUser + strPassword + "CUN";
|
||||||
|
char chSep = StrUtil.GetUnusedChar(strAll);
|
||||||
if(chSep == char.MinValue) throw new FormatException();
|
if(chSep == char.MinValue) throw new FormatException();
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
@@ -279,7 +275,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
string str = m_strUrl;
|
string str = m_strUrl;
|
||||||
|
|
||||||
if(m_strUser.Length > 0)
|
if(m_strUser.Length > 0)
|
||||||
str += @": " + m_strUser;
|
str += " (" + m_strUser + ")";
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -310,19 +306,22 @@ namespace ModernKeePassLib.Serialization
|
|||||||
return ioc;
|
return ioc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool CanProbablyAccess()
|
public bool CanProbablyAccess()
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
#if PCL
|
||||||
return false;
|
if(IsLocalFile())
|
||||||
#if TODO
|
return (StorageFile.IsAvailable);
|
||||||
|
#else
|
||||||
if(IsLocalFile()) return File.Exists(m_strUrl);
|
if(IsLocalFile()) return File.Exists(m_strUrl);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsLocalFile()
|
public bool IsLocalFile()
|
||||||
{
|
{
|
||||||
|
// Not just ":/", see e.g. AppConfigEx.ChangePathRelAbs
|
||||||
return (m_strUrl.IndexOf(@"://") < 0);
|
return (m_strUrl.IndexOf(@"://") < 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,15 +354,5 @@ namespace ModernKeePassLib.Serialization
|
|||||||
m_ioCredProtMode = IOCredProtMode.None;
|
m_ioCredProtMode = IOCredProtMode.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
if (!(obj is IOConnectionInfo)) return false;
|
|
||||||
IOConnectionInfo ioc = obj as IOConnectionInfo;
|
|
||||||
if (ioc.Path != this.Path) return false;
|
|
||||||
if (ioc.UserName != this.UserName) return false;
|
|
||||||
if (ioc.Password != this.Password) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,17 +19,27 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
//using System.Drawing;
|
using System.Text;
|
||||||
|
using System.Security;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
using ModernKeePassLib;
|
||||||
using ModernKeePassLib.Collections;
|
using ModernKeePassLib.Collections;
|
||||||
|
using ModernKeePassLib.Cryptography;
|
||||||
|
using ModernKeePassLib.Cryptography.Cipher;
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
|
using ModernKeePassLib.Resources;
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Serialization
|
namespace ModernKeePassLib.Serialization
|
||||||
{
|
{
|
||||||
public sealed partial class Kdb4File
|
/// <summary>
|
||||||
|
/// Serialization to KeePass KDBX files.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class KdbxFile
|
||||||
{
|
{
|
||||||
private enum KdbContext
|
private enum KdbContext
|
||||||
{
|
{
|
||||||
@@ -88,13 +98,17 @@ namespace ModernKeePassLib.Serialization
|
|||||||
xrs.IgnoreProcessingInstructions = true;
|
xrs.IgnoreProcessingInstructions = true;
|
||||||
xrs.IgnoreWhitespace = true;
|
xrs.IgnoreWhitespace = true;
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if !PCL
|
||||||
|
// these are default values, so no need to set them
|
||||||
|
#if !KeePassRT
|
||||||
|
#if !KeePassLibSD
|
||||||
xrs.ProhibitDtd = true;
|
xrs.ProhibitDtd = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TODO
|
|
||||||
xrs.ValidationType = ValidationType.None;
|
xrs.ValidationType = ValidationType.None;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return xrs;
|
return xrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,6 +213,17 @@ namespace ModernKeePassLib.Serialization
|
|||||||
case KdbContext.Meta:
|
case KdbContext.Meta:
|
||||||
if(xr.Name == ElemGenerator)
|
if(xr.Name == ElemGenerator)
|
||||||
ReadString(xr); // Ignore
|
ReadString(xr); // Ignore
|
||||||
|
else if(xr.Name == ElemHeaderHash)
|
||||||
|
{
|
||||||
|
string strHash = ReadString(xr);
|
||||||
|
if(!string.IsNullOrEmpty(strHash) && (m_pbHashOfHeader != null) &&
|
||||||
|
!m_bRepairMode)
|
||||||
|
{
|
||||||
|
byte[] pbHash = Convert.FromBase64String(strHash);
|
||||||
|
if(!MemUtil.ArraysEqual(pbHash, m_pbHashOfHeader))
|
||||||
|
throw new IOException(KLRes.FileCorrupted);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(xr.Name == ElemDbName)
|
else if(xr.Name == ElemDbName)
|
||||||
m_pwDatabase.Name = ReadString(xr);
|
m_pwDatabase.Name = ReadString(xr);
|
||||||
else if(xr.Name == ElemDbNameChanged)
|
else if(xr.Name == ElemDbNameChanged)
|
||||||
@@ -216,10 +241,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
else if(xr.Name == ElemDbColor)
|
else if(xr.Name == ElemDbColor)
|
||||||
{
|
{
|
||||||
string strColor = ReadString(xr);
|
string strColor = ReadString(xr);
|
||||||
#if TODO
|
/*if(!string.IsNullOrEmpty(strColor))
|
||||||
if(!string.IsNullOrEmpty(strColor))
|
m_pwDatabase.Color = ColorTranslator.FromHtml(strColor);*/
|
||||||
m_pwDatabase.Color = ColorTranslator.FromHtml(strColor);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if(xr.Name == ElemDbKeyChanged)
|
else if(xr.Name == ElemDbKeyChanged)
|
||||||
m_pwDatabase.MasterKeyChanged = ReadTime(xr);
|
m_pwDatabase.MasterKeyChanged = ReadTime(xr);
|
||||||
@@ -390,19 +413,14 @@ namespace ModernKeePassLib.Serialization
|
|||||||
else if(xr.Name == ElemFgColor)
|
else if(xr.Name == ElemFgColor)
|
||||||
{
|
{
|
||||||
string strColor = ReadString(xr);
|
string strColor = ReadString(xr);
|
||||||
#if TODO
|
/*if(!string.IsNullOrEmpty(strColor))
|
||||||
if(!string.IsNullOrEmpty(strColor))
|
m_ctxEntry.ForegroundColor = ColorTranslator.FromHtml(strColor);*/
|
||||||
m_ctxEntry.ForegroundColor = ColorTranslator.FromHtml(strColor);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if(xr.Name == ElemBgColor)
|
else if(xr.Name == ElemBgColor)
|
||||||
{
|
{
|
||||||
|
|
||||||
string strColor = ReadString(xr);
|
string strColor = ReadString(xr);
|
||||||
#if TODO
|
/*if(!string.IsNullOrEmpty(strColor))
|
||||||
if(!string.IsNullOrEmpty(strColor))
|
m_ctxEntry.BackgroundColor = ColorTranslator.FromHtml(strColor);*/
|
||||||
m_ctxEntry.BackgroundColor = ColorTranslator.FromHtml(strColor);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if(xr.Name == ElemOverrideUrl)
|
else if(xr.Name == ElemOverrideUrl)
|
||||||
m_ctxEntry.OverrideUrl = ReadString(xr);
|
m_ctxEntry.OverrideUrl = ReadString(xr);
|
||||||
@@ -436,10 +454,10 @@ namespace ModernKeePassLib.Serialization
|
|||||||
(ITimeLogger)m_ctxGroup : (ITimeLogger)m_ctxEntry);
|
(ITimeLogger)m_ctxGroup : (ITimeLogger)m_ctxEntry);
|
||||||
Debug.Assert(tl != null);
|
Debug.Assert(tl != null);
|
||||||
|
|
||||||
if(xr.Name == ElemLastModTime)
|
if(xr.Name == ElemCreationTime)
|
||||||
tl.LastModificationTime = ReadTime(xr);
|
|
||||||
else if(xr.Name == ElemCreationTime)
|
|
||||||
tl.CreationTime = ReadTime(xr);
|
tl.CreationTime = ReadTime(xr);
|
||||||
|
else if(xr.Name == ElemLastModTime)
|
||||||
|
tl.LastModificationTime = ReadTime(xr);
|
||||||
else if(xr.Name == ElemLastAccessTime)
|
else if(xr.Name == ElemLastAccessTime)
|
||||||
tl.LastAccessTime = ReadTime(xr);
|
tl.LastAccessTime = ReadTime(xr);
|
||||||
else if(xr.Name == ElemExpiryTime)
|
else if(xr.Name == ElemExpiryTime)
|
||||||
@@ -545,7 +563,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
return KdbContext.Meta;
|
return KdbContext.Meta;
|
||||||
else if((ctx == KdbContext.CustomIcon) && (xr.Name == ElemCustomIconItem))
|
else if((ctx == KdbContext.CustomIcon) && (xr.Name == ElemCustomIconItem))
|
||||||
{
|
{
|
||||||
if((m_uuidCustomIconID != PwUuid.Zero) && (m_pbCustomIconData != null))
|
if(!m_uuidCustomIconID.Equals(PwUuid.Zero) &&
|
||||||
|
(m_pbCustomIconData != null))
|
||||||
m_pwDatabase.CustomIcons.Add(new PwCustomIcon(
|
m_pwDatabase.CustomIcons.Add(new PwCustomIcon(
|
||||||
m_uuidCustomIconID, m_pbCustomIconData));
|
m_uuidCustomIconID, m_pbCustomIconData));
|
||||||
else { Debug.Assert(false); }
|
else { Debug.Assert(false); }
|
||||||
@@ -572,7 +591,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
else if((ctx == KdbContext.Group) && (xr.Name == ElemGroup))
|
else if((ctx == KdbContext.Group) && (xr.Name == ElemGroup))
|
||||||
{
|
{
|
||||||
if(PwUuid.Zero.EqualsValue(m_ctxGroup.Uuid))
|
if(PwUuid.Zero.Equals(m_ctxGroup.Uuid))
|
||||||
m_ctxGroup.Uuid = new PwUuid(true); // No assert (import)
|
m_ctxGroup.Uuid = new PwUuid(true); // No assert (import)
|
||||||
|
|
||||||
m_ctxGroups.Pop();
|
m_ctxGroups.Pop();
|
||||||
@@ -593,7 +612,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
else if((ctx == KdbContext.Entry) && (xr.Name == ElemEntry))
|
else if((ctx == KdbContext.Entry) && (xr.Name == ElemEntry))
|
||||||
{
|
{
|
||||||
// Create new UUID if absent
|
// Create new UUID if absent
|
||||||
if(PwUuid.Zero.EqualsValue(m_ctxEntry.Uuid))
|
if(PwUuid.Zero.Equals(m_ctxEntry.Uuid))
|
||||||
m_ctxEntry.Uuid = new PwUuid(true); // No assert (import)
|
m_ctxEntry.Uuid = new PwUuid(true); // No assert (import)
|
||||||
|
|
||||||
if(m_bEntryInHistory)
|
if(m_bEntryInHistory)
|
||||||
@@ -670,13 +689,21 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_bReadNextNode = false; // ReadElementString skips end tag
|
m_bReadNextNode = false; // ReadElementString skips end tag
|
||||||
|
#if PCL
|
||||||
return xr.ReadElementContentAsString();
|
return xr.ReadElementContentAsString();
|
||||||
|
#else
|
||||||
|
return xr.ReadElementString();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ReadStringRaw(XmlReader xr)
|
private string ReadStringRaw(XmlReader xr)
|
||||||
{
|
{
|
||||||
m_bReadNextNode = false; // ReadElementString skips end tag
|
m_bReadNextNode = false; // ReadElementString skips end tag
|
||||||
|
#if PCL
|
||||||
return xr.ReadElementContentAsString();
|
return xr.ReadElementContentAsString();
|
||||||
|
#else
|
||||||
|
return xr.ReadElementString();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ReadBool(XmlReader xr, bool bDefault)
|
private bool ReadBool(XmlReader xr, bool bDefault)
|
||||||
@@ -701,6 +728,9 @@ namespace ModernKeePassLib.Serialization
|
|||||||
string str = ReadString(xr);
|
string str = ReadString(xr);
|
||||||
|
|
||||||
int n;
|
int n;
|
||||||
|
if(StrUtil.TryParseIntInvariant(str, out n)) return n;
|
||||||
|
|
||||||
|
// Backward compatibility
|
||||||
if(StrUtil.TryParseInt(str, out n)) return n;
|
if(StrUtil.TryParseInt(str, out n)) return n;
|
||||||
|
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
@@ -712,6 +742,9 @@ namespace ModernKeePassLib.Serialization
|
|||||||
string str = ReadString(xr);
|
string str = ReadString(xr);
|
||||||
|
|
||||||
uint u;
|
uint u;
|
||||||
|
if(StrUtil.TryParseUIntInvariant(str, out u)) return u;
|
||||||
|
|
||||||
|
// Backward compatibility
|
||||||
if(StrUtil.TryParseUInt(str, out u)) return u;
|
if(StrUtil.TryParseUInt(str, out u)) return u;
|
||||||
|
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
@@ -723,6 +756,9 @@ namespace ModernKeePassLib.Serialization
|
|||||||
string str = ReadString(xr);
|
string str = ReadString(xr);
|
||||||
|
|
||||||
long l;
|
long l;
|
||||||
|
if(StrUtil.TryParseLongInvariant(str, out l)) return l;
|
||||||
|
|
||||||
|
// Backward compatibility
|
||||||
if(StrUtil.TryParseLong(str, out l)) return l;
|
if(StrUtil.TryParseLong(str, out l)) return l;
|
||||||
|
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
@@ -734,6 +770,9 @@ namespace ModernKeePassLib.Serialization
|
|||||||
string str = ReadString(xr);
|
string str = ReadString(xr);
|
||||||
|
|
||||||
ulong u;
|
ulong u;
|
||||||
|
if(StrUtil.TryParseULongInvariant(str, out u)) return u;
|
||||||
|
|
||||||
|
// Backward compatibility
|
||||||
if(StrUtil.TryParseULong(str, out u)) return u;
|
if(StrUtil.TryParseULong(str, out u)) return u;
|
||||||
|
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
@@ -757,7 +796,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
if(xb != null) return new ProtectedString(true, xb);
|
if(xb != null) return new ProtectedString(true, xb);
|
||||||
|
|
||||||
bool bProtect = false;
|
bool bProtect = false;
|
||||||
if(m_format == Kdb4Format.PlainXml)
|
if(m_format == KdbxFormat.PlainXml)
|
||||||
{
|
{
|
||||||
if(xr.MoveToAttribute(AttrProtectedInMemPlainXml))
|
if(xr.MoveToAttribute(AttrProtectedInMemPlainXml))
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,12 +21,20 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
using System.Xml;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
#else
|
#else
|
||||||
using ModernKeePassLibSD;
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Cryptography;
|
using ModernKeePassLib.Cryptography;
|
||||||
@@ -35,41 +43,35 @@ using ModernKeePassLib.Interfaces;
|
|||||||
using ModernKeePassLib.Keys;
|
using ModernKeePassLib.Keys;
|
||||||
using ModernKeePassLib.Resources;
|
using ModernKeePassLib.Resources;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.Serialization
|
namespace ModernKeePassLib.Serialization
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serialization to KeePass KDBX files.
|
/// Serialization to KeePass KDBX files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Kdb4File
|
public sealed partial class KdbxFile
|
||||||
{
|
{
|
||||||
private IOConnection m_connection;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load a KDB file from a file.
|
/// Load a KDB file from a file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="strFilePath">File to load.</param>
|
/// <param name="strFilePath">File to load.</param>
|
||||||
/// <param name="kdbFormat">Format specifier.</param>
|
/// <param name="kdbFormat">Format specifier.</param>
|
||||||
/// <param name="slLogger">Status logger (optional).</param>
|
/// <param name="slLogger">Status logger (optional).</param>
|
||||||
public async Task Load(string strFilePath, Kdb4Format kdbFormat, IStatusLogger slLogger)
|
public void Load(string strFilePath, KdbxFormat kdbFormat, IStatusLogger slLogger)
|
||||||
{
|
{
|
||||||
IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath);
|
IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath);
|
||||||
IOConnection ioConnection = new IOConnection();
|
Load(IOConnection.OpenRead(ioc), kdbFormat, slLogger);
|
||||||
Stream abc = await ioConnection.OpenRead(ioc);
|
|
||||||
Load(abc, kdbFormat, slLogger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load a KDB file from a stream.
|
/// Load a KDB file from a stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sSource">Stream to read the data from. Must contain
|
/// <param name="sSource">Stream to read the data from. Must contain
|
||||||
/// a KDB4 stream.</param>
|
/// a KDBX stream.</param>
|
||||||
/// <param name="kdbFormat">Format specifier.</param>
|
/// <param name="kdbFormat">Format specifier.</param>
|
||||||
/// <param name="slLogger">Status logger (optional).</param>
|
/// <param name="slLogger">Status logger (optional).</param>
|
||||||
public void Load(Stream sSource, Kdb4Format kdbFormat, IStatusLogger slLogger)
|
public void Load(Stream sSource, KdbxFormat kdbFormat, IStatusLogger slLogger)
|
||||||
{
|
{
|
||||||
|
|
||||||
Debug.Assert(sSource != null);
|
Debug.Assert(sSource != null);
|
||||||
if(sSource == null) throw new ArgumentNullException("sSource");
|
if(sSource == null) throw new ArgumentNullException("sSource");
|
||||||
|
|
||||||
@@ -85,7 +87,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
BinaryReaderEx brDecrypted = null;
|
BinaryReaderEx brDecrypted = null;
|
||||||
Stream readerStream = null;
|
Stream readerStream = null;
|
||||||
|
|
||||||
if(kdbFormat == Kdb4Format.Default)
|
if(kdbFormat == KdbxFormat.Default)
|
||||||
{
|
{
|
||||||
br = new BinaryReaderEx(hashedStream, encNoBom, KLRes.FileCorrupted);
|
br = new BinaryReaderEx(hashedStream, encNoBom, KLRes.FileCorrupted);
|
||||||
ReadHeader(br);
|
ReadHeader(br);
|
||||||
@@ -113,11 +115,11 @@ namespace ModernKeePassLib.Serialization
|
|||||||
readerStream = new GZipStream(sHashed, CompressionMode.Decompress);
|
readerStream = new GZipStream(sHashed, CompressionMode.Decompress);
|
||||||
else readerStream = sHashed;
|
else readerStream = sHashed;
|
||||||
}
|
}
|
||||||
else if(kdbFormat == Kdb4Format.PlainXml)
|
else if(kdbFormat == KdbxFormat.PlainXml)
|
||||||
readerStream = hashedStream;
|
readerStream = hashedStream;
|
||||||
else { Debug.Assert(false); throw new FormatException("KdbFormat"); }
|
else { Debug.Assert(false); throw new FormatException("KdbFormat"); }
|
||||||
|
|
||||||
if(kdbFormat != Kdb4Format.PlainXml) // Is an encrypted format
|
if(kdbFormat != KdbxFormat.PlainXml) // Is an encrypted format
|
||||||
{
|
{
|
||||||
if(m_pbProtectedStreamKey == null)
|
if(m_pbProtectedStreamKey == null)
|
||||||
{
|
{
|
||||||
@@ -130,35 +132,49 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
else m_randomStream = null; // No random stream for plain-text files
|
else m_randomStream = null; // No random stream for plain-text files
|
||||||
|
|
||||||
|
#if KeePassDebug_WriteXml
|
||||||
|
// FileStream fsOut = new FileStream("Raw.xml", FileMode.Create,
|
||||||
|
// FileAccess.Write, FileShare.None);
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// while(true)
|
||||||
|
// {
|
||||||
|
// int b = readerStream.ReadByte();
|
||||||
|
// if(b == -1) break;
|
||||||
|
// fsOut.WriteByte((byte)b);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch(Exception) { }
|
||||||
|
// fsOut.Close();
|
||||||
|
#endif
|
||||||
|
|
||||||
ReadXmlStreamed(readerStream, hashedStream);
|
ReadXmlStreamed(readerStream, hashedStream);
|
||||||
// ReadXmlDom(readerStream);
|
// ReadXmlDom(readerStream);
|
||||||
|
|
||||||
#if !KeePassWinRT
|
readerStream.Dispose();
|
||||||
readerStream.Close();
|
// GC.KeepAlive(br);
|
||||||
#endif
|
// GC.KeepAlive(brDecrypted);
|
||||||
GC.KeepAlive(brDecrypted);
|
|
||||||
GC.KeepAlive(br);
|
|
||||||
}
|
}
|
||||||
#if !KeePassWinRT
|
#if !PCL
|
||||||
catch(CryptographicException) // Thrown on invalid padding
|
catch(CryptographicException) // Thrown on invalid padding
|
||||||
{
|
{
|
||||||
throw new CryptographicException(KLRes.FileCorrupted);
|
throw new CryptographicException(KLRes.FileCorrupted);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
finally { CommonCleanUpRead(sSource, hashedStream); }
|
finally { CommonCleanUpRead(sSource, hashedStream); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CommonCleanUpRead(Stream sSource, HashingStreamEx hashedStream)
|
private void CommonCleanUpRead(Stream sSource, HashingStreamEx hashedStream)
|
||||||
{
|
{
|
||||||
|
hashedStream.Dispose();
|
||||||
m_pbHashOfFileOnDisk = hashedStream.Hash;
|
m_pbHashOfFileOnDisk = hashedStream.Hash;
|
||||||
|
|
||||||
|
sSource.Dispose();
|
||||||
|
|
||||||
// Reset memory protection settings (to always use reasonable
|
// Reset memory protection settings (to always use reasonable
|
||||||
// defaults)
|
// defaults)
|
||||||
m_pwDatabase.MemoryProtection = new MemoryProtectionConfig();
|
m_pwDatabase.MemoryProtection = new MemoryProtectionConfig();
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if !KeePassWinRT
|
|
||||||
// Remove old backups (this call is required here in order to apply
|
// Remove old backups (this call is required here in order to apply
|
||||||
// the default history maintenance settings for people upgrading from
|
// the default history maintenance settings for people upgrading from
|
||||||
// KeePass <= 2.14 to >= 2.15; also it ensures history integrity in
|
// KeePass <= 2.14 to >= 2.15; also it ensures history integrity in
|
||||||
@@ -166,17 +182,14 @@ namespace ModernKeePassLib.Serialization
|
|||||||
// the history maintenance settings)
|
// the history maintenance settings)
|
||||||
m_pwDatabase.MaintainBackups(); // Don't mark database as modified
|
m_pwDatabase.MaintainBackups(); // Don't mark database as modified
|
||||||
|
|
||||||
|
m_pbHashOfHeader = null;
|
||||||
// Is it ok to leave the stream open ????
|
|
||||||
hashedStream.Close();
|
|
||||||
sSource.Close();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadHeader(BinaryReaderEx br)
|
private void ReadHeader(BinaryReaderEx br)
|
||||||
{
|
{
|
||||||
Debug.Assert(br != null);
|
MemoryStream msHeader = new MemoryStream();
|
||||||
if(br == null) throw new ArgumentNullException("br");
|
Debug.Assert(br.CopyDataTo == null);
|
||||||
|
br.CopyDataTo = msHeader;
|
||||||
|
|
||||||
byte[] pbSig1 = br.ReadBytes(4);
|
byte[] pbSig1 = br.ReadBytes(4);
|
||||||
uint uSig1 = MemUtil.BytesToUInt32(pbSig1);
|
uint uSig1 = MemUtil.BytesToUInt32(pbSig1);
|
||||||
@@ -194,19 +207,27 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
byte[] pb = br.ReadBytes(4);
|
byte[] pb = br.ReadBytes(4);
|
||||||
uint uVersion = MemUtil.BytesToUInt32(pb);
|
uint uVersion = MemUtil.BytesToUInt32(pb);
|
||||||
|
if((uVersion & FileVersionCriticalMask) > (FileVersion32 & FileVersionCriticalMask))
|
||||||
if ((uVersion & FileVersionCriticalMask) > (FileVersion32 & FileVersionCriticalMask))
|
|
||||||
#if TODO
|
|
||||||
throw new FormatException(KLRes.FileVersionUnsupported +
|
throw new FormatException(KLRes.FileVersionUnsupported +
|
||||||
MessageService.NewParagraph + KLRes.FileNewVerReq);
|
Environment.NewLine + Environment.NewLine + KLRes.FileNewVerReq);
|
||||||
#else
|
|
||||||
throw new FormatException();
|
|
||||||
#endif
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(ReadHeaderField(br) == false)
|
if(ReadHeaderField(br) == false)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
br.CopyDataTo = null;
|
||||||
|
byte[] pbHeader = msHeader.ToArray();
|
||||||
|
msHeader.Dispose();
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
m_pbHashOfHeader = sha256.HashData(pbHeader.AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
|
m_pbHashOfHeader = sha256.ComputeHash(pbHeader);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ReadHeaderField(BinaryReaderEx brSource)
|
private bool ReadHeaderField(BinaryReaderEx brSource)
|
||||||
@@ -229,49 +250,49 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool bResult = true;
|
bool bResult = true;
|
||||||
Kdb4HeaderFieldID kdbID = (Kdb4HeaderFieldID)btFieldID;
|
KdbxHeaderFieldID kdbID = (KdbxHeaderFieldID)btFieldID;
|
||||||
switch(kdbID)
|
switch(kdbID)
|
||||||
{
|
{
|
||||||
case Kdb4HeaderFieldID.EndOfHeader:
|
case KdbxHeaderFieldID.EndOfHeader:
|
||||||
bResult = false; // Returning false indicates end of header
|
bResult = false; // Returning false indicates end of header
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Kdb4HeaderFieldID.CipherID:
|
case KdbxHeaderFieldID.CipherID:
|
||||||
SetCipher(pbData);
|
SetCipher(pbData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Kdb4HeaderFieldID.CompressionFlags:
|
case KdbxHeaderFieldID.CompressionFlags:
|
||||||
SetCompressionFlags(pbData);
|
SetCompressionFlags(pbData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Kdb4HeaderFieldID.MasterSeed:
|
case KdbxHeaderFieldID.MasterSeed:
|
||||||
m_pbMasterSeed = pbData;
|
m_pbMasterSeed = pbData;
|
||||||
CryptoRandom.Instance.AddEntropy(pbData);
|
CryptoRandom.Instance.AddEntropy(pbData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Kdb4HeaderFieldID.TransformSeed:
|
case KdbxHeaderFieldID.TransformSeed:
|
||||||
m_pbTransformSeed = pbData;
|
m_pbTransformSeed = pbData;
|
||||||
CryptoRandom.Instance.AddEntropy(pbData);
|
CryptoRandom.Instance.AddEntropy(pbData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Kdb4HeaderFieldID.TransformRounds:
|
case KdbxHeaderFieldID.TransformRounds:
|
||||||
m_pwDatabase.KeyEncryptionRounds = MemUtil.BytesToUInt64(pbData);
|
m_pwDatabase.KeyEncryptionRounds = MemUtil.BytesToUInt64(pbData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Kdb4HeaderFieldID.EncryptionIV:
|
case KdbxHeaderFieldID.EncryptionIV:
|
||||||
m_pbEncryptionIV = pbData;
|
m_pbEncryptionIV = pbData;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Kdb4HeaderFieldID.ProtectedStreamKey:
|
case KdbxHeaderFieldID.ProtectedStreamKey:
|
||||||
m_pbProtectedStreamKey = pbData;
|
m_pbProtectedStreamKey = pbData;
|
||||||
CryptoRandom.Instance.AddEntropy(pbData);
|
CryptoRandom.Instance.AddEntropy(pbData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Kdb4HeaderFieldID.StreamStartBytes:
|
case KdbxHeaderFieldID.StreamStartBytes:
|
||||||
m_pbStreamStartBytes = pbData;
|
m_pbStreamStartBytes = pbData;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Kdb4HeaderFieldID.InnerRandomStreamID:
|
case KdbxHeaderFieldID.InnerRandomStreamID:
|
||||||
SetInnerRandomStreamID(pbData);
|
SetInnerRandomStreamID(pbData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -314,42 +335,35 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
private Stream AttachStreamDecryptor(Stream s)
|
private Stream AttachStreamDecryptor(Stream s)
|
||||||
{
|
{
|
||||||
MemoryStream ms = new MemoryStream();
|
using (var ms = new MemoryStream())
|
||||||
|
{
|
||||||
Debug.Assert(m_pbMasterSeed.Length == 32);
|
Debug.Assert(m_pbMasterSeed.Length == 32);
|
||||||
if(m_pbMasterSeed.Length != 32)
|
if (m_pbMasterSeed.Length != 32)
|
||||||
throw new FormatException(KLRes.MasterSeedLengthInvalid);
|
throw new FormatException(KLRes.MasterSeedLengthInvalid);
|
||||||
ms.Write(m_pbMasterSeed, 0, 32);
|
ms.Write(m_pbMasterSeed, 0, 32);
|
||||||
|
|
||||||
Security.ProtectedBinary pb = m_pwDatabase.MasterKey.GenerateKey32(m_pbTransformSeed,
|
byte[] pKey32 = m_pwDatabase.MasterKey.GenerateKey32(m_pbTransformSeed,
|
||||||
m_pwDatabase.KeyEncryptionRounds);
|
m_pwDatabase.KeyEncryptionRounds).ReadData();
|
||||||
|
if (pKey32 == null || pKey32.Length != 32)
|
||||||
byte[] pKey32 = pb.ReadData();
|
|
||||||
if((pKey32 == null) || (pKey32.Length != 32))
|
|
||||||
throw new SecurityException(KLRes.InvalidCompositeKey);
|
throw new SecurityException(KLRes.InvalidCompositeKey);
|
||||||
ms.Write(pKey32, 0, 32);
|
ms.Write(pKey32, 0, 32);
|
||||||
|
|
||||||
byte[] aesKey = SHA256Managed.Instance.ComputeHash(ms.ToArray());
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
//SHA256Managed sha256 = new SHA256Managed();
|
var aesKey = sha256.HashData(ms.GetWindowsRuntimeBuffer()).ToArray();
|
||||||
//byte[] aesKey = sha256.ComputeHash(ms.ToArray());
|
#else
|
||||||
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
//ms.Close();
|
byte[] aesKey = sha256.ComputeHash(ms.ToArray());
|
||||||
|
#endif
|
||||||
Array.Clear(pKey32, 0, 32);
|
Array.Clear(pKey32, 0, 32);
|
||||||
|
|
||||||
if((aesKey == null) || (aesKey.Length != 32))
|
if (aesKey == null || aesKey.Length != 32)
|
||||||
throw new SecurityException(KLRes.FinalKeyCreationFailed);
|
throw new SecurityException(KLRes.FinalKeyCreationFailed);
|
||||||
|
|
||||||
ICipherEngine iEngine = CipherPool.GlobalPool.GetCipher(m_pwDatabase.DataCipherUuid);
|
ICipherEngine iEngine = CipherPool.GlobalPool.GetCipher(m_pwDatabase.DataCipherUuid);
|
||||||
if(iEngine == null) throw new SecurityException(KLRes.FileUnknownCipher);
|
if (iEngine == null) throw new SecurityException(KLRes.FileUnknownCipher);
|
||||||
return iEngine.DecryptStream(s, aesKey, m_pbEncryptionIV);
|
return iEngine.DecryptStream(s, aesKey, m_pbEncryptionIV);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete]
|
|
||||||
public static List<PwEntry> ReadEntries(PwDatabase pwDatabase, Stream msData)
|
|
||||||
{
|
|
||||||
return ReadEntries(msData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -359,11 +373,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
/// <returns>Extracted entries.</returns>
|
/// <returns>Extracted entries.</returns>
|
||||||
public static List<PwEntry> ReadEntries(Stream msData)
|
public static List<PwEntry> ReadEntries(Stream msData)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
/* KdbxFile f = new KdbxFile(pwDatabase);
|
||||||
return null;
|
f.m_format = KdbxFormat.PlainXml;
|
||||||
#if TODO
|
|
||||||
/* Kdb4File f = new Kdb4File(pwDatabase);
|
|
||||||
f.m_format = Kdb4Format.PlainXml;
|
|
||||||
|
|
||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
doc.Load(msData);
|
doc.Load(msData);
|
||||||
@@ -391,8 +402,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
return vEntries; */
|
return vEntries; */
|
||||||
|
|
||||||
PwDatabase pd = new PwDatabase();
|
PwDatabase pd = new PwDatabase();
|
||||||
Kdb4File f = new Kdb4File(pd);
|
KdbxFile f = new KdbxFile(pd);
|
||||||
f.Load(msData, Kdb4Format.PlainXml, null);
|
f.Load(msData, KdbxFormat.PlainXml, null);
|
||||||
|
|
||||||
List<PwEntry> vEntries = new List<PwEntry>();
|
List<PwEntry> vEntries = new List<PwEntry>();
|
||||||
foreach(PwEntry pe in pd.RootGroup.Entries)
|
foreach(PwEntry pe in pd.RootGroup.Entries)
|
||||||
@@ -402,7 +413,6 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
|
|
||||||
return vEntries;
|
return vEntries;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,39 +19,43 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Security;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.IO;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
//using System.Drawing;
|
using System.Security;
|
||||||
//using System.Drawing.Imaging;
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
#if !KeePassLibSD
|
|
||||||
#else
|
#else
|
||||||
using ModernKeePassLibSD;
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.Core;
|
||||||
|
#if !KeePassLibSD
|
||||||
|
using System.IO.Compression;
|
||||||
|
#else
|
||||||
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Collections;
|
using ModernKeePassLib.Collections;
|
||||||
using ModernKeePassLib.Cryptography;
|
using ModernKeePassLib.Cryptography;
|
||||||
using ModernKeePassLib.Cryptography.Cipher;
|
using ModernKeePassLib.Cryptography.Cipher;
|
||||||
|
using ModernKeePassLib.Delegates;
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
using ModernKeePassLib.Keys;
|
using ModernKeePassLib.Keys;
|
||||||
using ModernKeePassLib.Resources;
|
using ModernKeePassLib.Resources;
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
using ModernKeePassLib.Delegates;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.Serialization
|
namespace ModernKeePassLib.Serialization
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serialization to KeePass KDB files.
|
/// Serialization to KeePass KDBX files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Kdb4File
|
public sealed partial class KdbxFile
|
||||||
{
|
{
|
||||||
// public void Save(string strFile, PwGroup pgDataSource, Kdb4Format format,
|
// public void Save(string strFile, PwGroup pgDataSource, KdbxFormat format,
|
||||||
// IStatusLogger slLogger)
|
// IStatusLogger slLogger)
|
||||||
// {
|
// {
|
||||||
// bool bMadeUnhidden = UrlUtil.UnhideFile(strFile);
|
// bool bMadeUnhidden = UrlUtil.UnhideFile(strFile);
|
||||||
@@ -71,7 +75,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
/// be written.</param>
|
/// be written.</param>
|
||||||
/// <param name="format">Format of the file to create.</param>
|
/// <param name="format">Format of the file to create.</param>
|
||||||
/// <param name="slLogger">Logger that recieves status information.</param>
|
/// <param name="slLogger">Logger that recieves status information.</param>
|
||||||
public void Save(Stream sSaveTo, PwGroup pgDataSource, Kdb4Format format,
|
public void Save(Stream sSaveTo, PwGroup pgDataSource, KdbxFormat format,
|
||||||
IStatusLogger slLogger)
|
IStatusLogger slLogger)
|
||||||
{
|
{
|
||||||
Debug.Assert(sSaveTo != null);
|
Debug.Assert(sSaveTo != null);
|
||||||
@@ -99,112 +103,122 @@ namespace ModernKeePassLib.Serialization
|
|||||||
m_pbStreamStartBytes = cr.GetRandomBytes(32);
|
m_pbStreamStartBytes = cr.GetRandomBytes(32);
|
||||||
|
|
||||||
Stream writerStream;
|
Stream writerStream;
|
||||||
BinaryWriter bw = null;
|
if(m_format == KdbxFormat.Default)
|
||||||
if (m_format == Kdb4Format.Default)
|
|
||||||
{
|
{
|
||||||
bw = new BinaryWriter(hashedStream, encNoBom);
|
WriteHeader(hashedStream); // Also flushes the stream
|
||||||
WriteHeader(bw); // Also flushes bw
|
|
||||||
|
|
||||||
Stream sEncrypted = AttachStreamEncryptor(hashedStream);
|
Stream sEncrypted = AttachStreamEncryptor(hashedStream);
|
||||||
if ((sEncrypted == null) || (sEncrypted == hashedStream))
|
if((sEncrypted == null) || (sEncrypted == hashedStream))
|
||||||
throw new SecurityException(KLRes.CryptoStreamFailed);
|
throw new SecurityException(KLRes.CryptoStreamFailed);
|
||||||
|
|
||||||
sEncrypted.Write(m_pbStreamStartBytes, 0, m_pbStreamStartBytes.Length);
|
sEncrypted.Write(m_pbStreamStartBytes, 0, m_pbStreamStartBytes.Length);
|
||||||
|
|
||||||
Stream sHashed = new HashedBlockStream(sEncrypted, true);
|
Stream sHashed = new HashedBlockStream(sEncrypted, true);
|
||||||
|
|
||||||
if (m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
|
if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
|
||||||
writerStream = new GZipStream(sHashed, CompressionMode.Compress);
|
writerStream = new GZipStream(sHashed, CompressionMode.Compress);
|
||||||
else
|
else
|
||||||
writerStream = sHashed;
|
writerStream = sHashed;
|
||||||
}
|
}
|
||||||
else if (m_format == Kdb4Format.PlainXml)
|
else if(m_format == KdbxFormat.PlainXml)
|
||||||
writerStream = hashedStream;
|
writerStream = hashedStream;
|
||||||
else
|
else { Debug.Assert(false); throw new FormatException("KdbFormat"); }
|
||||||
{
|
|
||||||
Debug.Assert(false);
|
|
||||||
throw new FormatException("KdbFormat");
|
|
||||||
}
|
|
||||||
|
|
||||||
using (m_xmlWriter = XmlWriter.Create(writerStream, new XmlWriterSettings {Encoding = encNoBom}))
|
#if PCL
|
||||||
{
|
var settings = new XmlWriterSettings() {
|
||||||
|
Encoding = encNoBom,
|
||||||
|
Indent = true,
|
||||||
|
IndentChars = "\t",
|
||||||
|
NewLineChars = "\r\n",
|
||||||
|
};
|
||||||
|
m_xmlWriter = XmlWriter.Create(writerStream, settings);
|
||||||
|
#else
|
||||||
|
m_xmlWriter = new XmlTextWriter(writerStream, encNoBom);
|
||||||
|
#endif
|
||||||
WriteDocument(pgDataSource);
|
WriteDocument(pgDataSource);
|
||||||
|
|
||||||
m_xmlWriter.Flush();
|
m_xmlWriter.Flush();
|
||||||
|
m_xmlWriter.Dispose();
|
||||||
writerStream.Dispose();
|
writerStream.Dispose();
|
||||||
}
|
|
||||||
GC.KeepAlive(bw);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
finally { CommonCleanUpWrite(sSaveTo, hashedStream); }
|
finally { CommonCleanUpWrite(sSaveTo, hashedStream); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CommonCleanUpWrite(Stream sSaveTo, HashingStreamEx hashedStream)
|
private void CommonCleanUpWrite(Stream sSaveTo, HashingStreamEx hashedStream)
|
||||||
{
|
{
|
||||||
//hashedStream.Close();
|
hashedStream.Dispose();
|
||||||
m_pbHashOfFileOnDisk = hashedStream.Hash;
|
m_pbHashOfFileOnDisk = hashedStream.Hash;
|
||||||
|
|
||||||
sSaveTo.Dispose();
|
sSaveTo.Dispose();
|
||||||
|
|
||||||
m_xmlWriter = null;
|
m_xmlWriter = null;
|
||||||
|
m_pbHashOfHeader = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteHeader(BinaryWriter bw)
|
private void WriteHeader(Stream s)
|
||||||
{
|
{
|
||||||
Debug.Assert(bw != null);
|
MemoryStream ms = new MemoryStream();
|
||||||
if(bw == null) throw new ArgumentNullException("bw");
|
|
||||||
|
|
||||||
bw.Write(MemUtil.UInt32ToBytes(FileSignature1));
|
MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature1));
|
||||||
bw.Write(MemUtil.UInt32ToBytes(FileSignature2));
|
MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature2));
|
||||||
bw.Write(MemUtil.UInt32ToBytes(FileVersion32));
|
MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileVersion32));
|
||||||
|
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.CipherID,
|
WriteHeaderField(ms, KdbxHeaderFieldID.CipherID,
|
||||||
m_pwDatabase.DataCipherUuid.UuidBytes);
|
m_pwDatabase.DataCipherUuid.UuidBytes);
|
||||||
|
|
||||||
int nCprID = (int)m_pwDatabase.Compression;
|
int nCprID = (int)m_pwDatabase.Compression;
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.CompressionFlags,
|
WriteHeaderField(ms, KdbxHeaderFieldID.CompressionFlags,
|
||||||
MemUtil.UInt32ToBytes((uint)nCprID));
|
MemUtil.UInt32ToBytes((uint)nCprID));
|
||||||
|
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.MasterSeed, m_pbMasterSeed);
|
WriteHeaderField(ms, KdbxHeaderFieldID.MasterSeed, m_pbMasterSeed);
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.TransformSeed, m_pbTransformSeed);
|
WriteHeaderField(ms, KdbxHeaderFieldID.TransformSeed, m_pbTransformSeed);
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.TransformRounds, MemUtil.UInt64ToBytes(m_pwDatabase.KeyEncryptionRounds));
|
WriteHeaderField(ms, KdbxHeaderFieldID.TransformRounds,
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.EncryptionIV, m_pbEncryptionIV);
|
MemUtil.UInt64ToBytes(m_pwDatabase.KeyEncryptionRounds));
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.ProtectedStreamKey, m_pbProtectedStreamKey);
|
WriteHeaderField(ms, KdbxHeaderFieldID.EncryptionIV, m_pbEncryptionIV);
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.StreamStartBytes, m_pbStreamStartBytes);
|
WriteHeaderField(ms, KdbxHeaderFieldID.ProtectedStreamKey, m_pbProtectedStreamKey);
|
||||||
|
WriteHeaderField(ms, KdbxHeaderFieldID.StreamStartBytes, m_pbStreamStartBytes);
|
||||||
|
|
||||||
int nIrsID = (int)m_craInnerRandomStream;
|
int nIrsID = (int)m_craInnerRandomStream;
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.InnerRandomStreamID,
|
WriteHeaderField(ms, KdbxHeaderFieldID.InnerRandomStreamID,
|
||||||
MemUtil.UInt32ToBytes((uint)nIrsID));
|
MemUtil.UInt32ToBytes((uint)nIrsID));
|
||||||
|
|
||||||
WriteHeaderField(bw, Kdb4HeaderFieldID.EndOfHeader, new byte[]{ (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' });
|
WriteHeaderField(ms, KdbxHeaderFieldID.EndOfHeader, new byte[]{
|
||||||
bw.Flush();
|
(byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' });
|
||||||
|
|
||||||
|
byte[] pbHeader = ms.ToArray();
|
||||||
|
ms.Dispose();
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
m_pbHashOfHeader = sha256.HashData(pbHeader.AsBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
|
m_pbHashOfHeader = sha256.ComputeHash(pbHeader);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
s.Write(pbHeader, 0, pbHeader.Length);
|
||||||
|
s.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteHeaderField(BinaryWriter bwOut,
|
private static void WriteHeaderField(Stream s, KdbxHeaderFieldID kdbID,
|
||||||
Kdb4HeaderFieldID kdbID, byte[] pbData)
|
byte[] pbData)
|
||||||
{
|
{
|
||||||
Debug.Assert(bwOut != null);
|
s.WriteByte((byte)kdbID);
|
||||||
if(bwOut == null) throw new ArgumentNullException("bwOut");
|
|
||||||
|
|
||||||
bwOut.Write((byte)kdbID);
|
|
||||||
|
|
||||||
if(pbData != null)
|
if(pbData != null)
|
||||||
{
|
{
|
||||||
ushort uLength = (ushort)pbData.Length;
|
ushort uLength = (ushort)pbData.Length;
|
||||||
bwOut.Write(uLength);
|
MemUtil.Write(s, MemUtil.UInt16ToBytes(uLength));
|
||||||
|
|
||||||
if(uLength > 0) bwOut.Write(pbData);
|
if(uLength > 0) s.Write(pbData, 0, pbData.Length);
|
||||||
}
|
}
|
||||||
else bwOut.Write((ushort)0);
|
else MemUtil.Write(s, MemUtil.UInt16ToBytes((ushort)0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream AttachStreamEncryptor(Stream s)
|
private Stream AttachStreamEncryptor(Stream s)
|
||||||
{
|
{
|
||||||
using (MemoryStream ms = new MemoryStream())
|
MemoryStream ms = new MemoryStream();
|
||||||
{
|
|
||||||
Debug.Assert(m_pbMasterSeed != null);
|
Debug.Assert(m_pbMasterSeed != null);
|
||||||
Debug.Assert(m_pbMasterSeed.Length == 32);
|
Debug.Assert(m_pbMasterSeed.Length == 32);
|
||||||
ms.Write(m_pbMasterSeed, 0, 32);
|
ms.Write(m_pbMasterSeed, 0, 32);
|
||||||
@@ -214,23 +228,28 @@ namespace ModernKeePassLib.Serialization
|
|||||||
ProtectedBinary pbinKey = m_pwDatabase.MasterKey.GenerateKey32(
|
ProtectedBinary pbinKey = m_pwDatabase.MasterKey.GenerateKey32(
|
||||||
m_pbTransformSeed, m_pwDatabase.KeyEncryptionRounds);
|
m_pbTransformSeed, m_pwDatabase.KeyEncryptionRounds);
|
||||||
Debug.Assert(pbinKey != null);
|
Debug.Assert(pbinKey != null);
|
||||||
if (pbinKey == null)
|
if(pbinKey == null)
|
||||||
throw new SecurityException(KLRes.InvalidCompositeKey);
|
throw new SecurityException(KLRes.InvalidCompositeKey);
|
||||||
byte[] pKey32 = pbinKey.ReadData();
|
byte[] pKey32 = pbinKey.ReadData();
|
||||||
if ((pKey32 == null) || (pKey32.Length != 32))
|
if((pKey32 == null) || (pKey32.Length != 32))
|
||||||
throw new SecurityException(KLRes.InvalidCompositeKey);
|
throw new SecurityException(KLRes.InvalidCompositeKey);
|
||||||
ms.Write(pKey32, 0, 32);
|
ms.Write(pKey32, 0, 32);
|
||||||
|
|
||||||
SHA256Managed sha256 = SHA256Managed.Instance;
|
#if PCL
|
||||||
|
var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
|
||||||
|
var aesKey = sha256.HashData(ms.GetWindowsRuntimeBuffer()).ToArray();
|
||||||
|
#else
|
||||||
|
SHA256Managed sha256 = new SHA256Managed();
|
||||||
byte[] aesKey = sha256.ComputeHash(ms.ToArray());
|
byte[] aesKey = sha256.ComputeHash(ms.ToArray());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ms.Dispose();
|
||||||
Array.Clear(pKey32, 0, 32);
|
Array.Clear(pKey32, 0, 32);
|
||||||
|
|
||||||
Debug.Assert(CipherPool.GlobalPool != null);
|
Debug.Assert(CipherPool.GlobalPool != null);
|
||||||
ICipherEngine iEngine = CipherPool.GlobalPool.GetCipher(m_pwDatabase.DataCipherUuid);
|
ICipherEngine iEngine = CipherPool.GlobalPool.GetCipher(m_pwDatabase.DataCipherUuid);
|
||||||
if(iEngine == null) throw new SecurityException(KLRes.FileUnknownCipher);
|
if(iEngine == null) throw new SecurityException(KLRes.FileUnknownCipher);
|
||||||
return iEngine.EncryptStream(s, aesKey, m_pbEncryptionIV);
|
return iEngine.EncryptStream(s, aesKey, m_pbEncryptionIV);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteDocument(PwGroup pgDataSource)
|
private void WriteDocument(PwGroup pgDataSource)
|
||||||
@@ -245,8 +264,11 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
BinPoolBuild(pgRoot);
|
BinPoolBuild(pgRoot);
|
||||||
|
|
||||||
m_xmlWriter.Settings.Indent = true;
|
#if !PCL
|
||||||
m_xmlWriter.Settings.IndentChars = "\t";
|
m_xmlWriter.Formatting = Formatting.Indented;
|
||||||
|
m_xmlWriter.IndentChar = '\t';
|
||||||
|
m_xmlWriter.Indentation = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
m_xmlWriter.WriteStartDocument(true);
|
m_xmlWriter.WriteStartDocument(true);
|
||||||
m_xmlWriter.WriteStartElement(ElemDocNode);
|
m_xmlWriter.WriteStartElement(ElemDocNode);
|
||||||
@@ -320,6 +342,11 @@ namespace ModernKeePassLib.Serialization
|
|||||||
m_xmlWriter.WriteStartElement(ElemMeta);
|
m_xmlWriter.WriteStartElement(ElemMeta);
|
||||||
|
|
||||||
WriteObject(ElemGenerator, PwDatabase.LocalizedAppName, false); // Generator name
|
WriteObject(ElemGenerator, PwDatabase.LocalizedAppName, false); // Generator name
|
||||||
|
|
||||||
|
if(m_pbHashOfHeader != null)
|
||||||
|
WriteObject(ElemHeaderHash, Convert.ToBase64String(
|
||||||
|
m_pbHashOfHeader), false);
|
||||||
|
|
||||||
WriteObject(ElemDbName, m_pwDatabase.Name, true);
|
WriteObject(ElemDbName, m_pwDatabase.Name, true);
|
||||||
WriteObject(ElemDbNameChanged, m_pwDatabase.NameChanged);
|
WriteObject(ElemDbNameChanged, m_pwDatabase.NameChanged);
|
||||||
WriteObject(ElemDbDesc, m_pwDatabase.Description, true);
|
WriteObject(ElemDbDesc, m_pwDatabase.Description, true);
|
||||||
@@ -361,7 +388,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
WriteObject(ElemNotes, pg.Notes, true);
|
WriteObject(ElemNotes, pg.Notes, true);
|
||||||
WriteObject(ElemIcon, (int)pg.IconId);
|
WriteObject(ElemIcon, (int)pg.IconId);
|
||||||
|
|
||||||
if(pg.CustomIconUuid != PwUuid.Zero)
|
if(!pg.CustomIconUuid.Equals(PwUuid.Zero))
|
||||||
WriteObject(ElemCustomIconID, pg.CustomIconUuid);
|
WriteObject(ElemCustomIconID, pg.CustomIconUuid);
|
||||||
|
|
||||||
WriteList(ElemTimes, pg);
|
WriteList(ElemTimes, pg);
|
||||||
@@ -386,7 +413,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
WriteObject(ElemUuid, pe.Uuid);
|
WriteObject(ElemUuid, pe.Uuid);
|
||||||
WriteObject(ElemIcon, (int)pe.IconId);
|
WriteObject(ElemIcon, (int)pe.IconId);
|
||||||
|
|
||||||
if(pe.CustomIconUuid != PwUuid.Zero)
|
if(!pe.CustomIconUuid.Equals(PwUuid.Zero))
|
||||||
WriteObject(ElemCustomIconID, pe.CustomIconUuid);
|
WriteObject(ElemCustomIconID, pe.CustomIconUuid);
|
||||||
|
|
||||||
WriteObject(ElemFgColor, StrUtil.ColorToUnnamedHtml(pe.ForegroundColor, true), false);
|
WriteObject(ElemFgColor, StrUtil.ColorToUnnamedHtml(pe.ForegroundColor, true), false);
|
||||||
@@ -452,8 +479,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
m_xmlWriter.WriteStartElement(name);
|
m_xmlWriter.WriteStartElement(name);
|
||||||
|
|
||||||
WriteObject(ElemLastModTime, times.LastModificationTime);
|
|
||||||
WriteObject(ElemCreationTime, times.CreationTime);
|
WriteObject(ElemCreationTime, times.CreationTime);
|
||||||
|
WriteObject(ElemLastModTime, times.LastModificationTime);
|
||||||
WriteObject(ElemLastAccessTime, times.LastAccessTime);
|
WriteObject(ElemLastAccessTime, times.LastAccessTime);
|
||||||
WriteObject(ElemExpiryTime, times.ExpiryTime);
|
WriteObject(ElemExpiryTime, times.ExpiryTime);
|
||||||
WriteObject(ElemExpires, times.Expires);
|
WriteObject(ElemExpires, times.Expires);
|
||||||
@@ -575,7 +602,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
Debug.Assert(name != null);
|
Debug.Assert(name != null);
|
||||||
|
|
||||||
m_xmlWriter.WriteStartElement(name);
|
m_xmlWriter.WriteStartElement(name);
|
||||||
m_xmlWriter.WriteString(value.ToString());
|
m_xmlWriter.WriteString(value.ToString(NumberFormatInfo.InvariantInfo));
|
||||||
m_xmlWriter.WriteEndElement();
|
m_xmlWriter.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +611,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
Debug.Assert(name != null);
|
Debug.Assert(name != null);
|
||||||
|
|
||||||
m_xmlWriter.WriteStartElement(name);
|
m_xmlWriter.WriteStartElement(name);
|
||||||
m_xmlWriter.WriteString(value.ToString());
|
m_xmlWriter.WriteString(value.ToString(NumberFormatInfo.InvariantInfo));
|
||||||
m_xmlWriter.WriteEndElement();
|
m_xmlWriter.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,7 +620,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
Debug.Assert(name != null);
|
Debug.Assert(name != null);
|
||||||
|
|
||||||
m_xmlWriter.WriteStartElement(name);
|
m_xmlWriter.WriteStartElement(name);
|
||||||
m_xmlWriter.WriteString(value.ToString());
|
m_xmlWriter.WriteString(value.ToString(NumberFormatInfo.InvariantInfo));
|
||||||
m_xmlWriter.WriteEndElement();
|
m_xmlWriter.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +629,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
Debug.Assert(name != null);
|
Debug.Assert(name != null);
|
||||||
|
|
||||||
m_xmlWriter.WriteStartElement(name);
|
m_xmlWriter.WriteStartElement(name);
|
||||||
m_xmlWriter.WriteString(value.ToString());
|
m_xmlWriter.WriteString(value.ToString(NumberFormatInfo.InvariantInfo));
|
||||||
m_xmlWriter.WriteEndElement();
|
m_xmlWriter.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,7 +684,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
bProtected = m_pwDatabase.MemoryProtection.ProtectNotes;
|
bProtected = m_pwDatabase.MemoryProtection.ProtectNotes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bProtected && (m_format != Kdb4Format.PlainXml))
|
if(bProtected && (m_format != KdbxFormat.PlainXml))
|
||||||
{
|
{
|
||||||
m_xmlWriter.WriteAttributeString(AttrProtected, ValTrue);
|
m_xmlWriter.WriteAttributeString(AttrProtected, ValTrue);
|
||||||
|
|
||||||
@@ -667,7 +694,6 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
string strValue = value.ReadString();
|
string strValue = value.ReadString();
|
||||||
|
|
||||||
// If names should be localized, we need to apply the language-dependent
|
// If names should be localized, we need to apply the language-dependent
|
||||||
@@ -685,7 +711,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
// page area
|
// page area
|
||||||
if(char.IsSymbol(ch) || char.IsSurrogate(ch))
|
if(char.IsSymbol(ch) || char.IsSurrogate(ch))
|
||||||
{
|
{
|
||||||
UnicodeCategory cat = CharUnicodeInfo.GetUnicodeCategory(ch);
|
System.Globalization.UnicodeCategory cat =
|
||||||
|
CharUnicodeInfo.GetUnicodeCategory(ch);
|
||||||
// Map character to correct position in code page
|
// Map character to correct position in code page
|
||||||
chMapped = (char)((int)cat * 32 + ch);
|
chMapped = (char)((int)cat * 32 + ch);
|
||||||
}
|
}
|
||||||
@@ -697,7 +724,11 @@ namespace ModernKeePassLib.Serialization
|
|||||||
// in the low ANSI range (up to 255) when calling
|
// in the low ANSI range (up to 255) when calling
|
||||||
// ToLower on them with invariant culture (see
|
// ToLower on them with invariant culture (see
|
||||||
// http://lists.ximian.com/pipermail/mono-patches/2002-February/086106.html )
|
// http://lists.ximian.com/pipermail/mono-patches/2002-February/086106.html )
|
||||||
|
#if !KeePassLibSD
|
||||||
chMapped = char.ToLowerInvariant(ch);
|
chMapped = char.ToLowerInvariant(ch);
|
||||||
|
#else
|
||||||
|
chMapped = char.ToLower(ch);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -707,8 +738,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
strValue = sb.ToString(); // Correct string for current code page
|
strValue = sb.ToString(); // Correct string for current code page
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((m_format == KdbxFormat.PlainXml) && bProtected)
|
||||||
if((m_format == Kdb4Format.PlainXml) && bProtected)
|
|
||||||
m_xmlWriter.WriteAttributeString(AttrProtectedInMemPlainXml, ValTrue);
|
m_xmlWriter.WriteAttributeString(AttrProtectedInMemPlainXml, ValTrue);
|
||||||
|
|
||||||
m_xmlWriter.WriteString(StrUtil.SafeXmlString(strValue));
|
m_xmlWriter.WriteString(StrUtil.SafeXmlString(strValue));
|
||||||
@@ -742,7 +772,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
private void SubWriteValue(ProtectedBinary value)
|
private void SubWriteValue(ProtectedBinary value)
|
||||||
{
|
{
|
||||||
if(value.IsProtected && (m_format != Kdb4Format.PlainXml))
|
if(value.IsProtected && (m_format != KdbxFormat.PlainXml))
|
||||||
{
|
{
|
||||||
m_xmlWriter.WriteAttributeString(AttrProtected, ValTrue);
|
m_xmlWriter.WriteAttributeString(AttrProtected, ValTrue);
|
||||||
|
|
||||||
@@ -810,8 +840,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
/// to the stream.</returns>
|
/// to the stream.</returns>
|
||||||
public static bool WriteEntries(Stream msOutput, PwEntry[] vEntries)
|
public static bool WriteEntries(Stream msOutput, PwEntry[] vEntries)
|
||||||
{
|
{
|
||||||
/* Kdb4File f = new Kdb4File(pwDatabase);
|
/* KdbxFile f = new KdbxFile(pwDatabase);
|
||||||
f.m_format = Kdb4Format.PlainXml;
|
f.m_format = KdbxFormat.PlainXml;
|
||||||
|
|
||||||
XmlTextWriter xtw = null;
|
XmlTextWriter xtw = null;
|
||||||
try { xtw = new XmlTextWriter(msOutput, StrUtil.Utf8); }
|
try { xtw = new XmlTextWriter(msOutput, StrUtil.Utf8); }
|
||||||
@@ -843,8 +873,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
foreach(PwEntry peCopy in vEntries)
|
foreach(PwEntry peCopy in vEntries)
|
||||||
pd.RootGroup.AddEntry(peCopy.CloneDeep(), true);
|
pd.RootGroup.AddEntry(peCopy.CloneDeep(), true);
|
||||||
|
|
||||||
Kdb4File f = new Kdb4File(pd);
|
KdbxFile f = new KdbxFile(pd);
|
||||||
f.Save(msOutput, null, Kdb4Format.PlainXml, null);
|
f.Save(msOutput, null, KdbxFormat.PlainXml, null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -29,6 +29,10 @@ using System.Diagnostics;
|
|||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PCL
|
||||||
|
using Windows.Storage;
|
||||||
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Collections;
|
using ModernKeePassLib.Collections;
|
||||||
using ModernKeePassLib.Cryptography;
|
using ModernKeePassLib.Cryptography;
|
||||||
using ModernKeePassLib.Delegates;
|
using ModernKeePassLib.Delegates;
|
||||||
@@ -39,10 +43,10 @@ using ModernKeePassLib.Utility;
|
|||||||
namespace ModernKeePassLib.Serialization
|
namespace ModernKeePassLib.Serialization
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <c>Kdb4File</c> class supports saving the data to various
|
/// The <c>KdbxFile</c> class supports saving the data to various
|
||||||
/// formats.
|
/// formats.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum Kdb4Format
|
public enum KdbxFormat
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default, encrypted file format.
|
/// The default, encrypted file format.
|
||||||
@@ -56,37 +60,37 @@ namespace ModernKeePassLib.Serialization
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serialization to KeePass KDB files.
|
/// Serialization to KeePass KDBX files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Kdb4File
|
public sealed partial class KdbxFile
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// File identifier, first 32-bit value.
|
/// File identifier, first 32-bit value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const uint FileSignature1 = 0x9AA2D903;
|
internal const uint FileSignature1 = 0x9AA2D903;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// File identifier, second 32-bit value.
|
/// File identifier, second 32-bit value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const uint FileSignature2 = 0xB54BFB67;
|
internal const uint FileSignature2 = 0xB54BFB67;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// File version of files saved by the current <c>Kdb4File</c> class.
|
/// File version of files saved by the current <c>KdbxFile</c> class.
|
||||||
/// KeePass 2.07 has version 1.01, 2.08 has 1.02, 2.09 has 2.00,
|
/// KeePass 2.07 has version 1.01, 2.08 has 1.02, 2.09 has 2.00,
|
||||||
/// 2.10 has 2.02, 2.11 has 2.04, 2.15 has 3.00.
|
/// 2.10 has 2.02, 2.11 has 2.04, 2.15 has 3.00, 2.20 has 3.01.
|
||||||
/// The first 2 bytes are critical (i.e. loading will fail, if the
|
/// The first 2 bytes are critical (i.e. loading will fail, if the
|
||||||
/// file version is too high), the last 2 bytes are informational.
|
/// file version is too high), the last 2 bytes are informational.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const uint FileVersion32 = 0x00030000;
|
private const uint FileVersion32 = 0x00030001;
|
||||||
|
|
||||||
private const uint FileVersionCriticalMask = 0xFFFF0000;
|
private const uint FileVersionCriticalMask = 0xFFFF0000;
|
||||||
|
|
||||||
// KeePass 1.x signature
|
// KeePass 1.x signature
|
||||||
private const uint FileSignatureOld1 = 0x9AA2D903;
|
internal const uint FileSignatureOld1 = 0x9AA2D903;
|
||||||
private const uint FileSignatureOld2 = 0xB54BFB65;
|
internal const uint FileSignatureOld2 = 0xB54BFB65;
|
||||||
// KeePass 2.x pre-release (alpha and beta) signature
|
// KeePass 2.x pre-release (alpha and beta) signature
|
||||||
private const uint FileSignaturePreRelease1 = 0x9AA2D903;
|
internal const uint FileSignaturePreRelease1 = 0x9AA2D903;
|
||||||
private const uint FileSignaturePreRelease2 = 0xB54BFB66;
|
internal const uint FileSignaturePreRelease2 = 0xB54BFB66;
|
||||||
|
|
||||||
private const string ElemDocNode = "KeePassFile";
|
private const string ElemDocNode = "KeePassFile";
|
||||||
private const string ElemMeta = "Meta";
|
private const string ElemMeta = "Meta";
|
||||||
@@ -95,6 +99,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
private const string ElemEntry = "Entry";
|
private const string ElemEntry = "Entry";
|
||||||
|
|
||||||
private const string ElemGenerator = "Generator";
|
private const string ElemGenerator = "Generator";
|
||||||
|
private const string ElemHeaderHash = "HeaderHash";
|
||||||
private const string ElemDbName = "DatabaseName";
|
private const string ElemDbName = "DatabaseName";
|
||||||
private const string ElemDbNameChanged = "DatabaseNameChanged";
|
private const string ElemDbNameChanged = "DatabaseNameChanged";
|
||||||
private const string ElemDbDesc = "DatabaseDescription";
|
private const string ElemDbDesc = "DatabaseDescription";
|
||||||
@@ -190,9 +195,13 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
private PwDatabase m_pwDatabase; // Not null, see constructor
|
private PwDatabase m_pwDatabase; // Not null, see constructor
|
||||||
|
|
||||||
|
#if PCL
|
||||||
private XmlWriter m_xmlWriter = null;
|
private XmlWriter m_xmlWriter = null;
|
||||||
|
#else
|
||||||
|
private XmlTextWriter m_xmlWriter = null;
|
||||||
|
#endif
|
||||||
private CryptoRandomStream m_randomStream = null;
|
private CryptoRandomStream m_randomStream = null;
|
||||||
private Kdb4Format m_format = Kdb4Format.Default;
|
private KdbxFormat m_format = KdbxFormat.Default;
|
||||||
private IStatusLogger m_slLogger = null;
|
private IStatusLogger m_slLogger = null;
|
||||||
|
|
||||||
private byte[] m_pbMasterSeed = null;
|
private byte[] m_pbMasterSeed = null;
|
||||||
@@ -208,6 +217,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
private Dictionary<string, ProtectedBinary> m_dictBinPool =
|
private Dictionary<string, ProtectedBinary> m_dictBinPool =
|
||||||
new Dictionary<string, ProtectedBinary>();
|
new Dictionary<string, ProtectedBinary>();
|
||||||
|
|
||||||
|
private byte[] m_pbHashOfHeader = null;
|
||||||
private byte[] m_pbHashOfFileOnDisk = null;
|
private byte[] m_pbHashOfFileOnDisk = null;
|
||||||
|
|
||||||
private readonly DateTime m_dtNow = DateTime.Now; // Cache current time
|
private readonly DateTime m_dtNow = DateTime.Now; // Cache current time
|
||||||
@@ -217,7 +227,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
private const uint NeutralLanguageID = NeutralLanguageOffset + NeutralLanguageIDSec;
|
private const uint NeutralLanguageID = NeutralLanguageOffset + NeutralLanguageIDSec;
|
||||||
private static bool m_bLocalizedNames = false;
|
private static bool m_bLocalizedNames = false;
|
||||||
|
|
||||||
private enum Kdb4HeaderFieldID : byte
|
private enum KdbxHeaderFieldID : byte
|
||||||
{
|
{
|
||||||
EndOfHeader = 0,
|
EndOfHeader = 0,
|
||||||
Comment = 1,
|
Comment = 1,
|
||||||
@@ -261,7 +271,7 @@ namespace ModernKeePassLib.Serialization
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pwDataStore">The <c>PwDatabase</c> instance that the
|
/// <param name="pwDataStore">The <c>PwDatabase</c> instance that the
|
||||||
/// class will load file data into or use to create a KDBX file.</param>
|
/// class will load file data into or use to create a KDBX file.</param>
|
||||||
public Kdb4File(PwDatabase pwDataStore)
|
public KdbxFile(PwDatabase pwDataStore)
|
||||||
{
|
{
|
||||||
Debug.Assert(pwDataStore != null);
|
Debug.Assert(pwDataStore != null);
|
||||||
if(pwDataStore == null) throw new ArgumentNullException("pwDataStore");
|
if(pwDataStore == null) throw new ArgumentNullException("pwDataStore");
|
||||||
@@ -322,7 +332,8 @@ namespace ModernKeePassLib.Serialization
|
|||||||
|
|
||||||
if(BinPoolFind(pb) != null) return; // Exists already
|
if(BinPoolFind(pb) != null) return; // Exists already
|
||||||
|
|
||||||
m_dictBinPool.Add(m_dictBinPool.Count.ToString(), pb);
|
m_dictBinPool.Add(m_dictBinPool.Count.ToString(
|
||||||
|
NumberFormatInfo.InvariantInfo), pb);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string BinPoolFind(ProtectedBinary pb)
|
private string BinPoolFind(ProtectedBinary pb)
|
||||||
@@ -350,12 +361,6 @@ namespace ModernKeePassLib.Serialization
|
|||||||
private static void SaveBinary(string strName, ProtectedBinary pb,
|
private static void SaveBinary(string strName, ProtectedBinary pb,
|
||||||
string strSaveDir)
|
string strSaveDir)
|
||||||
{
|
{
|
||||||
// TODO Bert: Needs to be implemented.
|
|
||||||
#if !TODO
|
|
||||||
Debug.Assert(false,"not implemented");
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
|
||||||
if(pb == null) { Debug.Assert(false); return; }
|
if(pb == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(strName)) strName = "File.bin";
|
if(string.IsNullOrEmpty(strName)) strName = "File.bin";
|
||||||
@@ -370,15 +375,28 @@ namespace ModernKeePassLib.Serialization
|
|||||||
string strDesc = UrlUtil.StripExtension(strName);
|
string strDesc = UrlUtil.StripExtension(strName);
|
||||||
|
|
||||||
strPath += strDesc;
|
strPath += strDesc;
|
||||||
if(iTry > 1) strPath += " (" + iTry.ToString() + ")";
|
if(iTry > 1)
|
||||||
|
strPath += " (" + iTry.ToString(NumberFormatInfo.InvariantInfo) +
|
||||||
|
")";
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(strExt)) strPath += "." + strExt;
|
if(!string.IsNullOrEmpty(strExt)) strPath += "." + strExt;
|
||||||
|
|
||||||
++iTry;
|
++iTry;
|
||||||
}
|
}
|
||||||
|
#if PCL
|
||||||
|
while(ApplicationData.Current.RoamingFolder.GetFileAsync(strPath).GetResults() != null);
|
||||||
|
#else
|
||||||
while(File.Exists(strPath));
|
while(File.Exists(strPath));
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if PCL
|
||||||
|
byte[] pbData = pb.ReadData();
|
||||||
|
var file = ApplicationData.Current.RoamingFolder.GetFileAsync(strPath).GetResults();
|
||||||
|
using (var stream = file.OpenAsync(FileAccessMode.ReadWrite).GetResults().AsStream()) {
|
||||||
|
stream.Write (pbData, 0, pbData.Length);
|
||||||
|
}
|
||||||
|
MemUtil.ZeroByteArray(pbData);
|
||||||
|
#elif !KeePassLibSD
|
||||||
byte[] pbData = pb.ReadData();
|
byte[] pbData = pb.ReadData();
|
||||||
File.WriteAllBytes(strPath, pbData);
|
File.WriteAllBytes(strPath, pbData);
|
||||||
MemUtil.ZeroByteArray(pbData);
|
MemUtil.ZeroByteArray(pbData);
|
||||||
@@ -389,9 +407,6 @@ namespace ModernKeePassLib.Serialization
|
|||||||
fs.Write(pbData, 0, pbData.Length);
|
fs.Write(pbData, 0, pbData.Length);
|
||||||
fs.Close();
|
fs.Close();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using ModernKeePassLib.Resources;
|
using ModernKeePassLib.Resources;
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
@@ -41,17 +41,13 @@ namespace ModernKeePassLib.Serialization
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
string str = KLRes.OldFormat + ((m_strFormat.Length > 0) ?
|
string str = KLRes.OldFormat + ((m_strFormat.Length > 0) ?
|
||||||
(@" (" + m_strFormat + @")") : string.Empty) + ".";
|
(@" (" + m_strFormat + @")") : string.Empty) + ".";
|
||||||
|
|
||||||
if(m_type == OldFormatType.KeePass1x)
|
if(m_type == OldFormatType.KeePass1x)
|
||||||
str += MessageService.NewParagraph + KLRes.KeePass1xHint;
|
str += Environment.NewLine + Environment.NewLine + KLRes.KeePass1xHint;
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,21 +17,14 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// BERT TODO: Removed completely for the time being */
|
|
||||||
|
|
||||||
#if TODO
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows.Forms;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using ModernKeePassLib.Utility;
|
using ModernKeePassLib.Utility;
|
||||||
|
|
||||||
@@ -46,8 +39,8 @@ namespace ModernKeePassLib.Translation
|
|||||||
|
|
||||||
private const string m_strControlRelative = @"%c";
|
private const string m_strControlRelative = @"%c";
|
||||||
|
|
||||||
internal const NumberStyles m_nsParser = NumberStyles.AllowLeadingSign |
|
internal const NumberStyles m_nsParser = (NumberStyles.AllowLeadingSign |
|
||||||
NumberStyles.AllowDecimalPoint;
|
NumberStyles.AllowDecimalPoint);
|
||||||
internal static readonly CultureInfo m_lclInv = CultureInfo.InvariantCulture;
|
internal static readonly CultureInfo m_lclInv = CultureInfo.InvariantCulture;
|
||||||
|
|
||||||
private string m_strPosX = string.Empty;
|
private string m_strPosX = string.Empty;
|
||||||
@@ -116,7 +109,7 @@ namespace ModernKeePassLib.Translation
|
|||||||
else { Debug.Assert(false); }
|
else { Debug.Assert(false); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
internal void ApplyTo(Control c)
|
internal void ApplyTo(Control c)
|
||||||
{
|
{
|
||||||
Debug.Assert(c != null); if(c == null) return;
|
Debug.Assert(c != null); if(c == null) return;
|
||||||
@@ -271,7 +264,7 @@ namespace ModernKeePassLib.Translation
|
|||||||
return m_strMemberName.CompareTo(kpOther.Name);
|
return m_strMemberName.CompareTo(kpOther.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
private static readonly Type[] m_vTextControls = new Type[] {
|
private static readonly Type[] m_vTextControls = new Type[] {
|
||||||
typeof(MenuStrip), typeof(PictureBox), typeof(ListView),
|
typeof(MenuStrip), typeof(PictureBox), typeof(ListView),
|
||||||
typeof(TreeView), typeof(ToolStrip), typeof(WebBrowser),
|
typeof(TreeView), typeof(ToolStrip), typeof(WebBrowser),
|
||||||
@@ -313,8 +306,8 @@ namespace ModernKeePassLib.Translation
|
|||||||
|
|
||||||
if(c is Form)
|
if(c is Form)
|
||||||
{
|
{
|
||||||
WriteCpiParam(sb, c.ClientSize.Width.ToString());
|
WriteCpiParam(sb, c.ClientSize.Width.ToString(KpccLayout.m_lclInv));
|
||||||
WriteCpiParam(sb, c.ClientSize.Height.ToString());
|
WriteCpiParam(sb, c.ClientSize.Height.ToString(KpccLayout.m_lclInv));
|
||||||
}
|
}
|
||||||
else // Normal control
|
else // Normal control
|
||||||
{
|
{
|
||||||
@@ -402,5 +395,3 @@ namespace ModernKeePassLib.Translation
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,9 +17,6 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Bert TODO: completely removed for the time being */
|
|
||||||
|
|
||||||
#if TODO
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -69,6 +66,7 @@ namespace ModernKeePassLib.Translation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
private Form m_formEnglish = null;
|
private Form m_formEnglish = null;
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public Form FormEnglish
|
public Form FormEnglish
|
||||||
@@ -77,7 +75,6 @@ namespace ModernKeePassLib.Translation
|
|||||||
set { m_formEnglish = value; }
|
set { m_formEnglish = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !KeePassLibSD
|
|
||||||
public void ApplyTo(Form form)
|
public void ApplyTo(Form form)
|
||||||
{
|
{
|
||||||
Debug.Assert(form != null); if(form == null) throw new ArgumentNullException("form");
|
Debug.Assert(form != null); if(form == null) throw new ArgumentNullException("form");
|
||||||
@@ -107,5 +104,3 @@ namespace ModernKeePassLib.Translation
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //TODO
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,9 +17,6 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* BERT TODO: Completely removed for the time being */
|
|
||||||
|
|
||||||
#if TODO
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -69,7 +66,7 @@ namespace ModernKeePassLib.Translation
|
|||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
public void ApplyTo(ToolStripItemCollection tsic)
|
public void ApplyTo(ToolStripItemCollection tsic)
|
||||||
{
|
{
|
||||||
if(tsic == null) throw new ArgumentNullException("tsic");
|
if(tsic == null) throw new ArgumentNullException("tsic");
|
||||||
@@ -100,5 +97,3 @@ namespace ModernKeePassLib.Translation
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //TODO
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,9 +17,6 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Bert TODO: completely removed for the time being */
|
|
||||||
|
|
||||||
#if TODO
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -156,7 +153,7 @@ namespace ModernKeePassLib.Translation
|
|||||||
return new Dictionary<string, string>();
|
return new Dictionary<string, string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
public void ApplyTo(Form form)
|
public void ApplyTo(Form form)
|
||||||
{
|
{
|
||||||
if(form == null) throw new ArgumentNullException("form");
|
if(form == null) throw new ArgumentNullException("form");
|
||||||
@@ -253,5 +250,3 @@ namespace ModernKeePassLib.Translation
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -49,9 +49,9 @@ namespace ModernKeePassLib.Utility
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
string strDirSep = string.Empty;
|
string strDirSep = string.Empty;
|
||||||
strDirSep += Path.DirectorySeparatorChar;
|
strDirSep += UrlUtil.LocalDirSepChar;
|
||||||
|
|
||||||
string strTemp = Path.GetTempPath();
|
string strTemp = UrlUtil.GetTempPath();
|
||||||
if(!strTemp.EndsWith(strDirSep))
|
if(!strTemp.EndsWith(strDirSep))
|
||||||
strTemp += strDirSep;
|
strTemp += strDirSep;
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
strTime = strTime.Replace(':', '-');
|
strTime = strTime.Replace(':', '-');
|
||||||
|
|
||||||
strPath += strTime + "-" + Environment.TickCount.ToString(
|
strPath += strTime + "-" + Environment.TickCount.ToString(
|
||||||
CultureInfo.InvariantCulture) + ".log.gz";
|
NumberFormatInfo.InvariantInfo) + ".log.gz";
|
||||||
|
|
||||||
FileStream fsOut = new FileStream(strPath, FileMode.Create,
|
FileStream fsOut = new FileStream(strPath, FileMode.Create,
|
||||||
FileAccess.Write, FileShare.None);
|
FileAccess.Write, FileShare.None);
|
||||||
@@ -81,12 +81,8 @@ namespace ModernKeePassLib.Utility
|
|||||||
{
|
{
|
||||||
if(m_swOut == null) return;
|
if(m_swOut == null) return;
|
||||||
|
|
||||||
Debug.Assert(false, "not yet implemented");
|
m_swOut.Dispose();
|
||||||
return;
|
|
||||||
#if TODO
|
|
||||||
m_swOut.Close();
|
|
||||||
m_swOut = null;
|
m_swOut = null;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Log(string strText)
|
public static void Log(string strText)
|
||||||
|
|||||||
57
ModernKeePassLib/Utility/ColorTranslator.cs
Normal file
57
ModernKeePassLib/Utility/ColorTranslator.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace KeePass2PCL.Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Replacement for System.Drawing.ColorTranslator.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Colors are stored in the kdbx database file in HTML format (#XXXXXX).
|
||||||
|
/// </remarks>
|
||||||
|
public static class ColorTranslator
|
||||||
|
{
|
||||||
|
static Regex longForm = new Regex("^#([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts an HTML color value to a Color.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The Color.</returns>
|
||||||
|
/// <param name="htmlColor">HTML color code.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">If htmlColor is null.</exception>
|
||||||
|
/// <exception cref="ArgumentException">If htmlColor did not match the pattern "#XXXXXX".</exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// Currently only understands "#XXXXXX". "#XXX" or named colors will
|
||||||
|
/// throw and exception.
|
||||||
|
/// </remarks>
|
||||||
|
public static Color FromHtml(string htmlColor)
|
||||||
|
{
|
||||||
|
if (htmlColor == null)
|
||||||
|
throw new ArgumentNullException("htmlColor");
|
||||||
|
Match match = longForm.Match(htmlColor);
|
||||||
|
if (match.Success) {
|
||||||
|
var r = int.Parse(match.Groups[1].Value, NumberStyles.HexNumber);
|
||||||
|
var g = int.Parse(match.Groups[2].Value, NumberStyles.HexNumber);
|
||||||
|
var b = int.Parse(match.Groups[3].Value, NumberStyles.HexNumber);
|
||||||
|
return Color.FromArgb(r, g, b);
|
||||||
|
}
|
||||||
|
throw new ArgumentException(string.Format("Could not parse HTML color '{0}'.", htmlColor), "htmlColor");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a color to an HTML color code.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>String containing the color code.</returns>
|
||||||
|
/// <param name="htmlColor">The Color to convert</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// The string is in the format "#XXXXXX"
|
||||||
|
/// </remarks>
|
||||||
|
public static string ToHtml(Color htmlColor)
|
||||||
|
{
|
||||||
|
return string.Format("#{0:x2}{1:x2}{2:x2}", htmlColor.R, htmlColor.G, htmlColor.B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
115
ModernKeePassLib/Utility/GfxUtil.cs
Normal file
115
ModernKeePassLib/Utility/GfxUtil.cs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
|
Copyright (C) 2003-2014 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
|
||||||
|
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.Text;
|
||||||
|
using System.IO;
|
||||||
|
#if KeePass2PCL
|
||||||
|
using Splat;
|
||||||
|
#else
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
#endif
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace KeePass2PCL.Utility
|
||||||
|
{
|
||||||
|
public static class GfxUtil
|
||||||
|
{
|
||||||
|
#if KeePassRT
|
||||||
|
public static Image LoadImage(byte[] pb)
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream(pb, false);
|
||||||
|
try { return Image.FromStream(ms); }
|
||||||
|
finally { ms.Close(); }
|
||||||
|
}
|
||||||
|
#elif KeePass2PCL
|
||||||
|
public static IBitmap LoadImage(byte[] pb)
|
||||||
|
{
|
||||||
|
using (var ms = new MemoryStream(pb, false)) {
|
||||||
|
return BitmapLoader.Current.Load(ms, null, null).Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
public static Image LoadImage(byte[] pb)
|
||||||
|
{
|
||||||
|
if(pb == null) throw new ArgumentNullException("pb");
|
||||||
|
|
||||||
|
MemoryStream ms = new MemoryStream(pb, false);
|
||||||
|
try { return LoadImagePriv(ms); }
|
||||||
|
catch(Exception)
|
||||||
|
{
|
||||||
|
Image imgIco = TryLoadIco(pb);
|
||||||
|
if(imgIco != null) return imgIco;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally { ms.Close(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image LoadImagePriv(Stream s)
|
||||||
|
{
|
||||||
|
// Image.FromStream wants the stream to be open during
|
||||||
|
// the whole lifetime of the image; as we can't guarantee
|
||||||
|
// this, we make a copy of the image
|
||||||
|
Image imgSrc = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#if !KeePassLibSD
|
||||||
|
imgSrc = Image.FromStream(s);
|
||||||
|
Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height,
|
||||||
|
PixelFormat.Format32bppArgb);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bmp.SetResolution(imgSrc.HorizontalResolution,
|
||||||
|
imgSrc.VerticalResolution);
|
||||||
|
Debug.Assert(bmp.Size == imgSrc.Size);
|
||||||
|
}
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
#else
|
||||||
|
imgSrc = new Bitmap(s);
|
||||||
|
Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using(Graphics g = Graphics.FromImage(bmp))
|
||||||
|
{
|
||||||
|
g.Clear(Color.Transparent);
|
||||||
|
g.DrawImage(imgSrc, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
finally { if(imgSrc != null) imgSrc.Dispose(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image TryLoadIco(byte[] pb)
|
||||||
|
{
|
||||||
|
#if !KeePassLibSD
|
||||||
|
MemoryStream ms = new MemoryStream(pb, false);
|
||||||
|
try { return (new Icon(ms)).ToBitmap(); }
|
||||||
|
catch(Exception) { }
|
||||||
|
finally { ms.Close(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,12 +18,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
|
using System.IO.Compression;
|
||||||
#else
|
#else
|
||||||
using ModernKeePassLibSD;
|
using KeePassLibSD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ModernKeePassLib.Utility
|
namespace ModernKeePassLib.Utility
|
||||||
@@ -33,6 +36,73 @@ namespace ModernKeePassLib.Utility
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class MemUtil
|
public static class MemUtil
|
||||||
{
|
{
|
||||||
|
private static readonly uint[] m_vSBox = new uint[256] {
|
||||||
|
0xCD2FACB3, 0xE78A7F5C, 0x6F0803FC, 0xBCF6E230,
|
||||||
|
0x3A321712, 0x06403DB1, 0xD2F84B95, 0xDF22A6E4,
|
||||||
|
0x07CE9E5B, 0x31788A0C, 0xF683F6F4, 0xEA061F49,
|
||||||
|
0xFA5C2ACA, 0x4B9E494E, 0xB0AB25BA, 0x767731FC,
|
||||||
|
0x261893A7, 0x2B09F2CE, 0x046261E4, 0x41367B4B,
|
||||||
|
0x18A7F225, 0x8F923C0E, 0x5EF3A325, 0x28D0435E,
|
||||||
|
0x84C22919, 0xED66873C, 0x8CEDE444, 0x7FC47C24,
|
||||||
|
0xFCFC6BA3, 0x676F928D, 0xB4147187, 0xD8FB126E,
|
||||||
|
0x7D798D17, 0xFF82E424, 0x1712FA5B, 0xABB09DD5,
|
||||||
|
0x8156BA63, 0x84E4D969, 0xC937FB9A, 0x2F1E5BFC,
|
||||||
|
0x178ECA11, 0x0E71CD5F, 0x52AAC6F4, 0x71EEFC8F,
|
||||||
|
0x7090D749, 0x21CACA31, 0x92996378, 0x0939A8A8,
|
||||||
|
0xE9EE1934, 0xD2718616, 0xF2500543, 0xB911873C,
|
||||||
|
0xD3CB3EEC, 0x2BA0DBEB, 0xB42D0A27, 0xECE67C0F,
|
||||||
|
0x302925F0, 0x6114F839, 0xD39E6307, 0xE28970D6,
|
||||||
|
0xEB982F99, 0x941B4CDF, 0xC540E550, 0x8124FC45,
|
||||||
|
0x98B025C7, 0xE2BF90EA, 0x4F57C976, 0xCF546FE4,
|
||||||
|
0x59566DC8, 0xE3F4360D, 0xF5F9D231, 0xD6180B22,
|
||||||
|
0xB54E088A, 0xB5DFE6A6, 0x3637A36F, 0x056E9284,
|
||||||
|
0xAFF8FBC5, 0x19E01648, 0x8611F043, 0xDAE44337,
|
||||||
|
0xF61B6A1C, 0x257ACD9E, 0xDD35F507, 0xEF05CAFA,
|
||||||
|
0x05EB4A83, 0xFC25CA92, 0x0A4728E6, 0x9CF150EF,
|
||||||
|
0xAEEF67DE, 0xA9472337, 0x57C81EFE, 0x3E5E009F,
|
||||||
|
0x02CB03BB, 0x2BA85674, 0xF21DC251, 0x78C34A34,
|
||||||
|
0xABB1F5BF, 0xB95A2FBD, 0x1FB47777, 0x9A96E8AC,
|
||||||
|
0x5D2D2838, 0x55AAC92A, 0x99EE324E, 0x10F6214B,
|
||||||
|
0x58ABDFB1, 0x2008794D, 0xBEC880F0, 0xE75E5341,
|
||||||
|
0x88015C34, 0x352D8FBF, 0x622B7F6C, 0xF5C59EA2,
|
||||||
|
0x1F759D8E, 0xADE56159, 0xCC7B4C25, 0x5B8BC48C,
|
||||||
|
0xB6BD15AF, 0x3C5B5110, 0xE74A7C3D, 0xEE613161,
|
||||||
|
0x156A1C67, 0x72C06817, 0xEA0A6F69, 0x4CECF993,
|
||||||
|
0xCA9D554C, 0x8E20361F, 0x42D396B9, 0x595DE578,
|
||||||
|
0x749D7955, 0xFD1BA5FD, 0x81FC160E, 0xDB97E28C,
|
||||||
|
0x7CF148F7, 0x0B0B3CF5, 0x534DE605, 0x46421066,
|
||||||
|
0xD4B68DD1, 0x9E479CE6, 0xAE667A9D, 0xBC082082,
|
||||||
|
0xB06DD6EF, 0x20F0F23F, 0xB99E1551, 0xF47A2E3A,
|
||||||
|
0x71DA50C6, 0x67B65779, 0x2A8CB376, 0x1EA71EEE,
|
||||||
|
0x29ABCD50, 0xB6EB0C6B, 0x23C10511, 0x6F3F2144,
|
||||||
|
0x6AF23012, 0xF696BD9E, 0xB94099D8, 0xAD5A9C81,
|
||||||
|
0x7A0794FA, 0x7EDF59D6, 0x1E72E574, 0x8561913C,
|
||||||
|
0x4E4D568F, 0xEECB9928, 0x9C124D2E, 0x0848B82C,
|
||||||
|
0xF1CA395F, 0x9DAF43DC, 0xF77EC323, 0x394E9B59,
|
||||||
|
0x7E200946, 0x8B811D68, 0x16DA3305, 0xAB8DE2C3,
|
||||||
|
0xE6C53B64, 0x98C2D321, 0x88A97D81, 0xA7106419,
|
||||||
|
0x8E52F7BF, 0x8ED262AF, 0x7CCA974E, 0xF0933241,
|
||||||
|
0x040DD437, 0xE143B3D4, 0x3019F56F, 0xB741521D,
|
||||||
|
0xF1745362, 0x4C435F9F, 0xB4214D0D, 0x0B0C348B,
|
||||||
|
0x5051D189, 0x4C30447E, 0x7393D722, 0x95CEDD0B,
|
||||||
|
0xDD994E80, 0xC3D22ED9, 0x739CD900, 0x131EB9C4,
|
||||||
|
0xEF1062B2, 0x4F0DE436, 0x52920073, 0x9A7F3D80,
|
||||||
|
0x896E7B1B, 0x2C8BBE5A, 0xBD304F8A, 0xA993E22C,
|
||||||
|
0x134C41A0, 0xFA989E00, 0x39CE9726, 0xFB89FCCF,
|
||||||
|
0xE8FBAC97, 0xD4063FFC, 0x935A2B5A, 0x44C8EE83,
|
||||||
|
0xCB2BC7B6, 0x02989E92, 0x75478BEA, 0x144378D0,
|
||||||
|
0xD853C087, 0x8897A34E, 0xDD23629D, 0xBDE2A2A2,
|
||||||
|
0x581D8ECC, 0x5DA8AEE8, 0xFF8AAFD0, 0xBA2BCF6E,
|
||||||
|
0x4BD98DAC, 0xF2EDB9E4, 0xFA2DC868, 0x47E84661,
|
||||||
|
0xECEB1C7D, 0x41705CA4, 0x5982E4D4, 0xEB5204A1,
|
||||||
|
0xD196CAFB, 0x6414804D, 0x3ABD4B46, 0x8B494C26,
|
||||||
|
0xB432D52B, 0x39C5356B, 0x6EC80BF7, 0x71BE5483,
|
||||||
|
0xCEC4A509, 0xE9411D61, 0x52F341E5, 0xD2E6197B,
|
||||||
|
0x4F02826C, 0xA9E48838, 0xD1F8F247, 0xE4957FB3,
|
||||||
|
0x586CCA99, 0x9A8B6A5B, 0x4998FBEA, 0xF762BE4C,
|
||||||
|
0x90DFE33C, 0x9731511E, 0x88C6A82F, 0xDD65A4D4
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert a hexadecimal string to a byte array. The input string must be
|
/// Convert a hexadecimal string to a byte array. The input string must be
|
||||||
/// even (i.e. its length is a multiple of 2).
|
/// even (i.e. its length is a multiple of 2).
|
||||||
@@ -116,6 +186,63 @@ namespace ModernKeePassLib.Utility
|
|||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decode Base32 strings according to RFC 4648.
|
||||||
|
/// </summary>
|
||||||
|
public static byte[] ParseBase32(string str)
|
||||||
|
{
|
||||||
|
if((str == null) || ((str.Length % 8) != 0))
|
||||||
|
{
|
||||||
|
Debug.Assert(false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong uMaxBits = (ulong)str.Length * 5UL;
|
||||||
|
List<byte> l = new List<byte>((int)(uMaxBits / 8UL) + 1);
|
||||||
|
Debug.Assert(l.Count == 0);
|
||||||
|
|
||||||
|
for(int i = 0; i < str.Length; i += 8)
|
||||||
|
{
|
||||||
|
ulong u = 0;
|
||||||
|
int nBits = 0;
|
||||||
|
|
||||||
|
for(int j = 0; j < 8; ++j)
|
||||||
|
{
|
||||||
|
char ch = str[i + j];
|
||||||
|
if(ch == '=') break;
|
||||||
|
|
||||||
|
ulong uValue;
|
||||||
|
if((ch >= 'A') && (ch <= 'Z'))
|
||||||
|
uValue = (ulong)(ch - 'A');
|
||||||
|
else if((ch >= 'a') && (ch <= 'z'))
|
||||||
|
uValue = (ulong)(ch - 'a');
|
||||||
|
else if((ch >= '2') && (ch <= '7'))
|
||||||
|
uValue = (ulong)(ch - '2') + 26UL;
|
||||||
|
else { Debug.Assert(false); return null; }
|
||||||
|
|
||||||
|
u <<= 5;
|
||||||
|
u += uValue;
|
||||||
|
nBits += 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nBitsTooMany = (nBits % 8);
|
||||||
|
u >>= nBitsTooMany;
|
||||||
|
nBits -= nBitsTooMany;
|
||||||
|
Debug.Assert((nBits % 8) == 0);
|
||||||
|
|
||||||
|
int idxNewBytes = l.Count;
|
||||||
|
while(nBits > 0)
|
||||||
|
{
|
||||||
|
l.Add((byte)(u & 0xFF));
|
||||||
|
u >>= 8;
|
||||||
|
nBits -= 8;
|
||||||
|
}
|
||||||
|
l.Reverse(idxNewBytes, l.Count - idxNewBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return l.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set all bytes in a byte array to zero.
|
/// Set all bytes in a byte array to zero.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -123,7 +250,8 @@ namespace ModernKeePassLib.Utility
|
|||||||
/// to zero.</param>
|
/// to zero.</param>
|
||||||
public static void ZeroByteArray(byte[] pbArray)
|
public static void ZeroByteArray(byte[] pbArray)
|
||||||
{
|
{
|
||||||
Debug.Assert(pbArray != null); if(pbArray == null) throw new ArgumentNullException("pbArray");
|
Debug.Assert(pbArray != null);
|
||||||
|
if(pbArray == null) throw new ArgumentNullException("pbArray");
|
||||||
|
|
||||||
// for(int i = 0; i < pbArray.Length; ++i)
|
// for(int i = 0; i < pbArray.Length; ++i)
|
||||||
// pbArray[i] = 0;
|
// pbArray[i] = 0;
|
||||||
@@ -274,6 +402,31 @@ namespace ModernKeePassLib.Utility
|
|||||||
pbBuffer[nBufferOffset + i] ^= pbSource[nSourceOffset + i];
|
pbBuffer[nBufferOffset + i] ^= pbSource[nSourceOffset + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fast hash that can be used e.g. for hash tables.
|
||||||
|
/// The algorithm might change in the future; do not store
|
||||||
|
/// the hashes for later use.
|
||||||
|
/// </summary>
|
||||||
|
public static uint Hash32(byte[] v, int iStart, int iLength)
|
||||||
|
{
|
||||||
|
uint u = 0x326F637B;
|
||||||
|
|
||||||
|
if(v == null) { Debug.Assert(false); return u; }
|
||||||
|
if(iStart < 0) { Debug.Assert(false); return u; }
|
||||||
|
if(iLength < 0) { Debug.Assert(false); return u; }
|
||||||
|
|
||||||
|
int m = iStart + iLength;
|
||||||
|
if(m > v.Length) { Debug.Assert(false); return u; }
|
||||||
|
|
||||||
|
for(int i = iStart; i < m; ++i)
|
||||||
|
{
|
||||||
|
u ^= m_vSBox[v[i]];
|
||||||
|
u *= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
public static void CopyStream(Stream sSource, Stream sTarget)
|
public static void CopyStream(Stream sSource, Stream sTarget)
|
||||||
{
|
{
|
||||||
Debug.Assert((sSource != null) && (sTarget != null));
|
Debug.Assert((sSource != null) && (sTarget != null));
|
||||||
@@ -282,19 +435,54 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
const int nBufSize = 4096;
|
const int nBufSize = 4096;
|
||||||
byte[] pbBuf = new byte[nBufSize];
|
byte[] pbBuf = new byte[nBufSize];
|
||||||
int nRead;
|
|
||||||
|
|
||||||
while((nRead = sSource.Read(pbBuf, 0, nBufSize)) > 0)
|
while(true)
|
||||||
|
{
|
||||||
|
int nRead = sSource.Read(pbBuf, 0, nBufSize);
|
||||||
|
if(nRead == 0) break;
|
||||||
|
|
||||||
sTarget.Write(pbBuf, 0, nRead);
|
sTarget.Write(pbBuf, 0, nRead);
|
||||||
|
}
|
||||||
|
|
||||||
// Do not close any of the streams
|
// Do not close any of the streams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] Read(Stream s, int nCount)
|
||||||
|
{
|
||||||
|
if(s == null) throw new ArgumentNullException("s");
|
||||||
|
if(nCount < 0) throw new ArgumentOutOfRangeException("nCount");
|
||||||
|
|
||||||
|
byte[] pb = new byte[nCount];
|
||||||
|
int iOffset = 0;
|
||||||
|
while(nCount > 0)
|
||||||
|
{
|
||||||
|
int iRead = s.Read(pb, iOffset, nCount);
|
||||||
|
if(iRead == 0) break;
|
||||||
|
|
||||||
|
iOffset += iRead;
|
||||||
|
nCount -= iRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iOffset != pb.Length)
|
||||||
|
{
|
||||||
|
byte[] pbPart = new byte[iOffset];
|
||||||
|
Array.Copy(pb, pbPart, iOffset);
|
||||||
|
return pbPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Write(Stream s, byte[] pbData)
|
||||||
|
{
|
||||||
|
if(s == null) { Debug.Assert(false); return; }
|
||||||
|
if(pbData == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
s.Write(pbData, 0, pbData.Length);
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] Compress(byte[] pbData)
|
public static byte[] Compress(byte[] pbData)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
if(pbData == null) throw new ArgumentNullException("pbData");
|
if(pbData == null) throw new ArgumentNullException("pbData");
|
||||||
if(pbData.Length == 0) return pbData;
|
if(pbData.Length == 0) return pbData;
|
||||||
|
|
||||||
@@ -302,20 +490,16 @@ namespace ModernKeePassLib.Utility
|
|||||||
GZipStream gz = new GZipStream(msCompressed, CompressionMode.Compress);
|
GZipStream gz = new GZipStream(msCompressed, CompressionMode.Compress);
|
||||||
MemoryStream msSource = new MemoryStream(pbData, false);
|
MemoryStream msSource = new MemoryStream(pbData, false);
|
||||||
MemUtil.CopyStream(msSource, gz);
|
MemUtil.CopyStream(msSource, gz);
|
||||||
gz.Close();
|
gz.Dispose();
|
||||||
msSource.Close();
|
msSource.Dispose();
|
||||||
|
|
||||||
byte[] pbCompressed = msCompressed.ToArray();
|
byte[] pbCompressed = msCompressed.ToArray();
|
||||||
msCompressed.Close();
|
msCompressed.Dispose();
|
||||||
return pbCompressed;
|
return pbCompressed;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] Decompress(byte[] pbCompressed)
|
public static byte[] Decompress(byte[] pbCompressed)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
if(pbCompressed == null) throw new ArgumentNullException("pbCompressed");
|
if(pbCompressed == null) throw new ArgumentNullException("pbCompressed");
|
||||||
if(pbCompressed.Length == 0) return pbCompressed;
|
if(pbCompressed.Length == 0) return pbCompressed;
|
||||||
|
|
||||||
@@ -323,13 +507,12 @@ namespace ModernKeePassLib.Utility
|
|||||||
GZipStream gz = new GZipStream(msCompressed, CompressionMode.Decompress);
|
GZipStream gz = new GZipStream(msCompressed, CompressionMode.Decompress);
|
||||||
MemoryStream msData = new MemoryStream();
|
MemoryStream msData = new MemoryStream();
|
||||||
MemUtil.CopyStream(gz, msData);
|
MemUtil.CopyStream(gz, msData);
|
||||||
gz.Close();
|
gz.Dispose();
|
||||||
msCompressed.Close();
|
msCompressed.Dispose();
|
||||||
|
|
||||||
byte[] pbData = msData.ToArray();
|
byte[] pbData = msData.ToArray();
|
||||||
msData.Close();
|
msData.Dispose();
|
||||||
return pbData;
|
return pbData;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int IndexOf<T>(T[] vHaystack, T[] vNeedle)
|
public static int IndexOf<T>(T[] vHaystack, T[] vNeedle)
|
||||||
@@ -361,11 +544,81 @@ namespace ModernKeePassLib.Utility
|
|||||||
if(v == null) throw new ArgumentNullException("v");
|
if(v == null) throw new ArgumentNullException("v");
|
||||||
if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset");
|
if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset");
|
||||||
if(iLength < 0) throw new ArgumentOutOfRangeException("iLength");
|
if(iLength < 0) throw new ArgumentOutOfRangeException("iLength");
|
||||||
if(iOffset + iLength > v.Length) throw new ArgumentException();
|
if((iOffset + iLength) > v.Length) throw new ArgumentException();
|
||||||
|
|
||||||
T[] r = new T[iLength];
|
T[] r = new T[iLength];
|
||||||
Array.Copy(v, iOffset, r, 0, iLength);
|
Array.Copy(v, iOffset, r, 0, iLength);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<T> Union<T>(IEnumerable<T> a, IEnumerable<T> b,
|
||||||
|
IEqualityComparer<T> cmp)
|
||||||
|
{
|
||||||
|
if(a == null) throw new ArgumentNullException("a");
|
||||||
|
if(b == null) throw new ArgumentNullException("b");
|
||||||
|
|
||||||
|
Dictionary<T, bool> d = ((cmp != null) ?
|
||||||
|
(new Dictionary<T, bool>(cmp)) : (new Dictionary<T, bool>()));
|
||||||
|
|
||||||
|
foreach(T ta in a)
|
||||||
|
{
|
||||||
|
if(d.ContainsKey(ta)) continue; // Prevent duplicates
|
||||||
|
|
||||||
|
d[ta] = true;
|
||||||
|
yield return ta;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(T tb in b)
|
||||||
|
{
|
||||||
|
if(d.ContainsKey(tb)) continue; // Prevent duplicates
|
||||||
|
|
||||||
|
d[tb] = true;
|
||||||
|
yield return tb;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<T> Intersect<T>(IEnumerable<T> a, IEnumerable<T> b,
|
||||||
|
IEqualityComparer<T> cmp)
|
||||||
|
{
|
||||||
|
if(a == null) throw new ArgumentNullException("a");
|
||||||
|
if(b == null) throw new ArgumentNullException("b");
|
||||||
|
|
||||||
|
Dictionary<T, bool> d = ((cmp != null) ?
|
||||||
|
(new Dictionary<T, bool>(cmp)) : (new Dictionary<T, bool>()));
|
||||||
|
|
||||||
|
foreach(T tb in b) { d[tb] = true; }
|
||||||
|
|
||||||
|
foreach(T ta in a)
|
||||||
|
{
|
||||||
|
if(d.Remove(ta)) // Prevent duplicates
|
||||||
|
yield return ta;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<T> Except<T>(IEnumerable<T> a, IEnumerable<T> b,
|
||||||
|
IEqualityComparer<T> cmp)
|
||||||
|
{
|
||||||
|
if(a == null) throw new ArgumentNullException("a");
|
||||||
|
if(b == null) throw new ArgumentNullException("b");
|
||||||
|
|
||||||
|
Dictionary<T, bool> d = ((cmp != null) ?
|
||||||
|
(new Dictionary<T, bool>(cmp)) : (new Dictionary<T, bool>()));
|
||||||
|
|
||||||
|
foreach(T tb in b) { d[tb] = true; }
|
||||||
|
|
||||||
|
foreach(T ta in a)
|
||||||
|
{
|
||||||
|
if(d.ContainsKey(ta)) continue;
|
||||||
|
|
||||||
|
d[ta] = true; // Prevent duplicates
|
||||||
|
yield return ta;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,9 +17,6 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* BERT TODO: All removed for the time being */
|
|
||||||
|
|
||||||
#if false
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
@@ -121,7 +118,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
Exception exObj = (obj as Exception);
|
Exception exObj = (obj as Exception);
|
||||||
string strObj = (obj as string);
|
string strObj = (obj as string);
|
||||||
#if !KeePassLibSD
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
StringCollection scObj = (obj as StringCollection);
|
StringCollection scObj = (obj as StringCollection);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -132,7 +129,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
else if((exObj.Message != null) && (exObj.Message.Length > 0))
|
else if((exObj.Message != null) && (exObj.Message.Length > 0))
|
||||||
strAppend = exObj.Message;
|
strAppend = exObj.Message;
|
||||||
}
|
}
|
||||||
#if !KeePassLibSD
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
else if(scObj != null)
|
else if(scObj != null)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
@@ -161,25 +158,31 @@ namespace ModernKeePassLib.Utility
|
|||||||
return sbText.ToString();
|
return sbText.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DialogResult SafeShowMessageBox(string strText, string strTitle,
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
|
internal static Form GetTopForm()
|
||||||
|
{
|
||||||
|
FormCollection fc = Application.OpenForms;
|
||||||
|
if((fc == null) || (fc.Count == 0)) return null;
|
||||||
|
|
||||||
|
return fc[fc.Count - 1];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
internal static DialogResult SafeShowMessageBox(string strText, string strTitle,
|
||||||
MessageBoxButtons mb, MessageBoxIcon mi, MessageBoxDefaultButton mdb)
|
MessageBoxButtons mb, MessageBoxIcon mi, MessageBoxDefaultButton mdb)
|
||||||
{
|
{
|
||||||
#if KeePassLibSD
|
#if (KeePassLibSD || KeePassRT)
|
||||||
return MessageBox.Show(strText, strTitle, mb, mi, mdb);
|
return MessageBox.Show(strText, strTitle, mb, mi, mdb);
|
||||||
#else
|
#else
|
||||||
IWin32Window wnd = null;
|
IWin32Window wnd = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FormCollection fc = Application.OpenForms;
|
Form f = GetTopForm();
|
||||||
if((fc != null) && (fc.Count > 0))
|
|
||||||
{
|
|
||||||
Form f = fc[fc.Count - 1];
|
|
||||||
if((f != null) && f.InvokeRequired)
|
if((f != null) && f.InvokeRequired)
|
||||||
return (DialogResult)f.Invoke(new SafeShowMessageBoxInternalDelegate(
|
return (DialogResult)f.Invoke(new SafeShowMessageBoxInternalDelegate(
|
||||||
SafeShowMessageBoxInternal), f, strText, strTitle, mb, mi, mdb);
|
SafeShowMessageBoxInternal), f, strText, strTitle, mb, mi, mdb);
|
||||||
else wnd = f;
|
else wnd = f;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch(Exception) { Debug.Assert(false); }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
if(wnd == null)
|
if(wnd == null)
|
||||||
@@ -203,7 +206,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
internal delegate DialogResult SafeShowMessageBoxInternalDelegate(IWin32Window iParent,
|
internal delegate DialogResult SafeShowMessageBoxInternalDelegate(IWin32Window iParent,
|
||||||
string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi,
|
string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi,
|
||||||
MessageBoxDefaultButton mdb);
|
MessageBoxDefaultButton mdb);
|
||||||
@@ -318,7 +321,8 @@ namespace ModernKeePassLib.Utility
|
|||||||
return dr;
|
return dr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool AskYesNo(string strText, string strTitle, bool bDefaultToYes)
|
public static bool AskYesNo(string strText, string strTitle, bool bDefaultToYes,
|
||||||
|
MessageBoxIcon mbi)
|
||||||
{
|
{
|
||||||
++m_uCurrentMessageCount;
|
++m_uCurrentMessageCount;
|
||||||
|
|
||||||
@@ -327,24 +331,29 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
if(MessageService.MessageShowing != null)
|
if(MessageService.MessageShowing != null)
|
||||||
MessageService.MessageShowing(null, new MessageServiceEventArgs(
|
MessageService.MessageShowing(null, new MessageServiceEventArgs(
|
||||||
strTitleEx, strTextEx, MessageBoxButtons.YesNo, m_mbiQuestion));
|
strTitleEx, strTextEx, MessageBoxButtons.YesNo, mbi));
|
||||||
|
|
||||||
DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx,
|
DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx,
|
||||||
MessageBoxButtons.YesNo, m_mbiQuestion, bDefaultToYes ?
|
MessageBoxButtons.YesNo, mbi, bDefaultToYes ?
|
||||||
MessageBoxDefaultButton.Button1 : MessageBoxDefaultButton.Button2);
|
MessageBoxDefaultButton.Button1 : MessageBoxDefaultButton.Button2);
|
||||||
|
|
||||||
--m_uCurrentMessageCount;
|
--m_uCurrentMessageCount;
|
||||||
return (dr == DialogResult.Yes);
|
return (dr == DialogResult.Yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool AskYesNo(string strText, string strTitle, bool bDefaultToYes)
|
||||||
|
{
|
||||||
|
return AskYesNo(strText, strTitle, bDefaultToYes, m_mbiQuestion);
|
||||||
|
}
|
||||||
|
|
||||||
public static bool AskYesNo(string strText, string strTitle)
|
public static bool AskYesNo(string strText, string strTitle)
|
||||||
{
|
{
|
||||||
return AskYesNo(strText, strTitle, true);
|
return AskYesNo(strText, strTitle, true, m_mbiQuestion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool AskYesNo(string strText)
|
public static bool AskYesNo(string strText)
|
||||||
{
|
{
|
||||||
return AskYesNo(strText, null, true);
|
return AskYesNo(strText, null, true, m_mbiQuestion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShowLoadWarning(string strFilePath, Exception ex)
|
public static void ShowLoadWarning(string strFilePath, Exception ex)
|
||||||
@@ -423,5 +432,3 @@ namespace ModernKeePassLib.Utility
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // false
|
|
||||||
|
|||||||
324
ModernKeePassLib/Utility/MonoWorkarounds.cs
Normal file
324
ModernKeePassLib/Utility/MonoWorkarounds.cs
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
/*
|
||||||
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
|
Copyright (C) 2003-2014 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
|
||||||
|
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.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
using KeePass2PCL.Native;
|
||||||
|
|
||||||
|
namespace KeePass2PCL.Utility
|
||||||
|
{
|
||||||
|
public static class MonoWorkarounds
|
||||||
|
{
|
||||||
|
private static bool? m_bReq = null;
|
||||||
|
public static bool IsRequired()
|
||||||
|
{
|
||||||
|
if(!m_bReq.HasValue) m_bReq = NativeLib.IsUnix();
|
||||||
|
return m_bReq.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1245:
|
||||||
|
// Key events not raised while Alt is down, and nav keys out of order.
|
||||||
|
// https://sourceforge.net/p/keepass/bugs/1245/
|
||||||
|
// 1254:
|
||||||
|
// NumericUpDown bug: text is drawn below up/down buttons.
|
||||||
|
// https://sourceforge.net/p/keepass/bugs/1254/
|
||||||
|
// 5795:
|
||||||
|
// Text in input field is incomplete.
|
||||||
|
// https://bugzilla.xamarin.com/show_bug.cgi?id=5795
|
||||||
|
// https://sourceforge.net/p/keepass/discussion/329220/thread/d23dc88b/
|
||||||
|
// 10163:
|
||||||
|
// WebRequest GetResponse call missing, breaks WebDAV due to no PUT.
|
||||||
|
// https://bugzilla.xamarin.com/show_bug.cgi?id=10163
|
||||||
|
// https://sourceforge.net/p/keepass/bugs/1117/
|
||||||
|
// https://sourceforge.net/p/keepass/discussion/329221/thread/9422258c/
|
||||||
|
// https://github.com/mono/mono/commit/8e67b8c2fc7cb66bff7816ebf7c1039fb8cfc43b
|
||||||
|
// https://bugzilla.xamarin.com/show_bug.cgi?id=1512
|
||||||
|
// https://sourceforge.net/p/keepass/patches/89/
|
||||||
|
// 12525:
|
||||||
|
// PictureBox not rendered when bitmap height >= control height.
|
||||||
|
// https://bugzilla.xamarin.com/show_bug.cgi?id=12525
|
||||||
|
// https://sourceforge.net/p/keepass/discussion/329220/thread/54f61e9a/
|
||||||
|
// 586901:
|
||||||
|
// RichTextBox doesn't handle Unicode string correctly.
|
||||||
|
// https://bugzilla.novell.com/show_bug.cgi?id=586901
|
||||||
|
// 620618:
|
||||||
|
// ListView column headers not drawn.
|
||||||
|
// https://bugzilla.novell.com/show_bug.cgi?id=620618
|
||||||
|
// 649266:
|
||||||
|
// Calling Control.Hide doesn't remove the application from taskbar.
|
||||||
|
// https://bugzilla.novell.com/show_bug.cgi?id=649266
|
||||||
|
// 686017:
|
||||||
|
// Minimum sizes must be enforced.
|
||||||
|
// http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=686017
|
||||||
|
// 801414:
|
||||||
|
// Mono recreates the main window incorrectly.
|
||||||
|
// https://bugs.launchpad.net/ubuntu/+source/keepass2/+bug/801414
|
||||||
|
// 891029:
|
||||||
|
// Increase tab control height, otherwise Mono throws exceptions.
|
||||||
|
// https://sourceforge.net/projects/keepass/forums/forum/329221/topic/4519750
|
||||||
|
// https://bugs.launchpad.net/ubuntu/+source/keepass2/+bug/891029
|
||||||
|
// 836428016:
|
||||||
|
// ListView group header selection unsupported.
|
||||||
|
// https://sourceforge.net/p/keepass/discussion/329221/thread/31dae0f0/
|
||||||
|
// 3574233558:
|
||||||
|
// Problems with minimizing windows, no content rendered.
|
||||||
|
// https://sourceforge.net/p/keepass/discussion/329220/thread/d50a79d6/
|
||||||
|
public static bool IsRequired(uint uBugID)
|
||||||
|
{
|
||||||
|
if(!MonoWorkarounds.IsRequired()) return false;
|
||||||
|
|
||||||
|
ulong v = NativeLib.MonoVersion;
|
||||||
|
if(v != 0)
|
||||||
|
{
|
||||||
|
if(uBugID == 10163)
|
||||||
|
return (v >= 0x0002000B00000000UL); // >= 2.11
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ApplyTo(Form f)
|
||||||
|
{
|
||||||
|
if(!MonoWorkarounds.IsRequired()) return;
|
||||||
|
if(f == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
|
f.HandleCreated += MonoWorkarounds.OnFormHandleCreated;
|
||||||
|
SetWmClass(f);
|
||||||
|
|
||||||
|
ApplyToControlsRec(f.Controls, f, MonoWorkarounds.ApplyToControl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Release(Form f)
|
||||||
|
{
|
||||||
|
if(!MonoWorkarounds.IsRequired()) return;
|
||||||
|
if(f == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
|
f.HandleCreated -= MonoWorkarounds.OnFormHandleCreated;
|
||||||
|
|
||||||
|
ApplyToControlsRec(f.Controls, f, MonoWorkarounds.ReleaseControl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (!KeePassLibSD && !KeePassRT)
|
||||||
|
private delegate void MwaControlHandler(Control c, Form fContext);
|
||||||
|
|
||||||
|
private static void ApplyToControlsRec(Control.ControlCollection cc,
|
||||||
|
Form fContext, MwaControlHandler fn)
|
||||||
|
{
|
||||||
|
if(cc == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
foreach(Control c in cc)
|
||||||
|
{
|
||||||
|
fn(c, fContext);
|
||||||
|
ApplyToControlsRec(c.Controls, fContext, fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyToControl(Control c, Form fContext)
|
||||||
|
{
|
||||||
|
Button btn = (c as Button);
|
||||||
|
if(btn != null) ApplyToButton(btn, fContext);
|
||||||
|
|
||||||
|
NumericUpDown nc = (c as NumericUpDown);
|
||||||
|
if((nc != null) && MonoWorkarounds.IsRequired(1254))
|
||||||
|
{
|
||||||
|
if(nc.TextAlign == HorizontalAlignment.Right)
|
||||||
|
nc.TextAlign = HorizontalAlignment.Left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class MwaHandlerInfo
|
||||||
|
{
|
||||||
|
private readonly Delegate m_fnOrg; // May be null
|
||||||
|
public Delegate FunctionOriginal
|
||||||
|
{
|
||||||
|
get { return m_fnOrg; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Delegate m_fnOvr;
|
||||||
|
public Delegate FunctionOverride
|
||||||
|
{
|
||||||
|
get { return m_fnOvr; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly DialogResult m_dr;
|
||||||
|
public DialogResult Result
|
||||||
|
{
|
||||||
|
get { return m_dr; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Form m_fContext;
|
||||||
|
public Form FormContext
|
||||||
|
{
|
||||||
|
get { return m_fContext; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public MwaHandlerInfo(Delegate fnOrg, Delegate fnOvr, DialogResult dr,
|
||||||
|
Form fContext)
|
||||||
|
{
|
||||||
|
m_fnOrg = fnOrg;
|
||||||
|
m_fnOvr = fnOvr;
|
||||||
|
m_dr = dr;
|
||||||
|
m_fContext = fContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EventHandlerList GetEventHandlers(Component c,
|
||||||
|
out object objClickEvent)
|
||||||
|
{
|
||||||
|
FieldInfo fi = typeof(Control).GetField("ClickEvent", // Mono
|
||||||
|
BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if(fi == null)
|
||||||
|
fi = typeof(Control).GetField("EventClick", // .NET
|
||||||
|
BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
if(fi == null) { Debug.Assert(false); objClickEvent = null; return null; }
|
||||||
|
|
||||||
|
objClickEvent = fi.GetValue(null);
|
||||||
|
if(objClickEvent == null) { Debug.Assert(false); return null; }
|
||||||
|
|
||||||
|
PropertyInfo pi = typeof(Component).GetProperty("Events",
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
return (pi.GetValue(c, null) as EventHandlerList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<object, MwaHandlerInfo> m_dictHandlers =
|
||||||
|
new Dictionary<object, MwaHandlerInfo>();
|
||||||
|
private static void ApplyToButton(Button btn, Form fContext)
|
||||||
|
{
|
||||||
|
DialogResult dr = btn.DialogResult;
|
||||||
|
if(dr == DialogResult.None) return; // No workaround required
|
||||||
|
|
||||||
|
object objClickEvent;
|
||||||
|
EventHandlerList ehl = GetEventHandlers(btn, out objClickEvent);
|
||||||
|
if(ehl == null) { Debug.Assert(false); return; }
|
||||||
|
Delegate fnClick = ehl[objClickEvent]; // May be null
|
||||||
|
|
||||||
|
EventHandler fnOvr = new EventHandler(MonoWorkarounds.OnButtonClick);
|
||||||
|
m_dictHandlers[btn] = new MwaHandlerInfo(fnClick, fnOvr, dr, fContext);
|
||||||
|
|
||||||
|
btn.DialogResult = DialogResult.None;
|
||||||
|
if(fnClick != null) ehl.RemoveHandler(objClickEvent, fnClick);
|
||||||
|
ehl[objClickEvent] = fnOvr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ReleaseControl(Control c, Form fContext)
|
||||||
|
{
|
||||||
|
Button btn = (c as Button);
|
||||||
|
if(btn != null) ReleaseButton(btn, fContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ReleaseButton(Button btn, Form fContext)
|
||||||
|
{
|
||||||
|
MwaHandlerInfo hi;
|
||||||
|
m_dictHandlers.TryGetValue(btn, out hi);
|
||||||
|
if(hi == null) return;
|
||||||
|
|
||||||
|
object objClickEvent;
|
||||||
|
EventHandlerList ehl = GetEventHandlers(btn, out objClickEvent);
|
||||||
|
if(ehl == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
ehl.RemoveHandler(objClickEvent, hi.FunctionOverride);
|
||||||
|
if(hi.FunctionOriginal != null)
|
||||||
|
ehl[objClickEvent] = hi.FunctionOriginal;
|
||||||
|
|
||||||
|
btn.DialogResult = hi.Result;
|
||||||
|
m_dictHandlers.Remove(btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnButtonClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Button btn = (sender as Button);
|
||||||
|
if(btn == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
MwaHandlerInfo hi;
|
||||||
|
m_dictHandlers.TryGetValue(btn, out hi);
|
||||||
|
if(hi == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
Form f = hi.FormContext;
|
||||||
|
|
||||||
|
// Set current dialog result by setting the form's private
|
||||||
|
// variable; the DialogResult property can't be used,
|
||||||
|
// because it raises close events
|
||||||
|
FieldInfo fiRes = typeof(Form).GetField("dialog_result",
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
if(fiRes == null) { Debug.Assert(false); return; }
|
||||||
|
if(f != null) fiRes.SetValue(f, hi.Result);
|
||||||
|
|
||||||
|
if(hi.FunctionOriginal != null)
|
||||||
|
hi.FunctionOriginal.Method.Invoke(hi.FunctionOriginal.Target,
|
||||||
|
new object[] { btn, e });
|
||||||
|
|
||||||
|
// Raise close events, if the click event handler hasn't
|
||||||
|
// reset the dialog result
|
||||||
|
if((f != null) && (f.DialogResult == hi.Result))
|
||||||
|
f.DialogResult = hi.Result; // Raises close events
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetWmClass(Form f)
|
||||||
|
{
|
||||||
|
NativeMethods.SetWmClass(f, PwDefs.UnixName, PwDefs.ResClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnFormHandleCreated(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Form f = (sender as Form);
|
||||||
|
if(f == null) { Debug.Assert(false); return; }
|
||||||
|
|
||||||
|
if(!f.IsHandleCreated) return; // Prevent infinite loop
|
||||||
|
|
||||||
|
SetWmClass(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the value of the private <c>shown_raised</c> member
|
||||||
|
/// variable of a form.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Previous <c>shown_raised</c> value.</returns>
|
||||||
|
internal static bool ExchangeFormShownRaised(Form f, bool bNewValue)
|
||||||
|
{
|
||||||
|
if(f == null) { Debug.Assert(false); return true; }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FieldInfo fi = typeof(Form).GetField("shown_raised",
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
if(fi == null) { Debug.Assert(false); return true; }
|
||||||
|
|
||||||
|
bool bPrevious = (bool)fi.GetValue(f);
|
||||||
|
|
||||||
|
fi.SetValue(f, bNewValue);
|
||||||
|
|
||||||
|
return bPrevious;
|
||||||
|
}
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,15 +18,27 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
//using System.Drawing;
|
|
||||||
using ModernKeePassLib.WinRTAdaptors;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
#if PCL
|
||||||
|
using Windows.Security.Cryptography;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Security.Cryptography.DataProtection;
|
||||||
|
using Windows.Storage.Streams;
|
||||||
|
using Windows.UI;
|
||||||
using ModernKeePassLib.Collections;
|
using ModernKeePassLib.Collections;
|
||||||
|
using ModernKeePassLib.Cryptography.PasswordGenerator;
|
||||||
using ModernKeePassLib.Security;
|
using ModernKeePassLib.Security;
|
||||||
|
using ModernKeePassLib.Resources;
|
||||||
|
using UnicodeEncoding = System.Text.UnicodeEncoding;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Utility
|
namespace ModernKeePassLib.Utility
|
||||||
{
|
{
|
||||||
@@ -208,13 +220,14 @@ namespace ModernKeePassLib.Utility
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if(m_lEncs == null)
|
if(m_lEncs != null) return m_lEncs;
|
||||||
{
|
|
||||||
m_lEncs = new List<StrEncodingInfo>();
|
|
||||||
#if !KeePassWinRT
|
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Default,
|
|
||||||
|
|
||||||
|
List<StrEncodingInfo> l = new List<StrEncodingInfo>();
|
||||||
|
|
||||||
|
l.Add(new StrEncodingInfo(StrEncodingType.Default,
|
||||||
|
#if PCL || KeePassRT
|
||||||
|
StrUtil.Utf8.WebName, StrUtil.Utf8, 1, null));
|
||||||
|
#else
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
Encoding.Default.EncodingName,
|
Encoding.Default.EncodingName,
|
||||||
#else
|
#else
|
||||||
@@ -222,39 +235,32 @@ namespace ModernKeePassLib.Utility
|
|||||||
#endif
|
#endif
|
||||||
Encoding.Default,
|
Encoding.Default,
|
||||||
(uint)Encoding.Default.GetBytes("a").Length, null));
|
(uint)Encoding.Default.GetBytes("a").Length, null));
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Ascii,
|
#endif
|
||||||
|
#if !PCL && !KeePassRT
|
||||||
|
l.Add(new StrEncodingInfo(StrEncodingType.Ascii,
|
||||||
"ASCII", Encoding.ASCII, 1, null));
|
"ASCII", Encoding.ASCII, 1, null));
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Utf7,
|
l.Add(new StrEncodingInfo(StrEncodingType.Utf7,
|
||||||
"Unicode (UTF-7)", Encoding.UTF7, 1, null));
|
"Unicode (UTF-7)", Encoding.UTF7, 1, null));
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Utf8,
|
#endif
|
||||||
|
l.Add(new StrEncodingInfo(StrEncodingType.Utf8,
|
||||||
"Unicode (UTF-8)", StrUtil.Utf8, 1, new byte[] { 0xEF, 0xBB, 0xBF }));
|
"Unicode (UTF-8)", StrUtil.Utf8, 1, new byte[] { 0xEF, 0xBB, 0xBF }));
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Utf16LE,
|
l.Add(new StrEncodingInfo(StrEncodingType.Utf16LE,
|
||||||
"Unicode (UTF-16 LE)", new UnicodeEncoding(false, false),
|
"Unicode (UTF-16 LE)", new UnicodeEncoding(false, false),
|
||||||
2, new byte[] { 0xFF, 0xFE }));
|
2, new byte[] { 0xFF, 0xFE }));
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Utf16BE,
|
l.Add(new StrEncodingInfo(StrEncodingType.Utf16BE,
|
||||||
"Unicode (UTF-16 BE)", new UnicodeEncoding(true, false),
|
"Unicode (UTF-16 BE)", new UnicodeEncoding(true, false),
|
||||||
2, new byte[] { 0xFE, 0xFF }));
|
2, new byte[] { 0xFE, 0xFF }));
|
||||||
#if !KeePassLibSD
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Utf32LE,
|
l.Add(new StrEncodingInfo(StrEncodingType.Utf32LE,
|
||||||
"Unicode (UTF-32 LE)", new UTF32Encoding(false, false),
|
"Unicode (UTF-32 LE)", new UTF32Encoding(false, false),
|
||||||
4, new byte[] { 0xFF, 0xFE, 0x0, 0x0 }));
|
4, new byte[] { 0xFF, 0xFE, 0x0, 0x0 }));
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Utf32BE,
|
l.Add(new StrEncodingInfo(StrEncodingType.Utf32BE,
|
||||||
"Unicode (UTF-32 BE)", new UTF32Encoding(true, false),
|
"Unicode (UTF-32 BE)", new UTF32Encoding(true, false),
|
||||||
4, new byte[] { 0x0, 0x0, 0xFE, 0xFF }));
|
4, new byte[] { 0x0, 0x0, 0xFE, 0xFF }));
|
||||||
#endif
|
#endif
|
||||||
#else // KeePassWinRT
|
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Utf8,
|
|
||||||
"Unicode (UTF-8)", StrUtil.Utf8, 1, new byte[] { 0xEF, 0xBB, 0xBF }));
|
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Utf16LE,
|
|
||||||
"Unicode (UTF-16 LE)", new UnicodeEncoding(false, false),
|
|
||||||
2, new byte[] { 0xFF, 0xFE }));
|
|
||||||
m_lEncs.Add(new StrEncodingInfo(StrEncodingType.Utf16BE,
|
|
||||||
"Unicode (UTF-16 BE)", new UnicodeEncoding(true, false),
|
|
||||||
2, new byte[] { 0xFE, 0xFF }));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_lEncs;
|
m_lEncs = l;
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,16 +288,21 @@ namespace ModernKeePassLib.Utility
|
|||||||
// {
|
// {
|
||||||
// char ch = str[i];
|
// char ch = str[i];
|
||||||
// if((int)ch >= 256)
|
// if((int)ch >= 256)
|
||||||
// {
|
// sbEncoded.Append(StrUtil.RtfEncodeChar(ch));
|
||||||
// sbEncoded.Append("\\u");
|
|
||||||
// sbEncoded.Append((int)ch);
|
|
||||||
// sbEncoded.Append('?');
|
|
||||||
// }
|
|
||||||
// else sbEncoded.Append(ch);
|
// else sbEncoded.Append(ch);
|
||||||
// }
|
// }
|
||||||
// return sbEncoded.ToString();
|
// return sbEncoded.ToString();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
public static string RtfEncodeChar(char ch)
|
||||||
|
{
|
||||||
|
// Unicode character values must be encoded using
|
||||||
|
// 16-bit numbers (decimal); Unicode values greater
|
||||||
|
// than 32767 must be expressed as negative numbers
|
||||||
|
short sh = (short)ch;
|
||||||
|
return ("\\u" + sh.ToString(NumberFormatInfo.InvariantInfo) + "?");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert a string into a valid HTML sequence representing that string.
|
/// Convert a string into a valid HTML sequence representing that string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -308,7 +319,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
str = str.Replace("\'", @"'");
|
str = str.Replace("\'", @"'");
|
||||||
|
|
||||||
str = NormalizeNewLines(str, false);
|
str = NormalizeNewLines(str, false);
|
||||||
str = str.Replace("\n", @"<br />");
|
str = str.Replace("\n", @"<br />" + Environment.NewLine);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -479,59 +490,59 @@ namespace ModernKeePassLib.Utility
|
|||||||
/// <returns>String representing the exception.</returns>
|
/// <returns>String representing the exception.</returns>
|
||||||
public static string FormatException(Exception excp)
|
public static string FormatException(Exception excp)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return "";
|
|
||||||
#if TODO
|
|
||||||
string strText = string.Empty;
|
string strText = string.Empty;
|
||||||
|
|
||||||
if(excp.Message != null)
|
if(excp.Message != null)
|
||||||
strText += excp.Message + MessageService.NewLine;
|
strText += excp.Message + Environment.NewLine;
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
if(excp.Source != null)
|
if(excp.Source != null)
|
||||||
strText += excp.Source + MessageService.NewLine;
|
strText += excp.Source + Environment.NewLine;
|
||||||
#endif
|
#endif
|
||||||
if(excp.StackTrace != null)
|
if(excp.StackTrace != null)
|
||||||
strText += excp.StackTrace + MessageService.NewLine;
|
strText += excp.StackTrace + Environment.NewLine;
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
|
#if !PCL && !KeePassRT
|
||||||
if(excp.TargetSite != null)
|
if(excp.TargetSite != null)
|
||||||
strText += excp.TargetSite.ToString() + MessageService.NewLine;
|
strText += excp.TargetSite.ToString() + MessageService.NewLine;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(excp.Data != null)
|
if(excp.Data != null)
|
||||||
{
|
{
|
||||||
strText += MessageService.NewLine;
|
strText += Environment.NewLine;
|
||||||
foreach(DictionaryEntry de in excp.Data)
|
foreach(DictionaryEntry de in excp.Data)
|
||||||
strText += @"'" + de.Key + @"' -> '" + de.Value + @"'" +
|
strText += @"'" + de.Key + @"' -> '" + de.Value + @"'" +
|
||||||
MessageService.NewLine;
|
Environment.NewLine;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(excp.InnerException != null)
|
if(excp.InnerException != null)
|
||||||
{
|
{
|
||||||
strText += MessageService.NewLine + "Inner:" + MessageService.NewLine;
|
strText += Environment.NewLine + "Inner:" + Environment.NewLine;
|
||||||
if(excp.InnerException.Message != null)
|
if(excp.InnerException.Message != null)
|
||||||
strText += excp.InnerException.Message + MessageService.NewLine;
|
strText += excp.InnerException.Message + Environment.NewLine;
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
if(excp.InnerException.Source != null)
|
if(excp.InnerException.Source != null)
|
||||||
strText += excp.InnerException.Source + MessageService.NewLine;
|
strText += excp.InnerException.Source + Environment.NewLine;
|
||||||
#endif
|
#endif
|
||||||
if(excp.InnerException.StackTrace != null)
|
if(excp.InnerException.StackTrace != null)
|
||||||
strText += excp.InnerException.StackTrace + MessageService.NewLine;
|
strText += excp.InnerException.StackTrace + Environment.NewLine;
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
|
#if !PCL && !KeePassRT
|
||||||
if(excp.InnerException.TargetSite != null)
|
if(excp.InnerException.TargetSite != null)
|
||||||
strText += excp.InnerException.TargetSite.ToString();
|
strText += excp.InnerException.TargetSite.ToString();
|
||||||
|
#endif
|
||||||
|
|
||||||
if(excp.InnerException.Data != null)
|
if(excp.InnerException.Data != null)
|
||||||
{
|
{
|
||||||
strText += MessageService.NewLine;
|
strText += Environment.NewLine;
|
||||||
foreach(DictionaryEntry de in excp.InnerException.Data)
|
foreach(DictionaryEntry de in excp.InnerException.Data)
|
||||||
strText += @"'" + de.Key + @"' -> '" + de.Value + @"'" +
|
strText += @"'" + de.Key + @"' -> '" + de.Value + @"'" +
|
||||||
MessageService.NewLine;
|
Environment.NewLine;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return strText;
|
return strText;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryParseUShort(string str, out ushort u)
|
public static bool TryParseUShort(string str, out ushort u)
|
||||||
@@ -550,7 +561,25 @@ namespace ModernKeePassLib.Utility
|
|||||||
return int.TryParse(str, out n);
|
return int.TryParse(str, out n);
|
||||||
#else
|
#else
|
||||||
try { n = int.Parse(str); return true; }
|
try { n = int.Parse(str); return true; }
|
||||||
catch(Exception) { n = 0; return false; }
|
catch(Exception) { n = 0; }
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryParseIntInvariant(string str, out int n)
|
||||||
|
{
|
||||||
|
#if !KeePassLibSD
|
||||||
|
return int.TryParse(str, NumberStyles.Integer,
|
||||||
|
NumberFormatInfo.InvariantInfo, out n);
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
n = int.Parse(str, NumberStyles.Integer,
|
||||||
|
NumberFormatInfo.InvariantInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch(Exception) { n = 0; }
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,7 +589,25 @@ namespace ModernKeePassLib.Utility
|
|||||||
return uint.TryParse(str, out u);
|
return uint.TryParse(str, out u);
|
||||||
#else
|
#else
|
||||||
try { u = uint.Parse(str); return true; }
|
try { u = uint.Parse(str); return true; }
|
||||||
catch(Exception) { u = 0; return false; }
|
catch(Exception) { u = 0; }
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryParseUIntInvariant(string str, out uint u)
|
||||||
|
{
|
||||||
|
#if !KeePassLibSD
|
||||||
|
return uint.TryParse(str, NumberStyles.Integer,
|
||||||
|
NumberFormatInfo.InvariantInfo, out u);
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
u = uint.Parse(str, NumberStyles.Integer,
|
||||||
|
NumberFormatInfo.InvariantInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch(Exception) { u = 0; }
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,7 +617,25 @@ namespace ModernKeePassLib.Utility
|
|||||||
return long.TryParse(str, out n);
|
return long.TryParse(str, out n);
|
||||||
#else
|
#else
|
||||||
try { n = long.Parse(str); return true; }
|
try { n = long.Parse(str); return true; }
|
||||||
catch(Exception) { n = 0; return false; }
|
catch(Exception) { n = 0; }
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryParseLongInvariant(string str, out long n)
|
||||||
|
{
|
||||||
|
#if !KeePassLibSD
|
||||||
|
return long.TryParse(str, NumberStyles.Integer,
|
||||||
|
NumberFormatInfo.InvariantInfo, out n);
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
n = long.Parse(str, NumberStyles.Integer,
|
||||||
|
NumberFormatInfo.InvariantInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch(Exception) { n = 0; }
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,7 +645,25 @@ namespace ModernKeePassLib.Utility
|
|||||||
return ulong.TryParse(str, out u);
|
return ulong.TryParse(str, out u);
|
||||||
#else
|
#else
|
||||||
try { u = ulong.Parse(str); return true; }
|
try { u = ulong.Parse(str); return true; }
|
||||||
catch(Exception) { u = 0; return false; }
|
catch(Exception) { u = 0; }
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryParseULongInvariant(string str, out ulong u)
|
||||||
|
{
|
||||||
|
#if !KeePassLibSD
|
||||||
|
return ulong.TryParse(str, NumberStyles.Integer,
|
||||||
|
NumberFormatInfo.InvariantInfo, out u);
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
u = ulong.Parse(str, NumberStyles.Integer,
|
||||||
|
NumberFormatInfo.InvariantInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch(Exception) { u = 0; }
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,19 +731,34 @@ namespace ModernKeePassLib.Utility
|
|||||||
Debug.Assert(strText != null); // No throw
|
Debug.Assert(strText != null); // No throw
|
||||||
if(string.IsNullOrEmpty(strText)) return strText;
|
if(string.IsNullOrEmpty(strText)) return strText;
|
||||||
|
|
||||||
char[] vChars = strText.ToCharArray();
|
int nLength = strText.Length;
|
||||||
StringBuilder sb = new StringBuilder(strText.Length, strText.Length);
|
StringBuilder sb = new StringBuilder(nLength);
|
||||||
char ch;
|
|
||||||
|
|
||||||
for(int i = 0; i < vChars.Length; ++i)
|
for(int i = 0; i < nLength; ++i)
|
||||||
{
|
{
|
||||||
ch = vChars[i];
|
char ch = strText[i];
|
||||||
|
|
||||||
if(((ch >= 0x20) && (ch <= 0xD7FF)) ||
|
if(((ch >= '\u0020') && (ch <= '\uD7FF')) ||
|
||||||
(ch == 0x9) || (ch == 0xA) || (ch == 0xD) ||
|
(ch == '\u0009') || (ch == '\u000A') || (ch == '\u000D') ||
|
||||||
((ch >= 0xE000) && (ch <= 0xFFFD)))
|
((ch >= '\uE000') && (ch <= '\uFFFD')))
|
||||||
sb.Append(ch);
|
sb.Append(ch);
|
||||||
// Range ((ch >= 0x10000) && (ch <= 0x10FFFF)) excluded
|
else if((ch >= '\uD800') && (ch <= '\uDBFF')) // High surrogate
|
||||||
|
{
|
||||||
|
if((i + 1) < nLength)
|
||||||
|
{
|
||||||
|
char chLow = strText[i + 1];
|
||||||
|
if((chLow >= '\uDC00') && (chLow <= '\uDFFF')) // Low sur.
|
||||||
|
{
|
||||||
|
sb.Append(ch);
|
||||||
|
sb.Append(chLow);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
else { Debug.Assert(false); } // Low sur. invalid
|
||||||
|
}
|
||||||
|
else { Debug.Assert(false); } // Low sur. missing
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Assert((ch < '\uDC00') || (ch > '\uDFFF')); // Lonely low sur.
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
@@ -669,22 +767,24 @@ namespace ModernKeePassLib.Utility
|
|||||||
private static Regex m_rxNaturalSplit = null;
|
private static Regex m_rxNaturalSplit = null;
|
||||||
public static int CompareNaturally(string strX, string strY)
|
public static int CompareNaturally(string strX, string strY)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return 0;
|
|
||||||
#if TODO
|
|
||||||
Debug.Assert(strX != null);
|
Debug.Assert(strX != null);
|
||||||
if(strX == null) throw new ArgumentNullException("strX");
|
if(strX == null) throw new ArgumentNullException("strX");
|
||||||
Debug.Assert(strY != null);
|
Debug.Assert(strY != null);
|
||||||
if(strY == null) throw new ArgumentNullException("strY");
|
if(strY == null) throw new ArgumentNullException("strY");
|
||||||
|
|
||||||
if(NativeMethods.SupportsStrCmpNaturally)
|
/*if(NativeMethods.SupportsStrCmpNaturally)
|
||||||
return NativeMethods.StrCmpNaturally(strX, strY);
|
return NativeMethods.StrCmpNaturally(strX, strY);*/
|
||||||
|
|
||||||
strX = strX.ToLower(); // Case-insensitive comparison
|
strX = strX.ToLower(); // Case-insensitive comparison
|
||||||
strY = strY.ToLower();
|
strY = strY.ToLower();
|
||||||
|
|
||||||
if(m_rxNaturalSplit == null)
|
if(m_rxNaturalSplit == null)
|
||||||
m_rxNaturalSplit = new Regex(@"([0-9]+)", RegexOptions.Compiled);
|
m_rxNaturalSplit = new Regex(@"([0-9]+)",
|
||||||
|
#if PCL || KeePassRT
|
||||||
|
RegexOptions.None);
|
||||||
|
#else
|
||||||
|
RegexOptions.Compiled);
|
||||||
|
#endif
|
||||||
|
|
||||||
string[] vPartsX = m_rxNaturalSplit.Split(strX);
|
string[] vPartsX = m_rxNaturalSplit.Split(strX);
|
||||||
string[] vPartsY = m_rxNaturalSplit.Split(strY);
|
string[] vPartsY = m_rxNaturalSplit.Split(strY);
|
||||||
@@ -716,7 +816,6 @@ namespace ModernKeePassLib.Utility
|
|||||||
if(vPartsX.Length == vPartsY.Length) return 0;
|
if(vPartsX.Length == vPartsY.Length) return 0;
|
||||||
if(vPartsX.Length < vPartsY.Length) return -1;
|
if(vPartsX.Length < vPartsY.Length) return -1;
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string RemoveAccelerator(string strMenuText)
|
public static string RemoveAccelerator(string strMenuText)
|
||||||
@@ -740,6 +839,54 @@ namespace ModernKeePassLib.Utility
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string AddAccelerator(string strMenuText,
|
||||||
|
List<char> lAvailKeys)
|
||||||
|
{
|
||||||
|
if(strMenuText == null) { Debug.Assert(false); return null; }
|
||||||
|
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];
|
||||||
|
|
||||||
|
#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; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if(xa < 0) return strMenuText;
|
||||||
|
|
||||||
|
lAvailKeys.RemoveAt(xa);
|
||||||
|
return strMenuText.Insert(xs, @"&");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string EncodeMenuText(string strText)
|
||||||
|
{
|
||||||
|
if(strText == null) throw new ArgumentNullException("strText");
|
||||||
|
|
||||||
|
return strText.Replace(@"&", @"&&");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string EncodeToolTipText(string strText)
|
||||||
|
{
|
||||||
|
if(strText == null) throw new ArgumentNullException("strText");
|
||||||
|
|
||||||
|
return strText.Replace(@"&", @"&&&");
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsHexString(string str, bool bStrict)
|
public static bool IsHexString(string str, bool bStrict)
|
||||||
{
|
{
|
||||||
if(str == null) throw new ArgumentNullException("str");
|
if(str == null) throw new ArgumentNullException("str");
|
||||||
@@ -888,6 +1035,36 @@ namespace ModernKeePassLib.Utility
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetNewLineSeq(string str)
|
||||||
|
{
|
||||||
|
if(str == null) { Debug.Assert(false); return Environment.NewLine; }
|
||||||
|
|
||||||
|
int n = str.Length, nLf = 0, nCr = 0, nCrLf = 0;
|
||||||
|
char chLast = char.MinValue;
|
||||||
|
for(int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
char ch = str[i];
|
||||||
|
|
||||||
|
if(ch == '\r') ++nCr;
|
||||||
|
else if(ch == '\n')
|
||||||
|
{
|
||||||
|
++nLf;
|
||||||
|
if(chLast == '\r') ++nCrLf;
|
||||||
|
}
|
||||||
|
|
||||||
|
chLast = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
nCr -= nCrLf;
|
||||||
|
nLf -= nCrLf;
|
||||||
|
|
||||||
|
int nMax = Math.Max(nCrLf, Math.Max(nCr, nLf));
|
||||||
|
if(nMax == 0) return Environment.NewLine;
|
||||||
|
|
||||||
|
if(nCrLf == nMax) return "\r\n";
|
||||||
|
return ((nLf == nMax) ? "\n" : "\r");
|
||||||
|
}
|
||||||
|
|
||||||
public static string AlphaNumericOnly(string str)
|
public static string AlphaNumericOnly(string str)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrEmpty(str)) return str;
|
if(string.IsNullOrEmpty(str)) return str;
|
||||||
@@ -965,85 +1142,85 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
public static string VersionToString(ulong uVersion)
|
public static string VersionToString(ulong uVersion)
|
||||||
{
|
{
|
||||||
return VersionToString(uVersion, false);
|
return VersionToString(uVersion, 1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
public static string VersionToString(ulong uVersion,
|
public static string VersionToString(ulong uVersion,
|
||||||
bool bEnsureAtLeastTwoComp)
|
bool bEnsureAtLeastTwoComp)
|
||||||
{
|
{
|
||||||
string str = string.Empty;
|
return VersionToString(uVersion, (bEnsureAtLeastTwoComp ? 2U : 1U));
|
||||||
bool bMultiComp = false;
|
}
|
||||||
|
|
||||||
|
public static string VersionToString(ulong uVersion, uint uMinComp)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
uint uComp = 0;
|
||||||
|
|
||||||
for(int i = 0; i < 4; ++i)
|
for(int i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
ushort us = (ushort)(uVersion & 0xFFFFUL);
|
if(uVersion == 0UL) break;
|
||||||
|
|
||||||
if((us != 0) || (str.Length > 0))
|
ushort us = (ushort)(uVersion >> 48);
|
||||||
|
|
||||||
|
if(sb.Length > 0) sb.Append('.');
|
||||||
|
|
||||||
|
sb.Append(us.ToString(NumberFormatInfo.InvariantInfo));
|
||||||
|
++uComp;
|
||||||
|
|
||||||
|
uVersion <<= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(uComp < uMinComp)
|
||||||
{
|
{
|
||||||
if(str.Length > 0)
|
if(sb.Length > 0) sb.Append('.');
|
||||||
{
|
|
||||||
str = "." + str;
|
sb.Append('0');
|
||||||
bMultiComp = true;
|
++uComp;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = us.ToString() + str;
|
return sb.ToString();
|
||||||
}
|
|
||||||
|
|
||||||
uVersion >>= 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bEnsureAtLeastTwoComp && !bMultiComp && (str.Length > 0))
|
|
||||||
str += ".0";
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly byte[] m_pbOptEnt = { 0xA5, 0x74, 0x2E, 0xEC };
|
private static readonly byte[] m_pbOptEnt = { 0xA5, 0x74, 0x2E, 0xEC };
|
||||||
|
|
||||||
public static string EncryptString(string strPlainText)
|
public static string EncryptString(string strPlainText)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
if(string.IsNullOrEmpty(strPlainText)) return string.Empty;
|
if(string.IsNullOrEmpty(strPlainText)) return string.Empty;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] pbPlain = StrUtil.Utf8.GetBytes(strPlainText);
|
byte[] pbPlain = StrUtil.Utf8.GetBytes(strPlainText);
|
||||||
byte[] pbEnc = ProtectedData.Protect(pbPlain, m_pbOptEnt,
|
|
||||||
DataProtectionScope.CurrentUser);
|
|
||||||
|
|
||||||
#if !KeePassLibSD
|
var provider = new DataProtectionProvider("Local=user");
|
||||||
|
var pbEnc = provider.ProtectAsync(pbPlain.AsBuffer()).GetResults();
|
||||||
|
|
||||||
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
return Convert.ToBase64String(pbEnc, Base64FormattingOptions.None);
|
return Convert.ToBase64String(pbEnc, Base64FormattingOptions.None);
|
||||||
#else
|
#else
|
||||||
return Convert.ToBase64String(pbEnc);
|
return Convert.ToBase64String(pbEnc.ToArray());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
catch(Exception) { Debug.Assert(false); }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
return strPlainText;
|
return strPlainText;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string DecryptString(string strCipherText)
|
public static string DecryptString(string strCipherText)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
if(string.IsNullOrEmpty(strCipherText)) return string.Empty;
|
if(string.IsNullOrEmpty(strCipherText)) return string.Empty;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] pbEnc = Convert.FromBase64String(strCipherText);
|
byte[] pbEnc = Convert.FromBase64String(strCipherText);
|
||||||
byte[] pbPlain = ProtectedData.Unprotect(pbEnc, m_pbOptEnt,
|
var provider = new DataProtectionProvider("Local=user");
|
||||||
DataProtectionScope.CurrentUser);
|
var pbPlain = provider.UnprotectAsync(pbEnc.AsBuffer()).GetResults().ToArray();
|
||||||
|
|
||||||
return StrUtil.Utf8.GetString(pbPlain, 0, pbPlain.Length);
|
return StrUtil.Utf8.GetString(pbPlain, 0, pbPlain.Length);
|
||||||
}
|
}
|
||||||
catch(Exception) { Debug.Assert(false); }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
return strCipherText;
|
return strCipherText;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string SerializeIntArray(int[] vNumbers)
|
public static string SerializeIntArray(int[] vNumbers)
|
||||||
@@ -1054,7 +1231,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
for(int i = 0; i < vNumbers.Length; ++i)
|
for(int i = 0; i < vNumbers.Length; ++i)
|
||||||
{
|
{
|
||||||
if(i > 0) sb.Append(' ');
|
if(i > 0) sb.Append(' ');
|
||||||
sb.Append(vNumbers[i]);
|
sb.Append(vNumbers[i].ToString(NumberFormatInfo.InvariantInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
@@ -1071,7 +1248,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
for(int i = 0; i < vParts.Length; ++i)
|
for(int i = 0; i < vParts.Length; ++i)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
if(!TryParseInt(vParts[i], out n)) { Debug.Assert(false); }
|
if(!TryParseIntInvariant(vParts[i], out n)) { Debug.Assert(false); }
|
||||||
v[i] = n;
|
v[i] = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1131,7 +1308,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
Array.Reverse(pb);
|
Array.Reverse(pb);
|
||||||
for(int i = 0; i < pb.Length; ++i) pb[i] = (byte)(pb[i] ^ 0x65);
|
for(int i = 0; i < pb.Length; ++i) pb[i] = (byte)(pb[i] ^ 0x65);
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
return Convert.ToBase64String(pb, Base64FormattingOptions.None);
|
return Convert.ToBase64String(pb, Base64FormattingOptions.None);
|
||||||
#else
|
#else
|
||||||
return Convert.ToBase64String(pb);
|
return Convert.ToBase64String(pb);
|
||||||
@@ -1249,9 +1426,33 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
public static bool IsDataUri(string strUri)
|
public static bool IsDataUri(string strUri)
|
||||||
{
|
{
|
||||||
if(strUri == null) { Debug.Assert(false); return false; }
|
return IsDataUri(strUri, null);
|
||||||
|
}
|
||||||
|
|
||||||
return strUri.StartsWith("data:", StrUtil.CaseIgnoreCmp);
|
public static bool IsDataUri(string strUri, string strReqMimeType)
|
||||||
|
{
|
||||||
|
if(strUri == null) { Debug.Assert(false); return false; }
|
||||||
|
// strReqMimeType may be null
|
||||||
|
|
||||||
|
const string strPrefix = "data:";
|
||||||
|
if(!strUri.StartsWith(strPrefix, StrUtil.CaseIgnoreCmp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int iC = strUri.IndexOf(',');
|
||||||
|
if(iC < 0) return false;
|
||||||
|
|
||||||
|
if(!string.IsNullOrEmpty(strReqMimeType))
|
||||||
|
{
|
||||||
|
int iS = strUri.IndexOf(';', 0, iC);
|
||||||
|
int iTerm = ((iS >= 0) ? iS : iC);
|
||||||
|
|
||||||
|
string strMime = strUri.Substring(strPrefix.Length,
|
||||||
|
iTerm - strPrefix.Length);
|
||||||
|
if(!strMime.Equals(strReqMimeType, StrUtil.CaseIgnoreCmp))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1267,7 +1468,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
if(strMimeType == null) strMimeType = "application/octet-stream";
|
if(strMimeType == null) strMimeType = "application/octet-stream";
|
||||||
|
|
||||||
#if !KeePassLibSD && TODO
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
return ("data:" + strMimeType + ";base64," + Convert.ToBase64String(
|
return ("data:" + strMimeType + ";base64," + Convert.ToBase64String(
|
||||||
pbData, Base64FormattingOptions.None));
|
pbData, Base64FormattingOptions.None));
|
||||||
#else
|
#else
|
||||||
@@ -1283,9 +1484,6 @@ namespace ModernKeePassLib.Utility
|
|||||||
/// <returns>Decoded binary data.</returns>
|
/// <returns>Decoded binary data.</returns>
|
||||||
public static byte[] DataUriToData(string strDataUri)
|
public static byte[] DataUriToData(string strDataUri)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
if(strDataUri == null) throw new ArgumentNullException("strDataUri");
|
if(strDataUri == null) throw new ArgumentNullException("strDataUri");
|
||||||
if(!strDataUri.StartsWith("data:", StrUtil.CaseIgnoreCmp)) return null;
|
if(!strDataUri.StartsWith("data:", StrUtil.CaseIgnoreCmp)) return null;
|
||||||
|
|
||||||
@@ -1301,20 +1499,25 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
MemoryStream ms = new MemoryStream();
|
MemoryStream ms = new MemoryStream();
|
||||||
|
|
||||||
|
#if PCL || KeePassRT
|
||||||
|
Encoding enc = StrUtil.Utf8;
|
||||||
|
#else
|
||||||
|
Encoding enc = Encoding.ASCII;
|
||||||
|
#endif
|
||||||
|
|
||||||
string[] v = strData.Split('%');
|
string[] v = strData.Split('%');
|
||||||
byte[] pb = Encoding.ASCII.GetBytes(v[0]);
|
byte[] pb = enc.GetBytes(v[0]);
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
for(int i = 1; i < v.Length; ++i)
|
for(int i = 1; i < v.Length; ++i)
|
||||||
{
|
{
|
||||||
ms.WriteByte(Convert.ToByte(v[i].Substring(0, 2), 16));
|
ms.WriteByte(Convert.ToByte(v[i].Substring(0, 2), 16));
|
||||||
pb = Encoding.ASCII.GetBytes(v[i].Substring(2));
|
pb = enc.GetBytes(v[i].Substring(2));
|
||||||
ms.Write(pb, 0, pb.Length);
|
ms.Write(pb, 0, pb.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
pb = ms.ToArray();
|
pb = ms.ToArray();
|
||||||
ms.Close();
|
ms.Dispose();
|
||||||
return pb;
|
return pb;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1358,5 +1561,72 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string[] m_vPrefSepChars = null;
|
||||||
|
/// <summary>
|
||||||
|
/// Find a character that does not occur within a given text.
|
||||||
|
/// </summary>
|
||||||
|
public static char GetUnusedChar(string strText)
|
||||||
|
{
|
||||||
|
if(strText == null) { Debug.Assert(false); return '@'; }
|
||||||
|
|
||||||
|
if(m_vPrefSepChars == null)
|
||||||
|
m_vPrefSepChars = new string[5] {
|
||||||
|
"@!$%#/\\:;,.*-_?",
|
||||||
|
PwCharSet.UpperCase, PwCharSet.LowerCase,
|
||||||
|
PwCharSet.Digits, PwCharSet.PrintableAsciiSpecial
|
||||||
|
};
|
||||||
|
|
||||||
|
for(int i = 0; i < m_vPrefSepChars.Length; ++i)
|
||||||
|
{
|
||||||
|
foreach(char ch in m_vPrefSepChars[i])
|
||||||
|
{
|
||||||
|
if(strText.IndexOf(ch) < 0) return ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(char ch = '\u00C0'; ch < char.MaxValue; ++ch)
|
||||||
|
{
|
||||||
|
if(strText.IndexOf(ch) < 0) return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
return char.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static char ByteToSafeChar(byte bt)
|
||||||
|
{
|
||||||
|
const char chDefault = '.';
|
||||||
|
|
||||||
|
// 00-1F are C0 control chars
|
||||||
|
if(bt < 0x20) return chDefault;
|
||||||
|
|
||||||
|
// 20-7F are basic Latin; 7F is DEL
|
||||||
|
if(bt < 0x7F) return (char)bt;
|
||||||
|
|
||||||
|
// 80-9F are C1 control chars
|
||||||
|
if(bt < 0xA0) return chDefault;
|
||||||
|
|
||||||
|
// A0-FF are Latin-1 supplement; AD is soft hyphen
|
||||||
|
if(bt == 0xAD) return '-';
|
||||||
|
return (char)bt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Count(string str, string strNeedle)
|
||||||
|
{
|
||||||
|
if(str == null) { Debug.Assert(false); return 0; }
|
||||||
|
if(string.IsNullOrEmpty(strNeedle)) { Debug.Assert(false); return 0; }
|
||||||
|
|
||||||
|
int iOffset = 0, iCount = 0;
|
||||||
|
while(iOffset < str.Length)
|
||||||
|
{
|
||||||
|
int p = str.IndexOf(strNeedle, iOffset);
|
||||||
|
if(p < 0) break;
|
||||||
|
|
||||||
|
++iCount;
|
||||||
|
iOffset = p + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,8 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Globalization;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
using ModernKeePassLib.Interfaces;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Utility
|
namespace ModernKeePassLib.Utility
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -33,6 +38,11 @@ namespace ModernKeePassLib.Utility
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const int PwTimeLength = 7;
|
public const int PwTimeLength = 7;
|
||||||
|
|
||||||
|
#if !KeePassLibSD
|
||||||
|
private static string m_strDtfStd = null;
|
||||||
|
private static string m_strDtfDate = null;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pack a <c>DateTime</c> object into 5 bytes. Layout: 2 zero bits,
|
/// Pack a <c>DateTime</c> object into 5 bytes. Layout: 2 zero bits,
|
||||||
/// year 12 bits, month 4 bits, day 5 bits, hour 5 bits, minute 6
|
/// year 12 bits, month 4 bits, day 5 bits, hour 5 bits, minute 6
|
||||||
@@ -138,17 +148,118 @@ namespace ModernKeePassLib.Utility
|
|||||||
{
|
{
|
||||||
DateTime dt;
|
DateTime dt;
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if KeePassLibSD
|
||||||
if(DateTime.TryParse(strDisplay, out dt)) return dt;
|
|
||||||
#else
|
|
||||||
try { dt = DateTime.Parse(strDisplay); return dt; }
|
try { dt = DateTime.Parse(strDisplay); return dt; }
|
||||||
catch(Exception) { }
|
catch(Exception) { }
|
||||||
|
#else
|
||||||
|
if(DateTime.TryParse(strDisplay, out dt)) return dt;
|
||||||
|
|
||||||
|
// For some custom formats specified using the Control Panel,
|
||||||
|
// DateTime.ToString returns the correct string, but
|
||||||
|
// DateTime.TryParse fails (e.g. for "//dd/MMM/yyyy");
|
||||||
|
// https://sourceforge.net/p/keepass/discussion/329221/thread/3a225b29/?limit=25&page=1#c6ae
|
||||||
|
if((m_strDtfStd == null) || (m_strDtfDate == null))
|
||||||
|
{
|
||||||
|
DateTime dtUni = new DateTime(2111, 3, 4, 5, 6, 7);
|
||||||
|
m_strDtfStd = DeriveCustomFormat(ToDisplayString(dtUni), dtUni);
|
||||||
|
m_strDtfDate = DeriveCustomFormat(ToDisplayStringDateOnly(dtUni), dtUni);
|
||||||
|
}
|
||||||
|
const DateTimeStyles dts = DateTimeStyles.AllowWhiteSpaces;
|
||||||
|
if(DateTime.TryParseExact(strDisplay, m_strDtfStd, null, dts, out dt))
|
||||||
|
return dt;
|
||||||
|
if(DateTime.TryParseExact(strDisplay, m_strDtfDate, null, dts, out dt))
|
||||||
|
return dt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
return DateTime.Now;
|
return DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !KeePassLibSD
|
||||||
|
private static string DeriveCustomFormat(string strDT, DateTime dt)
|
||||||
|
{
|
||||||
|
string[] vPlh = new string[] {
|
||||||
|
// Names, sorted by length
|
||||||
|
"MMMM", "dddd",
|
||||||
|
"MMM", "ddd",
|
||||||
|
"gg", "g",
|
||||||
|
|
||||||
|
// Numbers, the ones with prefix '0' first
|
||||||
|
"yyyy", "yyy", "yy", "y",
|
||||||
|
"MM", "M",
|
||||||
|
"dd", "d",
|
||||||
|
"HH", "hh", "H", "h",
|
||||||
|
"mm", "m",
|
||||||
|
"ss", "s",
|
||||||
|
|
||||||
|
"tt", "t"
|
||||||
|
};
|
||||||
|
|
||||||
|
List<string> lValues = new List<string>();
|
||||||
|
foreach(string strPlh in vPlh)
|
||||||
|
{
|
||||||
|
string strEval = strPlh;
|
||||||
|
if(strEval.Length == 1) strEval = @"%" + strPlh; // Make custom
|
||||||
|
|
||||||
|
lValues.Add(dt.ToString(strEval));
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sbAll = new StringBuilder();
|
||||||
|
sbAll.Append("dfFghHKmMstyz:/\"\'\\%");
|
||||||
|
sbAll.Append(strDT);
|
||||||
|
foreach(string strVEnum in lValues) { sbAll.Append(strVEnum); }
|
||||||
|
|
||||||
|
List<char> lCodes = new List<char>();
|
||||||
|
for(int i = 0; i < vPlh.Length; ++i)
|
||||||
|
{
|
||||||
|
char ch = StrUtil.GetUnusedChar(sbAll.ToString());
|
||||||
|
lCodes.Add(ch);
|
||||||
|
sbAll.Append(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
string str = strDT;
|
||||||
|
for(int i = 0; i < vPlh.Length; ++i)
|
||||||
|
{
|
||||||
|
string strValue = lValues[i];
|
||||||
|
if(string.IsNullOrEmpty(strValue)) continue;
|
||||||
|
|
||||||
|
str = str.Replace(strValue, new string(lCodes[i], 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sbFmt = new StringBuilder();
|
||||||
|
bool bInLiteral = false;
|
||||||
|
foreach(char ch in str)
|
||||||
|
{
|
||||||
|
int iCode = lCodes.IndexOf(ch);
|
||||||
|
|
||||||
|
// The escape character doesn't work correctly (e.g.
|
||||||
|
// "dd\\.MM\\.yyyy\\ HH\\:mm\\:ss" doesn't work, but
|
||||||
|
// "dd'.'MM'.'yyyy' 'HH':'mm':'ss" does); use '' instead
|
||||||
|
|
||||||
|
// if(iCode >= 0) sbFmt.Append(vPlh[iCode]);
|
||||||
|
// else // Literal
|
||||||
|
// {
|
||||||
|
// sbFmt.Append('\\');
|
||||||
|
// sbFmt.Append(ch);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(iCode >= 0)
|
||||||
|
{
|
||||||
|
if(bInLiteral) { sbFmt.Append('\''); bInLiteral = false; }
|
||||||
|
sbFmt.Append(vPlh[iCode]);
|
||||||
|
}
|
||||||
|
else // Literal
|
||||||
|
{
|
||||||
|
if(!bInLiteral) { sbFmt.Append('\''); bInLiteral = true; }
|
||||||
|
sbFmt.Append(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(bInLiteral) sbFmt.Append('\'');
|
||||||
|
|
||||||
|
return sbFmt.ToString();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public static string SerializeUtc(DateTime dt)
|
public static string SerializeUtc(DateTime dt)
|
||||||
{
|
{
|
||||||
string str = dt.ToUniversalTime().ToString("s");
|
string str = dt.ToUniversalTime().ToString("s");
|
||||||
@@ -218,5 +329,44 @@ namespace ModernKeePassLib.Utility
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private static readonly DateTime m_dtInvMin =
|
||||||
|
new DateTime(2999, 12, 27, 23, 59, 59);
|
||||||
|
private static readonly DateTime m_dtInvMax =
|
||||||
|
new DateTime(2999, 12, 29, 23, 59, 59);
|
||||||
|
public static int Compare(DateTime dtA, DateTime dtB, bool bUnkIsPast)
|
||||||
|
{
|
||||||
|
if(bUnkIsPast)
|
||||||
|
{
|
||||||
|
// 2999-12-28 23:59:59 in KeePass 1.x means 'unknown';
|
||||||
|
// expect time zone corruption (twice)
|
||||||
|
// bool bInvA = ((dtA.Year == 2999) && (dtA.Month == 12) &&
|
||||||
|
// (dtA.Day >= 27) && (dtA.Day <= 29) && (dtA.Minute == 59) &&
|
||||||
|
// (dtA.Second == 59));
|
||||||
|
// bool bInvB = ((dtB.Year == 2999) && (dtB.Month == 12) &&
|
||||||
|
// (dtB.Day >= 27) && (dtB.Day <= 29) && (dtB.Minute == 59) &&
|
||||||
|
// (dtB.Second == 59));
|
||||||
|
// Faster due to internal implementation of DateTime:
|
||||||
|
bool bInvA = ((dtA >= m_dtInvMin) && (dtA <= m_dtInvMax) &&
|
||||||
|
(dtA.Minute == 59) && (dtA.Second == 59));
|
||||||
|
bool bInvB = ((dtB >= m_dtInvMin) && (dtB <= m_dtInvMax) &&
|
||||||
|
(dtB.Minute == 59) && (dtB.Second == 59));
|
||||||
|
|
||||||
|
if(bInvA) return (bInvB ? 0 : -1);
|
||||||
|
if(bInvB) return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dtA.CompareTo(dtB);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int CompareLastMod(ITimeLogger tlA, ITimeLogger tlB,
|
||||||
|
bool bUnkIsPast)
|
||||||
|
{
|
||||||
|
if(tlA == null) { Debug.Assert(false); return ((tlB == null) ? 0 : -1); }
|
||||||
|
if(tlB == null) { Debug.Assert(false); return 1; }
|
||||||
|
|
||||||
|
return Compare(tlA.LastModificationTime, tlB.LastModificationTime,
|
||||||
|
bUnkIsPast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,11 +20,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
using ModernKeePassLib.Native;
|
#if PCL
|
||||||
|
using Windows.Storage;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ModernKeePassLib.Utility
|
namespace ModernKeePassLib.Utility
|
||||||
{
|
{
|
||||||
@@ -34,16 +36,30 @@ namespace ModernKeePassLib.Utility
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class UrlUtil
|
public static class UrlUtil
|
||||||
{
|
{
|
||||||
// Bert TODO: Temporary fix, most of this class is not needed in WINRT.
|
private static readonly char[] m_vDirSeps = new char[] {
|
||||||
private static readonly char DirectorySeparatorChar = '/';
|
'\\', '/', UrlUtil.LocalDirSepChar };
|
||||||
|
#if !PCL
|
||||||
|
private static readonly char[] m_vPathTrimCharsWs = new char[] {
|
||||||
|
'\"', ' ', '\t', '\r', '\n' };
|
||||||
|
#endif
|
||||||
|
|
||||||
private static readonly char[] m_vDirSeps = new char[] { '\\', '/',
|
public static char LocalDirSepChar
|
||||||
DirectorySeparatorChar };
|
{
|
||||||
|
#if KeePassRT
|
||||||
|
get { return '\\'; }
|
||||||
|
#elif PCL
|
||||||
|
//get { return PortablePath.DirectorySeparatorChar; }
|
||||||
|
get { return '\\'; }
|
||||||
|
#else
|
||||||
|
get { return Path.DirectorySeparatorChar; }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the directory (path) of a file name. The returned string is
|
/// Get the directory (path) of a file name. The returned string may be
|
||||||
/// terminated by a directory separator character. Example:
|
/// terminated by a directory separator character. Example:
|
||||||
/// passing <c>C:\\My Documents\\My File.kdb</c> in <paramref name="strFile" />
|
/// passing <c>C:\\My Documents\\My File.kdb</c> in <paramref name="strFile" />
|
||||||
|
/// and <c>true</c> to <paramref name="bAppendTerminatingChar"/>
|
||||||
/// would produce this string: <c>C:\\My Documents\\</c>.
|
/// would produce this string: <c>C:\\My Documents\\</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="strFile">Full path of a file.</param>
|
/// <param name="strFile">Full path of a file.</param>
|
||||||
@@ -54,8 +70,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
/// of <c>X:</c>, overriding <paramref name="bAppendTerminatingChar" />).
|
/// of <c>X:</c>, overriding <paramref name="bAppendTerminatingChar" />).
|
||||||
/// This should only be set to <c>true</c>, if the returned path is directly
|
/// This should only be set to <c>true</c>, if the returned path is directly
|
||||||
/// passed to some directory API.</param>
|
/// passed to some directory API.</param>
|
||||||
/// <returns>Directory of the file. The return value is an empty string
|
/// <returns>Directory of the file.</returns>
|
||||||
/// (<c>""</c>) if the input parameter is <c>null</c>.</returns>
|
|
||||||
public static string GetFileDirectory(string strFile, bool bAppendTerminatingChar,
|
public static string GetFileDirectory(string strFile, bool bAppendTerminatingChar,
|
||||||
bool bEnsureValidDirSpec)
|
bool bEnsureValidDirSpec)
|
||||||
{
|
{
|
||||||
@@ -63,14 +78,15 @@ namespace ModernKeePassLib.Utility
|
|||||||
if(strFile == null) throw new ArgumentNullException("strFile");
|
if(strFile == null) throw new ArgumentNullException("strFile");
|
||||||
|
|
||||||
int nLastSep = strFile.LastIndexOfAny(m_vDirSeps);
|
int nLastSep = strFile.LastIndexOfAny(m_vDirSeps);
|
||||||
if(nLastSep < 0) return strFile; // None
|
if(nLastSep < 0) return string.Empty; // No directory
|
||||||
|
|
||||||
if(bEnsureValidDirSpec && (nLastSep == 2) && (strFile[1] == ':') &&
|
if(bEnsureValidDirSpec && (nLastSep == 2) && (strFile[1] == ':') &&
|
||||||
(strFile[2] == '\\')) // Length >= 3 and Windows root directory
|
(strFile[2] == '\\')) // Length >= 3 and Windows root directory
|
||||||
bAppendTerminatingChar = true;
|
bAppendTerminatingChar = true;
|
||||||
|
|
||||||
if(!bAppendTerminatingChar) return strFile.Substring(0, nLastSep);
|
if(!bAppendTerminatingChar) return strFile.Substring(0, nLastSep);
|
||||||
return EnsureTerminatingSeparator(strFile.Substring(0, nLastSep), false);
|
return EnsureTerminatingSeparator(strFile.Substring(0, nLastSep),
|
||||||
|
(strFile[nLastSep] == '/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -151,7 +167,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(bUrl) return (strPath + '/');
|
if(bUrl) return (strPath + '/');
|
||||||
return (strPath + DirectorySeparatorChar);
|
return (strPath + UrlUtil.LocalDirSepChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /// <summary>
|
/* /// <summary>
|
||||||
@@ -214,13 +230,22 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
public static string GetQuotedAppPath(string strPath)
|
public static string GetQuotedAppPath(string strPath)
|
||||||
{
|
{
|
||||||
int nFirst = strPath.IndexOf('\"');
|
if(strPath == null) { Debug.Assert(false); return string.Empty; }
|
||||||
int nSecond = strPath.IndexOf('\"', nFirst + 1);
|
|
||||||
|
|
||||||
if((nFirst >= 0) && (nSecond >= 0))
|
// int nFirst = strPath.IndexOf('\"');
|
||||||
return strPath.Substring(nFirst + 1, nSecond - nFirst - 1);
|
// int nSecond = strPath.IndexOf('\"', nFirst + 1);
|
||||||
|
// if((nFirst >= 0) && (nSecond >= 0))
|
||||||
|
// return strPath.Substring(nFirst + 1, nSecond - nFirst - 1);
|
||||||
|
// return strPath;
|
||||||
|
|
||||||
return strPath;
|
string str = strPath.Trim();
|
||||||
|
if(str.Length <= 1) return str;
|
||||||
|
if(str[0] != '\"') return str;
|
||||||
|
|
||||||
|
int iSecond = str.IndexOf('\"', 1);
|
||||||
|
if(iSecond <= 0) return str;
|
||||||
|
|
||||||
|
return str.Substring(1, iSecond - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string FileUrlToPath(string strUrl)
|
public static string FileUrlToPath(string strUrl)
|
||||||
@@ -232,14 +257,14 @@ namespace ModernKeePassLib.Utility
|
|||||||
if(str.StartsWith(@"file:///", StrUtil.CaseIgnoreCmp))
|
if(str.StartsWith(@"file:///", StrUtil.CaseIgnoreCmp))
|
||||||
str = str.Substring(8, str.Length - 8);
|
str = str.Substring(8, str.Length - 8);
|
||||||
|
|
||||||
str = str.Replace('/', DirectorySeparatorChar);
|
str = str.Replace('/', UrlUtil.LocalDirSepChar);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool UnhideFile(string strFile)
|
public static bool UnhideFile(string strFile)
|
||||||
{
|
{
|
||||||
#if KeePassLibSD || !TODO
|
#if (PCL || KeePassLibSD || KeePassRT)
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
if(strFile == null) throw new ArgumentNullException("strFile");
|
if(strFile == null) throw new ArgumentNullException("strFile");
|
||||||
@@ -259,7 +284,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
public static bool HideFile(string strFile, bool bHide)
|
public static bool HideFile(string strFile, bool bHide)
|
||||||
{
|
{
|
||||||
#if KeePassLibSD || !TODO
|
#if (PCL || KeePassLibSD || KeePassRT)
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
if(strFile == null) throw new ArgumentNullException("strFile");
|
if(strFile == null) throw new ArgumentNullException("strFile");
|
||||||
@@ -300,7 +325,9 @@ namespace ModernKeePassLib.Utility
|
|||||||
return strTargetFile;
|
return strTargetFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
if(NativeLib.IsUnix())
|
if(NativeLib.IsUnix())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
bool bBaseUnc = IsUncPath(strBaseFile);
|
bool bBaseUnc = IsUncPath(strBaseFile);
|
||||||
bool bTargetUnc = IsUncPath(strTargetFile);
|
bool bTargetUnc = IsUncPath(strTargetFile);
|
||||||
@@ -319,21 +346,19 @@ namespace ModernKeePassLib.Utility
|
|||||||
StringBuilder sbRel = new StringBuilder();
|
StringBuilder sbRel = new StringBuilder();
|
||||||
for(int j = i; j < (vBase.Length - 1); ++j)
|
for(int j = i; j < (vBase.Length - 1); ++j)
|
||||||
{
|
{
|
||||||
if(sbRel.Length > 0) sbRel.Append(DirectorySeparatorChar);
|
if(sbRel.Length > 0) sbRel.Append(UrlUtil.LocalDirSepChar);
|
||||||
sbRel.Append("..");
|
sbRel.Append("..");
|
||||||
}
|
}
|
||||||
for(int k = i; k < vTarget.Length; ++k)
|
for(int k = i; k < vTarget.Length; ++k)
|
||||||
{
|
{
|
||||||
if(sbRel.Length > 0) sbRel.Append(DirectorySeparatorChar);
|
if(sbRel.Length > 0) sbRel.Append(UrlUtil.LocalDirSepChar);
|
||||||
sbRel.Append(vTarget[k]);
|
sbRel.Append(vTarget[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sbRel.ToString();
|
return sbRel.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if KeePassLibSD || !TODO
|
#if (!PCL && !KeePassLibSD && !KeePassRT)
|
||||||
return strTargetFile;
|
|
||||||
#else
|
|
||||||
try // Windows
|
try // Windows
|
||||||
{
|
{
|
||||||
const int nMaxPath = NativeMethods.MAX_PATH * 2;
|
const int nMaxPath = NativeMethods.MAX_PATH * 2;
|
||||||
@@ -347,7 +372,8 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
catch(Exception) { Debug.Assert(false); return strTargetFile; }
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
return strTargetFile;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,9 +405,6 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
public static string GetShortestAbsolutePath(string strPath)
|
public static string GetShortestAbsolutePath(string strPath)
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "not yet implemented");
|
|
||||||
return null;
|
|
||||||
#if TODO
|
|
||||||
if(strPath == null) throw new ArgumentNullException("strPath");
|
if(strPath == null) throw new ArgumentNullException("strPath");
|
||||||
if(strPath.Length == 0) return string.Empty;
|
if(strPath.Length == 0) return string.Empty;
|
||||||
|
|
||||||
@@ -426,7 +449,20 @@ namespace ModernKeePassLib.Utility
|
|||||||
}
|
}
|
||||||
|
|
||||||
string str;
|
string str;
|
||||||
try { str = Path.GetFullPath(strPath); }
|
try
|
||||||
|
{
|
||||||
|
#if KeePassRT
|
||||||
|
var dirT = StorageFolder.GetFolderFromPathAsync(
|
||||||
|
strPath).GetResults();
|
||||||
|
str = dirT.Path;
|
||||||
|
#elif PCL
|
||||||
|
//var dirT = FileSystem.Current.GetFolderFromPathAsync(strPath).Result;
|
||||||
|
str = ApplicationData.Current.RoamingFolder.Path;
|
||||||
|
//str = dirT.Path;
|
||||||
|
#else
|
||||||
|
str = Path.GetFullPath(strPath);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
catch(Exception) { Debug.Assert(false); return strPath; }
|
catch(Exception) { Debug.Assert(false); return strPath; }
|
||||||
|
|
||||||
Debug.Assert(str.IndexOf("\\..\\") < 0);
|
Debug.Assert(str.IndexOf("\\..\\") < 0);
|
||||||
@@ -437,7 +473,6 @@ namespace ModernKeePassLib.Utility
|
|||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetUrlLength(string strText, int nOffset)
|
public static int GetUrlLength(string strText, int nOffset)
|
||||||
@@ -483,7 +518,7 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
public static string ConvertSeparators(string strPath)
|
public static string ConvertSeparators(string strPath)
|
||||||
{
|
{
|
||||||
return ConvertSeparators(strPath, DirectorySeparatorChar);
|
return ConvertSeparators(strPath, UrlUtil.LocalDirSepChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ConvertSeparators(string strPath, char chSeparator)
|
public static string ConvertSeparators(string strPath, char chSeparator)
|
||||||
@@ -595,5 +630,106 @@ namespace ModernKeePassLib.Utility
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !PCL
|
||||||
|
public static string GetTempPath()
|
||||||
|
{
|
||||||
|
string strDir;
|
||||||
|
if(NativeLib.IsUnix())
|
||||||
|
strDir = NativeMethods.GetUserRuntimeDir();
|
||||||
|
#if KeePassRT
|
||||||
|
else strDir = Windows.Storage.ApplicationData.Current.TemporaryFolder.Path;
|
||||||
|
#else
|
||||||
|
else strDir = Path.GetTempPath();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(Directory.Exists(strDir) == false)
|
||||||
|
Directory.CreateDirectory(strDir);
|
||||||
|
}
|
||||||
|
catch(Exception) { Debug.Assert(false); }
|
||||||
|
|
||||||
|
return strDir;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !PCL && !KeePassLibSD
|
||||||
|
// Structurally mostly equivalent to UrlUtil.GetFileInfos
|
||||||
|
public static List<string> GetFilePaths(string strDir, string strPattern,
|
||||||
|
SearchOption opt)
|
||||||
|
{
|
||||||
|
List<string> l = new List<string>();
|
||||||
|
if(strDir == null) { Debug.Assert(false); return l; }
|
||||||
|
if(strPattern == null) { Debug.Assert(false); return l; }
|
||||||
|
|
||||||
|
string[] v = Directory.GetFiles(strDir, strPattern, opt);
|
||||||
|
if(v == null) { Debug.Assert(false); return l; }
|
||||||
|
|
||||||
|
// Only accept files with the correct extension; GetFiles may
|
||||||
|
// return additional files, see GetFiles documentation
|
||||||
|
string strExt = GetExtension(strPattern);
|
||||||
|
if(!string.IsNullOrEmpty(strExt) && (strExt.IndexOf('*') < 0) &&
|
||||||
|
(strExt.IndexOf('?') < 0))
|
||||||
|
{
|
||||||
|
strExt = "." + strExt;
|
||||||
|
|
||||||
|
foreach(string strPathRaw in v)
|
||||||
|
{
|
||||||
|
if(strPathRaw == null) { Debug.Assert(false); continue; }
|
||||||
|
string strPath = strPathRaw.Trim(m_vPathTrimCharsWs);
|
||||||
|
if(strPath.Length == 0) { Debug.Assert(false); continue; }
|
||||||
|
Debug.Assert(strPath == strPathRaw);
|
||||||
|
|
||||||
|
if(!strPath.EndsWith(strExt, StrUtil.CaseIgnoreCmp))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
l.Add(strPathRaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else l.AddRange(v);
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Structurally mostly equivalent to UrlUtil.GetFilePaths
|
||||||
|
public static List<FileInfo> GetFileInfos(DirectoryInfo di, string strPattern,
|
||||||
|
SearchOption opt)
|
||||||
|
{
|
||||||
|
List<FileInfo> l = new List<FileInfo>();
|
||||||
|
if(di == null) { Debug.Assert(false); return l; }
|
||||||
|
if(strPattern == null) { Debug.Assert(false); return l; }
|
||||||
|
|
||||||
|
FileInfo[] v = di.GetFiles(strPattern, opt);
|
||||||
|
if(v == null) { Debug.Assert(false); return l; }
|
||||||
|
|
||||||
|
// Only accept files with the correct extension; GetFiles may
|
||||||
|
// return additional files, see GetFiles documentation
|
||||||
|
string strExt = GetExtension(strPattern);
|
||||||
|
if(!string.IsNullOrEmpty(strExt) && (strExt.IndexOf('*') < 0) &&
|
||||||
|
(strExt.IndexOf('?') < 0))
|
||||||
|
{
|
||||||
|
strExt = "." + strExt;
|
||||||
|
|
||||||
|
foreach(FileInfo fi in v)
|
||||||
|
{
|
||||||
|
if(fi == null) { Debug.Assert(false); continue; }
|
||||||
|
string strPathRaw = fi.FullName;
|
||||||
|
if(strPathRaw == null) { Debug.Assert(false); continue; }
|
||||||
|
string strPath = strPathRaw.Trim(m_vPathTrimCharsWs);
|
||||||
|
if(strPath.Length == 0) { Debug.Assert(false); continue; }
|
||||||
|
Debug.Assert(strPath == strPathRaw);
|
||||||
|
|
||||||
|
if(!strPath.EndsWith(strExt, StrUtil.CaseIgnoreCmp))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
l.Add(fi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else l.AddRange(v);
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace ModernKeePassLib.WinRTAdaptors
|
|
||||||
{
|
|
||||||
// BERT TODO: Whole class is just a non-functional stub
|
|
||||||
|
|
||||||
public struct Color
|
|
||||||
{
|
|
||||||
public byte A
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{ return 255; }
|
|
||||||
}
|
|
||||||
public byte R
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public byte G
|
|
||||||
{
|
|
||||||
get { return 150; }
|
|
||||||
}
|
|
||||||
public byte B
|
|
||||||
{
|
|
||||||
get { return 200; }
|
|
||||||
}
|
|
||||||
public bool isEmpty
|
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Color Empty
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
Color abc;
|
|
||||||
return abc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -522,7 +522,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Microsoft.NETCore.Platforms/1.1.0": {
|
"Microsoft.NETCore.Platforms/1.1.0": {
|
||||||
"sha512": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
|
"sha512": "+XHS7n+M0uDgC28FAzPVRvDG2SvxtkprfAdbd0Cf9Fqa8YgMuXPXvoTB0SW/W/Z6kbuvp0fVeDItXnC9rnL+XA==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -626,7 +626,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Microsoft.NETCore.Targets/1.1.0": {
|
"Microsoft.NETCore.Targets/1.1.0": {
|
||||||
"sha512": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==",
|
"sha512": "dUUadXhJMY9VZYrGVdJDKzcXsYcUmadCTd1Kz4VQgLuZhaC+QlbC7tDkFSE+snB5TBLxmRU3ZfX8ur4buLawqQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -638,7 +638,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Microsoft.NETCore.Windows.ApiSets/1.0.1": {
|
"Microsoft.NETCore.Windows.ApiSets/1.0.1": {
|
||||||
"sha512": "SaToCvvsGMxTgtLv/BrFQ5IFMPRE1zpWbnqbpwykJa8W5XiX82CXI6K2o7yf5xS7EP6t/JzFLV0SIDuWpvBZVw==",
|
"sha512": "q0mF2juY/56CMT5b+bi8uh90ZiH1DB8TCoaK6nOTRZPQmRiqz+8JuOIu1upvy21SZHoesIl9alCFXK5MlfKFuQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -776,7 +776,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"runtime.native.System/4.3.0": {
|
"runtime.native.System/4.3.0": {
|
||||||
"sha512": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==",
|
"sha512": "HhykbX7CxJfRxeSnztqdszl4wvsxTi3Q5vhPitlPQt5LKBI6q2cvXrQjBS1FTBgdA3O+rliE86qsDCu1mzLXYg==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -787,7 +787,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Collections/4.3.0": {
|
"System.Collections/4.3.0": {
|
||||||
"sha512": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==",
|
"sha512": "odtewSKaGFM1cRV0i2f+fF1wDTcPLisgZVNa1Jrm88mDNAxD52TRh0U51jwqs73RH91GYI4ogCkF9r7W0zVoDw==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -852,7 +852,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Collections.Concurrent/4.3.0": {
|
"System.Collections.Concurrent/4.3.0": {
|
||||||
"sha512": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==",
|
"sha512": "574p/+ur5xdbM7fZCoFJLM2pqCO4B843KdXjrxYZC9AGSiDwAtlq90gkgg3xg5YwcDPa/C7Y0Uylh2n7QIZ5nQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -917,7 +917,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Diagnostics.Debug/4.3.0": {
|
"System.Diagnostics.Debug/4.3.0": {
|
||||||
"sha512": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==",
|
"sha512": "1woBURpg50IpEZZ7BK8AZe1T24GsBY+e6MyEufMAPVMZoVzRDRwejOLLfIIkgY2hgw0bk6CXAFg4dB2iFF5IVQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -982,7 +982,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Diagnostics.Tools/4.3.0": {
|
"System.Diagnostics.Tools/4.3.0": {
|
||||||
"sha512": "UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==",
|
"sha512": "cNBqRhfTSwBU0OfXuTvV+sRaE8EfJRYrkh1giN74UvENZb6SHLJw23GroCIrvyV4j03gp0a1028I4dEsRi0XoQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1036,7 +1036,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Diagnostics.Tracing/4.3.0": {
|
"System.Diagnostics.Tracing/4.3.0": {
|
||||||
"sha512": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==",
|
"sha512": "sE7+yUZUrkcebditDSxZLnsCwG/oI4RELRdhSmen0ig1AH1kW5b9ztJ7HQbK3sCIuY0Yd5OvqyX0pOie4T35fQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1123,7 +1123,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Globalization/4.3.0": {
|
"System.Globalization/4.3.0": {
|
||||||
"sha512": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==",
|
"sha512": "VqCYVd4WTRcRl/U08cJOFmyDFPs79CFfcEbav+p7Q5Sj7Lokf0R+mD0TEc+f8+GVBRtaff6b+mknJnIR44LvYQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1188,7 +1188,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.IO/4.3.0": {
|
"System.IO/4.3.0": {
|
||||||
"sha512": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
|
"sha512": "YsCDVvNbX1fQsiQuBRb7Wy/v+L14iJ0JhzInNXsblcU2wUZ8fD33Q5RBRZ4PUu2iZKQ6KnrfaOxWScxoGcIoPA==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1266,7 +1266,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.IO.Compression/4.3.0": {
|
"System.IO.Compression/4.3.0": {
|
||||||
"sha512": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==",
|
"sha512": "+G+M250pfD6KOqeADMPvbO2jPqV0UMtE3YECosM/p5bU0Krytlo0qNBrqtbk7uHJS3kOle5kk3T7zlxd/z/pTA==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1334,7 +1334,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Linq/4.3.0": {
|
"System.Linq/4.3.0": {
|
||||||
"sha512": "5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==",
|
"sha512": "w9wJuI2T9KXZmY/AS7E4PUVzGPS0jhlx1YlKsgzShgNj6Vk9iN7R8qRwWB2kvD+Ki58cpRwM87fVD5yivijJEg==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1403,7 +1403,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Linq.Expressions/4.3.0": {
|
"System.Linq.Expressions/4.3.0": {
|
||||||
"sha512": "PGKkrd2khG4CnlyJwxwwaWWiSiWFNBGlgXvJpeO0xCXrZ89ODrQ6tjEWS/kOqZ8GwEOUATtKtzp1eRgmYNfclg==",
|
"sha512": "EjVvFE83n3Ih05PIJ611aMBS321nFT7FS1yIpcnVHLVB3GqaCWaVPMg7/kklhlohrUPXJ4PS5CeUlIBmXMva8w==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1484,11 +1484,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Net.Http/4.3.2": {
|
"System.Net.Http/4.3.2": {
|
||||||
"sha512": "y7hv0o0weI0j0mvEcBOdt1F3CAADiWlcw3e54m8TfYiRmBPDIsHElx8QUPDlY4x6yWXKPGN0Z2TuXCTPgkm5WQ==",
|
"sha512": "wMTk4xwcImunKYNGcMC35TFe/8LKBhzc1INgatMHmbGt6hNu3IsxcwpYD8r2zstiv64uKK+GTgfxJ7Lh91Qnqw==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"System.Net.Http.4.3.2.nupkg.sha512",
|
|
||||||
"System.Net.Http.nuspec",
|
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
"dotnet_library_license.txt",
|
"dotnet_library_license.txt",
|
||||||
"lib/Xamarinmac20/_._",
|
"lib/Xamarinmac20/_._",
|
||||||
@@ -1519,11 +1517,13 @@
|
|||||||
"runtimes/unix/lib/netstandard1.6/System.Net.Http.dll",
|
"runtimes/unix/lib/netstandard1.6/System.Net.Http.dll",
|
||||||
"runtimes/win/lib/net46/System.Net.Http.dll",
|
"runtimes/win/lib/net46/System.Net.Http.dll",
|
||||||
"runtimes/win/lib/netcore50/System.Net.Http.dll",
|
"runtimes/win/lib/netcore50/System.Net.Http.dll",
|
||||||
"runtimes/win/lib/netstandard1.3/System.Net.Http.dll"
|
"runtimes/win/lib/netstandard1.3/System.Net.Http.dll",
|
||||||
|
"system.net.http.4.3.2.nupkg.sha512",
|
||||||
|
"system.net.http.nuspec"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Net.Primitives/4.3.0": {
|
"System.Net.Primitives/4.3.0": {
|
||||||
"sha512": "qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==",
|
"sha512": "Ds2qmHelD5W4JYm+FOub7/4OWbVWKXXsL4+pVVhZxd3urA9yYI6UFPMEnIbK9mCG7rvoli+PVpbczlcy8H+Jmg==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1599,7 +1599,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Net.Requests/4.3.0": {
|
"System.Net.Requests/4.3.0": {
|
||||||
"sha512": "OZNUuAs0kDXUzm7U5NZ1ojVta5YFZmgT2yxBqsQ7Eseq5Ahz88LInGRuNLJ/NP2F8W1q7tse1pKDthj3reF5QA==",
|
"sha512": "ZvKLMYR1iGBh3ianvGnqMojG8uLtq1jhviCrojW2QUZEPUYKhB28gtLt5iW51nsvmGhFh1WTHvh9CenMuxzLbQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1679,7 +1679,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.ObjectModel/4.3.0": {
|
"System.ObjectModel/4.3.0": {
|
||||||
"sha512": "bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==",
|
"sha512": "yXnz+D4S6l25VS9SuCrS8cyVKWgeAQJ/v2epBlTL1cM+Xs6rx0/6gUAXTTruCZiO1UjrhX56isX8DKL267D5gQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1746,7 +1746,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Reflection/4.3.0": {
|
"System.Reflection/4.3.0": {
|
||||||
"sha512": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
|
"sha512": "gWKa+cLy5BkkDxp6iuKYNQVNlxir4VYpR7siMIW8vQI7lR9E5PsR+Fmm6h+ZzTCu2XFMf9sNvRYRw727QmJ0fw==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1824,7 +1824,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Reflection.Extensions/4.3.0": {
|
"System.Reflection.Extensions/4.3.0": {
|
||||||
"sha512": "rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==",
|
"sha512": "MZ0vyVl3i7SpA8hLhKjb8wrJ9s4a/bggVHasDqNrbpbkbyMaaYxi8dUDduh5K7RFAHJaR45BAW7+TMbpoQ7Oqg==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1878,7 +1878,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Reflection.Primitives/4.3.0": {
|
"System.Reflection.Primitives/4.3.0": {
|
||||||
"sha512": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
|
"sha512": "QcIJSKt4ksNWnTWkNc7fqdnaARA4or2omXIXVi1hzccV8AixhcW4gVNfpdz/jE1cldDBRSeySM5PbF8M3GUHbA==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1932,7 +1932,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Resources.ResourceManager/4.3.0": {
|
"System.Resources.ResourceManager/4.3.0": {
|
||||||
"sha512": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==",
|
"sha512": "DRxdwZJGYZA+sp8Ht53dvNPr8NLsbBzctIrpbx4UFylYbDsoDQzJwchNarrRnwiIfsZHkXYA3HCKewNr62XiRw==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -1986,7 +1986,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Runtime/4.3.0": {
|
"System.Runtime/4.3.0": {
|
||||||
"sha512": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
|
"sha512": "a+38DiHlk4UA1NMs7Ty0/izJb/ukQtEhDgoy2xrGppdA/nVOkOC1JtR9HCcYYHfxXxQNNsjQ66NNvrbM3oVTrw==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2075,7 +2075,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Runtime.Extensions/4.3.0": {
|
"System.Runtime.Extensions/4.3.0": {
|
||||||
"sha512": "guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==",
|
"sha512": "P78VOZ2fZUq3otcfcf+6zd+EhWijXhI/BWk/wd9RnWFAddhO4hnlpiqxAIw1yPTZJSWRG5VboYyUmB8xcmcHpQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2153,7 +2153,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Runtime.InteropServices/4.3.0": {
|
"System.Runtime.InteropServices/4.3.0": {
|
||||||
"sha512": "uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==",
|
"sha512": "6CC8BIjVaMtHM3OvOOO0cirqqF6CNluOPtc/DNBkieZhMiz676cszc5ciNCiIWcTcNW+Mb0Cs8LWZrhK7W+rdQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2243,7 +2243,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Runtime.InteropServices.RuntimeInformation/4.3.0": {
|
"System.Runtime.InteropServices.RuntimeInformation/4.3.0": {
|
||||||
"sha512": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==",
|
"sha512": "rf6Ebmg9wgokWKK14uiVNdyBY7g4yLaZ4edbiE6XcNX5fyqtgHZTKuP2MFkkzQWL9NGX2LSIfodKQNVnOM+qCA==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2275,7 +2275,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Runtime.Numerics/4.3.0": {
|
"System.Runtime.Numerics/4.3.0": {
|
||||||
"sha512": "yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==",
|
"sha512": "H73WuUWJAH5UQE1MIxWLdqg+skdOBBwGA+fLu4JgPHJ+0tivNLBrN4TQdJGDvVeGPxrN229R5muocedVVAIfbA==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2382,7 +2382,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Text.Encoding/4.3.0": {
|
"System.Text.Encoding/4.3.0": {
|
||||||
"sha512": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
|
"sha512": "3hnC4XGk/ip1HnQuDpA5L3aOsYXSl4I7OlwSb40WlTIEVtOP9VrcqPN4kuT2L3a1kXXr8emjPePQcbtYVjRvjw==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2447,7 +2447,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Text.Encoding.Extensions/4.3.0": {
|
"System.Text.Encoding.Extensions/4.3.0": {
|
||||||
"sha512": "YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==",
|
"sha512": "q9p8y7bgIQR7IQJQBeOL3TT4H0vg634anhTKgbao9gHvFmmGJkJF6eNhX6Tfcu5vFbKqd+I1+kW/6hVdZXqPmQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2512,7 +2512,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Text.RegularExpressions/4.3.0": {
|
"System.Text.RegularExpressions/4.3.0": {
|
||||||
"sha512": "RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==",
|
"sha512": "SJ9qrjcnDx6YwpMpIgeKL1K/4/uDAHCT6Id3aey/z66H9SIX8PcG2TQ+gYNg7VGm7tI0wkLsV+8dMxbxTam7Yw==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2593,7 +2593,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Threading/4.3.0": {
|
"System.Threading/4.3.0": {
|
||||||
"sha512": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==",
|
"sha512": "cm4+iLU+Gvodk221rboVLwWguLuPOl/bkcCtr+k9hc4tvngnw/dJaoUPqIEsU/FWcCusXk4po3ydFxmRp2lXyw==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2661,7 +2661,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Threading.Tasks/4.3.0": {
|
"System.Threading.Tasks/4.3.0": {
|
||||||
"sha512": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
|
"sha512": "1je8yxoIxd0iVjfJbb9DXNIfTt6ESMRIwNwoaB0WhxSfJMLOhfJ3mb9UQsa6Q/98g6jEOyFdSAbr+fPEgwbKUg==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2726,7 +2726,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Threading.Timer/4.3.0": {
|
"System.Threading.Timer/4.3.0": {
|
||||||
"sha512": "Z6YfyYTCg7lOZjJzBjONJTFKGN9/NIYKSxhU5GRd+DTwHSZyvWp1xuI5aR+dLg+ayyC5Xv57KiY4oJ0tMO89fQ==",
|
"sha512": "BzzEELyI/Jct8o0jOeXisFR5uawc5yhFVlgboaxWWWV/Fjahi/ESRRaHlR1HMWAyZsNnybq7v57YgWTVd+NAkg==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2778,7 +2778,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Xml.ReaderWriter/4.3.0": {
|
"System.Xml.ReaderWriter/4.3.0": {
|
||||||
"sha512": "GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==",
|
"sha512": "41StQbCnhTjv/daEuN55cqY4rUYP1NQI9a8cQktBxDbF5QLFsIvcr9mIFGQ2nrzrk3DYHKwpJ9AkVuMiYymtHg==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
@@ -2847,7 +2847,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"System.Xml.XDocument/4.3.0": {
|
"System.Xml.XDocument/4.3.0": {
|
||||||
"sha512": "5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==",
|
"sha512": "WT8lBJSEINzk3c9dm3n0vlqb9Z9PoORD29n/rbkcNh3feSZTJeYQ5+xgSbJhdsyvpmsRsE56fdsH4fchJt65PQ==",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"files": [
|
"files": [
|
||||||
"ThirdPartyNotices.txt",
|
"ThirdPartyNotices.txt",
|
||||||
|
|||||||
Reference in New Issue
Block a user