aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorluigi1111 <luigi1111w@gmail.com>2020-05-08 12:21:59 -0500
committerluigi1111 <luigi1111w@gmail.com>2020-05-08 12:21:59 -0500
commit8b6978b2a5e1788a32360239f0257ce5327eb88c (patch)
treee65cf41f1813ff1b9edc515f421b25e50da53d46 /src
parent7536e922e916150497162f8becca88738a02da9e (diff)
parent86d21a34baacb7d317b8774b3409781bb3dde037 (diff)
downloadmonzero-gui-8b6978b2a5e1788a32360239f0257ce5327eb88c.tar.gz
monzero-gui-8b6978b2a5e1788a32360239f0257ce5327eb88c.tar.xz
monzero-gui-8b6978b2a5e1788a32360239f0257ce5327eb88c.zip
Merge pull request #2829
86d21a3 trezor: support new passphrase entry mechanism (ph4r05)
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/libwalletqt/PassphraseHelper.cpp70
-rw-r--r--src/libwalletqt/PassphraseHelper.h74
-rw-r--r--src/libwalletqt/Wallet.cpp73
-rw-r--r--src/libwalletqt/Wallet.h11
-rw-r--r--src/libwalletqt/WalletListenerImpl.cpp97
-rw-r--r--src/libwalletqt/WalletListenerImpl.h68
-rw-r--r--src/libwalletqt/WalletManager.cpp74
-rw-r--r--src/libwalletqt/WalletManager.h17
-rw-r--r--src/qt/ScopeGuard.h205
10 files changed, 583 insertions, 109 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index de84824b..3c45c5c4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -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"
diff --git a/src/libwalletqt/PassphraseHelper.cpp b/src/libwalletqt/PassphraseHelper.cpp
new file mode 100644
index 00000000..9e851f1b
--- /dev/null
+++ b/src/libwalletqt/PassphraseHelper.cpp
@@ -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();
+}
diff --git a/src/libwalletqt/PassphraseHelper.h b/src/libwalletqt/PassphraseHelper.h
new file mode 100644
index 00000000..03274992
--- /dev/null
+++ b/src/libwalletqt/PassphraseHelper.h
@@ -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
diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp
index 355ce6a9..2d7f6722 100644
--- a/src/libwalletqt/Wallet.cpp
+++ b/src/libwalletqt/Wallet.cpp
@@ -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)
diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h
index 3450b1ce..f333f935 100644
--- a/src/libwalletqt/Wallet.h
+++ b/src/libwalletqt/Wallet.h
@@ -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;
};
diff --git a/src/libwalletqt/WalletListenerImpl.cpp b/src/libwalletqt/WalletListenerImpl.cpp
new file mode 100644
index 00000000..efcfa112
--- /dev/null
+++ b/src/libwalletqt/WalletListenerImpl.cpp
@@ -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);
+}
diff --git a/src/libwalletqt/WalletListenerImpl.h b/src/libwalletqt/WalletListenerImpl.h
new file mode 100644
index 00000000..9a134547
--- /dev/null
+++ b/src/libwalletqt/WalletListenerImpl.h
@@ -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
diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp
index a5c9e0ff..62836149 100644
--- a/src/libwalletqt/WalletManager.cpp
+++ b/src/libwalletqt/WalletManager.cpp
@@ -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_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);
+ m_phelper.onPassphraseEntered(passphrase, enter_on_device, entry_abort);
}
- virtual void onDeviceButtonRequest(uint64_t code) override
+ virtual Monero::optional<std::string> onDevicePassphraseRequest(bool & on_device) override
{
- emit m_mgr->deviceButtonRequest(code);
+ qDebug() << __FUNCTION__;
+ return m_phelper.onDevicePassphraseRequest(on_device);
}
- virtual void onDeviceButtonPressed() override
+ virtual void onDeviceButtonRequest(uint64_t code) override
{
- emit m_mgr->deviceButtonPressed();
+ qDebug() << __FUNCTION__;
+ emit m_mgr->deviceButtonRequest(code);
}
- virtual void onSetWallet(Monero::Wallet * wallet) override
+ virtual void onDeviceButtonPressed() 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);
+ }
}
diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h
index 01767716..3564ad61 100644
--- a/src/libwalletqt/WalletManager.h
+++ b/src/libwalletqt/WalletManager.h
@@ -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;
};
diff --git a/src/qt/ScopeGuard.h b/src/qt/ScopeGuard.h
new file mode 100644
index 00000000..6d5df044
--- /dev/null
+++ b/src/qt/ScopeGuard.h
@@ -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_ */