gui: Add YubiKey support to widgets

* Add YubiKey support to the GUI widgets.

Signed-off-by: Kyle Manna <kyle@kylemanna.com>
This commit is contained in:
Kyle Manna 2014-05-26 00:49:28 -07:00
parent 9556d8e6da
commit ba8fd25604
6 changed files with 124 additions and 0 deletions

View File

@ -15,14 +15,18 @@
* 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 <QtConcurrentRun>
#include "ChangeMasterKeyWidget.h" #include "ChangeMasterKeyWidget.h"
#include "ui_ChangeMasterKeyWidget.h" #include "ui_ChangeMasterKeyWidget.h"
#include "core/FilePath.h" #include "core/FilePath.h"
#include "keys/FileKey.h" #include "keys/FileKey.h"
#include "keys/PasswordKey.h" #include "keys/PasswordKey.h"
#include "keys/YkChallengeResponseKey.h"
#include "gui/FileDialog.h" #include "gui/FileDialog.h"
#include "gui/MessageBox.h" #include "gui/MessageBox.h"
#include "crypto/Random.h"
ChangeMasterKeyWidget::ChangeMasterKeyWidget(QWidget* parent) ChangeMasterKeyWidget::ChangeMasterKeyWidget(QWidget* parent)
: DialogyWidget(parent) : DialogyWidget(parent)
@ -81,6 +85,15 @@ void ChangeMasterKeyWidget::clearForms()
m_ui->togglePasswordButton->setChecked(false); m_ui->togglePasswordButton->setChecked(false);
// TODO: clear m_ui->keyFileCombo // TODO: clear m_ui->keyFileCombo
m_ui->challengeResponseGroup->setChecked(false);
m_ui->challengeResponseCombo->clear();
/* YubiKey init is slow */
connect(YubiKey::instance(), SIGNAL(detected(int,bool)),
SLOT(ykDetected(int,bool)),
Qt::QueuedConnection);
QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
m_ui->enterPasswordEdit->setFocus(); m_ui->enterPasswordEdit->setFocus();
} }
@ -128,6 +141,14 @@ void ChangeMasterKeyWidget::generateKey()
m_key.addKey(fileKey); m_key.addKey(fileKey);
} }
if (m_ui->challengeResponseGroup->isChecked()) {
int i = m_ui->challengeResponseCombo->currentIndex();
i = m_ui->challengeResponseCombo->itemData(i).toInt();
YkChallengeResponseKey key(i);
m_key.addChallengeResponseKey(key);
}
Q_EMIT editFinished(true); Q_EMIT editFinished(true);
} }
@ -136,3 +157,11 @@ void ChangeMasterKeyWidget::reject()
{ {
Q_EMIT editFinished(false); Q_EMIT editFinished(false);
} }
void ChangeMasterKeyWidget::ykDetected(int slot, bool blocking)
{
YkChallengeResponseKey yk(slot, blocking);
m_ui->challengeResponseCombo->addItem(yk.getName(), QVariant(slot));
m_ui->challengeResponseGroup->setEnabled(true);
}

View File

@ -47,6 +47,7 @@ private Q_SLOTS:
void reject(); void reject();
void createKeyFile(); void createKeyFile();
void browseKeyFile(); void browseKeyFile();
void ykDetected(int slot, bool blocking);
private: private:
const QScopedPointer<Ui::ChangeMasterKeyWidget> m_ui; const QScopedPointer<Ui::ChangeMasterKeyWidget> m_ui;

View File

@ -123,6 +123,31 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="challengeResponseGroup">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Challenge Response</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<widget class="QComboBox" name="challengeResponseCombo"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="challengeResponseLabel">
<property name="text">
<string>Challenge Response:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">

View File

