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:
Janek Bevendorff 2017-02-20 22:07:01 +01:00
parent 7174549441
commit eb23dda99b
No known key found for this signature in database
GPG Key ID: CFEC2F6850BFFA53
5 changed files with 71 additions and 12 deletions

View File

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

View File

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

View File

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

View File

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

View File

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