Update to version 2.42.1

Some changes
Removed FutureAccesList code as it works only with UWP
This commit is contained in:
Geoffroy BONNEVILLE
2019-07-26 18:28:53 +02:00
parent 85b0e9f321
commit 26e8e5c223
52 changed files with 1373 additions and 506 deletions

View File

@@ -23,18 +23,19 @@ using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using Windows.Storage.AccessCache;
#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT)
using System.Security.AccessControl;
#endif
using ModernKeePassLib.Native;
using ModernKeePassLib.Utility;
using System.Threading.Tasks;
#if ModernKeePassLib
using Windows.Storage;
using Windows.Storage.Streams;
#endif
using ModernKeePassLib.Cryptography;
using ModernKeePassLib.Delegates;
using ModernKeePassLib.Native;
using ModernKeePassLib.Resources;
using ModernKeePassLib.Utility;
namespace ModernKeePassLib.Serialization
{
@@ -210,10 +211,10 @@ namespace ModernKeePassLib.Serialization
// trying to set 'Owner' or 'Group' can result in an
// UnauthorizedAccessException; thus we restore 'Access' (DACL) only
const AccessControlSections acs = AccessControlSections.Access;
#endif
bool bEfsEncrypted = false;
byte[] pbSec = null;
DateTime? otCreation = null;
bool bBaseExists = IOConnection.FileExists(m_iocBase);
@@ -228,9 +229,7 @@ namespace ModernKeePassLib.Serialization
try { if(bEfsEncrypted) File.Decrypt(m_iocBase.Path); } // For TxF
catch(Exception) { Debug.Assert(false); }
#endif
#if ModernKeePassLib
otCreation = m_iocBase.StorageFile.DateCreated.UtcDateTime;
#else
#if !ModernKeePassLib
otCreation = File.GetCreationTimeUtc(m_iocBase.Path);
#endif
#if !ModernKeePassLib
@@ -238,7 +237,7 @@ namespace ModernKeePassLib.Serialization
FileSecurity sec = File.GetAccessControl(m_iocBase.Path, acs);
if(sec != null) pbSec = sec.GetSecurityDescriptorBinaryForm();
#endif
}
}
catch(Exception) { Debug.Assert(NativeLib.IsUnix()); }
// if((long)(faBase & FileAttributes.ReadOnly) != 0)
@@ -337,6 +336,7 @@ namespace ModernKeePassLib.Serialization
{
if(NativeLib.IsUnix()) return;
if(!m_iocBase.IsLocalFile()) return;
if(IsOneDriveWorkaroundRequired()) return;
string strID = StrUtil.AlphaNumericOnly(Convert.ToBase64String(
CryptoRandom.Instance.GetRandomBytes(16)));
@@ -354,7 +354,7 @@ namespace ModernKeePassLib.Serialization
#if ModernKeePassLib
var tempFile = ApplicationData.Current.TemporaryFolder.CreateFileAsync(m_iocTemp.Path).GetAwaiter()
.GetResult();
m_iocTemp = IOConnectionInfo.FromFile(tempFile);
m_iocTemp = IOConnectionInfo.FromStorageFile(tempFile);
#else
m_iocTemp = IOConnectionInfo.FromPath(strTemp);
#endif
@@ -370,13 +370,10 @@ namespace ModernKeePassLib.Serialization
if(TxfMoveWithTx()) return true;
// Move the temporary file onto the base file's drive first,
// such that it cannot happen that both the base file and
// the temporary file are deleted/corrupted
#if ModernKeePassLib
m_iocTemp.StorageFile = ApplicationData.Current.TemporaryFolder.CreateFileAsync(m_iocTemp.Path).GetAwaiter()
.GetResult();
#else
// Move the temporary file onto the base file's drive first,
// such that it cannot happen that both the base file and
// the temporary file are deleted/corrupted
#if !ModernKeePassLib
const uint f = (NativeMethods.MOVEFILE_COPY_ALLOWED |
NativeMethods.MOVEFILE_REPLACE_EXISTING);
bool b = NativeMethods.MoveFileEx(m_iocTemp.Path, m_iocTxfMidFallback.Path, f);
@@ -391,9 +388,7 @@ namespace ModernKeePassLib.Serialization
private bool TxfMoveWithTx()
{
#if ModernKeePassLib
return true;
#else
#if !ModernKeePassLib
IntPtr hTx = new IntPtr((int)NativeMethods.INVALID_HANDLE_VALUE);
Debug.Assert(hTx.ToInt64() == NativeMethods.INVALID_HANDLE_VALUE);
try
@@ -438,9 +433,8 @@ namespace ModernKeePassLib.Serialization
catch(Exception) { Debug.Assert(false); }
}
}
return false;
#endif
return false;
}
internal static void ClearOld()
@@ -470,5 +464,89 @@ namespace ModernKeePassLib.Serialization
}
catch(Exception) { Debug.Assert(false); }
}
// https://sourceforge.net/p/keepass/discussion/329220/thread/672ffecc65/
// https://sourceforge.net/p/keepass/discussion/329221/thread/514786c23a/
private bool IsOneDriveWorkaroundRequired()
{
#if !ModernKeePassLib
if(NativeLib.IsUnix()) return false;
try
{
string strReleaseId = (Registry.GetValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
"ReleaseId", string.Empty) as string);
if(strReleaseId != "1809") return false;
string strFile = m_iocBase.Path;
GFunc<string, string, bool> fMatch = delegate(string strRoot, string strSfx)
{
if(string.IsNullOrEmpty(strRoot)) return false;
string strPfx = UrlUtil.EnsureTerminatingSeparator(
strRoot, false) + strSfx;
return strFile.StartsWith(strPfx, StrUtil.CaseIgnoreCmp);
};
GFunc<string, string, bool> fMatchEnv = delegate(string strEnv, string strSfx)
{
return fMatch(Environment.GetEnvironmentVariable(strEnv), strSfx);
};
string strKnown = NativeMethods.GetKnownFolderPath(
NativeMethods.FOLDERID_SkyDrive);
if(fMatch(strKnown, string.Empty)) return true;
if(fMatchEnv("USERPROFILE", "OneDrive\\")) return true;
if(fMatchEnv("OneDrive", string.Empty)) return true;
if(fMatchEnv("OneDriveCommercial", string.Empty)) return true;
if(fMatchEnv("OneDriveConsumer", string.Empty)) return true;
using(RegistryKey kAccs = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\OneDrive\\Accounts", false))
{
string[] vAccs = (((kAccs != null) ? kAccs.GetSubKeyNames() :
null) ?? new string[0]);
foreach(string strAcc in vAccs)
{
if(string.IsNullOrEmpty(strAcc)) { Debug.Assert(false); continue; }
using(RegistryKey kTenants = kAccs.OpenSubKey(
strAcc + "\\Tenants", false))
{
string[] vTenants = (((kTenants != null) ?
kTenants.GetSubKeyNames() : null) ?? new string[0]);
foreach(string strT in vTenants)
{
if(string.IsNullOrEmpty(strT)) { Debug.Assert(false); continue; }
using(RegistryKey kT = kTenants.OpenSubKey(strT, false))
{
string[] vPaths = (((kT != null) ?
kT.GetValueNames() : null) ?? new string[0]);
foreach(string strPath in vPaths)
{
if((strPath == null) || (strPath.Length < 4) ||
(strPath[1] != ':'))
{
Debug.Assert(false);
continue;
}
if(fMatch(strPath, string.Empty)) return true;
}
}
}
}
}
}
}
catch(Exception) { Debug.Assert(false); }
#endif
return false;
}
}
}

