Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/DatabaseOpenWidget.cpp')
-rw-r--r--src/gui/DatabaseOpenWidget.cpp334
1 files changed, 168 insertions, 166 deletions
diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp
index c610a773d..4dbe9dc9d 100644
--- a/src/gui/DatabaseOpenWidget.cpp
+++ b/src/gui/DatabaseOpenWidget.cpp
@@ -21,7 +21,7 @@
#include "core/Config.h"
#include "core/Database.h"
-#include "core/FilePath.h"
+#include "core/Resources.h"
#include "crypto/Random.h"
#include "format/KeePass2Reader.h"
#include "gui/FileDialog.h"
@@ -37,7 +37,11 @@
#include <QDesktopServices>
#include <QFont>
#include <QSharedPointer>
-#include <QtConcurrentRun>
+
+namespace
+{
+ constexpr int clearFormsDelay = 30000;
+}
DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
: DialogyWidget(parent)
@@ -48,52 +52,60 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
m_ui->messageWidget->setHidden(true);
+ m_hideTimer.setInterval(clearFormsDelay);
+ m_hideTimer.setSingleShot(true);
+ connect(&m_hideTimer, &QTimer::timeout, this, [this] {
+ // Reset the password field after being hidden for a set time
+ m_ui->editPassword->setText("");
+ m_ui->editPassword->setShowPassword(false);
+ });
+
QFont font;
font.setPointSize(font.pointSize() + 4);
font.setBold(true);
m_ui->labelHeadline->setFont(font);
m_ui->labelHeadline->setText(tr("Unlock KeePassXC Database"));
- m_ui->comboKeyFile->lineEdit()->addAction(m_ui->keyFileClearIcon, QLineEdit::TrailingPosition);
-
- m_ui->buttonTogglePassword->setIcon(filePath()->onOffIcon("actions", "password-show"));
- connect(m_ui->buttonTogglePassword, SIGNAL(toggled(bool)), m_ui->editPassword, SLOT(setShowPassword(bool)));
- connect(m_ui->buttonTogglePassword, SIGNAL(toggled(bool)), m_ui->editPassword, SLOT(setFocus()));
connect(m_ui->buttonBrowseFile, SIGNAL(clicked()), SLOT(browseKeyFile()));
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(openDatabase()));
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));
- m_ui->hardwareKeyLabelHelp->setIcon(filePath()->icon("actions", "system-help").pixmap(QSize(12, 12)));
+ m_ui->hardwareKeyLabelHelp->setIcon(resources()->icon("system-help").pixmap(QSize(12, 12)));
connect(m_ui->hardwareKeyLabelHelp, SIGNAL(clicked(bool)), SLOT(openHardwareKeyHelp()));
- m_ui->keyFileLabelHelp->setIcon(filePath()->icon("actions", "system-help").pixmap(QSize(12, 12)));
+ m_ui->keyFileLabelHelp->setIcon(resources()->icon("system-help").pixmap(QSize(12, 12)));
connect(m_ui->keyFileLabelHelp, SIGNAL(clicked(bool)), SLOT(openKeyFileHelp()));
- connect(m_ui->comboKeyFile->lineEdit(), SIGNAL(textChanged(QString)), SLOT(handleKeyFileComboEdited()));
- connect(m_ui->comboKeyFile, SIGNAL(currentIndexChanged(int)), SLOT(handleKeyFileComboChanged()));
- m_ui->keyFileClearIcon->setIcon(filePath()->icon("actions", "edit-clear-locationbar-rtl"));
+ connect(m_ui->keyFileLineEdit, SIGNAL(textChanged(QString)), SLOT(keyFileTextChanged()));
+ m_ui->keyFileLineEdit->addAction(m_ui->keyFileClearIcon, QLineEdit::TrailingPosition);
+ m_ui->keyFileClearIcon->setIcon(resources()->icon("edit-clear-locationbar-rtl"));
m_ui->keyFileClearIcon->setVisible(false);
- connect(m_ui->keyFileClearIcon, SIGNAL(triggered(bool)), SLOT(clearKeyFileEdit()));
+ connect(m_ui->keyFileClearIcon, SIGNAL(triggered(bool)), SLOT(clearKeyFileText()));
#ifdef WITH_XC_YUBIKEY
- m_ui->yubikeyProgress->setVisible(false);
- QSizePolicy sp = m_ui->yubikeyProgress->sizePolicy();
+ m_ui->hardwareKeyProgress->setVisible(false);
+ QSizePolicy sp = m_ui->hardwareKeyProgress->sizePolicy();
sp.setRetainSizeWhenHidden(true);
- m_ui->yubikeyProgress->setSizePolicy(sp);
+ m_ui->hardwareKeyProgress->setSizePolicy(sp);
- connect(m_ui->buttonRedetectYubikey, SIGNAL(clicked()), SLOT(pollYubikey()));
+ connect(m_ui->buttonRedetectYubikey, SIGNAL(clicked()), SLOT(pollHardwareKey()));
+ connect(YubiKey::instance(), SIGNAL(detectComplete(bool)), SLOT(hardwareKeyResponse(bool)), Qt::QueuedConnection);
+
+ connect(YubiKey::instance(), &YubiKey::userInteractionRequest, this, [this] {
+ // Show the press notification if we are in an independent window (e.g., DatabaseOpenDialog)
+ if (window() != getMainWindow()) {
+ m_ui->messageWidget->showMessage(tr("Please touch the button on your YubiKey!"),
+ MessageWidget::Information,
+ MessageWidget::DisableAutoHide);
+ }
+ });
+ connect(YubiKey::instance(), &YubiKey::challengeCompleted, this, [this] { m_ui->messageWidget->hide(); });
#else
m_ui->hardwareKeyLabel->setVisible(false);
m_ui->hardwareKeyLabelHelp->setVisible(false);
m_ui->buttonRedetectYubikey->setVisible(false);
- m_ui->comboChallengeResponse->setVisible(false);
- m_ui->yubikeyProgress->setVisible(false);
-#endif
-
-#ifdef Q_OS_MACOS
- // add random padding to layouts to align widgets properly
- m_ui->dialogButtonsLayout->setContentsMargins(10, 0, 15, 0);
- m_ui->gridLayout->setContentsMargins(10, 0, 0, 0);
+ m_ui->challengeResponseCombo->setVisible(false);
+ m_ui->hardwareKeyProgress->setVisible(false);
#endif
#ifndef WITH_XC_TOUCHID
@@ -113,68 +125,56 @@ void DatabaseOpenWidget::showEvent(QShowEvent* event)
{
DialogyWidget::showEvent(event);
m_ui->editPassword->setFocus();
-
-#ifdef WITH_XC_YUBIKEY
- // showEvent() may be called twice, so make sure we are only polling once
- if (!m_yubiKeyBeingPolled) {
- // clang-format off
- connect(YubiKey::instance(), SIGNAL(detected(int,bool)), SLOT(yubikeyDetected(int,bool)), Qt::QueuedConnection);
- connect(YubiKey::instance(), SIGNAL(detectComplete()), SLOT(yubikeyDetectComplete()), Qt::QueuedConnection);
- connect(YubiKey::instance(), SIGNAL(notFound()), SLOT(noYubikeyFound()), Qt::QueuedConnection);
- // clang-format on
-
- pollYubikey();
- m_yubiKeyBeingPolled = true;
- }
-#endif
+ m_hideTimer.stop();
}
void DatabaseOpenWidget::hideEvent(QHideEvent* event)
{
DialogyWidget::hideEvent(event);
-#ifdef WITH_XC_YUBIKEY
- // Don't listen to any Yubikey events if we are hidden
- disconnect(YubiKey::instance(), nullptr, this, nullptr);
- m_yubiKeyBeingPolled = false;
-#endif
-
- if (isVisible()) {
- return;
+ // Schedule form clearing if we are hidden
+ if (!isVisible()) {
+ m_hideTimer.start();
}
-
- clearForms();
}
void DatabaseOpenWidget::load(const QString& filename)
{
+ clearForms();
+
m_filename = filename;
m_ui->fileNameLabel->setRawText(m_filename);
- m_ui->comboKeyFile->addItem(tr("Select key file..."), -1);
- m_ui->comboKeyFile->setCurrentIndex(0);
m_ui->keyFileClearIcon->setVisible(false);
- m_keyFileComboEdited = false;
- if (config()->get("RememberLastKeyFiles").toBool()) {
- QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
+ if (config()->get(Config::RememberLastKeyFiles).toBool()) {
+ auto lastKeyFiles = config()->get(Config::LastKeyFiles).toHash();
if (lastKeyFiles.contains(m_filename)) {
- m_ui->comboKeyFile->addItem(lastKeyFiles[m_filename].toString());
- m_ui->comboKeyFile->setCurrentIndex(1);
+ m_ui->keyFileLineEdit->setText(lastKeyFiles[m_filename].toString());
}
}
- QHash<QString, QVariant> useTouchID = config()->get("UseTouchID").toHash();
+ QHash<QString, QVariant> useTouchID = config()->get(Config::UseTouchID).toHash();
m_ui->checkTouchID->setChecked(useTouchID.value(m_filename, false).toBool());
+
+#ifdef WITH_XC_YUBIKEY
+ // Only auto-poll for hardware keys if we previously used one with this database file
+ if (config()->get(Config::RememberLastKeyFiles).toBool()) {
+ auto lastChallengeResponse = config()->get(Config::LastChallengeResponse).toHash();
+ if (lastChallengeResponse.contains(m_filename)) {
+ pollHardwareKey();
+ }
+ }
+#endif
}
void DatabaseOpenWidget::clearForms()
{
m_ui->editPassword->setText("");
- m_ui->comboKeyFile->clear();
- m_ui->comboKeyFile->setEditText("");
+ m_ui->editPassword->setShowPassword(false);
+ m_ui->keyFileLineEdit->clear();
m_ui->checkTouchID->setChecked(false);
- m_ui->buttonTogglePassword->setChecked(false);
+ m_ui->challengeResponseCombo->clear();
m_db.reset();
}
@@ -183,23 +183,28 @@ QSharedPointer<Database> DatabaseOpenWidget::database()
return m_db;
}
+QString DatabaseOpenWidget::filename()
+{
+ return m_filename;
+}
+
void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile)
{
m_ui->editPassword->setText(pw);
- m_ui->comboKeyFile->setCurrentIndex(-1);
- m_ui->comboKeyFile->setEditText(keyFile);
+ m_ui->keyFileLineEdit->setText(keyFile);
openDatabase();
}
void DatabaseOpenWidget::openDatabase()
{
- QSharedPointer<CompositeKey> masterKey = databaseKey();
- if (!masterKey) {
+ m_ui->messageWidget->hide();
+
+ QSharedPointer<CompositeKey> databaseKey = buildDatabaseKey();
+ if (!databaseKey) {
return;
}
m_ui->editPassword->setShowPassword(false);
- m_ui->buttonTogglePassword->setChecked(false);
QCoreApplication::processEvents();
m_db.reset(new Database());
@@ -208,11 +213,31 @@ void DatabaseOpenWidget::openDatabase()
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
m_ui->passwordFormFrame->setEnabled(false);
QCoreApplication::processEvents();
- bool ok = m_db->open(m_filename, masterKey, &error, false);
+ bool ok = m_db->open(m_filename, databaseKey, &error, false);
QApplication::restoreOverrideCursor();
m_ui->passwordFormFrame->setEnabled(true);
- if (!ok) {
+ if (ok) {
+#ifdef WITH_XC_TOUCHID
+ QHash<QString, QVariant> useTouchID = config()->get(Config::UseTouchID).toHash();
+
+ // check if TouchID can & should be used to unlock the database next time
+ if (m_ui->checkTouchID->isChecked() && TouchID::getInstance().isAvailable()) {
+ // encrypt and store key blob
+ if (TouchID::getInstance().storeKey(m_filename, PasswordKey(m_ui->editPassword->text()).rawKey())) {
+ useTouchID.insert(m_filename, true);
+ }
+ } else {
+ // when TouchID not available or unchecked, reset for the current database
+ TouchID::getInstance().reset(m_filename);
+ useTouchID.insert(m_filename, false);
+ }
+
+ config()->set(Config::UseTouchID, useTouchID);
+#endif
+ emit dialogFinished(true);
+ clearForms();
+ } else {
if (m_ui->editPassword->text().isEmpty() && !m_retryUnlockWithEmptyPassword) {
QScopedPointer<QMessageBox> msgBox(new QMessageBox(this));
msgBox->setIcon(QMessageBox::Critical);
@@ -232,40 +257,12 @@ void DatabaseOpenWidget::openDatabase()
return;
}
}
+
m_retryUnlockWithEmptyPassword = false;
m_ui->messageWidget->showMessage(error, MessageWidget::MessageType::Error);
// Focus on the password field and select the input for easy retry
m_ui->editPassword->selectAll();
m_ui->editPassword->setFocus();
- return;
- }
-
- if (m_db) {
-#ifdef WITH_XC_TOUCHID
- QHash<QString, QVariant> useTouchID = config()->get("UseTouchID").toHash();
-
- // check if TouchID can & should be used to unlock the database next time
- if (m_ui->checkTouchID->isChecked() && TouchID::getInstance().isAvailable()) {
- // encrypt and store key blob
- if (TouchID::getInstance().storeKey(m_filename, PasswordKey(m_ui->editPassword->text()).rawKey())) {
- useTouchID.insert(m_filename, true);
- }
- } else {
- // when TouchID not available or unchecked, reset for the current database
- TouchID::getInstance().reset(m_filename);
- useTouchID.insert(m_filename, false);
- }
-
- config()->set("UseTouchID", useTouchID);
-#endif
-
- if (m_ui->messageWidget->isVisible()) {
- m_ui->messageWidget->animatedHide();
- }
- emit dialogFinished(true);
- } else {
- m_ui->messageWidget->showMessage(error, MessageWidget::Error);
- m_ui->editPassword->setText("");
#ifdef WITH_XC_TOUCHID
// unable to unlock database, reset TouchID for the current database
@@ -274,12 +271,12 @@ void DatabaseOpenWidget::openDatabase()
}
}
-QSharedPointer<CompositeKey> DatabaseOpenWidget::databaseKey()
+QSharedPointer<CompositeKey> DatabaseOpenWidget::buildDatabaseKey()
{
- auto masterKey = QSharedPointer<CompositeKey>::create();
+ auto databaseKey = QSharedPointer<CompositeKey>::create();
if (!m_ui->editPassword->text().isEmpty() || m_retryUnlockWithEmptyPassword) {
- masterKey->addKey(QSharedPointer<PasswordKey>::create(m_ui->editPassword->text()));
+ databaseKey->addKey(QSharedPointer<PasswordKey>::create(m_ui->editPassword->text()));
}
#ifdef WITH_XC_TOUCHID
@@ -287,7 +284,7 @@ QSharedPointer<CompositeKey> DatabaseOpenWidget::databaseKey()
if (m_ui->checkTouchID->isChecked() && TouchID::getInstance().isAvailable()
&& m_ui->editPassword->text().isEmpty()) {
// clear empty password from composite key
- masterKey->clear();
+ databaseKey->clear();
// try to get, decrypt and use PasswordKey
QSharedPointer<QByteArray> passwordKey = TouchID::getInstance().getKey(m_filename);
@@ -296,23 +293,23 @@ QSharedPointer<CompositeKey> DatabaseOpenWidget::databaseKey()
if (passwordKey.isNull())
return QSharedPointer<CompositeKey>();
- masterKey->addKey(PasswordKey::fromRawKey(*passwordKey));
+ databaseKey->addKey(PasswordKey::fromRawKey(*passwordKey));
}
}
#endif
- QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
+ auto lastKeyFiles = config()->get(Config::LastKeyFiles).toHash();
lastKeyFiles.remove(m_filename);
auto key = QSharedPointer<FileKey>::create();
- QString keyFilename = m_ui->comboKeyFile->currentText();
- if (!m_ui->comboKeyFile->currentText().isEmpty() && m_keyFileComboEdited) {
+ QString keyFilename = m_ui->keyFileLineEdit->text();
+ if (!keyFilename.isEmpty()) {
QString errorMsg;
if (!key->load(keyFilename, &errorMsg)) {
m_ui->messageWidget->showMessage(tr("Failed to open key file: %1").arg(errorMsg), MessageWidget::Error);
return {};
}
- if (key->type() != FileKey::Hashed && !config()->get("Messages/NoLegacyKeyFileWarning").toBool()) {
+ if (key->type() != FileKey::Hashed && !config()->get(Config::Messages_NoLegacyKeyFileWarning).toBool()) {
QMessageBox legacyWarning;
legacyWarning.setWindowTitle(tr("Legacy key file format"));
legacyWarning.setText(tr("You are using a legacy key file format which may become\n"
@@ -323,42 +320,40 @@ QSharedPointer<CompositeKey> DatabaseOpenWidget::databaseKey()
legacyWarning.setDefaultButton(QMessageBox::Ok);
legacyWarning.setCheckBox(new QCheckBox(tr("Don't show this warning again")));
- connect(legacyWarning.checkBox(), &QCheckBox::stateChanged, [](int state) {
- config()->set("Messages/NoLegacyKeyFileWarning", state == Qt::CheckState::Checked);
+ connect(legacyWarning.checkBox(), &QCheckBox::stateChanged, this, [](int state) {
+ config()->set(Config::Messages_NoLegacyKeyFileWarning, state == Qt::CheckState::Checked);
});
legacyWarning.exec();
}
- masterKey->addKey(key);
- lastKeyFiles[m_filename] = keyFilename;
+ databaseKey->addKey(key);
+ lastKeyFiles.insert(m_filename, keyFilename);
}
- if (config()->get("RememberLastKeyFiles").toBool()) {
- config()->set("LastKeyFiles", lastKeyFiles);
+ if (config()->get(Config::RememberLastKeyFiles).toBool()) {
+ config()->set(Config::LastKeyFiles, lastKeyFiles);
}
#ifdef WITH_XC_YUBIKEY
- QHash<QString, QVariant> lastChallengeResponse = config()->get("LastChallengeResponse").toHash();
+ auto lastChallengeResponse = config()->get(Config::LastChallengeResponse).toHash();
lastChallengeResponse.remove(m_filename);
- int selectionIndex = m_ui->comboChallengeResponse->currentIndex();
+ int selectionIndex = m_ui->challengeResponseCombo->currentIndex();
if (selectionIndex > 0) {
- int comboPayload = m_ui->comboChallengeResponse->itemData(selectionIndex).toInt();
-
- // read blocking mode from LSB and slot index number from second LSB
- bool blocking = comboPayload & 1;
- int slot = comboPayload >> 1;
- auto crKey = QSharedPointer<YkChallengeResponseKey>(new YkChallengeResponseKey(slot, blocking));
- masterKey->addChallengeResponseKey(crKey);
- lastChallengeResponse[m_filename] = true;
+ auto slot = m_ui->challengeResponseCombo->itemData(selectionIndex).value<YubiKeySlot>();
+ auto crKey = QSharedPointer<YkChallengeResponseKey>(new YkChallengeResponseKey(slot));
+ databaseKey->addChallengeResponseKey(crKey);
+
+ // Qt doesn't read custom types in settings so stuff into a QString
+ lastChallengeResponse.insert(m_filename, QStringLiteral("%1:%2").arg(slot.first).arg(slot.second));
}
- if (config()->get("RememberLastKeyFiles").toBool()) {
- config()->set("LastChallengeResponse", lastChallengeResponse);
+ if (config()->get(Config::RememberLastKeyFiles).toBool()) {
+ config()->set(Config::LastChallengeResponse, lastChallengeResponse);
}
#endif
- return masterKey;
+ return databaseKey;
}
void DatabaseOpenWidget::reject()
@@ -369,7 +364,7 @@ void DatabaseOpenWidget::reject()
void DatabaseOpenWidget::browseKeyFile()
{
QString filters = QString("%1 (*);;%2 (*.key)").arg(tr("All files"), tr("Key files"));
- if (!config()->get("RememberLastKeyFiles").toBool()) {
+ if (!config()->get(Config::RememberLastKeyFiles).toBool()) {
fileDialog()->setNextForgetDialog();
}
QString filename = fileDialog()->getOpenFileName(this, tr("Select key file"), QString(), filters);
@@ -384,69 +379,76 @@ void DatabaseOpenWidget::browseKeyFile()
}
if (!filename.isEmpty()) {
- m_ui->comboKeyFile->setCurrentIndex(-1);
- m_ui->comboKeyFile->setEditText(filename);
+ m_ui->keyFileLineEdit->setText(filename);
}
}
-void DatabaseOpenWidget::clearKeyFileEdit()
+void DatabaseOpenWidget::clearKeyFileText()
{
- m_ui->comboKeyFile->setCurrentIndex(0);
- // make sure that handler is called even if 0 was the current index already
- handleKeyFileComboChanged();
+ m_ui->keyFileLineEdit->clear();
}
-void DatabaseOpenWidget::handleKeyFileComboEdited()
+void DatabaseOpenWidget::keyFileTextChanged()
{
- m_keyFileComboEdited = true;
- m_ui->keyFileClearIcon->setVisible(true);
+ m_ui->keyFileClearIcon->setVisible(!m_ui->keyFileLineEdit->text().isEmpty());
}
-void DatabaseOpenWidget::handleKeyFileComboChanged()
+void DatabaseOpenWidget::pollHardwareKey()
{
- m_keyFileComboEdited = m_ui->comboKeyFile->currentIndex() != 0;
- m_ui->keyFileClearIcon->setVisible(m_keyFileComboEdited);
-}
+ if (m_pollingHardwareKey) {
+ return;
+ }
+
+ m_ui->challengeResponseCombo->clear();
+ m_ui->challengeResponseCombo->addItem(tr("Detecting hardware keys…"));
-void DatabaseOpenWidget::pollYubikey()
-{
m_ui->buttonRedetectYubikey->setEnabled(false);
- m_ui->comboChallengeResponse->setEnabled(false);
- m_ui->comboChallengeResponse->clear();
- m_ui->comboChallengeResponse->addItem(tr("Select slot..."), -1);
- m_ui->yubikeyProgress->setVisible(true);
+ m_ui->challengeResponseCombo->setEnabled(false);
+ m_ui->hardwareKeyProgress->setVisible(true);
+ m_pollingHardwareKey = true;
- // YubiKey init is slow, detect asynchronously to not block the UI
- QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
+ YubiKey::instance()->findValidKeys();
}
-void DatabaseOpenWidget::yubikeyDetected(int slot, bool blocking)
+void DatabaseOpenWidget::hardwareKeyResponse(bool found)
{
- YkChallengeResponseKey yk(slot, blocking);
- // add detected YubiKey to combo box and encode blocking mode in LSB, slot number in second LSB
- m_ui->comboChallengeResponse->addItem(yk.getName(), QVariant((slot << 1) | blocking));
+ m_ui->challengeResponseCombo->clear();
+ m_ui->buttonRedetectYubikey->setEnabled(true);
+ m_ui->hardwareKeyProgress->setVisible(false);
+ m_pollingHardwareKey = false;
- if (config()->get("RememberLastKeyFiles").toBool()) {
- QHash<QString, QVariant> lastChallengeResponse = config()->get("LastChallengeResponse").toHash();
+ if (!found) {
+ m_ui->challengeResponseCombo->addItem(tr("No hardware keys detected"));
+ m_ui->challengeResponseCombo->setEnabled(false);
+ return;
+ } else {
+ m_ui->challengeResponseCombo->addItem(tr("Select hardware key…"));
+ }
+
+ YubiKeySlot lastUsedSlot;
+ if (config()->get(Config::RememberLastKeyFiles).toBool()) {
+ auto lastChallengeResponse = config()->get(Config::LastChallengeResponse).toHash();
if (lastChallengeResponse.contains(m_filename)) {
- m_ui->comboChallengeResponse->setCurrentIndex(1);
+ // Qt doesn't read custom types in settings so extract from QString
+ auto split = lastChallengeResponse.value(m_filename).toString().split(":");
+ if (split.size() > 1) {
+ lastUsedSlot = YubiKeySlot(split[0].toUInt(), split[1].toInt());
+ }
}
}
-}
-void DatabaseOpenWidget::yubikeyDetectComplete()
-{
- m_ui->comboChallengeResponse->setEnabled(true);
- m_ui->buttonRedetectYubikey->setEnabled(true);
- m_ui->yubikeyProgress->setVisible(false);
- m_yubiKeyBeingPolled = false;
-}
+ int selectedIndex = 0;
+ for (auto& slot : YubiKey::instance()->foundKeys()) {
+ // add detected YubiKey to combo box
+ m_ui->challengeResponseCombo->addItem(YubiKey::instance()->getDisplayName(slot), QVariant::fromValue(slot));
+ // Select this YubiKey + Slot if we used it in the past
+ if (lastUsedSlot == slot) {
+ selectedIndex = m_ui->challengeResponseCombo->count() - 1;
+ }
+ }
-void DatabaseOpenWidget::noYubikeyFound()
-{
- m_ui->buttonRedetectYubikey->setEnabled(true);
- m_ui->yubikeyProgress->setVisible(false);
- m_yubiKeyBeingPolled = false;
+ m_ui->challengeResponseCombo->setCurrentIndex(selectedIndex);
+ m_ui->challengeResponseCombo->setEnabled(true);
}
void DatabaseOpenWidget::openHardwareKeyHelp()