mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-04 08:00:16 -04:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
abb12accc7 | ||
2779e5b7c7 | |||
3970d485f6 | |||
![]() |
7b888cc4a2 | ||
![]() |
117513d6bf | ||
97511ab290 | |||
3131eca8a1 | |||
91a5507217 | |||
7d904b7120 | |||
![]() |
be72fc4f7e |
@@ -14,6 +14,9 @@ namespace ModernKeePass.Common
|
|||||||
{
|
{
|
||||||
public enum DatabaseStatus
|
public enum DatabaseStatus
|
||||||
{
|
{
|
||||||
|
Error = -3,
|
||||||
|
NoCompositeKey = -2,
|
||||||
|
CompositeKeyError = -1,
|
||||||
Closed = 0,
|
Closed = 0,
|
||||||
Opening = 1,
|
Opening = 1,
|
||||||
Opened = 2
|
Opened = 2
|
||||||
@@ -77,11 +80,11 @@ namespace ModernKeePass.Common
|
|||||||
/// <param name="key">The database composite key</param>
|
/// <param name="key">The database composite key</param>
|
||||||
/// <param name="createNew">True to create a new database before opening it</param>
|
/// <param name="createNew">True to create a new database before opening it</param>
|
||||||
/// <returns>An error message, if any</returns>
|
/// <returns>An error message, if any</returns>
|
||||||
public string Open(CompositeKey key, bool createNew = false)
|
public void Open(CompositeKey key, bool createNew = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (key == null) return "No composite key";
|
if (key == null) Status = DatabaseStatus.NoCompositeKey;
|
||||||
var ioConnection = IOConnectionInfo.FromFile(DatabaseFile);
|
var ioConnection = IOConnectionInfo.FromFile(DatabaseFile);
|
||||||
if (createNew) _pwDatabase.New(ioConnection, key);
|
if (createNew) _pwDatabase.New(ioConnection, key);
|
||||||
else _pwDatabase.Open(ioConnection, key, new NullStatusLogger());
|
else _pwDatabase.Open(ioConnection, key, new NullStatusLogger());
|
||||||
@@ -92,19 +95,14 @@ namespace ModernKeePass.Common
|
|||||||
RootGroup = new GroupVm(_pwDatabase.RootGroup, null, RecycleBinEnabled ? _pwDatabase.RecycleBinUuid : null);
|
RootGroup = new GroupVm(_pwDatabase.RootGroup, null, RecycleBinEnabled ? _pwDatabase.RecycleBinUuid : null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ArgumentNullException)
|
|
||||||
{
|
|
||||||
return "Password cannot be empty";
|
|
||||||
}
|
|
||||||
catch (InvalidCompositeKeyException)
|
catch (InvalidCompositeKeyException)
|
||||||
{
|
{
|
||||||
return "Wrong password";
|
Status = DatabaseStatus.CompositeKeyError;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return ex.Message;
|
Status = DatabaseStatus.Error;
|
||||||
}
|
}
|
||||||
return string.Empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -121,11 +119,19 @@ namespace ModernKeePass.Common
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Commit the changes to the currently opened database to file
|
/// Commit the changes to the currently opened database to file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Save()
|
public bool Save()
|
||||||
{
|
{
|
||||||
// TODO: Save is disabled for now for Argon2Kdf because it corrupts DB (read works)
|
if (_pwDatabase == null || !_pwDatabase.IsOpen) return false;
|
||||||
if (_pwDatabase == null || !_pwDatabase.IsOpen /*|| KdfPool.Get(KeyDerivation.KdfUuid) is Argon2Kdf*/) return;
|
try
|
||||||
_pwDatabase.Save(new NullStatusLogger());
|
{
|
||||||
|
_pwDatabase.Save(new NullStatusLogger());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageDialogHelper.ShowErrorDialog(ex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -23,5 +23,17 @@ namespace ModernKeePass.Common
|
|||||||
// Show the message dialog
|
// Show the message dialog
|
||||||
await messageDialog.ShowAsync();
|
await messageDialog.ShowAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async void ShowErrorDialog(Exception exception)
|
||||||
|
{
|
||||||
|
// Create the message dialog and set its content
|
||||||
|
var messageDialog = new MessageDialog(exception.Message, "Error occured");
|
||||||
|
|
||||||
|
// Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers
|
||||||
|
messageDialog.Commands.Add(new UICommand("OK"));
|
||||||
|
|
||||||
|
// Show the message dialog
|
||||||
|
await messageDialog.ShowAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushConverter}}"
|
Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushConverter}}"
|
||||||
Visibility="{Binding ShowComplexityIndicator, ElementName=UserControl, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
Visibility="{Binding ShowComplexityIndicator, ElementName=UserControl, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||||
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" />
|
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" />
|
||||||
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0" Content="Select key file from disk..." IsEnabled="{Binding HasKeyFile}" Click="KeyFileButton_Click" />
|
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0" Content="{Binding KeyFileText}" IsEnabled="{Binding HasKeyFile}" Click="KeyFileButton_Click" />
|
||||||
<Button Grid.Column="0" Grid.Row="2" Content="OK" Click="OpenButton_OnClick" Background="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" Foreground="{ThemeResource TextBoxBackgroundThemeBrush}" IsEnabled="{Binding IsValid}" />
|
<Button Grid.Column="0" Grid.Row="2" Content="OK" Click="OpenButton_OnClick" Background="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" Foreground="{ThemeResource TextBoxBackgroundThemeBrush}" IsEnabled="{Binding IsValid}" />
|
||||||
<TextBlock Grid.Column="1" Grid.Row="2" Height="28" FontSize="14" FontWeight="Light" HorizontalAlignment="Right" Text="{Binding Status}" Foreground="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" />
|
<TextBlock Grid.Column="1" Grid.Row="2" Height="28" FontSize="14" FontWeight="Light" HorizontalAlignment="Right" Text="{Binding Status}" Foreground="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@@ -3,7 +3,6 @@ using Windows.Storage.Pickers;
|
|||||||
using Windows.System;
|
using Windows.System;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Input;
|
using Windows.UI.Xaml.Input;
|
||||||
using ModernKeePass.Common;
|
|
||||||
using ModernKeePass.Events;
|
using ModernKeePass.Events;
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
|
|
||||||
@@ -56,7 +55,7 @@ namespace ModernKeePass.Controls
|
|||||||
ValidationChecking?.Invoke(this, new EventArgs());
|
ValidationChecking?.Invoke(this, new EventArgs());
|
||||||
|
|
||||||
if (UpdateKey) Model.UpdateKey();
|
if (UpdateKey) Model.UpdateKey();
|
||||||
else if (Model.OpenDatabase(CreateNew) == DatabaseHelper.DatabaseStatus.Opened)
|
else if (Model.OpenDatabase(CreateNew))
|
||||||
{
|
{
|
||||||
ValidationChecked?.Invoke(this, new PasswordEventArgs(Model.RootGroup));
|
ValidationChecked?.Invoke(this, new PasswordEventArgs(Model.RootGroup));
|
||||||
}
|
}
|
||||||
@@ -78,7 +77,9 @@ namespace ModernKeePass.Controls
|
|||||||
picker.FileTypeFilter.Add(".key");
|
picker.FileTypeFilter.Add(".key");
|
||||||
|
|
||||||
// Application now has read/write access to the picked file
|
// Application now has read/write access to the picked file
|
||||||
Model.KeyFile = await picker.PickSingleFileAsync();
|
var file = await picker.PickSingleFileAsync();
|
||||||
|
if (file == null) return;
|
||||||
|
Model.KeyFile = file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
|
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
|
||||||
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.7.0.28" />
|
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.8.0.28" />
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>ModernKeePass</DisplayName>
|
<DisplayName>ModernKeePass</DisplayName>
|
||||||
<PublisherDisplayName>wismna</PublisherDisplayName>
|
<PublisherDisplayName>wismna</PublisherDisplayName>
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
<Run Text="Dominik Reichl for the KeePass application and file format"/>
|
<Run Text="Dominik Reichl for the KeePass application and file format"/>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="30,0,0,0">
|
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="30,0,0,0">
|
||||||
<Run Text="ArtjomP for his PCL adapatation of the KeePass Library"/>
|
<Run Text="David Lechner for his PCL adapatation of the KeePass Library and his correlated tests"/>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Page>
|
</Page>
|
||||||
|
@@ -24,6 +24,6 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.7.0.0")]
|
[assembly: AssemblyVersion("1.8.0.0")]
|
||||||
[assembly: AssemblyFileVersion("1.7.0.0")]
|
[assembly: AssemblyFileVersion("1.8.0.0")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
@@ -1,4 +1,5 @@
|
|||||||
using Windows.Storage;
|
using System.Text;
|
||||||
|
using Windows.Storage;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePassLib.Cryptography;
|
using ModernKeePassLib.Cryptography;
|
||||||
@@ -24,6 +25,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
private string _status;
|
private string _status;
|
||||||
private StatusTypes _statusType;
|
private StatusTypes _statusType;
|
||||||
private StorageFile _keyFile;
|
private StorageFile _keyFile;
|
||||||
|
private string _keyFileText = "Select key file from disk...";
|
||||||
|
|
||||||
public bool HasPassword
|
public bool HasPassword
|
||||||
{
|
{
|
||||||
@@ -45,7 +47,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsValid => HasPassword || HasKeyFile;
|
public bool IsValid => HasPassword || HasKeyFile && KeyFile != null;
|
||||||
|
|
||||||
public string Status
|
public string Status
|
||||||
{
|
{
|
||||||
@@ -76,18 +78,37 @@ namespace ModernKeePass.ViewModels
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_keyFile = value;
|
_keyFile = value;
|
||||||
UpdateStatus($"Key file: {value.Name}", StatusTypes.Normal);
|
KeyFileText = value?.Name;
|
||||||
|
OnPropertyChanged("IsValid");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string KeyFileText
|
||||||
|
{
|
||||||
|
get { return _keyFileText; }
|
||||||
|
set { SetProperty(ref _keyFileText, value); }
|
||||||
|
}
|
||||||
|
|
||||||
public GroupVm RootGroup { get; set; }
|
public GroupVm RootGroup { get; set; }
|
||||||
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
||||||
|
|
||||||
public DatabaseHelper.DatabaseStatus OpenDatabase(bool createNew)
|
public bool OpenDatabase(bool createNew)
|
||||||
{
|
{
|
||||||
UpdateStatus(_app.Database.Open(CreateCompositeKey(), createNew), StatusTypes.Error);
|
_app.Database.Open(CreateCompositeKey(), createNew);
|
||||||
RootGroup = _app.Database.RootGroup;
|
switch (_app.Database.Status)
|
||||||
return _app.Database.Status;
|
{
|
||||||
|
case DatabaseHelper.DatabaseStatus.Opened:
|
||||||
|
RootGroup = _app.Database.RootGroup;
|
||||||
|
return true;
|
||||||
|
case DatabaseHelper.DatabaseStatus.CompositeKeyError:
|
||||||
|
var errorMessage = new StringBuilder("Error: wrong ");
|
||||||
|
if (HasPassword) errorMessage.Append("password");
|
||||||
|
if (HasPassword && HasKeyFile) errorMessage.Append(" or ");
|
||||||
|
if (HasKeyFile) errorMessage.Append("key file");
|
||||||
|
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateKey()
|
public void UpdateKey()
|
||||||
|
@@ -91,7 +91,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public SettingsDatabaseVm()
|
public SettingsDatabaseVm()
|
||||||
{
|
{
|
||||||
Groups = _app.Database.RootGroup.Groups;
|
Groups = _app?.Database.RootGroup.Groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move to another setting class (or a static class)
|
// TODO: Move to another setting class (or a static class)
|
||||||
|
@@ -8,9 +8,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
public void Save(bool close = true)
|
public void Save(bool close = true)
|
||||||
{
|
{
|
||||||
var app = (App)Application.Current;
|
var app = (App)Application.Current;
|
||||||
app.Database.Save();
|
if (close && app.Database.Save()) app.Database.Close();
|
||||||
if (!close) return;
|
|
||||||
app.Database.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Save(StorageFile file)
|
internal void Save(StorageFile file)
|
||||||
|
13
ModernKeePassLib/README.md
Normal file
13
ModernKeePassLib/README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# ModernKeePassLib
|
||||||
|
|
||||||
|
This is my adaptation of the KeePassLib (KeePass library) for the Universal Windows Platform and Windows Runtime (WinRT).
|
||||||
|
It aims at introducing as little change as possible to the original library: overall, except for namespace changes and some added classes (see below), there is almost no change.
|
||||||
|
|
||||||
|
Download the Nuget package [here](https://www.nuget.org/packages/ModernKeePassLib)
|
||||||
|
|
||||||
|
# Features
|
||||||
|
- Custom implementation of the System.Security.Cryptography.HashAlgoritm class by using WinRT equivalents
|
||||||
|
- Use of BouncyCastle PCL to implement AES key derivation features
|
||||||
|
- Lots of small changes in .NET methods (UTF8 instead of ASCII, string.)
|
||||||
|
- Disabled native functions (because not compatible with WinRT)
|
||||||
|
- Use of Splat for GfxUtil
|
46
README.md
46
README.md
@@ -1,20 +1,40 @@
|
|||||||
# Introduction
|
# Introduction
|
||||||
TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project.
|
**ModernKeePass** is port of the classic Windows application KeePass 2.x for the Windows Store.
|
||||||
|
It does not aim to be feature perfect, but aims at being simple to use and user-friendly.
|
||||||
|
|
||||||
# Getting Started
|
You can get it [here](https://www.microsoft.com/fr-fr/store/p/modernkeepass/9mwq48zk8nhv?rtc=1)
|
||||||
TODO: Guide users through getting your code up and running on their own system. In this section you can talk about:
|
|
||||||
1. Installation process
|
# Features
|
||||||
2. Software dependencies
|
- Works on Windows 10, 8.1 and RT
|
||||||
3. Latest releases
|
- Read and write support of KDBX files version 2, 3 and 4
|
||||||
4. API references
|
- Open database with password and key file
|
||||||
|
- Create new databases
|
||||||
|
- Create, edit and delete groups
|
||||||
|
- Create, edit and delete entries
|
||||||
|
- Generate passwords for entries
|
||||||
|
- Use Recycle Bin
|
||||||
|
- Search entries
|
||||||
|
- Use Semantic Zoom to see your entries in a grouped mode
|
||||||
|
- List recently opened databases
|
||||||
|
- Open database from Windows Explorer
|
||||||
|
- Change database encryption
|
||||||
|
- Change database compression
|
||||||
|
- Change database key derivation
|
||||||
|
- Displays entry colors and icons (set in KeePass)
|
||||||
|
|
||||||
# Build and Test
|
# Build and Test
|
||||||
TODO: Describe and show how to build your code and run the tests.
|
1. Clone the repository
|
||||||
|
2. Build the main app (the library reference dll is actually a NuGet dependency, built from the [**ModernKeePassLib** project](../ModernKeePassLib/README.md))
|
||||||
|
|
||||||
# Contribute
|
# Contribute
|
||||||
TODO: Explain how other users and developers can contribute to make your code better.
|
I'm not the best at creating nice assets, so if anyone would like to contribute some nice icons, it would be awesome :)
|
||||||
|
Otherwise, there are still many things left to implement:
|
||||||
|
- Entry custom fields
|
||||||
|
- Multi entry selection (for delete, or move)
|
||||||
|
- Move entries from a group to another
|
||||||
|
- Create key files
|
||||||
|
- Open database from URL (and maybe some clouds?)
|
||||||
|
|
||||||
If you want to learn more about creating good readme files then refer the following [guidelines](https://www.visualstudio.com/en-us/docs/git/create-a-readme). You can also seek inspiration from the below readme files:
|
# Credits
|
||||||
- [ASP.NET Core](https://github.com/aspnet/Home)
|
*Dominik Reichl* for the [KeePass application](https://keepass.info/), library and file format
|
||||||
- [Visual Studio Code](https://github.com/Microsoft/vscode)
|
*David Lechner* for his [PCL adapatation](https://github.com/dlech/KeePass2PCL) of the KeePass Library and the correlated tests which served as an inspiration basis for my own adaptation
|
||||||
- [Chakra Core](https://github.com/Microsoft/ChakraCore)
|
|
||||||
|
Reference in New Issue
Block a user