mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 22:44:29 +01:00
Ask passphrase when appropriate (Fix #1185)
This commit is contained in:
@@ -8,6 +8,7 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
|
using BTCPayServer.Hwi;
|
||||||
using BTCPayServer.ModelBinders;
|
using BTCPayServer.ModelBinders;
|
||||||
using BTCPayServer.Models;
|
using BTCPayServer.Models;
|
||||||
using BTCPayServer.Models.StoreViewModels;
|
using BTCPayServer.Models.StoreViewModels;
|
||||||
@@ -60,8 +61,27 @@ namespace BTCPayServer.Controllers
|
|||||||
Transport = new HwiWebSocketTransport(websocket)
|
Transport = new HwiWebSocketTransport(websocket)
|
||||||
};
|
};
|
||||||
Hwi.HwiDeviceClient device = null;
|
Hwi.HwiDeviceClient device = null;
|
||||||
|
HwiEnumerateEntry deviceEntry = null;
|
||||||
HDFingerprint? fingerprint = null;
|
HDFingerprint? fingerprint = null;
|
||||||
|
string password = null;
|
||||||
|
int? pin = null;
|
||||||
var websocketHelper = new WebSocketHelper(websocket);
|
var websocketHelper = new WebSocketHelper(websocket);
|
||||||
|
|
||||||
|
async Task<bool> RequireMoreInformation()
|
||||||
|
{
|
||||||
|
if (deviceEntry.NeedsPinSent is true && pin is null)
|
||||||
|
{
|
||||||
|
await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (deviceEntry.NeedsPassphraseSent is true && password == null)
|
||||||
|
{
|
||||||
|
await websocketHelper.Send("{ \"error\": \"need-passphrase\"}", cancellationToken);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
JObject o = null;
|
JObject o = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -70,12 +90,20 @@ namespace BTCPayServer.Controllers
|
|||||||
var command = await websocketHelper.NextMessageAsync(cancellationToken);
|
var command = await websocketHelper.NextMessageAsync(cancellationToken);
|
||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
|
case "set-passphrase":
|
||||||
|
device.Password = await websocketHelper.NextMessageAsync(cancellationToken);
|
||||||
|
password = device.Password;
|
||||||
|
break;
|
||||||
case "ask-sign":
|
case "ask-sign":
|
||||||
if (device == null)
|
if (device == null)
|
||||||
{
|
{
|
||||||
await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken);
|
await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (await RequireMoreInformation())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (walletId == null)
|
if (walletId == null)
|
||||||
{
|
{
|
||||||
await websocketHelper.Send("{ \"error\": \"invalid-walletId\"}", cancellationToken);
|
await websocketHelper.Send("{ \"error\": \"invalid-walletId\"}", cancellationToken);
|
||||||
@@ -92,6 +120,11 @@ namespace BTCPayServer.Controllers
|
|||||||
await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken);
|
await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
catch (Hwi.HwiException ex) when (ex.ErrorCode == Hwi.HwiErrorCode.NoPassword)
|
||||||
|
{
|
||||||
|
await websocketHelper.Send("{ \"error\": \"need-passphrase\"}", cancellationToken);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
await websocketHelper.Send("{ \"info\": \"ready\"}", cancellationToken);
|
await websocketHelper.Send("{ \"info\": \"ready\"}", cancellationToken);
|
||||||
o = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken));
|
o = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken));
|
||||||
@@ -119,6 +152,11 @@ namespace BTCPayServer.Controllers
|
|||||||
await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken);
|
await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
catch (Hwi.HwiException ex) when (ex.ErrorCode == Hwi.HwiErrorCode.NoPassword)
|
||||||
|
{
|
||||||
|
await websocketHelper.Send("{ \"error\": \"need-passphrase\"}", cancellationToken);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
catch (Hwi.HwiException)
|
catch (Hwi.HwiException)
|
||||||
{
|
{
|
||||||
await websocketHelper.Send("{ \"error\": \"user-reject\"}", cancellationToken);
|
await websocketHelper.Send("{ \"error\": \"user-reject\"}", cancellationToken);
|
||||||
@@ -136,11 +174,8 @@ namespace BTCPayServer.Controllers
|
|||||||
}
|
}
|
||||||
await device.PromptPinAsync(cancellationToken);
|
await device.PromptPinAsync(cancellationToken);
|
||||||
await websocketHelper.Send("{ \"info\": \"prompted, please input the pin\"}", cancellationToken);
|
await websocketHelper.Send("{ \"info\": \"prompted, please input the pin\"}", cancellationToken);
|
||||||
o = JObject.Parse(await websocketHelper.NextMessageAsync(cancellationToken));
|
pin = int.Parse(await websocketHelper.NextMessageAsync(cancellationToken), CultureInfo.InvariantCulture);
|
||||||
var pin = (int)o["pinCode"].Value<long>();
|
if (await device.SendPinAsync(pin.Value, cancellationToken))
|
||||||
var passphrase = o["passphrase"].Value<string>();
|
|
||||||
device.Password = passphrase;
|
|
||||||
if (await device.SendPinAsync(pin, cancellationToken))
|
|
||||||
{
|
{
|
||||||
await websocketHelper.Send("{ \"info\": \"the pin is correct\"}", cancellationToken);
|
await websocketHelper.Send("{ \"info\": \"the pin is correct\"}", cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -156,6 +191,10 @@ namespace BTCPayServer.Controllers
|
|||||||
await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken);
|
await websocketHelper.Send("{ \"error\": \"need-device\"}", cancellationToken);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (await RequireMoreInformation())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
JObject result = new JObject();
|
JObject result = new JObject();
|
||||||
var factory = network.NBXplorerNetwork.DerivationStrategyFactory;
|
var factory = network.NBXplorerNetwork.DerivationStrategyFactory;
|
||||||
var keyPath = new KeyPath("84'").Derive(network.CoinType).Derive(0, true);
|
var keyPath = new KeyPath("84'").Derive(network.CoinType).Derive(0, true);
|
||||||
@@ -169,6 +208,11 @@ namespace BTCPayServer.Controllers
|
|||||||
await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken);
|
await websocketHelper.Send("{ \"error\": \"need-pin\"}", cancellationToken);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
catch (Hwi.HwiException ex) when (ex.ErrorCode == Hwi.HwiErrorCode.NoPassword)
|
||||||
|
{
|
||||||
|
await websocketHelper.Send("{ \"error\": \"need-passphrase\"}", cancellationToken);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (fingerprint is null)
|
if (fingerprint is null)
|
||||||
{
|
{
|
||||||
fingerprint = (await device.GetXPubAsync(new KeyPath("44'"), cancellationToken)).ExtPubKey.ParentFingerprint;
|
fingerprint = (await device.GetXPubAsync(new KeyPath("44'"), cancellationToken)).ExtPubKey.ParentFingerprint;
|
||||||
@@ -196,13 +240,18 @@ namespace BTCPayServer.Controllers
|
|||||||
await websocketHelper.Send(result.ToString(), cancellationToken);
|
await websocketHelper.Send(result.ToString(), cancellationToken);
|
||||||
break;
|
break;
|
||||||
case "ask-device":
|
case "ask-device":
|
||||||
var devices = (await hwi.EnumerateDevicesAsync(cancellationToken)).ToList();
|
password = null;
|
||||||
device = devices.FirstOrDefault();
|
pin = null;
|
||||||
if (device == null)
|
deviceEntry = null;
|
||||||
|
device = null;
|
||||||
|
var entries = (await hwi.EnumerateEntriesAsync(cancellationToken)).ToList();
|
||||||
|
deviceEntry = entries.FirstOrDefault();
|
||||||
|
if (deviceEntry == null)
|
||||||
{
|
{
|
||||||
await websocketHelper.Send("{ \"error\": \"no-device\"}", cancellationToken);
|
await websocketHelper.Send("{ \"error\": \"no-device\"}", cancellationToken);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
device = new HwiDeviceClient(hwi, deviceEntry.DeviceSelector, deviceEntry.Model, deviceEntry.Fingerprint);
|
||||||
fingerprint = device.Fingerprint;
|
fingerprint = device.Fingerprint;
|
||||||
JObject json = new JObject();
|
JObject json = new JObject();
|
||||||
json.Add("model", device.Model.ToString());
|
json.Add("model", device.Model.ToString());
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<label for="Password" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
<label for="Password" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||||
</div>
|
</div>
|
||||||
<input id="Password" type="password" class="form-control" placeholder="Password" />
|
<input id="Password" type="password" class="form-control" placeholder="Passphrase" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -114,6 +114,11 @@ var vaultui = (function () {
|
|||||||
if (await self.askForPin())
|
if (await self.askForPin())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (json.error === "need-passphrase") {
|
||||||
|
handled = true;
|
||||||
|
if (await self.askForPassphrase())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
showError(json);
|
showError(json);
|
||||||
}
|
}
|
||||||
@@ -230,6 +235,15 @@ var vaultui = (function () {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.askForPassphrase = async function () {
|
||||||
|
if (!await self.ensureConnectedToBackend())
|
||||||
|
return false;
|
||||||
|
var passphrase = await self.getUserPassphrase();
|
||||||
|
self.bridge.socket.send("set-passphrase");
|
||||||
|
self.bridge.socket.send(passphrase);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
@@ -246,8 +260,7 @@ var vaultui = (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var pinCode = await self.getUserEnterPin();
|
var pinCode = await self.getUserEnterPin();
|
||||||
var passphrase = await self.getUserPassphrase();
|
self.bridge.socket.send(pinCode);
|
||||||
self.bridge.socket.send(JSON.stringify({ pinCode: pinCode, passphrase: passphrase }));
|
|
||||||
var json = await self.bridge.waitBackendMessage();
|
var json = await self.bridge.waitBackendMessage();
|
||||||
if (json.hasOwnProperty("error")) {
|
if (json.hasOwnProperty("error")) {
|
||||||
showError(json);
|
showError(json);
|
||||||
|
|||||||
Reference in New Issue
Block a user