mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
WIP Windows User Accounts Composite Key integration
This commit is contained in:
@@ -339,10 +339,6 @@
|
||||
<HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="ModernKeePassLib, Version=2.37.0.2000, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ModernKeePassLib.2.37.8000\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Splat.2.0.0\lib\Portable-Win81+Wpa81\Splat.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
@@ -435,7 +431,12 @@
|
||||
<Content Include="Assets\Wide310x150Logo.scale-180.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-80.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ModernKeePassLib\ModernKeePassLib.csproj">
|
||||
<Project>{2e710089-9559-4967-846c-e763dd1f3acb}</Project>
|
||||
<Name>ModernKeePassLib</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
|
@@ -270,4 +270,7 @@
|
||||
<data name="SettingsMenuItemSecurity" xml:space="preserve">
|
||||
<value>Security</value>
|
||||
</data>
|
||||
<data name="CompositeKeyErrorUserAccount" xml:space="preserve">
|
||||
<value>user account</value>
|
||||
</data>
|
||||
</root>
|
@@ -171,6 +171,9 @@
|
||||
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
|
||||
<value>Password</value>
|
||||
</data>
|
||||
<data name="CompositeKeyUserAccount.Text" xml:space="preserve">
|
||||
<value>Windows User Account</value>
|
||||
</data>
|
||||
<data name="DonateButton.Content" xml:space="preserve">
|
||||
<value>Donate</value>
|
||||
</data>
|
||||
|
@@ -271,4 +271,7 @@
|
||||
<data name="SettingsMenuItemSecurity" xml:space="preserve">
|
||||
<value>Sécurité</value>
|
||||
</data>
|
||||
<data name="CompositeKeyErrorUserAccount" xml:space="preserve">
|
||||
<value>compte utilisateur</value>
|
||||
</data>
|
||||
</root>
|
@@ -171,6 +171,9 @@
|
||||
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
|
||||
<value>Mot de passe</value>
|
||||
</data>
|
||||
<data name="CompositeKeyUserAccount.Text" xml:space="preserve">
|
||||
<value>Compte Utilisateur Windows</value>
|
||||
</data>
|
||||
<data name="DonateButton.Content" xml:space="preserve">
|
||||
<value>Donner</value>
|
||||
</data>
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -96,7 +96,6 @@ namespace ModernKeePass.ViewModels
|
||||
private bool _isEditMode;
|
||||
private PwEntry _reorderedEntry;
|
||||
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
|
||||
private string _filter = string.Empty;
|
||||
private bool _isMenuClosed = true;
|
||||
|
||||
public GroupVm() {}
|
||||
|
@@ -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);
|
||||
|
@@ -31,6 +31,7 @@
|
||||
<RowDefinition Height="45" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding HasPassword, Mode=TwoWay}" />
|
||||
@@ -55,7 +56,9 @@
|
||||
</ToolTipService.ToolTip>
|
||||
</SymbolIcon>
|
||||
</HyperlinkButton>
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="28" FontSize="14" FontWeight="Light" Text="{Binding Status}" Foreground="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" Visibility="{Binding Status, Converter={StaticResource EmptyStringToVisibilityConverter}}" />
|
||||
<Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" Content="{Binding ButtonLabel, ElementName=UserControl}" Click="OpenButton_OnClick" Background="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" Foreground="{ThemeResource TextBoxBackgroundThemeBrush}" IsEnabled="{Binding IsValid}" />
|
||||
<CheckBox Grid.Row="2" Grid.Column="0" IsChecked="{Binding HasUserAccount, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="1" x:Uid="CompositeKeyUserAccount" FontSize="14" VerticalAlignment="Center" />
|
||||
<Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Content="{Binding ButtonLabel, ElementName=UserControl}" Click="OpenButton_OnClick" Background="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" Foreground="{ThemeResource TextBoxBackgroundThemeBrush}" IsEnabled="{Binding IsValid}" />
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="4" Height="28" FontSize="14" FontWeight="Light" Text="{Binding Status}" Foreground="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" Visibility="{Binding Status, Converter={StaticResource EmptyStringToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
54
ModernKeePassLib/Cryptography/ProtectedData.cs
Normal file
54
ModernKeePassLib/Cryptography/ProtectedData.cs
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
@@ -81,6 +81,7 @@
|
||||
<Compile Include="Cryptography\PasswordGenerator\PwCharSet.cs" />
|
||||
<Compile Include="Cryptography\PasswordGenerator\PwProfile.cs" />
|
||||
<Compile Include="Cryptography\PopularPasswords.cs" />
|
||||
<Compile Include="Cryptography\ProtectedData.cs" />
|
||||
<Compile Include="Cryptography\QualityEstimation.cs" />
|
||||
<Compile Include="Cryptography\SelfTest.cs" />
|
||||
<Compile Include="Interfaces\IStructureItem.cs" />
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<package >
|
||||
<metadata>
|
||||
<id>ModernKeePassLib</id>
|
||||
<version>2.37.8000</version>
|
||||
<version>2.37.9000</version>
|
||||
<title>ModernKeePassLib</title>
|
||||
<authors>Geoffroy Bonneville</authors>
|
||||
<owners>Geoffroy Bonneville</owners>
|
||||
@@ -10,7 +10,7 @@
|
||||
<projectUrl>https://github.com/wismna/ModernKeePass</projectUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Portable KeePass Password Management Library that targets .Net Standard and WinRT. Allows reading, editing and writing to KeePass 2.x databases.</description>
|
||||
<releaseNotes>Code cleanup</releaseNotes>
|
||||
<releaseNotes>Implements Windows User Accounts</releaseNotes>
|
||||
<copyright>Copyright © 2017 Geoffroy Bonneville</copyright>
|
||||
<tags>KeePass KeePassLib Portable PCL NetStandard</tags>
|
||||
<dependencies>
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user