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:
Dusan Klinec
2020-04-11 12:43:21 +02:00
parent 38612c1285
commit 86d21a34ba
15 changed files with 732 additions and 133 deletions

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

View 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

View File

@@ -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)

View File

@@ -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;
};

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

View 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

View File

@@ -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);
}
}

View File

@@ -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;
};