Merge pull request #2919 from keepassxreboot/fix/database-filename

Correct opening files from command line; cleanup master key editing
This commit is contained in:
Jonathan White 2019-04-02 21:46:23 -04:00 committed by GitHub
commit 835e1b8787
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 85 additions and 46 deletions

View File

@ -388,11 +388,31 @@ const Metadata* Database::metadata() const
return m_metadata;
}
/**
* Returns the original file path that was provided for
* this database. This path may not exist, may contain
* unresolved symlinks, or have malformed slashes.
*
* @return original file path
*/
QString Database::filePath() const
{
return m_data.filePath;
}
/**
* Returns the canonical file path of this databases'
* set file path. This returns an empty string if the
* file does not exist or cannot be resolved.
*
* @return canonical file path
*/
QString Database::canonicalFilePath() const
{
QFileInfo fileInfo(m_data.filePath);
return fileInfo.canonicalFilePath();
}
void Database::setFilePath(const QString& filePath)
{
if (filePath == m_data.filePath) {

View File

@ -82,6 +82,7 @@ public:
QUuid uuid() const;
QString filePath() const;
QString canonicalFilePath() const;
void setFilePath(const QString& filePath);
Metadata* metadata();

View File

@ -1028,10 +1028,8 @@ bool KdbxXmlReader::readBool()
QDateTime KdbxXmlReader::readDateTime()
{
static QRegularExpression b64regex("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$");
QString str = readString();
if (b64regex.match(str).hasMatch()) {
if (Tools::isBase64(str.toLatin1())) {
QByteArray secsBytes = QByteArray::fromBase64(str.toUtf8()).leftJustified(8, '\0', true).left(8);
qint64 secs = Endian::bytesToSizedInt<quint64>(secsBytes, KeePass2::BYTEORDER);
return QDateTime(QDate(1, 1, 1), QTime(0, 0, 0, 0), Qt::UTC).addSecs(secs);

View File

@ -45,7 +45,6 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
m_ui->setupUi(this);
m_ui->messageWidget->setHidden(true);
m_ui->checkPassword->setChecked(true);
QFont font = m_ui->labelHeadline->font();
font.setBold(true);
@ -159,7 +158,7 @@ void DatabaseOpenWidget::clearForms()
m_ui->editPassword->setText("");
m_ui->comboKeyFile->clear();
m_ui->comboKeyFile->setEditText("");
m_ui->checkPassword->setChecked(true);
m_ui->checkPassword->setChecked(false);
m_ui->checkKeyFile->setChecked(false);
m_ui->checkChallengeResponse->setChecked(false);
m_ui->checkTouchID->setChecked(false);
@ -174,13 +173,8 @@ QSharedPointer<Database> DatabaseOpenWidget::database()
void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile)
{
if (!pw.isEmpty()) {
m_ui->editPassword->setText(pw);
}
if (!keyFile.isEmpty()) {
m_ui->comboKeyFile->setEditText(keyFile);
}
m_ui->editPassword->setText(pw);
m_ui->comboKeyFile->setEditText(keyFile);
openDatabase();
}
@ -191,9 +185,7 @@ void DatabaseOpenWidget::openDatabase()
return;
}
if (!m_ui->editPassword->isPasswordVisible()) {
m_ui->editPassword->setShowPassword(false);
}
m_ui->editPassword->setShowPassword(false);
QCoreApplication::processEvents();
m_db.reset(new Database());
@ -339,17 +331,20 @@ void DatabaseOpenWidget::reject()
void DatabaseOpenWidget::activatePassword()
{
m_ui->checkPassword->setChecked(true);
bool hasPassword = !m_ui->editPassword->text().isEmpty();
m_ui->checkPassword->setChecked(hasPassword);
}
void DatabaseOpenWidget::activateKeyFile()
{
m_ui->checkKeyFile->setChecked(true);
bool hasKeyFile = !m_ui->comboKeyFile->lineEdit()->text().isEmpty();
m_ui->checkKeyFile->setChecked(hasKeyFile);
}
void DatabaseOpenWidget::activateChallengeResponse()
{
m_ui->checkChallengeResponse->setChecked(true);
bool hasCR = m_ui->comboChallengeResponse->currentData().toInt() != -1;
m_ui->checkChallengeResponse->setChecked(hasCR);
}
void DatabaseOpenWidget::browseKeyFile()
@ -372,6 +367,7 @@ void DatabaseOpenWidget::pollYubikey()
m_ui->checkChallengeResponse->setChecked(false);
m_ui->comboChallengeResponse->setEnabled(false);
m_ui->comboChallengeResponse->clear();
m_ui->comboChallengeResponse->addItem(tr("Select slot..."), -1);
m_ui->yubikeyProgress->setVisible(true);
// YubiKey init is slow, detect asynchronously to not block the UI
@ -388,6 +384,7 @@ void DatabaseOpenWidget::yubikeyDetected(int slot, bool blocking)
QHash<QString, QVariant> lastChallengeResponse = config()->get("LastChallengeResponse").toHash();
if (lastChallengeResponse.contains(m_filename)) {
m_ui->checkChallengeResponse->setChecked(true);
m_ui->comboChallengeResponse->setCurrentIndex(1);
}
}
}

View File

@ -157,10 +157,8 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath,
for (int i = 0, c = count(); i < c; ++i) {
auto* dbWidget = databaseWidgetFromIndex(i);
Q_ASSERT(dbWidget);
if (dbWidget && dbWidget->database()->filePath() == canonicalFilePath) {
if (!password.isEmpty()) {
dbWidget->performUnlockDatabase(password, keyfile);
}
if (dbWidget && dbWidget->database()->canonicalFilePath() == canonicalFilePath) {
dbWidget->performUnlockDatabase(password, keyfile);
if (!inBackground) {
// switch to existing tab if file is already open
setCurrentIndex(indexOf(dbWidget));
@ -171,9 +169,7 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath,
auto* dbWidget = new DatabaseWidget(QSharedPointer<Database>::create(filePath), this);
addDatabaseTab(dbWidget, inBackground);
if (!password.isEmpty()) {
dbWidget->performUnlockDatabase(password, keyfile);
}
dbWidget->performUnlockDatabase(password, keyfile);
updateLastDatabases(filePath);
}

View File

@ -77,11 +77,8 @@ void DatabaseSettingsWidgetMasterKey::load(QSharedPointer<Database> db)
// database has no key, we are about to add a new one
m_passwordEditWidget->changeVisiblePage(KeyComponentWidget::Page::Edit);
m_passwordEditWidget->setPasswordVisible(true);
m_isDirty = true;
return;
}
bool isDirty = false;
bool hasAdditionalKeys = false;
for (const auto& key : m_db->key()->keys()) {
if (key->uuid() == PasswordKey::UUID) {
@ -103,7 +100,9 @@ void DatabaseSettingsWidgetMasterKey::load(QSharedPointer<Database> db)
setAdditionalKeyOptionsVisible(hasAdditionalKeys);
m_isDirty = isDirty;
connect(m_passwordEditWidget->findChild<QPushButton*>("removeButton"), SIGNAL(clicked()), SLOT(markDirty()));
connect(m_keyFileEditWidget->findChild<QPushButton*>("removeButton"), SIGNAL(clicked()), SLOT(markDirty()));
connect(m_yubiKeyEditWidget->findChild<QPushButton*>("removeButton"), SIGNAL(clicked()), SLOT(markDirty()));
}
void DatabaseSettingsWidgetMasterKey::initialize()

View File

@ -993,6 +993,13 @@ void EditEntryWidget::clear()
{
m_entry = nullptr;
m_db.reset();
m_mainUi->titleEdit->setText("");
m_mainUi->passwordEdit->setText("");
m_mainUi->passwordRepeatEdit->setText("");
m_mainUi->urlEdit->setText("");
m_mainUi->notesEdit->clear();
m_entryAttributes->clear();
m_advancedUi->attachmentsWidget->clearAttachments();
m_autoTypeAssoc->clear();

View File

@ -37,7 +37,7 @@ KeyComponentWidget::KeyComponentWidget(const QString& name, QWidget* parent)
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(reset()));
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)));
@ -46,11 +46,13 @@ KeyComponentWidget::KeyComponentWidget(const QString& name, QWidget* parent)
connect(this, SIGNAL(componentRemovalRequested()), SLOT(doRemove()));
connect(this, SIGNAL(componentAddChanged(bool)), SLOT(updateAddStatus(bool)));
blockSignals(true);
bool prev = blockSignals(true);
setComponentName(name);
blockSignals(prev);
prev = m_ui->stackedWidget->blockSignals(true);
m_ui->stackedWidget->setCurrentIndex(Page::AddNew);
updateSize();
blockSignals(false);
m_ui->stackedWidget->blockSignals(prev);
}
KeyComponentWidget::~KeyComponentWidget()
@ -164,21 +166,22 @@ void KeyComponentWidget::cancelEdit()
emit editCanceled();
}
void KeyComponentWidget::reset()
void KeyComponentWidget::showEvent(QShowEvent* event)
{
if (static_cast<Page>(m_ui->stackedWidget->currentIndex()) == Page::Edit) {
if (!m_ui->componentWidgetLayout->isEmpty()) {
auto* item = m_ui->componentWidgetLayout->takeAt(0);
if (item->widget()) {
delete item->widget();
}
delete item;
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;
}
QWidget* widget = componentEditWidget();
m_ui->componentWidgetLayout->addWidget(widget);
initComponentEditWidget(widget);
m_componentWidget = componentEditWidget();
m_ui->componentWidgetLayout->addWidget(m_componentWidget);
initComponentEditWidget(m_componentWidget);
}
QTimer::singleShot(0, this, SLOT(updateSize()));

View File

@ -20,6 +20,7 @@
#include <QScopedPointer>
#include <QWidget>
#include <QPointer>
namespace Ui
{
@ -109,6 +110,9 @@ signals:
void editCanceled();
void componentRemovalRequested();
protected:
void showEvent(QShowEvent* event) override ;
private slots:
void updateComponentName(const QString& name);
void updateComponentDescription(const QString& decription);
@ -117,7 +121,7 @@ private slots:
void doEdit();
void doRemove();
void cancelEdit();
void reset();
void resetComponentEditWidget();
void updateSize();
private:
@ -125,6 +129,7 @@ private:
Page m_previousPage = Page::AddNew;
QString m_componentName;
QString m_componentDescription;
QPointer<QWidget> m_componentWidget;
const QScopedPointer<Ui::KeyComponentWidget> m_ui;
};

View File

@ -92,6 +92,18 @@ void PasswordEditWidget::initComponentEditWidget(QWidget* widget)
m_compUi->enterPasswordEdit->setFocus();
}
void PasswordEditWidget::hideEvent(QHideEvent* event)
{
Q_ASSERT(m_compUi->enterPasswordEdit);
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()) {

View File

@ -44,6 +44,7 @@ public:
protected:
QWidget* componentEditWidget() override;
void initComponentEditWidget(QWidget* widget) override;
void hideEvent(QHideEvent* event) override;
private slots:
void showPasswordGenerator();