From b33259b1f2383602509ae97dc05d98661000f741 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Mon, 5 Feb 2018 13:25:16 +0100 Subject: [PATCH] relock database after successful autotype --- src/autotype/AutoType.cpp | 12 +++++++++++- src/autotype/AutoType.h | 2 ++ src/autotype/AutoTypeSelectDialog.cpp | 12 ++++++++++++ src/autotype/AutoTypeSelectDialog.h | 2 ++ src/gui/DatabaseTabWidget.cpp | 26 +++++++++++++++++++++++++- src/gui/DatabaseTabWidget.h | 2 ++ src/gui/SettingsWidget.cpp | 2 ++ src/gui/SettingsWidgetSecurity.ui | 7 +++++++ 8 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 0dfdedaec..e1f14d5bc 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -143,6 +143,8 @@ QStringList AutoType::windowTitles() void AutoType::resetInAutoType() { m_inAutoType.unlock(); + + emit autotypeRejected(); } void AutoType::raiseWindow() @@ -199,6 +201,7 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c { // no edit to the sequence beyond this point if (!verifyAutoTypeSyntax(sequence)) { + emit autotypeRejected(); return; } @@ -206,6 +209,7 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c ListDeleter actionsDeleter(&actions); if (!parseActions(sequence, entry, actions)) { + emit autotypeRejected(); return; } @@ -228,12 +232,16 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c for (AutoTypeAction* action : asConst(actions)) { if (m_plugin->activeWindow() != window) { qWarning("Active window changed, interrupting auto-type."); - break; + emit autotypeRejected(); + return; } action->accept(m_executor); QCoreApplication::processEvents(QEventLoop::AllEvents, 10); } + + // emit signal only if autotype performed correctly + emit autotypePerformed(); } /** @@ -300,6 +308,8 @@ void AutoType::performGlobalAutoType(const QList& dbList) message.append("\n\n"); message.append(windowTitle); MessageBox::information(nullptr, tr("Auto-Type - KeePassXC"), message); + + emit autotypeRejected(); } else if ((matchList.size() == 1) && !config()->get("security/autotypeask").toBool()) { executeAutoTypeActions(matchList.first().entry, nullptr, matchList.first().sequence); m_inAutoType.unlock(); diff --git a/src/autotype/AutoType.h b/src/autotype/AutoType.h index 3b22106bd..98a7bd7fa 100644 --- a/src/autotype/AutoType.h +++ b/src/autotype/AutoType.h @@ -64,6 +64,8 @@ public slots: signals: void globalShortcutTriggered(); + void autotypePerformed(); + void autotypeRejected(); private slots: void performAutoTypeFromGlobal(AutoTypeMatch match); diff --git a/src/autotype/AutoTypeSelectDialog.cpp b/src/autotype/AutoTypeSelectDialog.cpp index 3ef086481..eae9e6ffb 100644 --- a/src/autotype/AutoTypeSelectDialog.cpp +++ b/src/autotype/AutoTypeSelectDialog.cpp @@ -35,6 +35,7 @@ AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent) : QDialog(parent) , m_view(new AutoTypeSelectView(this)) , m_matchActivatedEmitted(false) + , m_rejected(false) { setAttribute(Qt::WA_DeleteOnClose); // Places the window on the active (virtual) desktop instead of where the main window is. @@ -83,6 +84,13 @@ void AutoTypeSelectDialog::done(int r) QDialog::done(r); } +void AutoTypeSelectDialog::reject() +{ + m_rejected = true; + + QDialog::reject(); +} + void AutoTypeSelectDialog::emitMatchActivated(const QModelIndex& index) { // make sure we don't emit the signal twice when both activated() and clicked() are triggered @@ -98,6 +106,10 @@ void AutoTypeSelectDialog::emitMatchActivated(const QModelIndex& index) void AutoTypeSelectDialog::matchRemoved() { + if (m_rejected) { + return; + } + if (m_view->model()->rowCount() == 0) { reject(); } diff --git a/src/autotype/AutoTypeSelectDialog.h b/src/autotype/AutoTypeSelectDialog.h index 83abd2d80..cee3c4087 100644 --- a/src/autotype/AutoTypeSelectDialog.h +++ b/src/autotype/AutoTypeSelectDialog.h @@ -39,6 +39,7 @@ signals: public slots: void done(int r) override; + void reject() override; private slots: void emitMatchActivated(const QModelIndex& index); @@ -47,6 +48,7 @@ private slots: private: AutoTypeSelectView* const m_view; bool m_matchActivatedEmitted; + bool m_rejected; }; #endif // KEEPASSX_AUTOTYPESELECTDIALOG_H diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index f9b7fbd72..b3963f7b1 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -54,6 +54,7 @@ const int DatabaseTabWidget::LastDatabasesCount = 5; DatabaseTabWidget::DatabaseTabWidget(QWidget* parent) : QTabWidget(parent) , m_dbWidgetStateSync(new DatabaseWidgetStateSync(this)) + , m_dbPendingLock(nullptr) { DragTabBar* tabBar = new DragTabBar(this); setTabBar(tabBar); @@ -63,6 +64,7 @@ DatabaseTabWidget::DatabaseTabWidget(QWidget* parent) connect(this, SIGNAL(currentChanged(int)), SLOT(emitActivateDatabaseChanged())); connect(this, SIGNAL(activateDatabaseChanged(DatabaseWidget*)), m_dbWidgetStateSync, SLOT(setActive(DatabaseWidget*))); connect(autoType(), SIGNAL(globalShortcutTriggered()), SLOT(performGlobalAutoType())); + connect(autoType(), SIGNAL(autotypePerformed()), SLOT(relockPendingDatabase())); } DatabaseTabWidget::~DatabaseTabWidget() @@ -737,6 +739,27 @@ void DatabaseTabWidget::lockDatabases() } } +/** + * This function relock the pending database when autotype has been performed successfully + * A database is marked as pending when it's unlocked after a global Auto-Type invocation + */ +void DatabaseTabWidget::relockPendingDatabase() +{ + if (!m_dbPendingLock || !config()->get("security/relockautotype").toBool()) { + return; + } + + if (m_dbPendingLock->currentMode() == DatabaseWidget::LockedMode || !m_dbPendingLock->dbHasKey()) { + m_dbPendingLock = nullptr; + return; + } + + m_dbPendingLock->lock(); + + emit databaseLocked(m_dbPendingLock); + m_dbPendingLock = nullptr; +} + void DatabaseTabWidget::modified() { Q_ASSERT(qobject_cast(sender())); @@ -827,6 +850,7 @@ void DatabaseTabWidget::performGlobalAutoType() if (unlockedDatabases.size() > 0) { autoType()->performGlobalAutoType(unlockedDatabases); } else if (m_dbList.size() > 0){ - indexDatabaseManagerStruct(0).dbWidget->showUnlockDialog(); + m_dbPendingLock = indexDatabaseManagerStruct(0).dbWidget; + m_dbPendingLock->showUnlockDialog(); } } diff --git a/src/gui/DatabaseTabWidget.h b/src/gui/DatabaseTabWidget.h index b839fb3ab..38f9b8474 100644 --- a/src/gui/DatabaseTabWidget.h +++ b/src/gui/DatabaseTabWidget.h @@ -79,6 +79,7 @@ public slots: bool isModified(int index = -1); void performGlobalAutoType(); void lockDatabases(); + void relockPendingDatabase(); QString databasePath(int index = -1); signals: @@ -117,6 +118,7 @@ private: QHash m_dbList; QPointer m_dbWidgetStateSync; + QPointer m_dbPendingLock; }; #endif // KEEPASSX_DATABASETABWIDGET_H diff --git a/src/gui/SettingsWidget.cpp b/src/gui/SettingsWidget.cpp index 919edf9fd..9e4152e25 100644 --- a/src/gui/SettingsWidget.cpp +++ b/src/gui/SettingsWidget.cpp @@ -161,6 +161,7 @@ void SettingsWidget::loadSettings() m_secUi->lockDatabaseIdleSpinBox->setValue(config()->get("security/lockdatabaseidlesec").toInt()); m_secUi->lockDatabaseMinimizeCheckBox->setChecked(config()->get("security/lockdatabaseminimize").toBool()); m_secUi->lockDatabaseOnScreenLockCheckBox->setChecked(config()->get("security/lockdatabasescreenlock").toBool()); + m_secUi->relockDatabaseAutoTypeCheckBox->setChecked(config()->get("security/relockautotype").toBool()); m_secUi->fallbackToGoogle->setChecked(config()->get("security/IconDownloadFallbackToGoogle").toBool()); m_secUi->passwordCleartextCheckBox->setChecked(config()->get("security/passwordscleartext").toBool()); @@ -233,6 +234,7 @@ void SettingsWidget::saveSettings() config()->set("security/lockdatabaseidlesec", m_secUi->lockDatabaseIdleSpinBox->value()); config()->set("security/lockdatabaseminimize", m_secUi->lockDatabaseMinimizeCheckBox->isChecked()); config()->set("security/lockdatabasescreenlock", m_secUi->lockDatabaseOnScreenLockCheckBox->isChecked()); + config()->set("security/relockautotype", m_secUi->relockDatabaseAutoTypeCheckBox->isChecked()); config()->set("security/IconDownloadFallbackToGoogle", m_secUi->fallbackToGoogle->isChecked()); config()->set("security/passwordscleartext", m_secUi->passwordCleartextCheckBox->isChecked()); diff --git a/src/gui/SettingsWidgetSecurity.ui b/src/gui/SettingsWidgetSecurity.ui index b1c41338d..da3def868 100644 --- a/src/gui/SettingsWidgetSecurity.ui +++ b/src/gui/SettingsWidgetSecurity.ui @@ -122,6 +122,13 @@ + + + + Re-lock previously locked database after performing Auto-Type + + +