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:
2025-12-05 15:30:38 +03:00
parent 4beca8f286
commit 84abdc1596
8 changed files with 88 additions and 12 deletions

View File

@@ -63,8 +63,8 @@ public class PassStoreFileAccessor : IPassStore
file.Seek((file.Position + 4096 - 1) / 4096 * 4096, SeekOrigin.Begin);
key.Salt = hdr.PreSalt;
this.key = hdr.KdfInfo.GetKdf().Derive(key, 32);
using OuterEncryptionReader cryptoReader = new(file, this.key, ((OuterAesHeader)hdr.OuterCryptoHeader).InitVector);
byte[] masterKey = hdr.KdfInfo.GetKdf().Derive(key, 32);
using OuterEncryptionReader cryptoReader = new(file, masterKey, ((OuterAesHeader)hdr.OuterCryptoHeader).InitVector);
using BinaryReader rd = new(cryptoReader);
{
@@ -103,6 +103,7 @@ public class PassStoreFileAccessor : IPassStore
throw PassStoreFileException.UnexpectedEndOfFile;
}
}
this.key = masterKey;
}
public void Lock()

View File

@@ -3,6 +3,7 @@
xmlns:vm="using:KeyKeeper.ViewModels"
x:Class="KeyKeeper.RepositoryWindow"
Title="KeyKeeper - Хранилище паролей"
CanResize="False"
Width="800"
Height="600"
Background="White"
@@ -13,7 +14,7 @@
<Grid>
<!-- Синий левый край -->
<Border Width="200"
Background="#2328C4"
Background="#2328C4"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"/>
<StackPanel Margin="20" HorizontalAlignment="Left">
@@ -42,8 +43,7 @@
</Border>
<!-- Save Passwords -->
<Button Content="Save Passwords"
Width="120"
<Button Content="Save Passwords"
Height="30"
Foreground="White"
HorizontalAlignment="Left"

View File

@@ -1,13 +1,20 @@
using System;
using Avalonia.Controls;
using KeyKeeper.ViewModels;
using KeyKeeper.Views;
namespace KeyKeeper;
public partial class RepositoryWindow: Window
{
public RepositoryWindow()
public RepositoryWindow(RepositoryWindowViewModel model)
{
InitializeComponent();
DataContext = model;
model.ShowErrorPopup = async (string message) =>
{
await new ErrorDialog(message).ShowDialog(this);
};
}
protected override void OnOpened(EventArgs e)

View File

@@ -10,7 +10,7 @@ public partial class LockedRepositoryViewModel : ViewModelBase
{
RepositoryWindowViewModel parent;
private IPassStore passStore;
private string password;
private string password = "";
public LockedRepositoryViewModel(IPassStore store, RepositoryWindowViewModel parent)
{
@@ -25,7 +25,7 @@ public partial class LockedRepositoryViewModel : ViewModelBase
}
[RelayCommand]
public void TryUnlock()
public async Task TryUnlock()
{
try
{
@@ -33,12 +33,28 @@ public partial class LockedRepositoryViewModel : ViewModelBase
parent.UpdateLockStatus();
} catch (PassStoreFileException e)
{
// TODO
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)
{
// TODO
Console.WriteLine(e);
await parent.ShowErrorPopup("Cannot open the password store file");
}
}
}

View File

@@ -1,3 +1,5 @@
using System;
using System.Threading.Tasks;
using KeyKeeper.PasswordStore;
namespace KeyKeeper.ViewModels;
@@ -7,6 +9,8 @@ public partial class RepositoryWindowViewModel : ViewModelBase
private object currentPage;
private IPassStore passStore;
public Func<string, Task> ShowErrorPopup;
public object CurrentPage
{
get => currentPage;

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

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

View File

@@ -82,9 +82,8 @@ namespace KeyKeeper.Views
private void OpenRepositoryWindow(IPassStore store)
{
var repositoryWindow = new RepositoryWindow()
var repositoryWindow = new RepositoryWindow(new RepositoryWindowViewModel(store))
{
DataContext = new RepositoryWindowViewModel(store),
WindowStartupLocation = WindowStartupLocation.CenterScreen
};
repositoryWindow.Closed += (s, e) => this.Show();