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:
BONNEVILLE Geoffroy
2017-12-26 17:54:13 +01:00
parent fba668860b
commit abbff449c0
13 changed files with 144 additions and 180 deletions

View 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;
}
}
}
}

View File

@@ -109,6 +109,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Actions\ClipboardAction.cs" />
<Compile Include="Actions\NavigateToUrlAction.cs" />
<Compile Include="Actions\SetupFocusAction.cs" />
<Compile Include="App.xaml.cs">
<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>
<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>
@@ -431,12 +436,6 @@
<Content Include="Assets\Wide310x150Logo.scale-180.png" />
<Content Include="Assets\Wide310x150Logo.scale-80.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ModernKeePassLib\ModernKeePassLib.csproj">
<Project>{2e710089-9559-4967-846c-e763dd1f3acb}</Project>
<Name>ModernKeePassLib</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0' ">
<VisualStudioVersion>12.0</VisualStudioVersion>
</PropertyGroup>

View File

@@ -193,7 +193,7 @@
<value>Copy password</value>
</data>
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
<value>Copy URL</value>
<value>Navigate to URL</value>
</data>
<data name="EntryLogin.Text" xml:space="preserve">
<value>User name or login</value>

View File

@@ -193,7 +193,7 @@
<value>Copier le mot de passe</value>
</data>
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
<value>Copier l'URL</value>
<value>Naviguer vers l'URL</value>
</data>
<data name="EntryLogin.Text" xml:space="preserve">
<value>Nom d'utilisateur ou login</value>

View File

@@ -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}}" />
<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"/>
<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="&#xE111;" 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="&#xE111;" 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" />
<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}" />

View File

@@ -92,20 +92,7 @@ namespace ModernKeePass.Views
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityRestoredTitle"), resource.GetResourceValue("EntryRestored"));
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)
{
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);

View File

@@ -255,7 +255,7 @@
<MenuFlyoutItem x:Uid="EntryItemCopyUrl">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<actions:ClipboardAction Text="{Binding Url}" />
<actions:NavigateToUrlAction Url="{Binding Url}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</MenuFlyoutItem>

View File

@@ -11,7 +11,6 @@
xmlns:viewModels="using:ModernKeePass.ViewModels"
mc:Ignorable="d" >
<UserControl.Resources>
<SolidColorBrush x:Key="ErrorColorBrush" Color="Red"/>
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushConverter"/>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
@@ -31,7 +30,6 @@
<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}" />
@@ -56,9 +54,7 @@
</ToolTipService.ToolTip>
</SymbolIcon>
</HyperlinkButton>
<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}}" />
<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.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}}" />
</Grid>
</UserControl>

View File

@@ -1,2 +1,2 @@
Error when opening file from Explorer corrected
Filter entries reverted to search entries because of regressions
New inline menu on Entries to quickly copy login, password, and navigate to URL
Design changes

View File

@@ -1,2 +1,2 @@
Correction d'un bug lors de l'ouverture d'un fichier par Explorer
R&amp;eacute;tablissement de la recherche d'entr&amp;eacute;es &amp;agrave; la place du filtre &amp;agrave; cause de r&amp;eacute;gressions multiples
Ajout d'un menu int&amp;eacute;gr&amp;eacute; &amp;agrave; la liste d'entr&amp;eacute;es afin de copier rapidement le login, mot de passe et de naviguer vers l'URL
Quelques changements de design

View File

