mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-12-28 08:49:42 -05:00
Remember if challenge-response was used for each database and allow to re-detect Yubikeys without closing the database first
This commit is contained in:
parent
7174549441
commit
eb23dda99b
@ -67,9 +67,10 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
|
|||||||
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(openDatabase()));
|
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(openDatabase()));
|
||||||
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));
|
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));
|
||||||
|
|
||||||
connect(YubiKey::instance(), SIGNAL(detected(int,bool)),
|
connect(m_ui->buttonRedetectYubikey, SIGNAL(clicked()), SLOT(pollYubikey()));
|
||||||
SLOT(ykDetected(int,bool)),
|
|
||||||
Qt::QueuedConnection);
|
connect(YubiKey::instance(), SIGNAL(detected(int,bool)), SLOT(yubikeyDetected(int,bool)), Qt::QueuedConnection);
|
||||||
|
connect(YubiKey::instance(), SIGNAL(notFound()), SLOT(noYubikeyFound()), Qt::QueuedConnection);
|
||||||
|
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
// add random padding to layouts to align widgets properly
|
// add random padding to layouts to align widgets properly
|
||||||
@ -105,9 +106,8 @@ void DatabaseOpenWidget::load(const QString& filename)
|
|||||||
|
|
||||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||||
|
|
||||||
/* YubiKey init is slow, detect asynchronously to not block the UI */
|
|
||||||
m_ui->comboChallengeResponse->clear();
|
m_ui->comboChallengeResponse->clear();
|
||||||
QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
|
pollYubikey();
|
||||||
|
|
||||||
m_ui->editPassword->setFocus();
|
m_ui->editPassword->setFocus();
|
||||||
}
|
}
|
||||||
@ -169,6 +169,7 @@ CompositeKey DatabaseOpenWidget::databaseKey()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
|
QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
|
||||||
|
QHash<QString, QVariant> lastChallengeResponse = config()->get("LastChallengeResponse").toHash();
|
||||||
|
|
||||||
if (m_ui->checkKeyFile->isChecked()) {
|
if (m_ui->checkKeyFile->isChecked()) {
|
||||||
FileKey key;
|
FileKey key;
|
||||||
@ -181,13 +182,19 @@ CompositeKey DatabaseOpenWidget::databaseKey()
|
|||||||
}
|
}
|
||||||
masterKey.addKey(key);
|
masterKey.addKey(key);
|
||||||
lastKeyFiles[m_filename] = keyFilename;
|
lastKeyFiles[m_filename] = keyFilename;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
lastKeyFiles.remove(m_filename);
|
lastKeyFiles.remove(m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_ui->checkChallengeResponse->isChecked()) {
|
||||||
|
lastChallengeResponse[m_filename] = true;
|
||||||
|
} else {
|
||||||
|
lastChallengeResponse.remove(m_filename);
|
||||||
|
}
|
||||||
|
|
||||||
if (config()->get("RememberLastKeyFiles").toBool()) {
|
if (config()->get("RememberLastKeyFiles").toBool()) {
|
||||||
config()->set("LastKeyFiles", lastKeyFiles);
|
config()->set("LastKeyFiles", lastKeyFiles);
|
||||||
|
config()->set("LastChallengeResponse", lastChallengeResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -240,10 +247,34 @@ void DatabaseOpenWidget::browseKeyFile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseOpenWidget::ykDetected(int slot, bool blocking)
|
void DatabaseOpenWidget::pollYubikey()
|
||||||
|
{
|
||||||
|
// YubiKey init is slow, detect asynchronously to not block the UI
|
||||||
|
m_ui->buttonRedetectYubikey->setEnabled(false);
|
||||||
|
m_ui->checkChallengeResponse->setEnabled(false);
|
||||||
|
m_ui->checkChallengeResponse->setChecked(false);
|
||||||
|
m_ui->comboChallengeResponse->setEnabled(false);
|
||||||
|
m_ui->comboChallengeResponse->clear();
|
||||||
|
QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseOpenWidget::yubikeyDetected(int slot, bool blocking)
|
||||||
{
|
{
|
||||||
YkChallengeResponseKey yk(slot, blocking);
|
YkChallengeResponseKey yk(slot, blocking);
|
||||||
m_ui->comboChallengeResponse->addItem(yk.getName(), QVariant(slot));
|
m_ui->comboChallengeResponse->addItem(yk.getName(), QVariant(slot));
|
||||||
m_ui->comboChallengeResponse->setEnabled(true);
|
m_ui->comboChallengeResponse->setEnabled(true);
|
||||||
m_ui->checkChallengeResponse->setEnabled(true);
|
m_ui->checkChallengeResponse->setEnabled(true);
|
||||||
|
m_ui->buttonRedetectYubikey->setEnabled(true);
|
||||||
|
|
||||||
|
if (config()->get("RememberLastKeyFiles").toBool()) {
|
||||||
|
QHash<QString, QVariant> lastChallengeResponse = config()->get("LastChallengeResponse").toHash();
|
||||||
|
if (lastChallengeResponse.contains(m_filename)) {
|
||||||
|
m_ui->checkChallengeResponse->setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatabaseOpenWidget::noYubikeyFound()
|
||||||
|
{
|
||||||
|
m_ui->buttonRedetectYubikey->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -58,9 +58,12 @@ private Q_SLOTS:
|
|||||||
void activateChallengeResponse();
|
void activateChallengeResponse();
|
||||||
void setOkButtonEnabled();
|
void setOkButtonEnabled();
|
||||||
void browseKeyFile();
|
void browseKeyFile();
|
||||||
void ykDetected(int slot, bool blocking);
|
void yubikeyDetected(int slot, bool blocking);
|
||||||
|
void noYubikeyFound();
|
||||||
|
void pollYubikey();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
const QScopedPointer<Ui::DatabaseOpenWidget> m_ui;
|
const QScopedPointer<Ui::DatabaseOpenWidget> m_ui;
|
||||||
Database* m_db;
|
Database* m_db;
|
||||||
QString m_filename;
|
QString m_filename;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>596</width>
|
<width>596</width>
|
||||||
<height>262</height>
|
<height>264</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0,1,0,0,3">
|
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0,1,0,0,3">
|
||||||
@ -165,6 +165,25 @@
|
|||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="buttonRedetectYubikey">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh</string>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -117,7 +117,6 @@ bool YubiKey::deinit()
|
|||||||
void YubiKey::detect()
|
void YubiKey::detect()
|
||||||
{
|
{
|
||||||
if (init()) {
|
if (init()) {
|
||||||
|
|
||||||
for (int i = 1; i < 3; i++) {
|
for (int i = 1; i < 3; i++) {
|
||||||
YubiKey::ChallengeResult result;
|
YubiKey::ChallengeResult result;
|
||||||
QByteArray rand = randomGen()->randomArray(1);
|
QByteArray rand = randomGen()->randomArray(1);
|
||||||
@ -126,10 +125,12 @@ void YubiKey::detect()
|
|||||||
result = challenge(i, false, rand, resp);
|
result = challenge(i, false, rand, resp);
|
||||||
|
|
||||||
if (result != YubiKey::ERROR) {
|
if (result != YubiKey::ERROR) {
|
||||||
Q_EMIT detected(i, result == YubiKey::WOULDBLOCK ? true : false);
|
emit detected(i, result == YubiKey::WOULDBLOCK ? true : false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
emit notFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,6 +56,11 @@ Q_SIGNALS:
|
|||||||
*/
|
*/
|
||||||
void detected(int slot, bool blocking);
|
void detected(int slot, bool blocking);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when no Yubikey could be found.
|
||||||
|
*/
|
||||||
|
void notFound();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit YubiKey();
|
explicit YubiKey();
|
||||||
static YubiKey* m_instance;
|
static YubiKey* m_instance;
|
||||||
|
Loading…
Reference in New Issue
Block a user