diff --git a/ModernKeePass/ModernKeePassApp.csproj b/ModernKeePass/ModernKeePassApp.csproj
index 5d47f5f..512239c 100644
--- a/ModernKeePass/ModernKeePassApp.csproj
+++ b/ModernKeePass/ModernKeePassApp.csproj
@@ -339,10 +339,6 @@
..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll
True
-
- ..\packages\ModernKeePassLib.2.37.8000\lib\netstandard1.2\ModernKeePassLib.dll
- True
-
..\packages\Splat.2.0.0\lib\Portable-Win81+Wpa81\Splat.dll
True
@@ -435,7 +431,12 @@
-
+
+
+ {2e710089-9559-4967-846c-e763dd1f3acb}
+ ModernKeePassLib
+
+
12.0
diff --git a/ModernKeePass/Strings/en-US/CodeBehind.resw b/ModernKeePass/Strings/en-US/CodeBehind.resw
index b562948..93ab783 100644
--- a/ModernKeePass/Strings/en-US/CodeBehind.resw
+++ b/ModernKeePass/Strings/en-US/CodeBehind.resw
@@ -270,4 +270,7 @@
Security
+
+ user account
+
\ No newline at end of file
diff --git a/ModernKeePass/Strings/en-US/Resources.resw b/ModernKeePass/Strings/en-US/Resources.resw
index 46f4554..3428892 100644
--- a/ModernKeePass/Strings/en-US/Resources.resw
+++ b/ModernKeePass/Strings/en-US/Resources.resw
@@ -171,6 +171,9 @@
Password
+
+ Windows User Account
+
Donate
diff --git a/ModernKeePass/Strings/fr-FR/CodeBehind.resw b/ModernKeePass/Strings/fr-FR/CodeBehind.resw
index b9a3e96..c69f9c2 100644
--- a/ModernKeePass/Strings/fr-FR/CodeBehind.resw
+++ b/ModernKeePass/Strings/fr-FR/CodeBehind.resw
@@ -271,4 +271,7 @@
Sécurité
+
+ compte utilisateur
+
\ No newline at end of file
diff --git a/ModernKeePass/Strings/fr-FR/Resources.resw b/ModernKeePass/Strings/fr-FR/Resources.resw
index 105cd3c..73a9d21 100644
--- a/ModernKeePass/Strings/fr-FR/Resources.resw
+++ b/ModernKeePass/Strings/fr-FR/Resources.resw
@@ -171,6 +171,9 @@
Mot de passe
+
+ Compte Utilisateur Windows
+
Donner
diff --git a/ModernKeePass/ViewModels/CompositeKeyVm.cs b/ModernKeePass/ViewModels/CompositeKeyVm.cs
index acb86a6..4db8d0a 100644
--- a/ModernKeePass/ViewModels/CompositeKeyVm.cs
+++ b/ModernKeePass/ViewModels/CompositeKeyVm.cs
@@ -44,7 +44,17 @@ namespace ModernKeePass.ViewModels
}
}
- public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFile != null);
+ public bool HasUserAccount
+ {
+ get { return _hasUserAccount; }
+ set
+ {
+ SetProperty(ref _hasUserAccount, value);
+ OnPropertyChanged("IsValid");
+ }
+ }
+
+ public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFile != null || HasUserAccount);
public string Status
{
@@ -91,8 +101,10 @@ namespace ModernKeePass.ViewModels
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
+
private bool _hasPassword;
private bool _hasKeyFile;
+ private bool _hasUserAccount;
private bool _isOpening;
private string _password = string.Empty;
private string _status;
@@ -136,6 +148,7 @@ namespace ModernKeePass.ViewModels
if (HasPassword) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
if (HasPassword && HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserOr"));
if (HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
+ if (HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserAccount"));
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
break;
case DatabaseService.DatabaseStatus.Error:
@@ -169,6 +182,7 @@ namespace ModernKeePass.ViewModels
var compositeKey = new CompositeKey();
if (HasPassword) compositeKey.AddUserKey(new KcpPassword(Password));
if (HasKeyFile && KeyFile != null) compositeKey.AddUserKey(new KcpKeyFile(IOConnectionInfo.FromFile(KeyFile)));
+ if (HasUserAccount) compositeKey.AddUserKey(new KcpUserAccount());
return compositeKey;
}
}
diff --git a/ModernKeePass/ViewModels/GroupVm.cs b/ModernKeePass/ViewModels/GroupVm.cs
index 4292b7b..4ecc268 100644
--- a/ModernKeePass/ViewModels/GroupVm.cs
+++ b/ModernKeePass/ViewModels/GroupVm.cs
@@ -96,7 +96,6 @@ namespace ModernKeePass.ViewModels
private bool _isEditMode;
private PwEntry _reorderedEntry;
private ObservableCollection _entries = new ObservableCollection();
- private string _filter = string.Empty;
private bool _isMenuClosed = true;
public GroupVm() {}
diff --git a/ModernKeePass/Views/GroupDetailPage.xaml.cs b/ModernKeePass/Views/GroupDetailPage.xaml.cs
index 8feccb3..9102396 100644
--- a/ModernKeePass/Views/GroupDetailPage.xaml.cs
+++ b/ModernKeePass/Views/GroupDetailPage.xaml.cs
@@ -169,7 +169,6 @@ namespace ModernKeePass.Views
Frame.Navigate(typeof(EntryDetailPage), entry);
}
-
private void GroupDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
diff --git a/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml b/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml
index b03eebb..c92f476 100644
--- a/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml
+++ b/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml
@@ -31,6 +31,7 @@
+
@@ -55,7 +56,9 @@
-
-
+
+
+
+
diff --git a/ModernKeePassLib/Cryptography/ProtectedData.cs b/ModernKeePassLib/Cryptography/ProtectedData.cs
new file mode 100644
index 0000000..cf9dcd5
--- /dev/null
+++ b/ModernKeePassLib/Cryptography/ProtectedData.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Runtime.InteropServices.WindowsRuntime;
+using Windows.Security.Cryptography.DataProtection;
+using Windows.Storage.Streams;
+using ModernKeePassLib.Native;
+
+namespace ModernKeePassLib.Cryptography
+{
+ public static class ProtectedData
+ {
+ public static byte[] Protect(byte[] userData, byte[] optionalEntropy, DataProtectionScope scope)
+ {
+ var provider =
+ new DataProtectionProvider(scope == DataProtectionScope.CurrentUser ? "LOCAL=user" : "LOCAL=machine");
+ // Encode the plaintext input message to a buffer.
+ var buffMsg = userData.AsBuffer();
+
+ // Encrypt the message.
+ IBuffer buffProtected;
+ try
+ {
+ buffProtected = provider.ProtectAsync(buffMsg).GetAwaiter().GetResult();
+ }
+ catch (Exception e)
+ {
+ throw;
+ }
+
+ return buffProtected.ToArray();
+ }
+
+
+ public static byte[] Unprotect(byte[] userData, byte[] optionalEntropy, DataProtectionScope scope)
+ {
+ var provider =
+ new DataProtectionProvider(scope == DataProtectionScope.CurrentUser ? "LOCAL=user" : "LOCAL=machine");
+ // Decode the encrypted input message to a buffer.
+ var buffMsg = userData.AsBuffer();
+
+ // Decrypt the message.
+ IBuffer buffUnprotected;
+ try
+ {
+ buffUnprotected = provider.UnprotectAsync(buffMsg).GetAwaiter().GetResult();
+ }
+ catch (Exception e)
+ {
+ throw;
+ }
+
+ return buffUnprotected.ToArray();
+ }
+ }
+}
diff --git a/ModernKeePassLib/Keys/KcpUserAccount.cs b/ModernKeePassLib/Keys/KcpUserAccount.cs
index b427dc8..802b503 100644
--- a/ModernKeePassLib/Keys/KcpUserAccount.cs
+++ b/ModernKeePassLib/Keys/KcpUserAccount.cs
@@ -98,8 +98,9 @@ namespace ModernKeePassLib.Keys
#endif
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
- strUserDir += PwDefs.ShortProductName;
+
#if !ModernKeePassLib
+ strUserDir += PwDefs.ShortProductName;
if(bCreate && !Directory.Exists(strUserDir))
Directory.CreateDirectory(strUserDir);
@@ -117,10 +118,13 @@ namespace ModernKeePassLib.Keys
{
string strFilePath = GetUserKeyFilePath(false);
#if ModernKeePassLib
- var fileStream = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult().OpenStreamForReadAsync().GetAwaiter().GetResult();
- var pbProtectedKey = new byte[(int)fileStream.Length];
- fileStream.Read(pbProtectedKey, 0, (int)fileStream.Length);
- fileStream.Dispose();
+ byte[] pbProtectedKey;
+ using (var fileStream = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult()
+ .OpenStreamForReadAsync().GetAwaiter().GetResult())
+ {
+ pbProtectedKey = new byte[(int) fileStream.Length];
+ fileStream.Read(pbProtectedKey, 0, (int) fileStream.Length);
+ }
#else
byte[] pbProtectedKey = File.ReadAllBytes(strFilePath);
#endif
@@ -148,9 +152,11 @@ namespace ModernKeePassLib.Keys
byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey,
m_pbEntropy, DataProtectionScope.CurrentUser);
#if ModernKeePassLib
- var fileStream = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult().OpenStreamForWriteAsync().GetAwaiter().GetResult();
- fileStream.Write(pbProtectedKey, 0, (int)fileStream.Length);
- fileStream.Dispose();
+ using (var fileStream = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult()
+ .OpenStreamForWriteAsync().GetAwaiter().GetResult())
+ {
+ fileStream.Write(pbProtectedKey, 0, (int) fileStream.Length);
+ }
#else
File.WriteAllBytes(strFilePath, pbProtectedKey);
#endif
diff --git a/ModernKeePassLib/ModernKeePassLib.csproj b/ModernKeePassLib/ModernKeePassLib.csproj
index 8e54fec..8cd02bb 100644
--- a/ModernKeePassLib/ModernKeePassLib.csproj
+++ b/ModernKeePassLib/ModernKeePassLib.csproj
@@ -81,6 +81,7 @@
+
diff --git a/ModernKeePassLib/ModernKeePassLib.nuspec b/ModernKeePassLib/ModernKeePassLib.nuspec
index f797fc9..4968abc 100644
--- a/ModernKeePassLib/ModernKeePassLib.nuspec
+++ b/ModernKeePassLib/ModernKeePassLib.nuspec
@@ -2,7 +2,7 @@
ModernKeePassLib
- 2.37.8000
+ 2.37.9000
ModernKeePassLib
Geoffroy Bonneville
Geoffroy Bonneville
@@ -10,7 +10,7 @@
https://github.com/wismna/ModernKeePass
false
Portable KeePass Password Management Library that targets .Net Standard and WinRT. Allows reading, editing and writing to KeePass 2.x databases.
- Code cleanup
+ Implements Windows User Accounts
Copyright © 2017 Geoffroy Bonneville
KeePass KeePassLib Portable PCL NetStandard
diff --git a/ModernKeePassLib/Native/Native.PCL.cs b/ModernKeePassLib/Native/Native.PCL.cs
index 7836989..aefad05 100644
--- a/ModernKeePassLib/Native/Native.PCL.cs
+++ b/ModernKeePassLib/Native/Native.PCL.cs
@@ -54,25 +54,12 @@ namespace ModernKeePassLib.Native
}
}
- internal enum DataProtectionScope
+ public 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,
diff --git a/ModernKeePassLib/Utility/StrUtil.cs b/ModernKeePassLib/Utility/StrUtil.cs
index 3d1216b..a2894c6 100644
--- a/ModernKeePassLib/Utility/StrUtil.cs
+++ b/ModernKeePassLib/Utility/StrUtil.cs
@@ -34,6 +34,7 @@ using System.Security.Cryptography;
#endif
using ModernKeePassLib.Collections;
+using ModernKeePassLib.Cryptography;
using ModernKeePassLib.Cryptography.PasswordGenerator;
using ModernKeePassLib.Native;
using ModernKeePassLib.Security;