Fix password generator responses (#7404)

* Respond directly to the current client instead of broadcasting

* Append requestID to generate-password response
This commit is contained in:
Sami Vänttinen 2022-02-23 00:52:51 +02:00 committed by Jonathan White
parent 6791024995
commit 7284a8062a
No known key found for this signature in database
GPG key ID: 440FC65F2E0C6E01
10 changed files with 500 additions and 316 deletions

View file

@ -23,6 +23,7 @@
#include "BrowserEntryConfig.h"
#include "BrowserEntrySaveDialog.h"
#include "BrowserHost.h"
#include "BrowserMessageBuilder.h"
#include "BrowserSettings.h"
#include "core/Tools.h"
#include "gui/MainWindow.h"
@ -39,6 +40,7 @@
#include <QJsonArray>
#include <QJsonObject>
#include <QListWidget>
#include <QLocalSocket>
#include <QProgressDialog>
#include <QUrl>
@ -64,6 +66,7 @@ BrowserService::BrowserService()
, m_browserHost(new BrowserHost)
, m_dialogActive(false)
, m_bringToFrontRequested(false)
, m_passwordGeneratorRequested(false)
, m_prevWindowState(WindowState::Normal)
, m_keepassBrowserUUID(Tools::hexToUuid("de887cc3036343b8974b5911b8816224"))
{
@ -311,37 +314,55 @@ QString BrowserService::getCurrentTotp(const QString& uuid)
return {};
}
void BrowserService::showPasswordGenerator(const QJsonObject& errorMessage, const QString& nonce)
void BrowserService::showPasswordGenerator(QLocalSocket* socket,
const QString& incrementedNonce,
const QString& publicKey,
const QString& secretKey)
{
if (!m_passwordGenerator) {
m_passwordGenerator.reset(PasswordGeneratorWidget::popupGenerator());
connect(m_passwordGenerator.data(), &PasswordGeneratorWidget::closed, m_passwordGenerator.data(), [=] {
if (!m_passwordGenerator->isPasswordGenerated()) {
m_browserHost->sendClientMessage(errorMessage);
auto errorMessage = browserMessageBuilder()->getErrorReply("generate-password",
ERROR_KEEPASS_ACTION_CANCELLED_OR_DENIED);
m_browserHost->sendClientMessage(socket, errorMessage);
}
m_passwordGenerator.reset();
hideWindow();
m_passwordGeneratorRequested = false;
});
connect(m_passwordGenerator.data(),
&PasswordGeneratorWidget::appliedPassword,
m_passwordGenerator.data(),
[=](const QString& password) { emit passwordGenerated(password, nonce); });
[=](const QString& password) {
QJsonObject message = browserMessageBuilder()->buildMessage(incrementedNonce);
message["password"] = password;
sendPassword(socket,
browserMessageBuilder()->buildResponse(
"generate-password", message, incrementedNonce, publicKey, secretKey));
});
}
m_passwordGeneratorRequested = true;
raiseWindow();
m_passwordGenerator->raise();
m_passwordGenerator->activateWindow();
}
void BrowserService::sendPassword(const QJsonObject& message)
void BrowserService::sendPassword(QLocalSocket* socket, const QJsonObject& message)
{
m_browserHost->sendClientMessage(message);
m_browserHost->sendClientMessage(socket, message);
hideWindow();
}
bool BrowserService::isPasswordGeneratorRequested() const
{
return m_passwordGeneratorRequested;
}
QString BrowserService::storeKey(const QString& key)
{
auto db = getDatabase();
@ -1382,7 +1403,7 @@ void BrowserService::databaseLocked(DatabaseWidget* dbWidget)
if (dbWidget) {
QJsonObject msg;
msg["action"] = QString("database-locked");
m_browserHost->sendClientMessage(msg);
m_browserHost->broadcastClientMessage(msg);
}
}
@ -1396,7 +1417,7 @@ void BrowserService::databaseUnlocked(DatabaseWidget* dbWidget)
QJsonObject msg;
msg["action"] = QString("database-unlocked");
m_browserHost->sendClientMessage(msg);
m_browserHost->broadcastClientMessage(msg);
auto db = dbWidget->database();
if (checkLegacySettings(db)) {
@ -1419,7 +1440,7 @@ void BrowserService::activeDatabaseChanged(DatabaseWidget* dbWidget)
m_currentDatabaseWidget = dbWidget;
}
void BrowserService::processClientMessage(const QJsonObject& message)
void BrowserService::processClientMessage(QLocalSocket* socket, const QJsonObject& message)
{
auto clientID = message["clientID"].toString();
if (clientID.isEmpty()) {
@ -1432,6 +1453,6 @@ void BrowserService::processClientMessage(const QJsonObject& message)
}
auto& action = m_browserClients.value(clientID);
auto response = action->processClientMessage(message);
m_browserHost->sendClientMessage(response);
auto response = action->processClientMessage(socket, message);
m_browserHost->sendClientMessage(socket, response);
}