mirror of
https://github.com/KeyKeeperApp/KeyKeeper.git
synced 2026-05-14 20:36:31 +03:00
unlock error reporting, bugfixes
- fix Locked property becoming true when the store in fact was not opened - fix password being null - make RepositoryWindow non-resizeable - show error popups in case of unlock error
This commit is contained in:
@@ -63,8 +63,8 @@ public class PassStoreFileAccessor : IPassStore
|
|||||||
file.Seek((file.Position + 4096 - 1) / 4096 * 4096, SeekOrigin.Begin);
|
file.Seek((file.Position + 4096 - 1) / 4096 * 4096, SeekOrigin.Begin);
|
||||||
|
|
||||||
key.Salt = hdr.PreSalt;
|
key.Salt = hdr.PreSalt;
|
||||||
this.key = hdr.KdfInfo.GetKdf().Derive(key, 32);
|
byte[] masterKey = hdr.KdfInfo.GetKdf().Derive(key, 32);
|
||||||
using OuterEncryptionReader cryptoReader = new(file, this.key, ((OuterAesHeader)hdr.OuterCryptoHeader).InitVector);
|
using OuterEncryptionReader cryptoReader = new(file, masterKey, ((OuterAesHeader)hdr.OuterCryptoHeader).InitVector);
|
||||||
using BinaryReader rd = new(cryptoReader);
|
using BinaryReader rd = new(cryptoReader);
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -103,6 +103,7 @@ public class PassStoreFileAccessor : IPassStore
|
|||||||
throw PassStoreFileException.UnexpectedEndOfFile;
|
throw PassStoreFileException.UnexpectedEndOfFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.key = masterKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Lock()
|
public void Lock()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
xmlns:vm="using:KeyKeeper.ViewModels"
|
xmlns:vm="using:KeyKeeper.ViewModels"
|
||||||
x:Class="KeyKeeper.RepositoryWindow"
|
x:Class="KeyKeeper.RepositoryWindow"
|
||||||
Title="KeyKeeper - Хранилище паролей"
|
Title="KeyKeeper - Хранилище паролей"
|
||||||
|
CanResize="False"
|
||||||
Width="800"
|
Width="800"
|
||||||
Height="600"
|
Height="600"
|
||||||
Background="White"
|
Background="White"
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
<Grid>
|
<Grid>
|
||||||
<!-- Синий левый край -->
|
<!-- Синий левый край -->
|
||||||
<Border Width="200"
|
<Border Width="200"
|
||||||
Background="#2328C4"
|
Background="#2328C4"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Stretch"/>
|
VerticalAlignment="Stretch"/>
|
||||||
<StackPanel Margin="20" HorizontalAlignment="Left">
|
<StackPanel Margin="20" HorizontalAlignment="Left">
|
||||||
@@ -42,8 +43,7 @@
|
|||||||
|
|
||||||
</Border>
|
</Border>
|
||||||
<!-- Save Passwords -->
|
<!-- Save Passwords -->
|
||||||
<Button Content="Save Passwords"
|
<Button Content="Save Passwords"
|
||||||
Width="120"
|
|
||||||
Height="30"
|
Height="30"
|
||||||
Foreground="White"
|
Foreground="White"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using KeyKeeper.ViewModels;
|
||||||
|
using KeyKeeper.Views;
|
||||||
|
|
||||||
namespace KeyKeeper;
|
namespace KeyKeeper;
|
||||||
|
|
||||||
public partial class RepositoryWindow: Window
|
public partial class RepositoryWindow: Window
|
||||||
{
|
{
|
||||||
public RepositoryWindow()
|
public RepositoryWindow(RepositoryWindowViewModel model)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
DataContext = model;
|
||||||
|
model.ShowErrorPopup = async (string message) =>
|
||||||
|
{
|
||||||
|
await new ErrorDialog(message).ShowDialog(this);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnOpened(EventArgs e)
|
protected override void OnOpened(EventArgs e)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public partial class LockedRepositoryViewModel : ViewModelBase
|
|||||||
{
|
{
|
||||||
RepositoryWindowViewModel parent;
|
RepositoryWindowViewModel parent;
|
||||||
private IPassStore passStore;
|
private IPassStore passStore;
|
||||||
private string password;
|
private string password = "";
|
||||||
|
|
||||||
public LockedRepositoryViewModel(IPassStore store, RepositoryWindowViewModel parent)
|
public LockedRepositoryViewModel(IPassStore store, RepositoryWindowViewModel parent)
|
||||||
{
|
{
|
||||||
@@ -25,7 +25,7 @@ public partial class LockedRepositoryViewModel : ViewModelBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void TryUnlock()
|
public async Task TryUnlock()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -33,12 +33,28 @@ public partial class LockedRepositoryViewModel : ViewModelBase
|
|||||||
parent.UpdateLockStatus();
|
parent.UpdateLockStatus();
|
||||||
} catch (PassStoreFileException e)
|
} catch (PassStoreFileException e)
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
Console.WriteLine("pass store file exception: " + e.Message);
|
Console.WriteLine("pass store file exception: " + e.Message);
|
||||||
|
if (e.Message == PassStoreFileException.ContentHMACMismatch.Message ||
|
||||||
|
e.Message == PassStoreFileException.InvalidBeginMarker.Message)
|
||||||
|
{
|
||||||
|
await parent.ShowErrorPopup("Incorrect password or corrupted file");
|
||||||
|
} else if (e.Message == PassStoreFileException.UnexpectedEndOfFile.Message ||
|
||||||
|
e.Message == PassStoreFileException.IncorrectMagicNumber.Message ||
|
||||||
|
e.Message == PassStoreFileException.InvalidCryptoHeader.Message ||
|
||||||
|
e.Message == PassStoreFileException.InvalidPassStoreEntry.Message)
|
||||||
|
{
|
||||||
|
await parent.ShowErrorPopup("Corrupted file");
|
||||||
|
} else if (e.Message == PassStoreFileException.UnsupportedVersion.Message)
|
||||||
|
{
|
||||||
|
await parent.ShowErrorPopup("Unsupported store file version");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
await parent.ShowErrorPopup("Unknown password store unlock error");
|
||||||
|
}
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
Console.WriteLine(e);
|
Console.WriteLine(e);
|
||||||
|
await parent.ShowErrorPopup("Cannot open the password store file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using KeyKeeper.PasswordStore;
|
using KeyKeeper.PasswordStore;
|
||||||
|
|
||||||
namespace KeyKeeper.ViewModels;
|
namespace KeyKeeper.ViewModels;
|
||||||
@@ -7,6 +9,8 @@ public partial class RepositoryWindowViewModel : ViewModelBase
|
|||||||
private object currentPage;
|
private object currentPage;
|
||||||
private IPassStore passStore;
|
private IPassStore passStore;
|
||||||
|
|
||||||
|
public Func<string, Task> ShowErrorPopup;
|
||||||
|
|
||||||
public object CurrentPage
|
public object CurrentPage
|
||||||
{
|
{
|
||||||
get => currentPage;
|
get => currentPage;
|
||||||
|
|||||||
31
src/KeyKeeper/Views/ErrorDialog.axaml
Normal file
31
src/KeyKeeper/Views/ErrorDialog.axaml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
x:Class="KeyKeeper.Views.ErrorDialog"
|
||||||
|
Width="350" Height="120"
|
||||||
|
Background="White"
|
||||||
|
CanResize="False"
|
||||||
|
Title="Error">
|
||||||
|
|
||||||
|
<Grid Margin="10" RowDefinitions="*,Auto">
|
||||||
|
<TextBlock x:Name="MessageText"
|
||||||
|
Grid.Row="0"
|
||||||
|
Foreground="Red"
|
||||||
|
FontSize="18"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<Button Grid.Row="1"
|
||||||
|
Content="OK"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="0,10,0,0"
|
||||||
|
Click="Ok_Click"
|
||||||
|
Background="#aaa" />
|
||||||
|
<Grid.Styles>
|
||||||
|
<Style Selector="Button /template/ ContentPresenter">
|
||||||
|
<Setter Property="Foreground" Value="#333" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Button:pointerover /template/ ContentPresenter">
|
||||||
|
<Setter Property="Background" Value="#ccc" />
|
||||||
|
<Setter Property="Foreground" Value="#444" />
|
||||||
|
</Style>
|
||||||
|
</Grid.Styles>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
18
src/KeyKeeper/Views/ErrorDialog.axaml.cs
Normal file
18
src/KeyKeeper/Views/ErrorDialog.axaml.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
|
||||||
|
namespace KeyKeeper.Views;
|
||||||
|
|
||||||
|
public partial class ErrorDialog : Window
|
||||||
|
{
|
||||||
|
public ErrorDialog(string message)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
MessageText.Text = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Ok_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,9 +82,8 @@ namespace KeyKeeper.Views
|
|||||||
|
|
||||||
private void OpenRepositoryWindow(IPassStore store)
|
private void OpenRepositoryWindow(IPassStore store)
|
||||||
{
|
{
|
||||||
var repositoryWindow = new RepositoryWindow()
|
var repositoryWindow = new RepositoryWindow(new RepositoryWindowViewModel(store))
|
||||||
{
|
{
|
||||||
DataContext = new RepositoryWindowViewModel(store),
|
|
||||||
WindowStartupLocation = WindowStartupLocation.CenterScreen
|
WindowStartupLocation = WindowStartupLocation.CenterScreen
|
||||||
};
|
};
|
||||||
repositoryWindow.Closed += (s, e) => this.Show();
|
repositoryWindow.Closed += (s, e) => this.Show();
|
||||||
|
|||||||
Reference in New Issue
Block a user