forked from Public/monero-gui
trezor: support new passphrase entry mechanism
- passphrase can be prompted also when wallet is running (thus added to the wallet listener) - device/host decision is now made on the host
This commit is contained in:
@@ -15,7 +15,9 @@ file(GLOB SOURCE_FILES
|
||||
"main/*.h"
|
||||
"main/*.cpp"
|
||||
"libwalletqt/WalletManager.cpp"
|
||||
"libwalletqt/WalletListenerImpl.cpp"
|
||||
"libwalletqt/Wallet.cpp"
|
||||
"libwalletqt/PassphraseHelper.cpp"
|
||||
"libwalletqt/PendingTransaction.cpp"
|
||||
"libwalletqt/TransactionHistory.cpp"
|
||||
"libwalletqt/TransactionInfo.cpp"
|
||||
@@ -29,6 +31,7 @@ file(GLOB SOURCE_FILES
|
||||
"libwalletqt/UnsignedTransaction.cpp"
|
||||
"libwalletqt/WalletManager.h"
|
||||
"libwalletqt/Wallet.h"
|
||||
"libwalletqt/PassphraseHelper.h"
|
||||
"libwalletqt/PendingTransaction.h"
|
||||
"libwalletqt/TransactionHistory.h"
|
||||
"libwalletqt/TransactionInfo.h"
|
||||
|
||||
70
src/libwalletqt/PassphraseHelper.cpp
Normal file
70
src/libwalletqt/PassphraseHelper.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2014-2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "PassphraseHelper.h"
|
||||
#include <QMutexLocker>
|
||||
#include <QDebug>
|
||||
|
||||
Monero::optional<std::string> PassphraseHelper::onDevicePassphraseRequest(bool & on_device)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
QMutexLocker locker(&m_mutex_pass);
|
||||
m_passphrase_on_device = true;
|
||||
m_passphrase_abort = false;
|
||||
|
||||
if (m_prompter != nullptr){
|
||||
m_prompter->onWalletPassphraseNeeded(on_device);
|
||||
}
|
||||
|
||||
m_cond_pass.wait(&m_mutex_pass);
|
||||
|
||||
if (m_passphrase_abort)
|
||||
{
|
||||
throw std::runtime_error("Passphrase entry abort");
|
||||
}
|
||||
|
||||
on_device = m_passphrase_on_device;
|
||||
if (!on_device) {
|
||||
auto tmpPass = m_passphrase.toStdString();
|
||||
m_passphrase = QString();
|
||||
return Monero::optional<std::string>(tmpPass);
|
||||
} else {
|
||||
return Monero::optional<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
void PassphraseHelper::onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
QMutexLocker locker(&m_mutex_pass);
|
||||
m_passphrase = passphrase;
|
||||
m_passphrase_abort = entry_abort;
|
||||
m_passphrase_on_device = enter_on_device;
|
||||
|
||||
m_cond_pass.wakeAll();
|
||||
}
|
||||
74
src/libwalletqt/PassphraseHelper.h
Normal file
74
src/libwalletqt/PassphraseHelper.h
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2014-2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef MONERO_GUI_PASSPHRASEHELPER_H
|
||||
#define MONERO_GUI_PASSPHRASEHELPER_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <wallet/api/wallet2_api.h>
|
||||
#include <QMutex>
|
||||
#include <QPointer>
|
||||
#include <QWaitCondition>
|
||||
#include <QMutex>
|
||||
|
||||
/**
|
||||
* Implements component responsible for showing entry prompt to the user,
|
||||
* typically Wallet / Wallet manager.
|
||||
*/
|
||||
class PassprasePrompter {
|
||||
public:
|
||||
virtual void onWalletPassphraseNeeded(bool onDevice) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements receiver of the passphrase responsible for passing it back to the wallet,
|
||||
* typically wallet listener.
|
||||
*/
|
||||
class PassphraseReceiver {
|
||||
public:
|
||||
virtual void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort) = 0;
|
||||
};
|
||||
|
||||
class PassphraseHelper {
|
||||
public:
|
||||
PassphraseHelper(PassprasePrompter * prompter=nullptr): m_prompter(prompter) {};
|
||||
PassphraseHelper(const PassphraseHelper & h): PassphraseHelper(h.m_prompter) {};
|
||||
Monero::optional<std::string> onDevicePassphraseRequest(bool & on_device);
|
||||
void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort);
|
||||
|
||||
private:
|
||||
PassprasePrompter * m_prompter;
|
||||
QWaitCondition m_cond_pass;
|
||||
QMutex m_mutex_pass;
|
||||
QString m_passphrase;
|
||||
bool m_passphrase_abort;
|
||||
bool m_passphrase_on_device;
|
||||
|
||||
};
|
||||
|
||||
#endif //MONERO_GUI_PASSPHRASEHELPER_H
|
||||
@@ -58,66 +58,6 @@ namespace {
|
||||
static constexpr char ATTRIBUTE_SUBADDRESS_ACCOUNT[] ="gui.subaddress_account";
|
||||
}
|
||||
|
||||
class WalletListenerImpl : public Monero::WalletListener
|
||||
{
|
||||
public:
|
||||
WalletListenerImpl(Wallet * w)
|
||||
: m_wallet(w)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void moneySpent(const std::string &txId, uint64_t amount) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->moneySpent(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
|
||||
virtual void moneyReceived(const std::string &txId, uint64_t amount) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->moneyReceived(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
virtual void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->unconfirmedMoneyReceived(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
virtual void newBlock(uint64_t height) override
|
||||
{
|
||||
// qDebug() << __FUNCTION__;
|
||||
emit m_wallet->newBlock(height, m_wallet->daemonBlockChainTargetHeight());
|
||||
}
|
||||
|
||||
virtual void updated() override
|
||||
{
|
||||
emit m_wallet->updated();
|
||||
}
|
||||
|
||||
// called when wallet refreshed by background thread or explicitly
|
||||
virtual void refreshed() override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->refreshed();
|
||||
}
|
||||
|
||||
virtual void onDeviceButtonRequest(uint64_t code) override
|
||||
{
|
||||
emit m_wallet->deviceButtonRequest(code);
|
||||
}
|
||||
|
||||
virtual void onDeviceButtonPressed() override
|
||||
{
|
||||
emit m_wallet->deviceButtonPressed();
|
||||
}
|
||||
|
||||
private:
|
||||
Wallet * m_wallet;
|
||||
};
|
||||
|
||||
Wallet::Wallet(QObject * parent)
|
||||
: Wallet(nullptr, parent)
|
||||
{
|
||||
@@ -1021,6 +961,19 @@ void Wallet::keyReuseMitigation2(bool mitigation)
|
||||
m_walletImpl->keyReuseMitigation2(mitigation);
|
||||
}
|
||||
|
||||
void Wallet::onWalletPassphraseNeeded(bool on_device)
|
||||
{
|
||||
emit this->walletPassphraseNeeded(on_device);
|
||||
}
|
||||
|
||||
void Wallet::onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort)
|
||||
{
|
||||
if (m_walletListener != nullptr)
|
||||
{
|
||||
m_walletListener->onPassphraseEntered(passphrase, enter_on_device, entry_abort);
|
||||
}
|
||||
}
|
||||
|
||||
Wallet::Wallet(Monero::Wallet *w, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_walletImpl(w)
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#include "PendingTransaction.h" // we need to have an access to the PendingTransaction::Priority enum here;
|
||||
#include "UnsignedTransaction.h"
|
||||
#include "NetworkType.h"
|
||||
#include "PassphraseHelper.h"
|
||||
#include "WalletListenerImpl.h"
|
||||
|
||||
namespace Monero {
|
||||
struct Wallet; // forward declaration
|
||||
@@ -57,7 +59,7 @@ class SubaddressModel;
|
||||
class SubaddressAccount;
|
||||
class SubaddressAccountModel;
|
||||
|
||||
class Wallet : public QObject
|
||||
class Wallet : public QObject, public PassprasePrompter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool disconnected READ disconnected NOTIFY disconnectedChanged)
|
||||
@@ -348,6 +350,10 @@ public:
|
||||
Q_INVOKABLE void segregationHeight(quint64 height);
|
||||
Q_INVOKABLE void keyReuseMitigation2(bool mitigation);
|
||||
|
||||
// Passphrase entry for hardware wallets
|
||||
Q_INVOKABLE void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort=false);
|
||||
virtual void onWalletPassphraseNeeded(bool on_device) override;
|
||||
|
||||
// TODO: setListenter() when it implemented in API
|
||||
signals:
|
||||
// emitted on every event happened with wallet
|
||||
@@ -367,6 +373,7 @@ signals:
|
||||
void walletCreationHeightChanged();
|
||||
void deviceButtonRequest(quint64 buttonCode);
|
||||
void deviceButtonPressed();
|
||||
void walletPassphraseNeeded(bool onDevice);
|
||||
void transactionCommitted(bool status, PendingTransaction *t, const QStringList& txid);
|
||||
void heightRefreshed(quint64 walletHeight, quint64 daemonHeight, quint64 targetHeight) const;
|
||||
void deviceShowAddressShowed();
|
||||
@@ -432,7 +439,7 @@ private:
|
||||
bool m_connectionStatusRunning;
|
||||
QString m_daemonUsername;
|
||||
QString m_daemonPassword;
|
||||
Monero::WalletListener *m_walletListener;
|
||||
WalletListenerImpl *m_walletListener;
|
||||
FutureScheduler m_scheduler;
|
||||
QMutex m_storeMutex;
|
||||
};
|
||||
|
||||
97
src/libwalletqt/WalletListenerImpl.cpp
Normal file
97
src/libwalletqt/WalletListenerImpl.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright (c) 2014-2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "WalletListenerImpl.h"
|
||||
#include "Wallet.h"
|
||||
|
||||
WalletListenerImpl::WalletListenerImpl(Wallet * w)
|
||||
: m_wallet(w)
|
||||
, m_phelper(w)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void WalletListenerImpl::moneySpent(const std::string &txId, uint64_t amount)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->moneySpent(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
void WalletListenerImpl::moneyReceived(const std::string &txId, uint64_t amount)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->moneyReceived(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
void WalletListenerImpl::unconfirmedMoneyReceived(const std::string &txId, uint64_t amount)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->unconfirmedMoneyReceived(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
void WalletListenerImpl::newBlock(uint64_t height)
|
||||
{
|
||||
// qDebug() << __FUNCTION__;
|
||||
emit m_wallet->newBlock(height, m_wallet->daemonBlockChainTargetHeight());
|
||||
}
|
||||
|
||||
void WalletListenerImpl::updated()
|
||||
{
|
||||
emit m_wallet->updated();
|
||||
}
|
||||
|
||||
// called when wallet refreshed by background thread or explicitly
|
||||
void WalletListenerImpl::refreshed()
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->refreshed();
|
||||
}
|
||||
|
||||
void WalletListenerImpl::onDeviceButtonRequest(uint64_t code)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->deviceButtonRequest(code);
|
||||
}
|
||||
|
||||
void WalletListenerImpl::onDeviceButtonPressed()
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->deviceButtonPressed();
|
||||
}
|
||||
|
||||
void WalletListenerImpl::onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
m_phelper.onPassphraseEntered(passphrase, enter_on_device, entry_abort);
|
||||
}
|
||||
|
||||
Monero::optional<std::string> WalletListenerImpl::onDevicePassphraseRequest(bool & on_device)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
return m_phelper.onDevicePassphraseRequest(on_device);
|
||||
}
|
||||
68
src/libwalletqt/WalletListenerImpl.h
Normal file
68
src/libwalletqt/WalletListenerImpl.h
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2014-2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef MONERO_GUI_WALLETLISTENERIMPL_H
|
||||
#define MONERO_GUI_WALLETLISTENERIMPL_H
|
||||
|
||||
#include "wallet/api/wallet2_api.h"
|
||||
#include "PassphraseHelper.h"
|
||||
|
||||
class Wallet;
|
||||
|
||||
class WalletListenerImpl : public Monero::WalletListener, public PassphraseReceiver
|
||||
{
|
||||
public:
|
||||
WalletListenerImpl(Wallet * w);
|
||||
|
||||
virtual void moneySpent(const std::string &txId, uint64_t amount) override;
|
||||
|
||||
virtual void moneyReceived(const std::string &txId, uint64_t amount) override;
|
||||
|
||||
virtual void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) override;
|
||||
|
||||
virtual void newBlock(uint64_t height) override;
|
||||
|
||||
virtual void updated() override;
|
||||
|
||||
// called when wallet refreshed by background thread or explicitly
|
||||
virtual void refreshed() override;
|
||||
|
||||
virtual void onDeviceButtonRequest(uint64_t code) override;
|
||||
|
||||
virtual void onDeviceButtonPressed() override;
|
||||
|
||||
virtual void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort) override;
|
||||
|
||||
virtual Monero::optional<std::string> onDevicePassphraseRequest(bool & on_device) override;
|
||||
|
||||
private:
|
||||
Wallet * m_wallet;
|
||||
PassphraseHelper m_phelper;
|
||||
};
|
||||
|
||||
#endif //MONERO_GUI_WALLETLISTENERIMPL_H
|
||||
@@ -42,11 +42,12 @@
|
||||
#include <QString>
|
||||
|
||||
#include "qt/updater.h"
|
||||
#include "qt/ScopeGuard.h"
|
||||
|
||||
class WalletPassphraseListenerImpl : public Monero::WalletListener
|
||||
class WalletPassphraseListenerImpl : public Monero::WalletListener, public PassphraseReceiver
|
||||
{
|
||||
public:
|
||||
WalletPassphraseListenerImpl(WalletManager * mgr): m_mgr(mgr), m_wallet(nullptr) {}
|
||||
WalletPassphraseListenerImpl(WalletManager * mgr): m_mgr(mgr), m_phelper(mgr) {}
|
||||
|
||||
virtual void moneySpent(const std::string &txId, uint64_t amount) override { (void)txId; (void)amount; };
|
||||
virtual void moneyReceived(const std::string &txId, uint64_t amount) override { (void)txId; (void)amount; };
|
||||
@@ -55,43 +56,33 @@ public:
|
||||
virtual void updated() override {};
|
||||
virtual void refreshed() override {};
|
||||
|
||||
virtual Monero::optional<std::string> onDevicePassphraseRequest(bool on_device) override
|
||||
virtual void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
if (on_device) return Monero::optional<std::string>();
|
||||
m_phelper.onPassphraseEntered(passphrase, enter_on_device, entry_abort);
|
||||
}
|
||||
|
||||
m_mgr->onWalletPassphraseNeeded(m_wallet);
|
||||
|
||||
if (m_mgr->m_passphrase_abort)
|
||||
{
|
||||
throw std::runtime_error("Passphrase entry abort");
|
||||
}
|
||||
|
||||
auto tmpPass = m_mgr->m_passphrase.toStdString();
|
||||
m_mgr->m_passphrase = QString();
|
||||
|
||||
return Monero::optional<std::string>(tmpPass);
|
||||
virtual Monero::optional<std::string> onDevicePassphraseRequest(bool & on_device) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
return m_phelper.onDevicePassphraseRequest(on_device);
|
||||
}
|
||||
|
||||
virtual void onDeviceButtonRequest(uint64_t code) override
|
||||
{
|
||||
emit m_mgr->deviceButtonRequest(code);
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_mgr->deviceButtonRequest(code);
|
||||
}
|
||||
|
||||
virtual void onDeviceButtonPressed() override
|
||||
{
|
||||
emit m_mgr->deviceButtonPressed();
|
||||
}
|
||||
|
||||
virtual void onSetWallet(Monero::Wallet * wallet) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
m_wallet = wallet;
|
||||
emit m_mgr->deviceButtonPressed();
|
||||
}
|
||||
|
||||
private:
|
||||
WalletManager * m_mgr;
|
||||
Monero::Wallet * m_wallet;
|
||||
PassphraseHelper m_phelper;
|
||||
};
|
||||
|
||||
WalletManager * WalletManager::m_instance = nullptr;
|
||||
@@ -123,6 +114,13 @@ Wallet *WalletManager::openWallet(const QString &path, const QString &password,
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
WalletPassphraseListenerImpl tmpListener(this);
|
||||
m_mutex_passphraseReceiver.lock();
|
||||
m_passphraseReceiver = &tmpListener;
|
||||
m_mutex_passphraseReceiver.unlock();
|
||||
const auto cleanup = sg::make_scope_guard([this]() noexcept {
|
||||
QMutexLocker passphrase_locker(&m_mutex_passphraseReceiver);
|
||||
this->m_passphraseReceiver = nullptr;
|
||||
});
|
||||
|
||||
if (m_currentWallet) {
|
||||
qDebug() << "Closing open m_currentWallet" << m_currentWallet;
|
||||
@@ -186,6 +184,13 @@ Wallet *WalletManager::createWalletFromDevice(const QString &path, const QString
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
WalletPassphraseListenerImpl tmpListener(this);
|
||||
m_mutex_passphraseReceiver.lock();
|
||||
m_passphraseReceiver = &tmpListener;
|
||||
m_mutex_passphraseReceiver.unlock();
|
||||
const auto cleanup = sg::make_scope_guard([this]() noexcept {
|
||||
QMutexLocker passphrase_locker(&m_mutex_passphraseReceiver);
|
||||
this->m_passphraseReceiver = nullptr;
|
||||
});
|
||||
|
||||
if (m_currentWallet) {
|
||||
qDebug() << "Closing open m_currentWallet" << m_currentWallet;
|
||||
@@ -529,6 +534,7 @@ bool WalletManager::clearWalletCache(const QString &wallet_path) const
|
||||
|
||||
WalletManager::WalletManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_passphraseReceiver(nullptr)
|
||||
, m_scheduler(this)
|
||||
{
|
||||
m_pimpl = Monero::WalletManagerFactory::getWalletManager();
|
||||
@@ -539,22 +545,16 @@ WalletManager::~WalletManager()
|
||||
m_scheduler.shutdownWaitForFinished();
|
||||
}
|
||||
|
||||
void WalletManager::onWalletPassphraseNeeded(Monero::Wallet *)
|
||||
void WalletManager::onWalletPassphraseNeeded(bool on_device)
|
||||
{
|
||||
m_mutex_pass.lock();
|
||||
m_passphrase_abort = false;
|
||||
emit this->walletPassphraseNeeded();
|
||||
|
||||
m_cond_pass.wait(&m_mutex_pass);
|
||||
m_mutex_pass.unlock();
|
||||
emit this->walletPassphraseNeeded(on_device);
|
||||
}
|
||||
|
||||
void WalletManager::onPassphraseEntered(const QString &passphrase, bool entry_abort)
|
||||
void WalletManager::onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort)
|
||||
{
|
||||
m_mutex_pass.lock();
|
||||
m_passphrase = passphrase;
|
||||
m_passphrase_abort = entry_abort;
|
||||
|
||||
m_cond_pass.wakeAll();
|
||||
m_mutex_pass.unlock();
|
||||
QMutexLocker locker(&m_mutex_passphraseReceiver);
|
||||
if (m_passphraseReceiver != nullptr)
|
||||
{
|
||||
m_passphraseReceiver->onPassphraseEntered(passphrase, enter_on_device, entry_abort);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,13 +38,14 @@
|
||||
#include <QWaitCondition>
|
||||
#include "qt/FutureScheduler.h"
|
||||
#include "NetworkType.h"
|
||||
#include "PassphraseHelper.h"
|
||||
|
||||
class Wallet;
|
||||
namespace Monero {
|
||||
struct WalletManager;
|
||||
}
|
||||
|
||||
class WalletManager : public QObject
|
||||
class WalletManager : public QObject, public PassprasePrompter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool connected READ connected)
|
||||
@@ -185,14 +186,14 @@ public:
|
||||
// clear/rename wallet cache
|
||||
Q_INVOKABLE bool clearWalletCache(const QString &fileName) const;
|
||||
|
||||
Q_INVOKABLE void onWalletPassphraseNeeded(Monero::Wallet * wallet);
|
||||
Q_INVOKABLE void onPassphraseEntered(const QString &passphrase, bool entry_abort=false);
|
||||
Q_INVOKABLE void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort=false);
|
||||
virtual void onWalletPassphraseNeeded(bool on_device) override;
|
||||
|
||||
signals:
|
||||
|
||||
void walletOpened(Wallet * wallet);
|
||||
void walletCreated(Wallet * wallet);
|
||||
void walletPassphraseNeeded();
|
||||
void walletPassphraseNeeded(bool onDevice);
|
||||
void deviceButtonRequest(quint64 buttonCode);
|
||||
void deviceButtonPressed();
|
||||
void checkUpdatesComplete(
|
||||
@@ -216,12 +217,8 @@ private:
|
||||
Monero::WalletManager * m_pimpl;
|
||||
mutable QMutex m_mutex;
|
||||
QPointer<Wallet> m_currentWallet;
|
||||
|
||||
QWaitCondition m_cond_pass;
|
||||
QMutex m_mutex_pass;
|
||||
QString m_passphrase;
|
||||
bool m_passphrase_abort;
|
||||
|
||||
PassphraseReceiver * m_passphraseReceiver;
|
||||
QMutex m_mutex_passphraseReceiver;
|
||||
FutureScheduler m_scheduler;
|
||||
};
|
||||
|
||||
|
||||
205
src/qt/ScopeGuard.h
Normal file
205
src/qt/ScopeGuard.h
Normal file
@@ -0,0 +1,205 @@
|
||||
// Author: ricab
|
||||
// Source: https://github.com/ricab/scope_guard
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
//
|
||||
// In jurisdictions that recognize copyright laws, the author or authors
|
||||
// of this software dedicate any and all copyright interest in the
|
||||
// software to the public domain. We make this dedication for the benefit
|
||||
// of the public at large and to the detriment of our heirs and
|
||||
// successors. We intend this dedication to be an overt act of
|
||||
// relinquishment in perpetuity of all present and future rights to this
|
||||
// software under copyright law.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// For more information, please refer to <http://unlicense.org>
|
||||
|
||||
#ifndef SCOPE_GUARD_HPP_
|
||||
#define SCOPE_GUARD_HPP_
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#if __cplusplus >= 201703L && defined(SG_REQUIRE_NOEXCEPT_IN_CPP17)
|
||||
#define SG_REQUIRE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
namespace sg
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
/* --- Some custom type traits --- */
|
||||
|
||||
// Type trait determining whether a type is callable with no arguments
|
||||
template<typename T, typename = void>
|
||||
struct is_noarg_callable_t
|
||||
: public std::false_type
|
||||
{}; // in general, false
|
||||
|
||||
template<typename T>
|
||||
struct is_noarg_callable_t<T, decltype(std::declval<T&&>()())>
|
||||
: public std::true_type
|
||||
{}; // only true when call expression valid
|
||||
|
||||
// Type trait determining whether a no-argument callable returns void
|
||||
template<typename T>
|
||||
struct returns_void_t
|
||||
: public std::is_same<void, decltype(std::declval<T&&>()())>
|
||||
{};
|
||||
|
||||
/* Type trait determining whether a no-arg callable is nothrow invocable if
|
||||
required. This is where SG_REQUIRE_NOEXCEPT logic is encapsulated. */
|
||||
template<typename T>
|
||||
struct is_nothrow_invocable_if_required_t
|
||||
: public
|
||||
#ifdef SG_REQUIRE_NOEXCEPT
|
||||
std::is_nothrow_invocable<T> /* Note: _r variants not enough to
|
||||
confirm void return: any return can be
|
||||
discarded so all returns are
|
||||
compatible with void */
|
||||
#else
|
||||
std::true_type
|
||||
#endif
|
||||
{};
|
||||
|
||||
// logic AND of two or more type traits
|
||||
template<typename A, typename B, typename... C>
|
||||
struct and_t : public and_t<A, and_t<B, C...>>
|
||||
{}; // for more than two arguments
|
||||
|
||||
template<typename A, typename B>
|
||||
struct and_t<A, B> : public std::conditional<A::value, B, A>::type
|
||||
{}; // for two arguments
|
||||
|
||||
// Type trait determining whether a type is a proper scope_guard callback.
|
||||
template<typename T>
|
||||
struct is_proper_sg_callback_t
|
||||
: public and_t<is_noarg_callable_t<T>,
|
||||
returns_void_t<T>,
|
||||
is_nothrow_invocable_if_required_t<T>,
|
||||
std::is_nothrow_destructible<T>>
|
||||
{};
|
||||
|
||||
|
||||
/* --- The actual scope_guard template --- */
|
||||
|
||||
template<typename Callback,
|
||||
typename = typename std::enable_if<
|
||||
is_proper_sg_callback_t<Callback>::value>::type>
|
||||
class scope_guard;
|
||||
|
||||
|
||||
/* --- Now the friend maker --- */
|
||||
|
||||
template<typename Callback>
|
||||
detail::scope_guard<Callback> make_scope_guard(Callback&& callback)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value); /*
|
||||
we need this in the inner namespace due to MSVC bugs preventing
|
||||
sg::detail::scope_guard from befriending a sg::make_scope_guard
|
||||
template instance in the parent namespace (see https://is.gd/xFfFhE). */
|
||||
|
||||
|
||||
/* --- The template specialization that actually defines the class --- */
|
||||
|
||||
template<typename Callback>
|
||||
class scope_guard<Callback> final
|
||||
{
|
||||
public:
|
||||
typedef Callback callback_type;
|
||||
|
||||
scope_guard(scope_guard&& other)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value);
|
||||
|
||||
~scope_guard() noexcept; // highlight noexcept dtor
|
||||
|
||||
void dismiss() noexcept;
|
||||
|
||||
public:
|
||||
scope_guard() = delete;
|
||||
scope_guard(const scope_guard&) = delete;
|
||||
scope_guard& operator=(const scope_guard&) = delete;
|
||||
scope_guard& operator=(scope_guard&&) = delete;
|
||||
|
||||
private:
|
||||
explicit scope_guard(Callback&& callback)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value); /*
|
||||
meant for friends only */
|
||||
|
||||
friend scope_guard<Callback> make_scope_guard<Callback>(Callback&&)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value); /*
|
||||
only make_scope_guard can create scope_guards from scratch (i.e. non-move)
|
||||
*/
|
||||
|
||||
private:
|
||||
Callback m_callback;
|
||||
bool m_active;
|
||||
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/* --- Now the single public maker function --- */
|
||||
|
||||
using detail::make_scope_guard; // see comment on declaration above
|
||||
|
||||
} // namespace sg
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
sg::detail::scope_guard<Callback>::scope_guard(Callback&& callback)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value)
|
||||
: m_callback(std::forward<Callback>(callback)) /* use () instead of {} because
|
||||
of DR 1467 (https://is.gd/WHmWuo), which still impacts older compilers
|
||||
(e.g. GCC 4.x and clang <=3.6, see https://godbolt.org/g/TE9tPJ and
|
||||
https://is.gd/Tsmh8G) */
|
||||
, m_active{true}
|
||||
{}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
sg::detail::scope_guard<Callback>::~scope_guard() noexcept
|
||||
{
|
||||
if(m_active)
|
||||
m_callback();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
sg::detail::scope_guard<Callback>::scope_guard(scope_guard&& other)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value)
|
||||
: m_callback(std::forward<Callback>(other.m_callback)) // idem
|
||||
, m_active{std::move(other.m_active)}
|
||||
{
|
||||
other.m_active = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
inline void sg::detail::scope_guard<Callback>::dismiss() noexcept
|
||||
{
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
inline auto sg::detail::make_scope_guard(Callback&& callback)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value)
|
||||
-> detail::scope_guard<Callback>
|
||||
{
|
||||
return detail::scope_guard<Callback>{std::forward<Callback>(callback)};
|
||||
}
|
||||
|
||||
#endif /* SCOPE_GUARD_HPP_ */
|
||||
Reference in New Issue
Block a user