@@ -1,62 +1,10 @@
using System;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Security.Cryptography.DataProtection;
using Windows.Storage.Streams;
using ModernKeePassLib.Native;
namespace ModernKeePassLib.Cryptography
{
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)
{
throw new NotImplementedException();

View File

@@ -20,7 +20,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Security;
#if ModernKeePassLib
@@ -36,136 +35,132 @@ using ModernKeePassLib.Utility;
namespace ModernKeePassLib.Keys
{
/// <summary>
/// A user key depending on the currently logged on Windows user account.
/// </summary>
public sealed class KcpUserAccount : IUserKey
{
private ProtectedBinary m_pbKeyData = null;
/// <summary>
/// A user key depending on the currently logged on Windows user account.
/// </summary>
public sealed class KcpUserAccount : IUserKey
{
private ProtectedBinary m_pbKeyData = null;
// Constant initialization vector (unique for KeePass)
private static readonly byte[] m_pbEntropy = new byte[] {
0xDE, 0x13, 0x5B, 0x5F, 0x18, 0xA3, 0x46, 0x70,
0xB2, 0x57, 0x24, 0x29, 0x69, 0x88, 0x98, 0xE6
};
// Constant initialization vector (unique for KeePass)
private static readonly byte[] m_pbEntropy = new byte[] {
0xDE, 0x13, 0x5B, 0x5F, 0x18, 0xA3, 0x46, 0x70,
0xB2, 0x57, 0x24, 0x29, 0x69, 0x88, 0x98, 0xE6
};
private const string UserKeyFileName = "ProtectedUserKey.bin";
private const string UserKeyFileName = "ProtectedUserKey.bin";
/// <summary>
/// Get key data. Querying this property is fast (it returns a
/// reference to a cached <c>ProtectedBinary</c> object).
/// If no key data is available, <c>null</c> is returned.
/// </summary>
public ProtectedBinary KeyData
{
get { return m_pbKeyData; }
}
/// <summary>
/// Get key data. Querying this property is fast (it returns a
/// reference to a cached <c>ProtectedBinary</c> object).
/// If no key data is available, <c>null</c> is returned.
/// </summary>
public ProtectedBinary KeyData
{
get { return m_pbKeyData; }
}
/// <summary>
/// Construct a user account key.
/// </summary>
public KcpUserAccount()
{
// Test if ProtectedData is supported -- throws an exception
// when running on an old system (Windows 98 / ME).
/*byte[] pbDummyData = new byte[128];
ProtectedData.Protect(pbDummyData, m_pbEntropy,
DataProtectionScope.CurrentUser);*/
/// <summary>
/// Construct a user account key.
/// </summary>
public KcpUserAccount()
{
// Test if ProtectedData is supported -- throws an exception
// when running on an old system (Windows 98 / ME).
byte[] pbDummyData = new byte[128];
ProtectedData.Protect(pbDummyData, m_pbEntropy,
DataProtectionScope.CurrentUser);
byte[] pbKey = LoadUserKey(false);
if(pbKey == null) pbKey = CreateUserKey();
if(pbKey == null) // Should never happen
{
Debug.Assert(false);
throw new SecurityException(KLRes.UserAccountKeyError);
}
byte[] pbKey = LoadUserKey(false);
if (pbKey == null) pbKey = CreateUserKey();
if (pbKey == null) // Should never happen
{
Debug.Assert(false);
throw new SecurityException(KLRes.UserAccountKeyError);
}
m_pbKeyData = new ProtectedBinary(true, pbKey);
MemUtil.ZeroByteArray(pbKey);
}
m_pbKeyData = new ProtectedBinary(true, pbKey);
MemUtil.ZeroByteArray(pbKey);
}
// public void Clear()
// {
// m_pbKeyData = null;
// }
// public void Clear()
// {
// m_pbKeyData = null;
// }
private static string GetUserKeyFilePath(bool bCreate)
{
private static string GetUserKeyFilePath(bool bCreate)
{
#if ModernKeePassLib
string strUserDir = Windows.Storage.ApplicationData.Current.RoamingFolder.Path;
string strUserDir = Windows.Storage.ApplicationData.Current.RoamingFolder.Path;
#else
string strUserDir = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData);
#endif
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
strUserDir += PwDefs.ShortProductName;
#if !ModernKeePassLib
strUserDir += PwDefs.ShortProductName;
if(bCreate && !Directory.Exists(strUserDir))
Directory.CreateDirectory(strUserDir);
#endif
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
return (strUserDir + UserKeyFileName);
}
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
return (strUserDir + UserKeyFileName);
}
private static byte[] LoadUserKey(bool bThrow)
{
byte[] pbKey = null;
private static byte[] LoadUserKey(bool bThrow)
{
byte[] pbKey = null;
#if !KeePassLibSD
try
{
string strFilePath = GetUserKeyFilePath(false);
try
{
string strFilePath = GetUserKeyFilePath(false);
#if ModernKeePassLib
var file = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult();
using (var fileStream = file.OpenReadAsync().GetAwaiter().GetResult())
{
pbKey = ProtectedData.UnprotectStream(fileStream).GetAwaiter().GetResult();
}
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();
#else
byte[] pbProtectedKey = File.ReadAllBytes(strFilePath);
#endif
pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy,
DataProtectionScope.CurrentUser);
#endif
}
catch(Exception)
{
if(bThrow) throw;
pbKey = null;
}
DataProtectionScope.CurrentUser);
}
catch (Exception)
{
if (bThrow) throw;
pbKey = null;
}
#endif
return pbKey;
}
return pbKey;
}
private static byte[] CreateUserKey()
{
private static byte[] CreateUserKey()
{
#if KeePassLibSD
return null;
#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
var file = ApplicationData.Current.RoamingFolder.CreateFileAsync(UserKeyFileName, CreationCollisionOption.ReplaceExisting).GetAwaiter().GetResult();
using (var fileStream = file.OpenAsync(FileAccessMode.ReadWrite).GetAwaiter().GetResult())
{
ProtectedData.ProtectStream(pbRandomKey, fileStream).GetAwaiter().GetResult();
}
var fileStream = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult().OpenStreamForWriteAsync().GetAwaiter().GetResult();
fileStream.Write(pbProtectedKey, 0, (int)fileStream.Length);
fileStream.Dispose();
#else
byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey,
m_pbEntropy, DataProtectionScope.CurrentUser);
File.WriteAllBytes(strFilePath, pbProtectedKey);
#endif
byte[] pbKey = LoadUserKey(true);
Debug.Assert(MemUtil.ArraysEqual(pbKey, pbRandomKey));
Debug.Assert(MemUtil.ArraysEqual(pbKey, pbRandomKey));
MemUtil.ZeroByteArray(pbRandomKey);
return pbKey;
MemUtil.ZeroByteArray(pbRandomKey);
return pbKey;
#endif
}
}
}
}
}

View File

@@ -2,7 +2,7 @@
<package >
<metadata>
<id>ModernKeePassLib</id>
<version>2.37.9000</version>
<version>2.37.8000</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>Implements Windows User Accounts</releaseNotes>
<releaseNotes></releaseNotes>
<copyright>Copyright © 2017 Geoffroy Bonneville</copyright>
<tags>KeePass KeePassLib Portable PCL NetStandard</tags>
<dependencies>