mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-12-27 16:29:44 -05:00
Show message when user needs to touch their YubiKey (still buggy when using multiple databases)
This commit is contained in:
parent
44ac7d152b
commit
d6c48a5cf1
@ -87,6 +87,11 @@ Application::Application(int& argc, char** argv)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget* Application::mainWindow() const
|
||||||
|
{
|
||||||
|
return m_mainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
void Application::setMainWindow(QWidget* mainWindow)
|
void Application::setMainWindow(QWidget* mainWindow)
|
||||||
{
|
{
|
||||||
m_mainWindow = mainWindow;
|
m_mainWindow = mainWindow;
|
||||||
|
@ -29,6 +29,7 @@ class Application : public QApplication
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Application(int& argc, char** argv);
|
Application(int& argc, char** argv);
|
||||||
|
QWidget* mainWindow() const;
|
||||||
void setMainWindow(QWidget* mainWindow);
|
void setMainWindow(QWidget* mainWindow);
|
||||||
|
|
||||||
bool event(QEvent* event) override;
|
bool event(QEvent* event) override;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "gui/FileDialog.h"
|
#include "gui/FileDialog.h"
|
||||||
#include "gui/MessageBox.h"
|
#include "gui/MessageBox.h"
|
||||||
#include "crypto/Random.h"
|
#include "crypto/Random.h"
|
||||||
|
#include "MainWindow.h"
|
||||||
|
|
||||||
#include "config-keepassx.h"
|
#include "config-keepassx.h"
|
||||||
|
|
||||||
@ -176,6 +177,8 @@ void ChangeMasterKeyWidget::generateKey()
|
|||||||
bool blocking = i & true;
|
bool blocking = i & true;
|
||||||
int slot = i >> 1;
|
int slot = i >> 1;
|
||||||
auto key = QSharedPointer<YkChallengeResponseKey>(new YkChallengeResponseKey(slot, blocking));
|
auto key = QSharedPointer<YkChallengeResponseKey>(new YkChallengeResponseKey(slot, blocking));
|
||||||
|
connect(key.data(), SIGNAL(userInteractionRequired()), SLOT(showYubiKeyPopup()));
|
||||||
|
connect(key.data(), SIGNAL(userConfirmed()), SLOT(hideYubiKeyPopup()));
|
||||||
m_key.addChallengeResponseKey(key);
|
m_key.addChallengeResponseKey(key);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -238,3 +241,15 @@ void ChangeMasterKeyWidget::setCancelEnabled(bool enabled)
|
|||||||
{
|
{
|
||||||
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(enabled);
|
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChangeMasterKeyWidget::showYubiKeyPopup()
|
||||||
|
{
|
||||||
|
KEEPASSXC_MAIN_WINDOW->displayGlobalMessage(tr("Please touch the button on your YubiKey!"), MessageWidget::Information);
|
||||||
|
KEEPASSXC_MAIN_WINDOW->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChangeMasterKeyWidget::hideYubiKeyPopup()
|
||||||
|
{
|
||||||
|
KEEPASSXC_MAIN_WINDOW->hideGlobalMessage();
|
||||||
|
KEEPASSXC_MAIN_WINDOW->setEnabled(true);
|
||||||
|
}
|
||||||
|
@ -55,6 +55,8 @@ private slots:
|
|||||||
void noYubikeyFound();
|
void noYubikeyFound();
|
||||||
void challengeResponseGroupToggled(bool checked);
|
void challengeResponseGroupToggled(bool checked);
|
||||||
void pollYubikey();
|
void pollYubikey();
|
||||||
|
void showYubiKeyPopup();
|
||||||
|
void hideYubiKeyPopup();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QScopedPointer<Ui::ChangeMasterKeyWidget> m_ui;
|
const QScopedPointer<Ui::ChangeMasterKeyWidget> m_ui;
|
||||||
|
@ -214,6 +214,8 @@ CompositeKey DatabaseOpenWidget::databaseKey()
|
|||||||
bool blocking = i & true;
|
bool blocking = i & true;
|
||||||
int slot = i >> 1;
|
int slot = i >> 1;
|
||||||
auto key = QSharedPointer<YkChallengeResponseKey>(new YkChallengeResponseKey(slot, blocking));
|
auto key = QSharedPointer<YkChallengeResponseKey>(new YkChallengeResponseKey(slot, blocking));
|
||||||
|
connect(key.data(), SIGNAL(userInteractionRequired()), SLOT(showYubiKeyPopup()));
|
||||||
|
connect(key.data(), SIGNAL(userConfirmed()), SLOT(hideYubiKeyPopup()));
|
||||||
masterKey.addChallengeResponseKey(key);
|
masterKey.addChallengeResponseKey(key);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -264,6 +266,18 @@ void DatabaseOpenWidget::pollYubikey()
|
|||||||
QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
|
QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseOpenWidget::showYubiKeyPopup()
|
||||||
|
{
|
||||||
|
m_ui->messageWidget->showMessage(tr("Please touch the button on your YubiKey!"), MessageWidget::Information);
|
||||||
|
KEEPASSXC_MAIN_WINDOW->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseOpenWidget::hideYubiKeyPopup()
|
||||||
|
{
|
||||||
|
m_ui->messageWidget->hideMessage();
|
||||||
|
KEEPASSXC_MAIN_WINDOW->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
void DatabaseOpenWidget::yubikeyDetected(int slot, bool blocking)
|
void DatabaseOpenWidget::yubikeyDetected(int slot, bool blocking)
|
||||||
{
|
{
|
||||||
YkChallengeResponseKey yk(slot, blocking);
|
YkChallengeResponseKey yk(slot, blocking);
|
||||||
|
@ -53,6 +53,8 @@ protected:
|
|||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void openDatabase();
|
virtual void openDatabase();
|
||||||
|
void showYubiKeyPopup();
|
||||||
|
void hideYubiKeyPopup();
|
||||||
void reject();
|
void reject();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "core/SignalMultiplexer.h"
|
#include "core/SignalMultiplexer.h"
|
||||||
#include "gui/DatabaseWidget.h"
|
#include "gui/DatabaseWidget.h"
|
||||||
|
#include "gui/Application.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
@ -43,6 +44,9 @@ public Q_SLOTS:
|
|||||||
void openDatabase(const QString& fileName, const QString& pw = QString(),
|
void openDatabase(const QString& fileName, const QString& pw = QString(),
|
||||||
const QString& keyFile = QString());
|
const QString& keyFile = QString());
|
||||||
void appExit();
|
void appExit();
|
||||||
|
void displayGlobalMessage(const QString& text, MessageWidget::MessageType type);
|
||||||
|
void displayTabMessage(const QString& text, MessageWidget::MessageType type);
|
||||||
|
void hideGlobalMessage();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
@ -75,9 +79,6 @@ private Q_SLOTS:
|
|||||||
void toggleWindow();
|
void toggleWindow();
|
||||||
void lockDatabasesAfterInactivity();
|
void lockDatabasesAfterInactivity();
|
||||||
void repairDatabase();
|
void repairDatabase();
|
||||||
void displayGlobalMessage(const QString& text, MessageWidget::MessageType type);
|
|
||||||
void displayTabMessage(const QString& text, MessageWidget::MessageType type);
|
|
||||||
void hideGlobalMessage();
|
|
||||||
void hideTabMessage();
|
void hideTabMessage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -106,4 +107,6 @@ private:
|
|||||||
bool appExitCalled;
|
bool appExitCalled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define KEEPASSXC_MAIN_WINDOW qobject_cast<MainWindow*>(qobject_cast<Application*>(qApp)->mainWindow())
|
||||||
|
|
||||||
#endif // KEEPASSX_MAINWINDOW_H
|
#endif // KEEPASSX_MAINWINDOW_H
|
||||||
|
@ -14,16 +14,19 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include "keys/YkChallengeResponseKey.h"
|
||||||
#include <QFile>
|
#include "keys/drivers/YubiKey.h"
|
||||||
#include <QXmlStreamReader>
|
|
||||||
|
|
||||||
#include "core/Tools.h"
|
#include "core/Tools.h"
|
||||||
#include "crypto/CryptoHash.h"
|
#include "crypto/CryptoHash.h"
|
||||||
#include "crypto/Random.h"
|
#include "crypto/Random.h"
|
||||||
|
|
||||||
#include "keys/YkChallengeResponseKey.h"
|
#include <QFile>
|
||||||
#include "keys/drivers/YubiKey.h"
|
#include <QXmlStreamReader>
|
||||||
|
#include <QtConcurrent>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QEventLoop>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
YkChallengeResponseKey::YkChallengeResponseKey(int slot, bool blocking)
|
YkChallengeResponseKey::YkChallengeResponseKey(int slot, bool blocking)
|
||||||
: m_slot(slot),
|
: m_slot(slot),
|
||||||
@ -39,12 +42,12 @@ QByteArray YkChallengeResponseKey::rawKey() const
|
|||||||
/**
|
/**
|
||||||
* Assumes yubikey()->init() was called
|
* Assumes yubikey()->init() was called
|
||||||
*/
|
*/
|
||||||
bool YkChallengeResponseKey::challenge(const QByteArray& chal)
|
bool YkChallengeResponseKey::challenge(const QByteArray& challenge)
|
||||||
{
|
{
|
||||||
return challenge(chal, 1);
|
return this->challenge(challenge, 1);
|
||||||
}
|
}
|
||||||
#include <QDebug>
|
|
||||||
bool YkChallengeResponseKey::challenge(const QByteArray& chal, unsigned retries)
|
bool YkChallengeResponseKey::challenge(const QByteArray& challenge, unsigned retries)
|
||||||
{
|
{
|
||||||
Q_ASSERT(retries > 0);
|
Q_ASSERT(retries > 0);
|
||||||
|
|
||||||
@ -55,13 +58,21 @@ bool YkChallengeResponseKey::challenge(const QByteArray& chal, unsigned retries)
|
|||||||
emit userInteractionRequired();
|
emit userInteractionRequired();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = YubiKey::instance()->challenge(m_slot, true, chal, m_key);
|
QFuture<YubiKey::ChallengeResult> future = QtConcurrent::run([this, challenge]() {
|
||||||
|
return YubiKey::instance()->challenge(m_slot, true, challenge, m_key);
|
||||||
|
});
|
||||||
|
|
||||||
|
QEventLoop loop;
|
||||||
|
QFutureWatcher<YubiKey::ChallengeResult> watcher;
|
||||||
|
watcher.setFuture(future);
|
||||||
|
connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||||
|
loop.exec();
|
||||||
|
|
||||||
if (m_blocking) {
|
if (m_blocking) {
|
||||||
emit userConfirmed();
|
emit userConfirmed();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != YubiKey::ERROR) {
|
if (future.result() != YubiKey::ERROR) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ public:
|
|||||||
YkChallengeResponseKey(int slot = -1, bool blocking = false);
|
YkChallengeResponseKey(int slot = -1, bool blocking = false);
|
||||||
|
|
||||||
QByteArray rawKey() const;
|
QByteArray rawKey() const;
|
||||||
bool challenge(const QByteArray& chal);
|
bool challenge(const QByteArray& challenge);
|
||||||
bool challenge(const QByteArray& chal, unsigned retries);
|
bool challenge(const QByteArray& challenge, unsigned retries);
|
||||||
QString getName() const;
|
QString getName() const;
|
||||||
bool isBlocking() const;
|
bool isBlocking() const;
|
||||||
|
|
||||||
|
@ -182,6 +182,7 @@ YubiKey::ChallengeResult YubiKey::challenge(int slot, bool mayBlock, const QByte
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ret = yk_challenge_response(m_yk, yk_cmd, mayBlock, paddedChallenge.size(), c, response.size(), r);
|
int ret = yk_challenge_response(m_yk, yk_cmd, mayBlock, paddedChallenge.size(), c, response.size(), r);
|
||||||
|
emit challenged();
|
||||||
|
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
|
|
||||||
|
@ -86,6 +86,11 @@ Q_SIGNALS:
|
|||||||
*/
|
*/
|
||||||
void detected(int slot, bool blocking);
|
void detected(int slot, bool blocking);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the YubiKey was challenged and has returned a response.
|
||||||
|
*/
|
||||||
|
void challenged();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when no Yubikey could be found.
|
* Emitted when no Yubikey could be found.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user