View File

@@ -24,7 +24,6 @@ using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
#if (!ModernKeePassLib && !KeePassLibSD && !KeePassUAP)
using System.Net.Cache;
using System.Net.Security;
@@ -600,7 +599,12 @@ namespace ModernKeePassLib.Serialization
private static Stream OpenReadLocal(IOConnectionInfo ioc)
{
#if ModernKeePassLib
return ioc.StorageFile.OpenAsync(FileAccessMode.Read).GetAwaiter().GetResult().AsStream();
#else
return new FileStream(ioc.Path, FileMode.Open, FileAccess.Read,
FileShare.Read);
#endif
}
#if (!ModernKeePassLib && !KeePassLibSD && !KeePassRT)
@@ -654,7 +658,7 @@ namespace ModernKeePassLib.Serialization
RaiseIOAccessPreEvent(ioc, IOAccessType.Exists);
#if ModernKeePassLib
return ioc.StorageFile.IsAvailable;
return ioc.StorageFile != null;
#else
if(ioc.IsLocalFile()) return File.Exists(ioc.Path);
@@ -696,7 +700,7 @@ namespace ModernKeePassLib.Serialization
#if ModernKeePassLib
if (!ioc.IsLocalFile()) return;
ioc.StorageFile?.DeleteAsync().GetAwaiter().GetResult();
ioc.StorageFile?.DeleteAsync().GetAwaiter().GetResult();
#else
if(ioc.IsLocalFile()) { File.Delete(ioc.Path); return; }
@@ -718,7 +722,7 @@ namespace ModernKeePassLib.Serialization
}
#endif
#endif
}
}
/// <summary>
/// Rename/move a file. For local file system and WebDAV, the
@@ -735,7 +739,7 @@ namespace ModernKeePassLib.Serialization
#if ModernKeePassLib
if (!iocFrom.IsLocalFile()) return;
iocFrom.StorageFile?.RenameAsync(iocTo.Path).GetAwaiter().GetResult();
iocFrom.StorageFile?.RenameAsync(iocTo.Path).GetAwaiter().GetResult();
#else
if(iocFrom.IsLocalFile()) { File.Move(iocFrom.Path, iocTo.Path); return; }

