mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-08-01 19:16:16 -04:00
Replace "Master Key" with "Database Credentials"
Definitions: * Database Key - Cryptographic hash used to perform encrypt/decrypt of the database. * Database Credentials - User facing term to refer to the collection of Password, Key File, and/or Hardware Key used to derive the Database Key. Changes: * Remove the term "master" and "key" from the user's lexicon and clarify the code base based on the definitions above. * Clean up wording in the UI to be clearer to the end user.
This commit is contained in:
parent
60bb593228
commit
3b459813ed
45 changed files with 162 additions and 162 deletions
201
src/gui/databasekey/KeyComponentWidget.cpp
Normal file
201
src/gui/databasekey/KeyComponentWidget.cpp
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "KeyComponentWidget.h"
|
||||
#include "ui_KeyComponentWidget.h"
|
||||
|
||||
#include <QStackedWidget>
|
||||
#include <QTimer>
|
||||
|
||||
KeyComponentWidget::KeyComponentWidget(QWidget* parent)
|
||||
: KeyComponentWidget({}, parent)
|
||||
{
|
||||
}
|
||||
|
||||
KeyComponentWidget::KeyComponentWidget(const QString& name, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::KeyComponentWidget())
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->addButton, SIGNAL(clicked(bool)), SIGNAL(componentAddRequested()));
|
||||
connect(m_ui->changeButton, SIGNAL(clicked(bool)), SIGNAL(componentEditRequested()));
|
||||
connect(m_ui->removeButton, SIGNAL(clicked(bool)), SIGNAL(componentRemovalRequested()));
|
||||
connect(m_ui->cancelButton, SIGNAL(clicked(bool)), SLOT(cancelEdit()));
|
||||
|
||||
connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(resetComponentEditWidget()));
|
||||
|
||||
connect(this, SIGNAL(nameChanged(QString)), SLOT(updateComponentName(QString)));
|
||||
connect(this, SIGNAL(descriptionChanged(QString)), SLOT(updateComponentDescription(QString)));
|
||||
connect(this, SIGNAL(componentAddRequested()), SLOT(doAdd()));
|
||||
connect(this, SIGNAL(componentEditRequested()), SLOT(doEdit()));
|
||||
connect(this, SIGNAL(componentRemovalRequested()), SLOT(doRemove()));
|
||||
connect(this, SIGNAL(componentAddChanged(bool)), SLOT(updateAddStatus(bool)));
|
||||
|
||||
bool prev = blockSignals(true);
|
||||
setComponentName(name);
|
||||
blockSignals(prev);
|
||||
|
||||
prev = m_ui->stackedWidget->blockSignals(true);
|
||||
m_ui->stackedWidget->setCurrentIndex(Page::AddNew);
|
||||
m_ui->stackedWidget->blockSignals(prev);
|
||||
}
|
||||
|
||||
KeyComponentWidget::~KeyComponentWidget()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name display name for the key component
|
||||
*/
|
||||
void KeyComponentWidget::setComponentName(const QString& name)
|
||||
{
|
||||
if (name == m_componentName) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_componentName = name;
|
||||
emit nameChanged(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The key component's display name
|
||||
*/
|
||||
QString KeyComponentWidget::componentName() const
|
||||
{
|
||||
return m_componentName;
|
||||
}
|
||||
|
||||
void KeyComponentWidget::setComponentDescription(const QString& description)
|
||||
{
|
||||
if (description == m_componentDescription) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_componentDescription = description;
|
||||
emit descriptionChanged(description);
|
||||
}
|
||||
|
||||
QString KeyComponentWidget::componentDescription() const
|
||||
{
|
||||
return m_componentDescription;
|
||||
}
|
||||
|
||||
void KeyComponentWidget::setComponentAdded(bool added)
|
||||
{
|
||||
if (m_isComponentAdded == added) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_isComponentAdded = added;
|
||||
emit componentAddChanged(added);
|
||||
}
|
||||
|
||||
bool KeyComponentWidget::componentAdded() const
|
||||
{
|
||||
return m_isComponentAdded;
|
||||
}
|
||||
|
||||
void KeyComponentWidget::changeVisiblePage(KeyComponentWidget::Page page)
|
||||
{
|
||||
m_previousPage = static_cast<Page>(m_ui->stackedWidget->currentIndex());
|
||||
m_ui->stackedWidget->setCurrentIndex(page);
|
||||
}
|
||||
|
||||
KeyComponentWidget::Page KeyComponentWidget::visiblePage() const
|
||||
{
|
||||
return static_cast<Page>(m_ui->stackedWidget->currentIndex());
|
||||
}
|
||||
|
||||
void KeyComponentWidget::updateComponentName(const QString& name)
|
||||
{
|
||||
m_ui->groupBox->setTitle(name);
|
||||
m_ui->addButton->setText(tr("Add %1", "Add a key component").arg(name));
|
||||
m_ui->changeButton->setText(tr("Change %1", "Change a key component").arg(name));
|
||||
m_ui->removeButton->setText(tr("Remove %1", "Remove a key component").arg(name));
|
||||
m_ui->changeOrRemoveLabel->setText(
|
||||
tr("%1 set, click to change or remove", "Change or remove a key component").arg(name));
|
||||
}
|
||||
|
||||
void KeyComponentWidget::updateComponentDescription(const QString& description)
|
||||
{
|
||||
m_ui->componentDescription->setText(description);
|
||||
}
|
||||
|
||||
void KeyComponentWidget::updateAddStatus(bool added)
|
||||
{
|
||||
if (added) {
|
||||
m_ui->stackedWidget->setCurrentIndex(Page::LeaveOrRemove);
|
||||
} else {
|
||||
m_ui->stackedWidget->setCurrentIndex(Page::AddNew);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyComponentWidget::doAdd()
|
||||
{
|
||||
changeVisiblePage(Page::Edit);
|
||||
}
|
||||
|
||||
void KeyComponentWidget::doEdit()
|
||||
{
|
||||
changeVisiblePage(Page::Edit);
|
||||
}
|
||||
|
||||
void KeyComponentWidget::doRemove()
|
||||
{
|
||||
changeVisiblePage(Page::AddNew);
|
||||
}
|
||||
|
||||
void KeyComponentWidget::cancelEdit()
|
||||
{
|
||||
m_ui->stackedWidget->setCurrentIndex(m_previousPage);
|
||||
emit editCanceled();
|
||||
}
|
||||
|
||||
void KeyComponentWidget::showEvent(QShowEvent* event)
|
||||
{
|
||||
resetComponentEditWidget();
|
||||
QWidget::showEvent(event);
|
||||
}
|
||||
|
||||
void KeyComponentWidget::resetComponentEditWidget()
|
||||
{
|
||||
if (!m_componentWidget || static_cast<Page>(m_ui->stackedWidget->currentIndex()) == Page::Edit) {
|
||||
if (m_componentWidget) {
|
||||
delete m_componentWidget;
|
||||
}
|
||||
|
||||
m_componentWidget = componentEditWidget();
|
||||
m_ui->componentWidgetLayout->addWidget(m_componentWidget);
|
||||
initComponentEditWidget(m_componentWidget);
|
||||
}
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(updateSize()));
|
||||
}
|
||||
|
||||
void KeyComponentWidget::updateSize()
|
||||
{
|
||||
for (int i = 0; i < m_ui->stackedWidget->count(); ++i) {
|
||||
if (m_ui->stackedWidget->currentIndex() == i) {
|
||||
m_ui->stackedWidget->widget(i)->setSizePolicy(
|
||||
m_ui->stackedWidget->widget(i)->sizePolicy().horizontalPolicy(), QSizePolicy::Preferred);
|
||||
} else {
|
||||
m_ui->stackedWidget->widget(i)->setSizePolicy(
|
||||
m_ui->stackedWidget->widget(i)->sizePolicy().horizontalPolicy(), QSizePolicy::Ignored);
|
||||
}
|
||||
}
|
||||
}
|
137
src/gui/databasekey/KeyComponentWidget.h
Normal file
137
src/gui/databasekey/KeyComponentWidget.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSXC_KEYCOMPONENTWIDGET_H
|
||||
#define KEEPASSXC_KEYCOMPONENTWIDGET_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <QScopedPointer>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class KeyComponentWidget;
|
||||
}
|
||||
class CompositeKey;
|
||||
class QStackedWidget;
|
||||
|
||||
class KeyComponentWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
// clang-format off
|
||||
Q_PROPERTY(QString componentName READ m_componentName READ componentName
|
||||
WRITE setComponentName NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString componentDescription READ m_componentDescription READ componentDescription
|
||||
WRITE setComponentDescription NOTIFY descriptionChanged)
|
||||
Q_PROPERTY(bool componentAdded READ m_isComponentAdded READ componentAdded
|
||||
WRITE setComponentAdded NOTIFY componentAddChanged)
|
||||
// clang-format on
|
||||
|
||||
public:
|
||||
enum Page
|
||||
{
|
||||
AddNew = 0,
|
||||
Edit = 1,
|
||||
LeaveOrRemove = 2
|
||||
};
|
||||
|
||||
explicit KeyComponentWidget(QWidget* parent = nullptr);
|
||||
explicit KeyComponentWidget(const QString& name, QWidget* parent = nullptr);
|
||||
Q_DISABLE_COPY(KeyComponentWidget);
|
||||
~KeyComponentWidget() override;
|
||||
|
||||
/**
|
||||
* Add the new key component to the given \link CompositeKey.
|
||||
* A caller should always check first with \link validate() if
|
||||
* the new key data is actually valid before adding it to a CompositeKey.
|
||||
*
|
||||
* @param key CompositeKey to add new key to
|
||||
* @return true if added successfully
|
||||
*/
|
||||
virtual bool addToCompositeKey(QSharedPointer<CompositeKey> key) = 0;
|
||||
|
||||
/**
|
||||
* Validate key component data to check if key component
|
||||
* may be added to a CompositeKey.
|
||||
*
|
||||
* @param errorMessage error message in case data is not valid
|
||||
* @return true if data is valid
|
||||
*/
|
||||
virtual bool validate(QString& errorMessage) const = 0;
|
||||
|
||||
void setComponentName(const QString& name);
|
||||
QString componentName() const;
|
||||
void setComponentDescription(const QString& name);
|
||||
QString componentDescription() const;
|
||||
void setComponentAdded(bool added);
|
||||
bool componentAdded() const;
|
||||
void changeVisiblePage(Page page);
|
||||
Page visiblePage() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Construct and return an instance of the key component edit widget
|
||||
* which is to be inserted into the component management UI.
|
||||
* Since previous widgets will be destroyed, every successive call to
|
||||
* this function must return a new widget.
|
||||
*
|
||||
* @return edit widget instance
|
||||
*/
|
||||
virtual QWidget* componentEditWidget() = 0;
|
||||
|
||||
/**
|
||||
* Initialize the key component widget created by \link componentEditWidget().
|
||||
* This method is called every time the component edit widget is shown.
|
||||
*
|
||||
* @param widget pointer to the widget
|
||||
*/
|
||||
virtual void initComponentEditWidget(QWidget* widget) = 0;
|
||||
|
||||
signals:
|
||||
void nameChanged(const QString& newName);
|
||||
void descriptionChanged(const QString& newDescription);
|
||||
void componentAddChanged(bool added);
|
||||
void componentAddRequested();
|
||||
void componentEditRequested();
|
||||
void editCanceled();
|
||||
void componentRemovalRequested();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* event) override;
|
||||
|
||||
private slots:
|
||||
void updateComponentName(const QString& name);
|
||||
void updateComponentDescription(const QString& decription);
|
||||
void updateAddStatus(bool added);
|
||||
void doAdd();
|
||||
void doEdit();
|
||||
void doRemove();
|
||||
void cancelEdit();
|
||||
void resetComponentEditWidget();
|
||||
void updateSize();
|
||||
|
||||
private:
|
||||
bool m_isComponentAdded = false;
|
||||
Page m_previousPage = Page::AddNew;
|
||||
QString m_componentName;
|
||||
QString m_componentDescription;
|
||||
QPointer<QWidget> m_componentWidget;
|
||||
|
||||
const QScopedPointer<Ui::KeyComponentWidget> m_ui;
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_KEYCOMPONENTWIDGET_H
|
226
src/gui/databasekey/KeyComponentWidget.ui
Normal file
226
src/gui/databasekey/KeyComponentWidget.ui
Normal file
|
@ -0,0 +1,226 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KeyComponentWidget</class>
|
||||
<widget class="QWidget" name="KeyComponentWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>354</width>
|
||||
<height>106</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QGroupBox { font-weight: bold; }</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Key Component</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="addPage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="componentDescription">
|
||||
<property name="text">
|
||||
<string>Key Component Description</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addButton">
|
||||
<property name="text">
|
||||
<string notr="true">Add Key Component</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="editPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="componentWidgetContainer" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="componentWidgetLayout">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="changeOrRemovePage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="changeOrRemoveLabel">
|
||||
<property name="text">
|
||||
<string>Key Component set, click to change or remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="changeButton">
|
||||
<property name="text">
|
||||
<string notr="true">Change Key Component</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="removeButton">
|
||||
<property name="text">
|
||||
<string notr="true">Remove Key Component</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
148
src/gui/databasekey/KeyFileEditWidget.cpp
Normal file
148
src/gui/databasekey/KeyFileEditWidget.cpp
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "KeyFileEditWidget.h"
|
||||
#include "ui_KeyFileEditWidget.h"
|
||||
#include <gui/dbsettings/DatabaseSettingsWidget.h>
|
||||
|
||||
#include "gui/FileDialog.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "keys/CompositeKey.h"
|
||||
#include "keys/FileKey.h"
|
||||
|
||||
KeyFileEditWidget::KeyFileEditWidget(DatabaseSettingsWidget* parent)
|
||||
: KeyComponentWidget(parent)
|
||||
, m_compUi(new Ui::KeyFileEditWidget())
|
||||
, m_parent(parent)
|
||||
{
|
||||
setComponentName(tr("Key File"));
|
||||
setComponentDescription(tr("<p>You can add a key file containing random bytes for additional security.</p>"
|
||||
"<p>You must keep it secret and never lose it or you will be locked out!</p>"));
|
||||
}
|
||||
|
||||
KeyFileEditWidget::~KeyFileEditWidget()
|
||||
{
|
||||
}
|
||||
|
||||
bool KeyFileEditWidget::addToCompositeKey(QSharedPointer<CompositeKey> key)
|
||||
{
|
||||
auto fileKey = QSharedPointer<FileKey>::create();
|
||||
QString fileKeyName = m_compUi->keyFileCombo->currentText();
|
||||
if (!fileKey->load(fileKeyName, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileKey->type() != FileKey::Hashed) {
|
||||
QMessageBox::warning(getMainWindow(),
|
||||
tr("Legacy key file format"),
|
||||
tr("You are using a legacy key file format which may become\n"
|
||||
"unsupported in the future.\n\n"
|
||||
"Generate a new key file in the database security settings."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
|
||||
key->addKey(fileKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyFileEditWidget::validate(QString& errorMessage) const
|
||||
{
|
||||
FileKey fileKey;
|
||||
QString fileKeyError;
|
||||
QString fileKeyName = m_compUi->keyFileCombo->currentText();
|
||||
if (!fileKey.load(fileKeyName, &fileKeyError)) {
|
||||
errorMessage = tr("Error loading the key file '%1'\nMessage: %2").arg(fileKeyName, fileKeyError);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QWidget* KeyFileEditWidget::componentEditWidget()
|
||||
{
|
||||
m_compEditWidget = new QWidget();
|
||||
m_compUi->setupUi(m_compEditWidget);
|
||||
|
||||
connect(m_compUi->createKeyFileButton, SIGNAL(clicked()), SLOT(createKeyFile()));
|
||||
connect(m_compUi->browseKeyFileButton, SIGNAL(clicked()), SLOT(browseKeyFile()));
|
||||
|
||||
return m_compEditWidget;
|
||||
}
|
||||
|
||||
void KeyFileEditWidget::initComponentEditWidget(QWidget* widget)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_ASSERT(m_compEditWidget);
|
||||
m_compUi->keyFileCombo->setFocus();
|
||||
}
|
||||
|
||||
void KeyFileEditWidget::createKeyFile()
|
||||
{
|
||||
Q_ASSERT(m_compEditWidget);
|
||||
if (!m_compEditWidget) {
|
||||
return;
|
||||
}
|
||||
QString filters = QString("%1 (*.key);;%2 (*)").arg(tr("Key files"), tr("All files"));
|
||||
QString fileName = fileDialog()->getSaveFileName(this, tr("Create Key File..."), QString(), filters);
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
QString errorMsg;
|
||||
bool created = FileKey::create(fileName, &errorMsg);
|
||||
if (!created) {
|
||||
MessageBox::critical(getMainWindow(),
|
||||
tr("Error creating key file"),
|
||||
tr("Unable to create key file: %1").arg(errorMsg),
|
||||
QMessageBox::Button::Ok);
|
||||
} else {
|
||||
m_compUi->keyFileCombo->setEditText(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyFileEditWidget::browseKeyFile()
|
||||
{
|
||||
Q_ASSERT(m_compEditWidget);
|
||||
if (!m_compEditWidget) {
|
||||
return;
|
||||
}
|
||||
QString filters = QString("%1 (*.key);;%2 (*)").arg(tr("Key files"), tr("All files"));
|
||||
QString fileName = fileDialog()->getOpenFileName(this, tr("Select a key file"), QString(), filters);
|
||||
|
||||
if (QFileInfo(fileName).canonicalFilePath() == m_parent->getDatabase()->canonicalFilePath()) {
|
||||
MessageBox::critical(getMainWindow(),
|
||||
tr("Invalid Key File"),
|
||||
tr("You cannot use the current database as its own keyfile. Please choose a different "
|
||||
"file or generate a new key file."));
|
||||
return;
|
||||
} else if (fileName.endsWith(".kdbx", Qt::CaseInsensitive)) {
|
||||
auto response =
|
||||
MessageBox::warning(getMainWindow(),
|
||||
tr("Suspicious Key File"),
|
||||
tr("The chosen key file looks like a password database file. A key file must be a "
|
||||
"static file that never changes or you will lose access to your database "
|
||||
"forever.\nAre you sure you want to continue with this file?"),
|
||||
MessageBox::Continue | MessageBox::Cancel,
|
||||
MessageBox::Cancel);
|
||||
if (response != MessageBox::Continue) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
m_compUi->keyFileCombo->setEditText(fileName);
|
||||
}
|
||||
}
|
57
src/gui/databasekey/KeyFileEditWidget.h
Normal file
57
src/gui/databasekey/KeyFileEditWidget.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSXC_KEYFILEEDITWIDGET_H
|
||||
#define KEEPASSXC_KEYFILEEDITWIDGET_H
|
||||
|
||||
#include "KeyComponentWidget.h"
|
||||
#include <QPointer>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class KeyFileEditWidget;
|
||||
}
|
||||
|
||||
class DatabaseSettingsWidget;
|
||||
|
||||
class KeyFileEditWidget : public KeyComponentWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit KeyFileEditWidget(DatabaseSettingsWidget* parent);
|
||||
Q_DISABLE_COPY(KeyFileEditWidget);
|
||||
~KeyFileEditWidget() override;
|
||||
|
||||
bool addToCompositeKey(QSharedPointer<CompositeKey> key) override;
|
||||
bool validate(QString& errorMessage) const override;
|
||||
|
||||
protected:
|
||||
QWidget* componentEditWidget() override;
|
||||
void initComponentEditWidget(QWidget* widget) override;
|
||||
|
||||
private slots:
|
||||
void createKeyFile();
|
||||
void browseKeyFile();
|
||||
|
||||
private:
|
||||
const QScopedPointer<Ui::KeyFileEditWidget> m_compUi;
|
||||
QPointer<QWidget> m_compEditWidget;
|
||||
const QPointer<DatabaseSettingsWidget> m_parent;
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_KEYFILEEDITWIDGET_H
|
94
src/gui/databasekey/KeyFileEditWidget.ui
Normal file
94
src/gui/databasekey/KeyFileEditWidget.ui
Normal file
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KeyFileEditWidget</class>
|
||||
<widget class="QWidget" name="KeyFileEditWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>370</width>
|
||||
<height>76</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="keyFileCombo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Key file selection</string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="browseKeyFileButton">
|
||||
<property name="accessibleName">
|
||||
<string>Browse for key file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="createKeyFileButton">
|
||||
<property name="accessibleName">
|
||||
<string>Generate a new key file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Generate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Note: Do not use a file that may change as that will prevent you from unlocking your database!</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
114
src/gui/databasekey/PasswordEditWidget.cpp
Normal file
114
src/gui/databasekey/PasswordEditWidget.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PasswordEditWidget.h"
|
||||
#include "ui_PasswordEditWidget.h"
|
||||
|
||||
#include "core/Resources.h"
|
||||
#include "gui/PasswordGeneratorWidget.h"
|
||||
#include "keys/CompositeKey.h"
|
||||
#include "keys/PasswordKey.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
PasswordEditWidget::PasswordEditWidget(QWidget* parent)
|
||||
: KeyComponentWidget(parent)
|
||||
, m_compUi(new Ui::PasswordEditWidget())
|
||||
{
|
||||
setComponentName(tr("Password"));
|
||||
setComponentDescription(tr("<p>A password is the primary method for securing your database.</p>"
|
||||
"<p>Good passwords are long and unique. KeePassXC can generate one for you.</p>"));
|
||||
}
|
||||
|
||||
PasswordEditWidget::~PasswordEditWidget()
|
||||
{
|
||||
}
|
||||
|
||||
bool PasswordEditWidget::addToCompositeKey(QSharedPointer<CompositeKey> key)
|
||||
{
|
||||
QString pw = m_compUi->enterPasswordEdit->text();
|
||||
if (!pw.isEmpty()) {
|
||||
key->addKey(QSharedPointer<PasswordKey>::create(pw));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param visible changed password visibility state
|
||||
*/
|
||||
void PasswordEditWidget::setPasswordVisible(bool visible)
|
||||
{
|
||||
m_compUi->enterPasswordEdit->setShowPassword(visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return password visibility state
|
||||
*/
|
||||
bool PasswordEditWidget::isPasswordVisible() const
|
||||
{
|
||||
return m_compUi->enterPasswordEdit->isPasswordVisible();
|
||||
}
|
||||
|
||||
bool PasswordEditWidget::isEmpty() const
|
||||
{
|
||||
return (visiblePage() == Page::Edit) && m_compUi->enterPasswordEdit->text().isEmpty();
|
||||
}
|
||||
|
||||
QWidget* PasswordEditWidget::componentEditWidget()
|
||||
{
|
||||
m_compEditWidget = new QWidget();
|
||||
m_compUi->setupUi(m_compEditWidget);
|
||||
m_compUi->enterPasswordEdit->enablePasswordGenerator();
|
||||
m_compUi->enterPasswordEdit->setRepeatPartner(m_compUi->repeatPasswordEdit);
|
||||
return m_compEditWidget;
|
||||
}
|
||||
|
||||
void PasswordEditWidget::initComponentEditWidget(QWidget* widget)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_ASSERT(m_compEditWidget);
|
||||
m_compUi->enterPasswordEdit->setFocus();
|
||||
}
|
||||
|
||||
void PasswordEditWidget::hideEvent(QHideEvent* event)
|
||||
{
|
||||
if (!isVisible() && m_compUi->enterPasswordEdit) {
|
||||
m_compUi->enterPasswordEdit->setText("");
|
||||
m_compUi->repeatPasswordEdit->setText("");
|
||||
}
|
||||
|
||||
QWidget::hideEvent(event);
|
||||
}
|
||||
|
||||
bool PasswordEditWidget::validate(QString& errorMessage) const
|
||||
{
|
||||
if (m_compUi->enterPasswordEdit->text() != m_compUi->repeatPasswordEdit->text()) {
|
||||
errorMessage = tr("Passwords do not match.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PasswordEditWidget::setPassword(const QString& password)
|
||||
{
|
||||
Q_ASSERT(m_compEditWidget);
|
||||
|
||||
m_compUi->enterPasswordEdit->setText(password);
|
||||
m_compUi->repeatPasswordEdit->setText(password);
|
||||
}
|
57
src/gui/databasekey/PasswordEditWidget.h
Normal file
57
src/gui/databasekey/PasswordEditWidget.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSXC_PASSWORDEDITWIDGET_H
|
||||
#define KEEPASSXC_PASSWORDEDITWIDGET_H
|
||||
|
||||
#include "KeyComponentWidget.h"
|
||||
#include <QPointer>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class PasswordEditWidget;
|
||||
}
|
||||
|
||||
class PasswordEditWidget : public KeyComponentWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PasswordEditWidget(QWidget* parent = nullptr);
|
||||
Q_DISABLE_COPY(PasswordEditWidget);
|
||||
~PasswordEditWidget() override;
|
||||
|
||||
bool addToCompositeKey(QSharedPointer<CompositeKey> key) override;
|
||||
void setPasswordVisible(bool visible);
|
||||
bool isPasswordVisible() const;
|
||||
bool isEmpty() const;
|
||||
bool validate(QString& errorMessage) const override;
|
||||
|
||||
protected:
|
||||
QWidget* componentEditWidget() override;
|
||||
void initComponentEditWidget(QWidget* widget) override;
|
||||
void hideEvent(QHideEvent* event) override;
|
||||
|
||||
private slots:
|
||||
void setPassword(const QString& password);
|
||||
|
||||
private:
|
||||
const QScopedPointer<Ui::PasswordEditWidget> m_compUi;
|
||||
QPointer<QWidget> m_compEditWidget;
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_PASSWORDEDITWIDGET_H
|
100
src/gui/databasekey/PasswordEditWidget.ui
Normal file
100
src/gui/databasekey/PasswordEditWidget.ui
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PasswordEditWidget</class>
|
||||
<widget class="QWidget" name="PasswordEditWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>571</width>
|
||||
<height>78</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="enterPasswordLabel">
|
||||
<property name="text">
|
||||
<string>Enter password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="PasswordEdit" name="enterPasswordEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Password field</string>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="repeatPasswordLabel">
|
||||
<property name="text">
|
||||
<string>Confirm password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="PasswordEdit" name="repeatPasswordEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Repeat password field</string>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>PasswordEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>gui/PasswordEdit.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>enterPasswordEdit</tabstop>
|
||||
<tabstop>repeatPasswordEdit</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
141
src/gui/databasekey/YubiKeyEditWidget.cpp
Normal file
141
src/gui/databasekey/YubiKeyEditWidget.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "YubiKeyEditWidget.h"
|
||||
#include "ui_YubiKeyEditWidget.h"
|
||||
|
||||
#include "config-keepassx.h"
|
||||
#include "core/AsyncTask.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "keys/CompositeKey.h"
|
||||
#include "keys/YkChallengeResponseKey.h"
|
||||
|
||||
YubiKeyEditWidget::YubiKeyEditWidget(QWidget* parent)
|
||||
: KeyComponentWidget(parent)
|
||||
, m_compUi(new Ui::YubiKeyEditWidget())
|
||||
{
|
||||
setComponentName(tr("YubiKey Challenge-Response"));
|
||||
setComponentDescription(
|
||||
tr("<p>If you own a <a href=\"https://www.yubico.com/\">YubiKey</a>, you can use it "
|
||||
"for additional security.</p><p>The YubiKey requires one of its slots to be programmed as "
|
||||
"<a href=\"https://www.yubico.com/products/services-software/personalization-tools/challenge-response/\">"
|
||||
"HMAC-SHA1 Challenge-Response</a>.</p>"));
|
||||
|
||||
connect(YubiKey::instance(), SIGNAL(detectComplete(bool)), SLOT(hardwareKeyResponse(bool)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
YubiKeyEditWidget::~YubiKeyEditWidget()
|
||||
{
|
||||
}
|
||||
|
||||
bool YubiKeyEditWidget::addToCompositeKey(QSharedPointer<CompositeKey> key)
|
||||
{
|
||||
if (!m_isDetected || !m_compEditWidget) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int selectionIndex = m_compUi->comboChallengeResponse->currentIndex();
|
||||
auto slot = m_compUi->comboChallengeResponse->itemData(selectionIndex).value<YubiKeySlot>();
|
||||
key->addChallengeResponseKey(QSharedPointer<YkChallengeResponseKey>::create(slot));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool YubiKeyEditWidget::validate(QString& errorMessage) const
|
||||
{
|
||||
if (!m_isDetected) {
|
||||
errorMessage = tr("Could not find any hardware keys!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform a test challenge response
|
||||
int selectionIndex = m_compUi->comboChallengeResponse->currentIndex();
|
||||
auto slot = m_compUi->comboChallengeResponse->itemData(selectionIndex).value<YubiKeySlot>();
|
||||
bool valid = AsyncTask::runAndWaitForFuture([&slot] { return YubiKey::instance()->testChallenge(slot); });
|
||||
if (!valid) {
|
||||
errorMessage = tr("Selected hardware key slot does not support challenge-response!");
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
QWidget* YubiKeyEditWidget::componentEditWidget()
|
||||
{
|
||||
m_compEditWidget = new QWidget();
|
||||
m_compUi->setupUi(m_compEditWidget);
|
||||
|
||||
QSizePolicy sp = m_compUi->yubikeyProgress->sizePolicy();
|
||||
sp.setRetainSizeWhenHidden(true);
|
||||
m_compUi->yubikeyProgress->setSizePolicy(sp);
|
||||
m_compUi->yubikeyProgress->setVisible(false);
|
||||
|
||||
#ifdef WITH_XC_YUBIKEY
|
||||
connect(m_compUi->buttonRedetectYubikey, SIGNAL(clicked()), SLOT(pollYubikey()));
|
||||
pollYubikey();
|
||||
#endif
|
||||
|
||||
return m_compEditWidget;
|
||||
}
|
||||
|
||||
void YubiKeyEditWidget::initComponentEditWidget(QWidget* widget)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
Q_ASSERT(m_compEditWidget);
|
||||
m_compUi->comboChallengeResponse->setFocus();
|
||||
}
|
||||
|
||||
void YubiKeyEditWidget::pollYubikey()
|
||||
{
|
||||
#ifdef WITH_XC_YUBIKEY
|
||||
if (!m_compEditWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_isDetected = false;
|
||||
m_compUi->comboChallengeResponse->clear();
|
||||
m_compUi->comboChallengeResponse->addItem(tr("Detecting hardware keys…"));
|
||||
m_compUi->buttonRedetectYubikey->setEnabled(false);
|
||||
m_compUi->comboChallengeResponse->setEnabled(false);
|
||||
m_compUi->yubikeyProgress->setVisible(true);
|
||||
|
||||
YubiKey::instance()->findValidKeys();
|
||||
#endif
|
||||
}
|
||||
|
||||
void YubiKeyEditWidget::hardwareKeyResponse(bool found)
|
||||
{
|
||||
if (!m_compEditWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_compUi->comboChallengeResponse->clear();
|
||||
m_compUi->buttonRedetectYubikey->setEnabled(true);
|
||||
m_compUi->yubikeyProgress->setVisible(false);
|
||||
|
||||
if (!found) {
|
||||
m_compUi->comboChallengeResponse->addItem(tr("No hardware keys detected"));
|
||||
m_isDetected = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& slot : YubiKey::instance()->foundKeys()) {
|
||||
// add detected YubiKey to combo box and encode blocking mode in LSB, slot number in second LSB
|
||||
m_compUi->comboChallengeResponse->addItem(YubiKey::instance()->getDisplayName(slot), QVariant::fromValue(slot));
|
||||
}
|
||||
|
||||
m_isDetected = true;
|
||||
m_compUi->comboChallengeResponse->setEnabled(true);
|
||||
}
|
57
src/gui/databasekey/YubiKeyEditWidget.h
Normal file
57
src/gui/databasekey/YubiKeyEditWidget.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSXC_YUBIKEYEDITWIDGET_H
|
||||
#define KEEPASSXC_YUBIKEYEDITWIDGET_H
|
||||
|
||||
#include "KeyComponentWidget.h"
|
||||
#include <QPointer>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class YubiKeyEditWidget;
|
||||
}
|
||||
|
||||
class YkChallengeResponseKey;
|
||||
|
||||
class YubiKeyEditWidget : public KeyComponentWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit YubiKeyEditWidget(QWidget* parent = nullptr);
|
||||
Q_DISABLE_COPY(YubiKeyEditWidget);
|
||||
~YubiKeyEditWidget() override;
|
||||
|
||||
bool addToCompositeKey(QSharedPointer<CompositeKey> key) override;
|
||||
bool validate(QString& errorMessage) const override;
|
||||
|
||||
protected:
|
||||
QWidget* componentEditWidget() override;
|
||||
void initComponentEditWidget(QWidget* widget) override;
|
||||
|
||||
private slots:
|
||||
void hardwareKeyResponse(bool found);
|
||||
void pollYubikey();
|
||||
|
||||
private:
|
||||
const QScopedPointer<Ui::YubiKeyEditWidget> m_compUi;
|
||||
QPointer<QWidget> m_compEditWidget;
|
||||
bool m_isDetected = false;
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_YUBIKEYEDITWIDGET_H
|
96
src/gui/databasekey/YubiKeyEditWidget.ui
Normal file
96
src/gui/databasekey/YubiKeyEditWidget.ui
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>YubiKeyEditWidget</class>
|
||||
<widget class="QWidget" name="YubiKeyEditWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>64</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<property name="verticalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="buttonRedetectYubikey">
|
||||
<property name="accessibleName">
|
||||
<string>Refresh hardware tokens</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Refresh</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="comboChallengeResponse">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Hardware key slot selection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QProgressBar" name="yubikeyProgress">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>2</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>comboChallengeResponse</tabstop>
|
||||
<tabstop>buttonRedetectYubikey</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
Add table
Add a link
Reference in a new issue