Fix crlf password handling
Resolves:
MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/CoinJoinTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/CoinJoinTabViewModel.cs
@@ -5,10 +5,12 @@ using System.Collections.Specialized;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
+using System.Threading.Tasks;
using Avalonia.Controls;
using NBitcoin;
using ReactiveUI;
using WalletWasabi.Gui.ViewModels;
+using WalletWasabi.Helpers;
using WalletWasabi.Logging;
using WalletWasabi.Models;
using WalletWasabi.Models.ChaumianCoinJoin;
@@ -85,73 +87,92 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
EnqueueCommand = ReactiveCommand.Create(async () =>
{
- var selectedCoins = AvailableCoinsList.Coins.Where(c => c.IsSelected).ToList();
+ await DoEnqueueAsync();
+ });
- if (!selectedCoins.Any())
+ DequeueCommand = ReactiveCommand.Create(async () =>
{
- WarningMessageEnqueue = "No coins are selected to enqueue.";
- return;
- }
+ var selectedCoins = QueuedCoinsList.Coins.Where(c => c.IsSelected).ToList();
- WarningMessageEnqueue = string.Empty;
+ foreach (var coin in selectedCoins)
+ {
+ coin.IsSelected = false;
+ }
try
{
- await Global.ChaumianClient.QueueCoinsToMixAsync(Password, selectedCoins.Select(c => c.Model).ToArray());
+ await Global.ChaumianClient.DequeueCoinsFromMixAsync(selectedCoins.Select(c => c.Model).ToArray());
}
catch (Exception ex)
{
Logger.LogWarning<CoinJoinTabViewModel>(ex);
- WarningMessageEnqueue = ex.ToTypeMessageString();
+ WarningMessageDequeue = ex.ToTypeMessageString();
if (ex is AggregateException aggex)
{
foreach (var iex in aggex.InnerExceptions)
{
- WarningMessageEnqueue += Environment.NewLine + iex.ToTypeMessageString();
+ WarningMessageDequeue += Environment.NewLine + iex.ToTypeMessageString();
}
}
- Password = string.Empty;
return;
}
- Password = string.Empty;
- WarningMessageEnqueue = string.Empty;
+ WarningMessageDequeue = string.Empty;
+ });
- foreach (var coin in selectedCoins)
+ this.WhenAnyValue(x => x.Password).Subscribe(async x =>
{
- coin.IsSelected = false;
+ if (x.NotNullAndNotEmpty())
+ {
+ char lastChar = x.Last();
+ if (lastChar == '\r' || lastChar == '\n') // If the last character is cr or lf then act like it'd be a sign to do the job.
+ {
+ Password = x.TrimEnd('\r', '\n');
+ await DoEnqueueAsync();
+ }
}
});
+ }
- DequeueCommand = ReactiveCommand.Create(async () =>
+ private async Task DoEnqueueAsync()
{
- var selectedCoins = QueuedCoinsList.Coins.Where(c => c.IsSelected).ToList();
+ Password = Guard.Correct(Password);
+ var selectedCoins = AvailableCoinsList.Coins.Where(c => c.IsSelected).ToList();
- foreach (var coin in selectedCoins)
+ if (!selectedCoins.Any())
{
- coin.IsSelected = false;
+ WarningMessageEnqueue = "No coins are selected to enqueue.";
+ return;
}
+ WarningMessageEnqueue = string.Empty;
+
try
{
- await Global.ChaumianClient.DequeueCoinsFromMixAsync(selectedCoins.Select(c => c.Model).ToArray());
+ await Global.ChaumianClient.QueueCoinsToMixAsync(Password, selectedCoins.Select(c => c.Model).ToArray());
}
catch (Exception ex)
{
Logger.LogWarning<CoinJoinTabViewModel>(ex);
- WarningMessageDequeue = ex.ToTypeMessageString();
+ WarningMessageEnqueue = ex.ToTypeMessageString();
if (ex is AggregateException aggex)
{
foreach (var iex in aggex.InnerExceptions)
{
- WarningMessageDequeue += Environment.NewLine + iex.ToTypeMessageString();
+ WarningMessageEnqueue += Environment.NewLine + iex.ToTypeMessageString();
}
}
+ Password = string.Empty;
return;
}
- WarningMessageDequeue = string.Empty;
- });
+ Password = string.Empty;
+ WarningMessageEnqueue = string.Empty;
+
+ foreach (var coin in selectedCoins)
+ {
+ coin.IsSelected = false;
+ }
}
private void ChaumianClient_CoinDequeued(object sender, SmartCoin e)

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
@@ -11,6 +11,7 @@ using ReactiveUI;
using WalletWasabi.Models;
using WalletWasabi.Services;
using WalletWasabi.Gui.ViewModels.Validation;
+using WalletWasabi.Helpers;
namespace WalletWasabi.Gui.Controls.WalletExplorer
{
@@ -49,7 +50,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
ResetMax();
- (this).WhenAnyValue(x => x.Amount).Subscribe(amount =>
+ this.WhenAnyValue(x => x.Amount).Subscribe(amount =>
{
if (!IgnoreAmountChanges)
{
@@ -89,6 +90,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
IsBusy = true;
try
{
+ Password = Guard.Correct(Password);
if (string.IsNullOrWhiteSpace(Label))
{
throw new InvalidOperationException("Label is required.");
@@ -155,6 +157,18 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
BuildTransactionButtonText = BuildTransactionButtonTextString;
}
});
+
+ this.WhenAnyValue(x => x.Password).Subscribe(x =>
+ {
+ if (x.NotNullAndNotEmpty())
+ {
+ char lastChar = x.Last();
+ if (lastChar == '\r' || lastChar == '\n') // If the last character is cr or lf then act like it'd be a sign to do the job.
+ {
+ Password = x.TrimEnd('\r', '\n');
+ }
+ }
+ });
}
private void SetMax()

MODIFY
WalletWasabi.Gui/Tabs/WalletManager/GenerateWalletViewModel.cs
WalletWasabi.Gui/Tabs/WalletManager/GenerateWalletViewModel.cs
@@ -5,6 +5,7 @@ using ReactiveUI;
using System;
using System.Collections.ObjectModel;
using System.IO;
+using System.Linq;
using WalletWasabi.Gui.Dialogs;
using WalletWasabi.Gui.ViewModels;
using WalletWasabi.Helpers;
@@ -20,14 +21,50 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
private string _walletName;
private bool _termsAccepted;
private string _validationMessage;
+ public WalletManagerViewModel Owner { get; }
public GenerateWalletViewModel(WalletManagerViewModel owner) : base("Generate Wallet")
{
+ Owner = owner;
+
GenerateCommand = ReactiveCommand.Create(() =>
+ {
+ DoGenerateCommand();
+ },
+ this.WhenAnyValue(x => x.TermsAccepted));
+
+ this.WhenAnyValue(x => x.Password).Subscribe(x =>
+ {
+ if (x.NotNullAndNotEmpty())
+ {
+ char lastChar = x.Last();
+ if (lastChar == '\r' || lastChar == '\n') // If the last character is cr or lf then act like it'd be a sign to do the job.
+ {
+ Password = x.TrimEnd('\r', '\n');
+ }
+ }
+ });
+ this.WhenAnyValue(x => x.PasswordConfirmation).Subscribe(x =>
+ {
+ if (x.NotNullAndNotEmpty())
+ {
+ char lastChar = x.Last();
+ if (lastChar == '\r' || lastChar == '\n') // If the last character is cr or lf then act like it'd be a sign to do the job.
+ {
+ PasswordConfirmation = x.TrimEnd('\r', '\n');
+ DoGenerateCommand();
+ }
+ }
+ });
+ }
+
+ private void DoGenerateCommand()
{
WalletName = Guard.Correct(WalletName);
string walletFilePath = Path.Combine(Global.WalletsDir, $"{WalletName}.json");
+ Password = Guard.Correct(Password); // Don't let whitespaces to the beginning and to the end.
+ PasswordConfirmation = Guard.Correct(PasswordConfirmation); // Don't let whitespaces to the beginning and to the end.
if (TermsAccepted == false)
{
@@ -51,7 +88,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
{
KeyManager.CreateNew(out Mnemonic mnemonic, Password, walletFilePath);
- owner.CurrentView = new GenerateWalletSuccessViewModel(owner, mnemonic);
+ Owner.CurrentView = new GenerateWalletSuccessViewModel(Owner, mnemonic);
}
catch (Exception ex)
{
@@ -59,8 +96,6 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
Logger.LogError<GenerateWalletViewModel>(ex);
}
}
- },
- this.WhenAnyValue(x => x.TermsAccepted));
}
public string Password

MODIFY
WalletWasabi.Gui/Tabs/WalletManager/RecoverWalletViewModel.cs
WalletWasabi.Gui/Tabs/WalletManager/RecoverWalletViewModel.cs
@@ -28,6 +28,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
{
WalletName = Guard.Correct(WalletName);
MnemonicWords = Guard.Correct(MnemonicWords);
+ Password = Guard.Correct(Password); // Don't let whitespaces to the beginning and to the end.
string walletFilePath = Path.Combine(Global.WalletsDir, $"{WalletName}.json");
@@ -65,6 +66,17 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
},
this.WhenAnyValue(x => x.TermsAccepted));
this.WhenAnyValue(x => x.MnemonicWords).Subscribe(x => UpdateSuggestions(x));
+ this.WhenAnyValue(x => x.Password).Subscribe(x =>
+ {
+ if (x.NotNullAndNotEmpty())
+ {
+ char lastChar = x.Last();
+ if (lastChar == '\r' || lastChar == '\n') // If the last character is cr or lf then act like it'd be a sign to do the job.
+ {
+ Password = x.TrimEnd('\r', '\n');
+ }
+ }
+ });
}
public string Password
@@ -136,7 +148,7 @@ namespace WalletWasabi.Gui.Tabs.WalletManager
if (string.IsNullOrEmpty(words))
return;
- var enteredWordList = words.Split(' ', StringSplitOptions.RemoveEmptyEntries);
+ string[] enteredWordList = words.Split(' ', StringSplitOptions.RemoveEmptyEntries);
var lastWorld = enteredWordList.LastOrDefault().Replace("\t", "");
if (lastWorld.Length < 1)

Fix crlf password handling
Resolves: https://github.com/zkSNACKs/WalletWasabi/issues/695