View File

@@ -25,14 +25,12 @@ using System.IO;
using System.Text;
using System.Xml.Serialization;
#if ModernKeePassLib
using System.Threading.Tasks;
using Windows.Storage;
//using PCLStorage;
#endif
using ModernKeePassLib.Interfaces;
using ModernKeePassLib.Utility;
using System.Threading.Tasks;
using Windows.Storage.AccessCache;
namespace ModernKeePassLib.Serialization
{
@@ -70,6 +68,8 @@ namespace ModernKeePassLib.Serialization
{
// private IOFileFormatHint m_ioHint = IOFileFormatHint.None;
public StorageFile StorageFile { get; set; }
private string m_strUrl = string.Empty;
public string Path
{
@@ -316,29 +316,17 @@ namespace ModernKeePassLib.Serialization
}
#if ModernKeePassLib
public static IOConnectionInfo FromFile(StorageFile file)
public static IOConnectionInfo FromStorageFile(StorageFile file)
{
IOConnectionInfo ioc = new IOConnectionInfo();
ioc.StorageFile = file;
ioc.Path = file.Path;
ioc.CredSaveMode = IOCredSaveMode.NoSave;
return ioc;
}
public static IOConnectionInfo FromPath(string strPath)
{
IOConnectionInfo ioc = new IOConnectionInfo();
ioc.Path = strPath;
ioc.StorageFile = StorageApplicationPermissions.FutureAccessList.GetFileAsync(strPath).GetAwaiter().GetResult();
ioc.StorageFile = file;
ioc.CredSaveMode = IOCredSaveMode.NoSave;
return ioc;
}
#else
public static IOConnectionInfo FromPath(string strPath)
public static IOConnectionInfo FromPath(string strPath)
{
IOConnectionInfo ioc = new IOConnectionInfo();
@@ -348,10 +336,6 @@ namespace ModernKeePassLib.Serialization
return ioc;
}
#endif
public StorageFile StorageFile { get; set; }
public bool CanProbablyAccess()
{
#if ModernKeePassLib

View File

@@ -30,13 +30,14 @@ using System.Drawing;
using ModernKeePassLib;
using ModernKeePassLib.Collections;
using ModernKeePassLib.Cryptography;
using ModernKeePassLib.Cryptography.Cipher;
using ModernKeePassLib.Interfaces;
using ModernKeePassLib.Resources;
using ModernKeePassLib.Security;
using ModernKeePassLib.Utility;
using ModernKeePassLib.Cryptography;
using ModernKeePassLib.Cryptography.Cipher;
namespace ModernKeePassLib.Serialization
{
/// <summary>
@@ -97,36 +98,10 @@ namespace ModernKeePassLib.Serialization
private void ReadXmlStreamed(Stream sXml, Stream sParent)
{
ReadDocumentStreamed(CreateXmlReader(sXml), sParent);
}
internal static XmlReaderSettings CreateStdXmlReaderSettings()
{
XmlReaderSettings xrs = new XmlReaderSettings();
xrs.CloseInput = true;
xrs.IgnoreComments = true;
xrs.IgnoreProcessingInstructions = true;
xrs.IgnoreWhitespace = true;
#if ModernKeePassLib || KeePassUAP
xrs.DtdProcessing = DtdProcessing.Prohibit;
#else
#if !KeePassLibSD
// Also see PrepMonoDev.sh script
xrs.ProhibitDtd = true; // Obsolete in .NET 4, but still there
// xrs.DtdProcessing = DtdProcessing.Prohibit; // .NET 4 only
#endif
xrs.ValidationType = ValidationType.None;
#endif
return xrs;
}
private static XmlReader CreateXmlReader(Stream readerStream)
{
XmlReaderSettings xrs = CreateStdXmlReaderSettings();
return XmlReader.Create(readerStream, xrs);
using(XmlReader xr = XmlUtilEx.CreateXmlReader(sXml))
{
ReadDocumentStreamed(xr, sParent);
}
}
private void ReadDocumentStreamed(XmlReader xr, Stream sParentStream)
@@ -179,7 +154,7 @@ namespace ModernKeePassLib.Serialization
}
++uTagCounter;
if(((uTagCounter % 256) == 0) && bSupportsStatus)
if(((uTagCounter & 0xFFU) == 0) && bSupportsStatus)
{
Debug.Assert(lStreamLength == sParentStream.Length);
uint uPct = (uint)((sParentStream.Position * 100) /
@@ -189,7 +164,8 @@ namespace ModernKeePassLib.Serialization
// position/length values (M120413)
if(uPct > 100) { Debug.Assert(false); uPct = 100; }
m_slLogger.SetProgress(uPct);
if(!m_slLogger.SetProgress(uPct))
throw new OperationCanceledException();
}
}
@@ -1028,28 +1004,31 @@ namespace ModernKeePassLib.Serialization
private void ReadUnknown(XmlReader xr)
{
Debug.Assert(false); // Unknown node!
Debug.Assert(xr.NodeType == XmlNodeType.Element);
if(xr.IsEmptyElement) { m_bReadNextNode = true; return; }
bool bRead = false;
int cOpen = 0;
string strUnknownName = xr.Name;
XorredBuffer xb = ProcessNode(xr);
if(xb != null) { xb.Dispose(); return; } // ProcessNode sets m_bReadNextNode
bool bRead = true;
while(true)
do
{
if(bRead) xr.Read();
bRead = true;
if(xr.NodeType == XmlNodeType.EndElement) break;
if(xr.NodeType != XmlNodeType.Element) { bRead = true; continue; }
if(xr.NodeType == XmlNodeType.EndElement) --cOpen;
else if(xr.NodeType == XmlNodeType.Element)
{
if(!xr.IsEmptyElement)
{
XorredBuffer xb = ProcessNode(xr);
if(xb != null) { xb.Dispose(); bRead = m_bReadNextNode; continue; }
ReadUnknown(xr);
bRead = m_bReadNextNode;
++cOpen;
}
}
}
while(cOpen > 0);
Debug.Assert(xr.Name == strUnknownName); // On end tag
m_bReadNextNode = true;
m_bReadNextNode = bRead;
}
private XorredBuffer ProcessNode(XmlReader xr)

View File

@@ -55,26 +55,23 @@ namespace ModernKeePassLib.Serialization
/// </summary>
public sealed partial class KdbxFile
{
/// <summary>
/// Load a KDBX file.
/// </summary>
/// <param name="strFilePath">File to load.</param>
/// <param name="fmt">Format.</param>
/// <param name="slLogger">Status logger (optional).</param>
#if ModernKeePassLib
public void Load(StorageFile file, KdbxFormat fmt, IStatusLogger slLogger)
{
IOConnectionInfo ioc = IOConnectionInfo.FromFile(file);
Load(IOConnection.OpenRead(ioc), fmt, slLogger);
}
{
IOConnectionInfo ioc = IOConnectionInfo.FromStorageFile(file);
#else
/// <summary>
/// Load a KDBX file.
/// </summary>
/// <param name="strFilePath">File to load.</param>
/// <param name="fmt">Format.</param>
/// <param name="slLogger">Status logger (optional).</param>
public void Load(string strFilePath, KdbxFormat fmt, IStatusLogger slLogger)
public void Load(string strFilePath, KdbxFormat fmt, IStatusLogger slLogger)
{
IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath);
#endif
Load(IOConnection.OpenRead(ioc), fmt, slLogger);
}
#endif
/// <summary>
/// Load a KDBX file from a stream.
@@ -202,19 +199,17 @@ namespace ModernKeePassLib.Serialization
}
#if KeePassDebug_WriteXml
// FileStream fsOut = new FileStream("Raw.xml", FileMode.Create,
// FileAccess.Write, FileShare.None);
// try
// {
// while(true)
// {
// int b = sXml.ReadByte();
// if(b == -1) break;
// fsOut.WriteByte((byte)b);
// }
// }
// catch(Exception) { }
// fsOut.Close();
#warning XML output is enabled!
/* using(FileStream fsOut = new FileStream("Raw.xml", FileMode.Create,
FileAccess.Write, FileShare.None))
{
while(true)
{
int b = sXml.ReadByte();
if(b == -1) throw new EndOfStreamException();
fsOut.WriteByte((byte)b);
}
} */
#endif
ReadXmlStreamed(sXml, sHashing);
@@ -413,7 +408,7 @@ namespace ModernKeePassLib.Serialization
default:
Debug.Assert(false);
if(m_slLogger != null)
m_slLogger.SetText(KLRes.UnknownHeaderId + @": " +
m_slLogger.SetText(KLRes.UnknownHeaderId + ": " +
kdbID.ToString() + "!", LogStatusType.Warning);
break;
}

View File

@@ -429,7 +429,7 @@ namespace ModernKeePassLib.Serialization
};
if(!pgRoot.TraverseTree(TraversalMethod.PreOrder, gh, eh))
throw new InvalidOperationException();
throw new OperationCanceledException();
while(groupStack.Count > 1)
{

View File

@@ -378,8 +378,8 @@ namespace ModernKeePassLib.Serialization
Debug.Assert(m_pwDatabase != null);
Debug.Assert(m_pwDatabase.MasterKey != null);
ProtectedBinary pbinUser = m_pwDatabase.MasterKey.GenerateKey32(
m_pwDatabase.KdfParameters);
ProtectedBinary pbinUser = m_pwDatabase.MasterKey.GenerateKey32Ex(
m_pwDatabase.KdfParameters, m_slLogger);
Debug.Assert(pbinUser != null);
if(pbinUser == null)
throw new SecurityException(KLRes.InvalidCompositeKey);
@@ -492,7 +492,7 @@ namespace ModernKeePassLib.Serialization
{
if(pb == null) { Debug.Assert(false); return; }
if(string.IsNullOrEmpty(strName)) strName = "File.bin";
strName = UrlUtil.GetSafeFileName(strName);
string strPath;
int iTry = 1;
@@ -500,8 +500,8 @@ namespace ModernKeePassLib.Serialization
{
strPath = UrlUtil.EnsureTerminatingSeparator(strSaveDir, false);
string strExt = UrlUtil.GetExtension(strName);
string strDesc = UrlUtil.StripExtension(strName);
string strExt = UrlUtil.GetExtension(strName);
strPath += strDesc;
if(iTry > 1)