@ -15,6 +15,8 @@
* 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 <QtConcurrentRun>
#include "DatabaseOpenWidget.h" #include "DatabaseOpenWidget.h"
#include "ui_DatabaseOpenWidget.h" #include "ui_DatabaseOpenWidget.h"
@ -27,6 +29,9 @@
#include "format/KeePass2Reader.h" #include "format/KeePass2Reader.h"
#include "keys/FileKey.h" #include "keys/FileKey.h"
#include "keys/PasswordKey.h" #include "keys/PasswordKey.h"
#include "keys/YkChallengeResponseKey.h"
#include "crypto/Random.h"
DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent) DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
: DialogyWidget(parent) : DialogyWidget(parent)
@ -49,6 +54,13 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
connect(m_ui->editPassword, SIGNAL(textChanged(QString)), SLOT(activatePassword())); connect(m_ui->editPassword, SIGNAL(textChanged(QString)), SLOT(activatePassword()));
connect(m_ui->comboKeyFile, SIGNAL(editTextChanged(QString)), SLOT(activateKeyFile())); connect(m_ui->comboKeyFile, SIGNAL(editTextChanged(QString)), SLOT(activateKeyFile()));
connect(m_ui->comboChallengeResponse, SIGNAL(activated(int)), SLOT(activateChallengeResponse()));
connect(m_ui->checkPassword, SIGNAL(toggled(bool)), SLOT(setOkButtonEnabled()));
connect(m_ui->checkKeyFile, SIGNAL(toggled(bool)), SLOT(setOkButtonEnabled()));
connect(m_ui->comboKeyFile, SIGNAL(editTextChanged(QString)), SLOT(setOkButtonEnabled()));
connect(m_ui->checkChallengeResponse, SIGNAL(toggled(bool)), SLOT(setOkButtonEnabled()));
connect(m_ui->comboChallengeResponse, SIGNAL(activated(int)), SLOT(setOkButtonEnabled()));
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()));
@ -79,6 +91,13 @@ 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 */
connect(YubiKey::instance(), SIGNAL(detected(int,bool)),
SLOT(ykDetected(int,bool)),
Qt::QueuedConnection);
QtConcurrent::run(YubiKey::instance(), &YubiKey::detect);
m_ui->editPassword->setFocus(); m_ui->editPassword->setFocus();
} }
@ -156,6 +175,15 @@ CompositeKey DatabaseOpenWidget::databaseKey()
config()->set("LastKeyFiles", lastKeyFiles); config()->set("LastKeyFiles", lastKeyFiles);
} }
if (m_ui->checkChallengeResponse->isChecked()) {
int i = m_ui->comboChallengeResponse->currentIndex();
i = m_ui->comboChallengeResponse->itemData(i).toInt();
YkChallengeResponseKey key(i);
masterKey.addChallengeResponseKey(key);
}
return masterKey; return masterKey;
} }
@ -174,6 +202,19 @@ void DatabaseOpenWidget::activateKeyFile()
m_ui->checkKeyFile->setChecked(true); m_ui->checkKeyFile->setChecked(true);
} }
void DatabaseOpenWidget::activateChallengeResponse()
{
m_ui->checkChallengeResponse->setChecked(true);
}
void DatabaseOpenWidget::setOkButtonEnabled()
{
bool enable = m_ui->checkPassword->isChecked() || m_ui->checkChallengeResponse->isChecked()
|| (m_ui->checkKeyFile->isChecked() && !m_ui->comboKeyFile->currentText().isEmpty());
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enable);
}
void DatabaseOpenWidget::browseKeyFile() void DatabaseOpenWidget::browseKeyFile()
{ {
QString filters = QString("%1 (*);;%2 (*.key)").arg(tr("All files"), tr("Key files")); QString filters = QString("%1 (*);;%2 (*.key)").arg(tr("All files"), tr("Key files"));
@ -183,3 +224,11 @@ void DatabaseOpenWidget::browseKeyFile()
m_ui->comboKeyFile->lineEdit()->setText(filename); m_ui->comboKeyFile->lineEdit()->setText(filename);
} }
} }
void DatabaseOpenWidget::ykDetected(int slot, bool blocking)
{
YkChallengeResponseKey yk(slot, blocking);
m_ui->comboChallengeResponse->addItem(yk.getName(), QVariant(slot));
m_ui->comboChallengeResponse->setEnabled(true);
m_ui->checkChallengeResponse->setEnabled(true);
}

View File

@ -55,7 +55,10 @@ protected Q_SLOTS:
private Q_SLOTS: private Q_SLOTS:
void activatePassword(); void activatePassword();
void activateKeyFile(); void activateKeyFile();
void activateChallengeResponse();
void setOkButtonEnabled();
void browseKeyFile(); void browseKeyFile();
void ykDetected(int slot, bool blocking);
protected: protected:
const QScopedPointer<Ui::DatabaseOpenWidget> m_ui; const QScopedPointer<Ui::DatabaseOpenWidget> m_ui;

View File

@ -111,6 +111,23 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkChallengeResponse">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Challenge Response:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboChallengeResponse">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>