Complete refactor of Browser Integration classes

* Removed option to attach KeePassXC to the browser extension. Users must use the proxy application to communicate with KeePassXC.
* Significantly streamlined proxy code. Used same implementation of stdin/stdout interface across all platforms.
* Moved browser service entry point to BrowserService class instead of NativeMessagingHost. BrowserService now coordinates the communication to/from clients.
* Moved settings page definition out of MainWindow
* Decoupled BrowserService from DatabaseTabWidget
* Reduced complexity of various functions and cleaned the ABI (public vs private).
* Eliminated BrowserClients class, moved functionality into the BrowserService
* Renamed HostInstaller to NativeMessageInstaller and renamed NativeMessageHost to BrowserHost.
* Recognize XDG_CONFIG_HOME when installing native message file on Linux. Fix #4121 and fix #4123.
This commit is contained in:
Jonathan White
2020-05-10 21:20:00 -04:00
parent 3b4057a78c
commit a145bf9119
43 changed files with 1221 additions and 1919 deletions

View File

@@ -1,7 +1,7 @@
/*
* Copyright (C) 2013 Francois Ferrand
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
* Copyright (C) 2020 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
@@ -21,8 +21,9 @@
#define BROWSERSERVICE_H
#include "core/Entry.h"
#include "gui/DatabaseTabWidget.h"
#include <QObject>
#include <QPointer>
#include <QSharedPointer>
#include <QtCore>
typedef QPair<QString, QString> StringPair;
@@ -33,28 +34,33 @@ enum
max_length = 16 * 1024
};
class DatabaseTabWidget;
class DatabaseWidget;
class BrowserHost;
class BrowserAction;
class BrowserService : public QObject
{
Q_OBJECT
public:
enum ReturnValue
{
Success,
Error,
Canceled
};
explicit BrowserService();
static BrowserService* instance();
explicit BrowserService(DatabaseTabWidget* parent);
void setEnabled(bool enabled);
QString getKey(const QString& id);
QString storeKey(const QString& key);
QString getDatabaseHash(bool legacy = false);
bool isDatabaseOpened() const;
bool openDatabase(bool triggerUnlock);
QString getDatabaseRootUuid();
QString getDatabaseRecycleBinUuid();
QJsonObject getDatabaseGroups(const QSharedPointer<Database>& selectedDb = {});
void lockDatabase();
QJsonObject getDatabaseGroups();
QJsonObject createNewGroup(const QString& groupName);
QString getKey(const QString& id);
void addEntry(const QString& id,
void addEntry(const QString& dbid,
const QString& login,
const QString& password,
const QString& url,
@@ -63,11 +69,22 @@ public:
const QString& group,
const QString& groupUuid,
const QSharedPointer<Database>& selectedDb = {});
QList<Entry*> searchEntries(const QSharedPointer<Database>& db, const QString& url, const QString& submitUrl);
QList<Entry*> searchEntries(const QString& url, const QString& submitUrl, const StringPairList& keyList);
void convertAttributesToCustomData(const QSharedPointer<Database>& currentDb = {});
bool updateEntry(const QString& dbid,
const QString& uuid,
const QString& login,
const QString& password,
const QString& url,
const QString& submitUrl);
QJsonArray findMatchingEntries(const QString& dbid,
const QString& url,
const QString& submitUrl,
const QString& realm,
const StringPairList& keyList,
const bool httpAuth = false);
static void convertAttributesToCustomData(QSharedPointer<Database> db);
public:
static const QString KEEPASSXCBROWSER_NAME;
static const QString KEEPASSXCBROWSER_OLD_NAME;
static const QString ASSOCIATE_KEY_PREFIX;
@@ -78,28 +95,12 @@ public:
static const QString ADDITIONAL_URL;
public slots:
QJsonArray findMatchingEntries(const QString& id,
const QString& url,
const QString& submitUrl,
const QString& realm,
const StringPairList& keyList,
const bool httpAuth = false);
QString storeKey(const QString& key);
ReturnValue updateEntry(const QString& id,
const QString& uuid,
const QString& login,
const QString& password,
const QString& url,
const QString& submitUrl);
void databaseLocked(DatabaseWidget* dbWidget);
void databaseUnlocked(DatabaseWidget* dbWidget);
void activateDatabaseChanged(DatabaseWidget* dbWidget);
void lockDatabase();
void activeDatabaseChanged(DatabaseWidget* dbWidget);
signals:
void databaseLocked();
void databaseUnlocked();
void databaseChanged();
private slots:
void processClientMessage(const QJsonObject& message);
private:
enum Access
@@ -116,7 +117,8 @@ private:
Hidden
};
private:
QList<Entry*> searchEntries(const QSharedPointer<Database>& db, const QString& url, const QString& submitUrl);
QList<Entry*> searchEntries(const QString& url, const QString& submitUrl, const StringPairList& keyList);
QList<Entry*> sortEntries(QList<Entry*>& pwEntries, const QString& host, const QString& submitUrl);
QList<Entry*> confirmEntries(QList<Entry*>& pwEntriesToConfirm,
const QString& url,
@@ -125,6 +127,7 @@ private:
const QString& realm,
const bool httpAuth);
QJsonObject prepareEntry(const Entry* entry);
QJsonArray getChildrenFromGroup(Group* group);
Access checkAccess(const Entry* entry, const QString& host, const QString& submitHost, const QString& realm);
Group* getDefaultEntryGroup(const QSharedPointer<Database>& selectedDb = {});
int
@@ -135,21 +138,35 @@ private:
QString baseDomain(const QString& hostname) const;
QSharedPointer<Database> getDatabase();
QSharedPointer<Database> selectedDatabase();
QJsonArray getChildrenFromGroup(Group* group);
bool moveSettingsToCustomData(Entry* entry, const QString& name) const;
int moveKeysToCustomData(Entry* entry, const QSharedPointer<Database>& db) const;
bool checkLegacySettings();
QString getDatabaseRootUuid();
QString getDatabaseRecycleBinUuid();
bool checkLegacySettings(QSharedPointer<Database> db);
void hideWindow() const;
void raiseWindow(const bool force = false);
private:
DatabaseTabWidget* const m_dbTabWidget;
static bool moveSettingsToCustomData(Entry* entry, const QString& name);
static int moveKeysToCustomData(Entry* entry, QSharedPointer<Database> db);
QPointer<BrowserHost> m_browserHost;
QHash<QString, QSharedPointer<BrowserAction>> m_browserClients;
bool m_dialogActive;
bool m_bringToFrontRequested;
WindowState m_prevWindowState;
QUuid m_keepassBrowserUUID;
QPointer<DatabaseWidget> m_currentDatabaseWidget;
Q_DISABLE_COPY(BrowserService);
friend class TestBrowser;
};
static inline BrowserService* browserService()
{
return BrowserService::instance();
}
#endif // BROWSERSERVICE_H