mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-04 08:00:16 -04:00
Removed User Account from composite key (probably never going to work as intended)
Changed copy URL to navigate to URL in entry quick menu
This commit is contained in:
33
ModernKeePass/Actions/NavigateToUrlAction.cs
Normal file
33
ModernKeePass/Actions/NavigateToUrlAction.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Microsoft.Xaml.Interactivity;
|
||||||
|
using ModernKeePass.Common;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Actions
|
||||||
|
{
|
||||||
|
public class NavigateToUrlAction : DependencyObject, IAction
|
||||||
|
{
|
||||||
|
public string Url
|
||||||
|
{
|
||||||
|
get { return (string)GetValue(UrlProperty); }
|
||||||
|
set { SetValue(UrlProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty UrlProperty =
|
||||||
|
DependencyProperty.Register("Url", typeof(string), typeof(NavigateToUrlAction), new PropertyMetadata(string.Empty));
|
||||||
|
|
||||||
|
public object Execute(object sender, object parameter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var uri = new Uri(Url);
|
||||||
|
return Windows.System.Launcher.LaunchUriAsync(uri).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageDialogHelper.ShowErrorDialog(ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -109,6 +109,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Actions\ClipboardAction.cs" />
|
<Compile Include="Actions\ClipboardAction.cs" />
|
||||||
|
<Compile Include="Actions\NavigateToUrlAction.cs" />
|
||||||
<Compile Include="Actions\SetupFocusAction.cs" />
|
<Compile Include="Actions\SetupFocusAction.cs" />
|
||||||
<Compile Include="App.xaml.cs">
|
<Compile Include="App.xaml.cs">
|
||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
@@ -339,6 +340,10 @@
|
|||||||
<HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</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">
|
<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>
|
<HintPath>..\packages\Splat.2.0.0\lib\Portable-Win81+Wpa81\Splat.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
@@ -431,12 +436,6 @@
|
|||||||
<Content Include="Assets\Wide310x150Logo.scale-180.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-180.png" />
|
||||||
<Content Include="Assets\Wide310x150Logo.scale-80.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' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@@ -193,7 +193,7 @@
|
|||||||
<value>Copy password</value>
|
<value>Copy password</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
|
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
|
||||||
<value>Copy URL</value>
|
<value>Navigate to URL</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EntryLogin.Text" xml:space="preserve">
|
<data name="EntryLogin.Text" xml:space="preserve">
|
||||||
<value>User name or login</value>
|
<value>User name or login</value>
|
||||||
|
@@ -193,7 +193,7 @@
|
|||||||
<value>Copier le mot de passe</value>
|
<value>Copier le mot de passe</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
|
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
|
||||||
<value>Copier l'URL</value>
|
<value>Naviguer vers l'URL</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EntryLogin.Text" xml:space="preserve">
|
<data name="EntryLogin.Text" xml:space="preserve">
|
||||||
<value>Nom d'utilisateur ou login</value>
|
<value>Nom d'utilisateur ou login</value>
|
||||||
|
@@ -458,7 +458,13 @@
|
|||||||
<ProgressBar Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}}" Maximum="128" Width="350" HorizontalAlignment="Left" Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushComplexityConverter}}" />
|
<ProgressBar Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}}" Maximum="128" Width="350" HorizontalAlignment="Left" Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushComplexityConverter}}" />
|
||||||
<CheckBox x:Uid="EntryShowPassword" HorizontalAlignment="Left" Margin="-3,0,0,0" IsChecked="{Binding IsRevealPassword, Mode=TwoWay}" IsEnabled="{Binding IsRevealPasswordEnabled}" />
|
<CheckBox x:Uid="EntryShowPassword" HorizontalAlignment="Left" Margin="-3,0,0,0" IsChecked="{Binding IsRevealPassword, Mode=TwoWay}" IsEnabled="{Binding IsRevealPasswordEnabled}" />
|
||||||
<TextBlock TextWrapping="Wrap" Text="URL" FontSize="18"/>
|
<TextBlock TextWrapping="Wrap" Text="URL" FontSize="18"/>
|
||||||
<local:TextBoxWithButton x:Name="UrlTextBox" HorizontalAlignment="Left" Text="{Binding Url, Mode=TwoWay}" Height="32" Width="350" MaxLength="256" Style="{StaticResource TextBoxWithButtonStyle}" ButtonClick="UrlButton_Click" ButtonSymbol="" ButtonTooltip="Navigate to URL" />
|
<local:TextBoxWithButton x:Name="UrlTextBox" HorizontalAlignment="Left" Text="{Binding Url, Mode=TwoWay}" Height="32" Width="350" MaxLength="256" Style="{StaticResource TextBoxWithButtonStyle}" ButtonSymbol="" ButtonTooltip="Navigate to URL">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<core:EventTriggerBehavior EventName="ButtonClick">
|
||||||
|
<actions:NavigateToUrlAction Url="{Binding Url}" />
|
||||||
|
</core:EventTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</local:TextBoxWithButton>
|
||||||
<TextBlock x:Uid="EntryNotes" TextWrapping="Wrap" FontSize="18" />
|
<TextBlock x:Uid="EntryNotes" TextWrapping="Wrap" FontSize="18" />
|
||||||
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" />
|
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" />
|
||||||
<CheckBox x:Uid="EntryExpirationDate" FontSize="18" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" />
|
<CheckBox x:Uid="EntryExpirationDate" FontSize="18" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" />
|
||||||
|
@@ -93,19 +93,6 @@ namespace ModernKeePass.Views
|
|||||||
if (Frame.CanGoBack) Frame.GoBack();
|
if (Frame.CanGoBack) Frame.GoBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UrlButton_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var uri = new Uri(UrlTextBox.Text);
|
|
||||||
await Windows.System.Launcher.LaunchUriAsync(uri);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageDialogHelper.ShowErrorDialog(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EntryDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
|
private void EntryDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
{
|
{
|
||||||
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
|
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
|
||||||
|
@@ -255,7 +255,7 @@
|
|||||||
<MenuFlyoutItem x:Uid="EntryItemCopyUrl">
|
<MenuFlyoutItem x:Uid="EntryItemCopyUrl">
|
||||||
<interactivity:Interaction.Behaviors>
|
<interactivity:Interaction.Behaviors>
|
||||||
<core:EventTriggerBehavior EventName="Click">
|
<core:EventTriggerBehavior EventName="Click">
|
||||||
<actions:ClipboardAction Text="{Binding Url}" />
|
<actions:NavigateToUrlAction Url="{Binding Url}" />
|
||||||
</core:EventTriggerBehavior>
|
</core:EventTriggerBehavior>
|
||||||
</interactivity:Interaction.Behaviors>
|
</interactivity:Interaction.Behaviors>
|
||||||
</MenuFlyoutItem>
|
</MenuFlyoutItem>
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
||||||
mc:Ignorable="d" >
|
mc:Ignorable="d" >
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<SolidColorBrush x:Key="ErrorColorBrush" Color="Red"/>
|
|
||||||
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
|
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
|
||||||
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushConverter"/>
|
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushConverter"/>
|
||||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||||
@@ -31,7 +30,6 @@
|
|||||||
<RowDefinition Height="45" />
|
<RowDefinition Height="45" />
|
||||||
<RowDefinition Height="40" />
|
<RowDefinition Height="40" />
|
||||||
<RowDefinition Height="40" />
|
<RowDefinition Height="40" />
|
||||||
<RowDefinition Height="40" />
|
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding HasPassword, Mode=TwoWay}" />
|
<CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding HasPassword, Mode=TwoWay}" />
|
||||||
@@ -56,9 +54,7 @@
|
|||||||
</ToolTipService.ToolTip>
|
</ToolTipService.ToolTip>
|
||||||
</SymbolIcon>
|
</SymbolIcon>
|
||||||
</HyperlinkButton>
|
</HyperlinkButton>
|
||||||
<CheckBox Grid.Row="2" Grid.Column="0" IsChecked="{Binding HasUserAccount, Mode=TwoWay}" />
|
<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}" />
|
||||||
<TextBlock Grid.Row="2" Grid.Column="1" x:Uid="CompositeKeyUserAccount" FontSize="14" VerticalAlignment="Center" />
|
<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="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>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
Error when opening file from Explorer corrected
|
New inline menu on Entries to quickly copy login, password, and navigate to URL
|
||||||
Filter entries reverted to search entries because of regressions
|
Design changes
|
@@ -1,2 +1,2 @@
|
|||||||
Correction d'un bug lors de l'ouverture d'un fichier par Explorer
|
Ajout d'un menu int&eacute;gr&eacute; &agrave; la liste d'entr&eacute;es afin de copier rapidement le login, mot de passe et de naviguer vers l'URL
|
||||||
R&eacute;tablissement de la recherche d'entr&eacute;es &agrave; la place du filtre &agrave; cause de r&eacute;gressions multiples
|
Quelques changements de design
|
@@ -1,62 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.Security.Cryptography.DataProtection;
|
|
||||||
using Windows.Storage.Streams;
|
|
||||||
using ModernKeePassLib.Native;
|
using ModernKeePassLib.Native;
|
||||||
|
|
||||||
namespace ModernKeePassLib.Cryptography
|
namespace ModernKeePassLib.Cryptography
|
||||||
{
|
{
|
||||||
public static class ProtectedData
|
public static class ProtectedData
|
||||||
{
|
{
|
||||||
public static async Task ProtectStream(byte[] buffer, IOutputStream stream)
|
|
||||||
{
|
|
||||||
//instantiate a DataProtectionProvider for decryption
|
|
||||||
var dpp = new DataProtectionProvider("LOCAL=user");
|
|
||||||
|
|
||||||
//Open a stream to load data in
|
|
||||||
using (var inputStream = new InMemoryRandomAccessStream())
|
|
||||||
{
|
|
||||||
//cteate data writer to write data to the input stream
|
|
||||||
using (var dw = new DataWriter(inputStream))
|
|
||||||
{
|
|
||||||
//write data to the stream
|
|
||||||
dw.WriteBuffer(buffer.AsBuffer());
|
|
||||||
await dw.StoreAsync();
|
|
||||||
|
|
||||||
//encrypt the intput stream into the file stream
|
|
||||||
await dpp.ProtectStreamAsync(inputStream.GetInputStreamAt(0),
|
|
||||||
stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<byte[]> UnprotectStream(IInputStream stream)
|
|
||||||
{
|
|
||||||
//instantiate a DataProtectionProvider for decryption
|
|
||||||
var dpp = new DataProtectionProvider();
|
|
||||||
|
|
||||||
//create a stream to decrypte the data to
|
|
||||||
using (var outputStream = new InMemoryRandomAccessStream())
|
|
||||||
{
|
|
||||||
//decrypt the data
|
|
||||||
await dpp.UnprotectStreamAsync(stream, outputStream);
|
|
||||||
|
|
||||||
//fill the data reader with the content of the outputStream,
|
|
||||||
//but from position 0
|
|
||||||
using (var dr = new DataReader(outputStream.GetInputStreamAt(0)))
|
|
||||||
{
|
|
||||||
//load data from the stream to the dataReader
|
|
||||||
await dr.LoadAsync((uint)outputStream.Size);
|
|
||||||
|
|
||||||
//load the data from the datareader into a buffer
|
|
||||||
IBuffer data = dr.ReadBuffer((uint)outputStream.Size);
|
|
||||||
|
|
||||||
return data.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] Unprotect(byte[] pbEnc, byte[] mPbOptEnt, DataProtectionScope currentUser)
|
public static byte[] Unprotect(byte[] pbEnc, byte[] mPbOptEnt, DataProtectionScope currentUser)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
@@ -20,7 +20,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
|
||||||
using System.Security;
|
using System.Security;
|
||||||
|
|
||||||
#if ModernKeePassLib
|
#if ModernKeePassLib
|
||||||
@@ -36,136 +35,132 @@ using ModernKeePassLib.Utility;
|
|||||||
|
|
||||||
namespace ModernKeePassLib.Keys
|
namespace ModernKeePassLib.Keys
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A user key depending on the currently logged on Windows user account.
|
/// A user key depending on the currently logged on Windows user account.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class KcpUserAccount : IUserKey
|
public sealed class KcpUserAccount : IUserKey
|
||||||
{
|
{
|
||||||
private ProtectedBinary m_pbKeyData = null;
|
private ProtectedBinary m_pbKeyData = null;
|
||||||
|
|
||||||
// Constant initialization vector (unique for KeePass)
|
// Constant initialization vector (unique for KeePass)
|
||||||
private static readonly byte[] m_pbEntropy = new byte[] {
|
private static readonly byte[] m_pbEntropy = new byte[] {
|
||||||
0xDE, 0x13, 0x5B, 0x5F, 0x18, 0xA3, 0x46, 0x70,
|
0xDE, 0x13, 0x5B, 0x5F, 0x18, 0xA3, 0x46, 0x70,
|
||||||
0xB2, 0x57, 0x24, 0x29, 0x69, 0x88, 0x98, 0xE6
|
0xB2, 0x57, 0x24, 0x29, 0x69, 0x88, 0x98, 0xE6
|
||||||
};
|
};
|
||||||
|
|
||||||
private const string UserKeyFileName = "ProtectedUserKey.bin";
|
private const string UserKeyFileName = "ProtectedUserKey.bin";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get key data. Querying this property is fast (it returns a
|
/// Get key data. Querying this property is fast (it returns a
|
||||||
/// reference to a cached <c>ProtectedBinary</c> object).
|
/// reference to a cached <c>ProtectedBinary</c> object).
|
||||||
/// If no key data is available, <c>null</c> is returned.
|
/// If no key data is available, <c>null</c> is returned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ProtectedBinary KeyData
|
public ProtectedBinary KeyData
|
||||||
{
|
{
|
||||||
get { return m_pbKeyData; }
|
get { return m_pbKeyData; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Construct a user account key.
|
/// Construct a user account key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public KcpUserAccount()
|
public KcpUserAccount()
|
||||||
{
|
{
|
||||||
// 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,
|
ProtectedData.Protect(pbDummyData, m_pbEntropy,
|
||||||
DataProtectionScope.CurrentUser);*/
|
DataProtectionScope.CurrentUser);
|
||||||
|
|
||||||
byte[] pbKey = LoadUserKey(false);
|
byte[] pbKey = LoadUserKey(false);
|
||||||
if(pbKey == null) pbKey = CreateUserKey();
|
if (pbKey == null) pbKey = CreateUserKey();
|
||||||
if(pbKey == null) // Should never happen
|
if (pbKey == null) // Should never happen
|
||||||
{
|
{
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
throw new SecurityException(KLRes.UserAccountKeyError);
|
throw new SecurityException(KLRes.UserAccountKeyError);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
||||||
MemUtil.ZeroByteArray(pbKey);
|
MemUtil.ZeroByteArray(pbKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void Clear()
|
// public void Clear()
|
||||||
// {
|
// {
|
||||||
// m_pbKeyData = null;
|
// m_pbKeyData = null;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private static string GetUserKeyFilePath(bool bCreate)
|
private static string GetUserKeyFilePath(bool bCreate)
|
||||||
{
|
{
|
||||||
#if ModernKeePassLib
|
#if ModernKeePassLib
|
||||||
string strUserDir = Windows.Storage.ApplicationData.Current.RoamingFolder.Path;
|
string strUserDir = Windows.Storage.ApplicationData.Current.RoamingFolder.Path;
|
||||||
#else
|
#else
|
||||||
string strUserDir = Environment.GetFolderPath(
|
string strUserDir = Environment.GetFolderPath(
|
||||||
Environment.SpecialFolder.ApplicationData);
|
Environment.SpecialFolder.ApplicationData);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||||
|
strUserDir += PwDefs.ShortProductName;
|
||||||
#if !ModernKeePassLib
|
#if !ModernKeePassLib
|
||||||
strUserDir += PwDefs.ShortProductName;
|
|
||||||
|
|
||||||
if(bCreate && !Directory.Exists(strUserDir))
|
if(bCreate && !Directory.Exists(strUserDir))
|
||||||
Directory.CreateDirectory(strUserDir);
|
Directory.CreateDirectory(strUserDir);
|
||||||
#endif
|
#endif
|
||||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||||
return (strUserDir + UserKeyFileName);
|
return (strUserDir + UserKeyFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] LoadUserKey(bool bThrow)
|
private static byte[] LoadUserKey(bool bThrow)
|
||||||
{
|
{
|
||||||
byte[] pbKey = null;
|
byte[] pbKey = null;
|
||||||
|
|
||||||
#if !KeePassLibSD
|
#if !KeePassLibSD
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string strFilePath = GetUserKeyFilePath(false);
|
string strFilePath = GetUserKeyFilePath(false);
|
||||||
#if ModernKeePassLib
|
#if ModernKeePassLib
|
||||||
var file = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult();
|
var fileStream = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult().OpenStreamForReadAsync().GetAwaiter().GetResult();
|
||||||
using (var fileStream = file.OpenReadAsync().GetAwaiter().GetResult())
|
var pbProtectedKey = new byte[(int)fileStream.Length];
|
||||||
{
|
fileStream.Read(pbProtectedKey, 0, (int)fileStream.Length);
|
||||||
pbKey = ProtectedData.UnprotectStream(fileStream).GetAwaiter().GetResult();
|
fileStream.Dispose();
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
byte[] pbProtectedKey = File.ReadAllBytes(strFilePath);
|
byte[] pbProtectedKey = File.ReadAllBytes(strFilePath);
|
||||||
|
#endif
|
||||||
pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy,
|
pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy,
|
||||||
DataProtectionScope.CurrentUser);
|
DataProtectionScope.CurrentUser);
|
||||||
#endif
|
}
|
||||||
}
|
catch (Exception)
|
||||||
catch(Exception)
|
{
|
||||||
{
|
if (bThrow) throw;
|
||||||
if(bThrow) throw;
|
pbKey = null;
|
||||||
pbKey = null;
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return pbKey;
|
return pbKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] CreateUserKey()
|
private static byte[] CreateUserKey()
|
||||||
{
|
{
|
||||||
#if KeePassLibSD
|
#if KeePassLibSD
|
||||||
return null;
|
return null;
|
||||||
#else
|
#else
|
||||||
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);
|
||||||
#if ModernKeePassLib
|
#if ModernKeePassLib
|
||||||
var file = ApplicationData.Current.RoamingFolder.CreateFileAsync(UserKeyFileName, CreationCollisionOption.ReplaceExisting).GetAwaiter().GetResult();
|
var fileStream = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult().OpenStreamForWriteAsync().GetAwaiter().GetResult();
|
||||||
using (var fileStream = file.OpenAsync(FileAccessMode.ReadWrite).GetAwaiter().GetResult())
|
fileStream.Write(pbProtectedKey, 0, (int)fileStream.Length);
|
||||||
{
|
fileStream.Dispose();
|
||||||
ProtectedData.ProtectStream(pbRandomKey, fileStream).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey,
|
|
||||||
m_pbEntropy, DataProtectionScope.CurrentUser);
|
|
||||||
File.WriteAllBytes(strFilePath, pbProtectedKey);
|
File.WriteAllBytes(strFilePath, pbProtectedKey);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
byte[] pbKey = LoadUserKey(true);
|
byte[] pbKey = LoadUserKey(true);
|
||||||
Debug.Assert(MemUtil.ArraysEqual(pbKey, pbRandomKey));
|
Debug.Assert(MemUtil.ArraysEqual(pbKey, pbRandomKey));
|
||||||
|
|
||||||
MemUtil.ZeroByteArray(pbRandomKey);
|
MemUtil.ZeroByteArray(pbRandomKey);
|
||||||
return pbKey;
|
return pbKey;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
<package >
|
<package >
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>ModernKeePassLib</id>
|
<id>ModernKeePassLib</id>
|
||||||
<version>2.37.9000</version>
|
<version>2.37.8000</version>
|
||||||
<title>ModernKeePassLib</title>
|
<title>ModernKeePassLib</title>
|
||||||
<authors>Geoffroy Bonneville</authors>
|
<authors>Geoffroy Bonneville</authors>
|
||||||
<owners>Geoffroy Bonneville</owners>
|
<owners>Geoffroy Bonneville</owners>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<projectUrl>https://github.com/wismna/ModernKeePass</projectUrl>
|
<projectUrl>https://github.com/wismna/ModernKeePass</projectUrl>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<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>
|
<description>Portable KeePass Password Management Library that targets .Net Standard and WinRT. Allows reading, editing and writing to KeePass 2.x databases.</description>
|
||||||
<releaseNotes>Implements Windows User Accounts</releaseNotes>
|
<releaseNotes></releaseNotes>
|
||||||
<copyright>Copyright © 2017 Geoffroy Bonneville</copyright>
|
<copyright>Copyright © 2017 Geoffroy Bonneville</copyright>
|
||||||
<tags>KeePass KeePassLib Portable PCL NetStandard</tags>
|
<tags>KeePass KeePassLib Portable PCL NetStandard</tags>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
Reference in New Issue
Block a user