Reduce use of static vars in browser plugin

* Convert BrowserSettings into instanced class
* Moved HostInstaller init into class constructor
This commit is contained in:
Jonathan White 2018-09-05 16:21:59 -04:00
parent 57e60681f2
commit 53a17c2355
No known key found for this signature in database
GPG Key ID: 440FC65F2E0C6E01
11 changed files with 209 additions and 203 deletions

View File

@ -270,8 +270,8 @@ QJsonObject BrowserAction::handleGetLogins(const QJsonObject& json, const QStrin
QJsonObject BrowserAction::handleGeneratePassword(const QJsonObject& json, const QString& action) QJsonObject BrowserAction::handleGeneratePassword(const QJsonObject& json, const QString& action)
{ {
const QString nonce = json.value("nonce").toString(); const QString nonce = json.value("nonce").toString();
const QString password = BrowserSettings::generatePassword(); const QString password = browserSettings()->generatePassword();
const QString bits = QString::number(BrowserSettings::getbits()); // For some reason this always returns 1140 bits? const QString bits = QString::number(browserSettings()->getbits()); // For some reason this always returns 1140 bits?
if (nonce.isEmpty() || password.isEmpty()) { if (nonce.isEmpty() || password.isEmpty()) {
return QJsonObject(); return QJsonObject();

View File

@ -66,36 +66,36 @@ BrowserOptionDialog::~BrowserOptionDialog()
void BrowserOptionDialog::loadSettings() void BrowserOptionDialog::loadSettings()
{ {
BrowserSettings settings; auto settings = browserSettings();
m_ui->enableBrowserSupport->setChecked(settings.isEnabled()); m_ui->enableBrowserSupport->setChecked(settings->isEnabled());
m_ui->showNotification->setChecked(settings.showNotification()); m_ui->showNotification->setChecked(settings->showNotification());
m_ui->bestMatchOnly->setChecked(settings.bestMatchOnly()); m_ui->bestMatchOnly->setChecked(settings->bestMatchOnly());
m_ui->unlockDatabase->setChecked(settings.unlockDatabase()); m_ui->unlockDatabase->setChecked(settings->unlockDatabase());
m_ui->matchUrlScheme->setChecked(settings.matchUrlScheme()); m_ui->matchUrlScheme->setChecked(settings->matchUrlScheme());
// hide unimplemented options // hide unimplemented options
// TODO: fix this // TODO: fix this
m_ui->showNotification->hide(); m_ui->showNotification->hide();
if (settings.sortByUsername()) { if (settings->sortByUsername()) {
m_ui->sortByUsername->setChecked(true); m_ui->sortByUsername->setChecked(true);
} else { } else {
m_ui->sortByTitle->setChecked(true); m_ui->sortByTitle->setChecked(true);
} }
m_ui->alwaysAllowAccess->setChecked(settings.alwaysAllowAccess()); m_ui->alwaysAllowAccess->setChecked(settings->alwaysAllowAccess());
m_ui->alwaysAllowUpdate->setChecked(settings.alwaysAllowUpdate()); m_ui->alwaysAllowUpdate->setChecked(settings->alwaysAllowUpdate());
m_ui->searchInAllDatabases->setChecked(settings.searchInAllDatabases()); m_ui->searchInAllDatabases->setChecked(settings->searchInAllDatabases());
m_ui->supportKphFields->setChecked(settings.supportKphFields()); m_ui->supportKphFields->setChecked(settings->supportKphFields());
m_ui->supportBrowserProxy->setChecked(settings.supportBrowserProxy()); m_ui->supportBrowserProxy->setChecked(settings->supportBrowserProxy());
m_ui->useCustomProxy->setChecked(settings.useCustomProxy()); m_ui->useCustomProxy->setChecked(settings->useCustomProxy());
m_ui->customProxyLocation->setText(settings.customProxyLocation()); m_ui->customProxyLocation->setText(settings->customProxyLocation());
m_ui->updateBinaryPath->setChecked(settings.updateBinaryPath()); m_ui->updateBinaryPath->setChecked(settings->updateBinaryPath());
m_ui->chromeSupport->setChecked(settings.chromeSupport()); m_ui->chromeSupport->setChecked(settings->chromeSupport());
m_ui->chromiumSupport->setChecked(settings.chromiumSupport()); m_ui->chromiumSupport->setChecked(settings->chromiumSupport());
m_ui->firefoxSupport->setChecked(settings.firefoxSupport()); m_ui->firefoxSupport->setChecked(settings->firefoxSupport());
m_ui->vivaldiSupport->setChecked(settings.vivaldiSupport()); m_ui->vivaldiSupport->setChecked(settings->vivaldiSupport());
#if defined(KEEPASSXC_DIST_APPIMAGE) #if defined(KEEPASSXC_DIST_APPIMAGE)
m_ui->supportBrowserProxy->setChecked(true); m_ui->supportBrowserProxy->setChecked(true);
@ -113,28 +113,28 @@ void BrowserOptionDialog::loadSettings()
void BrowserOptionDialog::saveSettings() void BrowserOptionDialog::saveSettings()
{ {
BrowserSettings settings; auto settings = browserSettings();
settings.setEnabled(m_ui->enableBrowserSupport->isChecked()); settings->setEnabled(m_ui->enableBrowserSupport->isChecked());
settings.setShowNotification(m_ui->showNotification->isChecked()); settings->setShowNotification(m_ui->showNotification->isChecked());
settings.setBestMatchOnly(m_ui->bestMatchOnly->isChecked()); settings->setBestMatchOnly(m_ui->bestMatchOnly->isChecked());
settings.setUnlockDatabase(m_ui->unlockDatabase->isChecked()); settings->setUnlockDatabase(m_ui->unlockDatabase->isChecked());
settings.setMatchUrlScheme(m_ui->matchUrlScheme->isChecked()); settings->setMatchUrlScheme(m_ui->matchUrlScheme->isChecked());
settings.setSortByUsername(m_ui->sortByUsername->isChecked()); settings->setSortByUsername(m_ui->sortByUsername->isChecked());
settings.setSupportBrowserProxy(m_ui->supportBrowserProxy->isChecked()); settings->setSupportBrowserProxy(m_ui->supportBrowserProxy->isChecked());
settings.setUseCustomProxy(m_ui->useCustomProxy->isChecked()); settings->setUseCustomProxy(m_ui->useCustomProxy->isChecked());
settings.setCustomProxyLocation(m_ui->customProxyLocation->text()); settings->setCustomProxyLocation(m_ui->customProxyLocation->text());
settings.setUpdateBinaryPath(m_ui->updateBinaryPath->isChecked()); settings->setUpdateBinaryPath(m_ui->updateBinaryPath->isChecked());
settings.setAlwaysAllowAccess(m_ui->alwaysAllowAccess->isChecked()); settings->setAlwaysAllowAccess(m_ui->alwaysAllowAccess->isChecked());
settings.setAlwaysAllowUpdate(m_ui->alwaysAllowUpdate->isChecked()); settings->setAlwaysAllowUpdate(m_ui->alwaysAllowUpdate->isChecked());
settings.setSearchInAllDatabases(m_ui->searchInAllDatabases->isChecked()); settings->setSearchInAllDatabases(m_ui->searchInAllDatabases->isChecked());
settings.setSupportKphFields(m_ui->supportKphFields->isChecked()); settings->setSupportKphFields(m_ui->supportKphFields->isChecked());
settings.setChromeSupport(m_ui->chromeSupport->isChecked()); settings->setChromeSupport(m_ui->chromeSupport->isChecked());
settings.setChromiumSupport(m_ui->chromiumSupport->isChecked()); settings->setChromiumSupport(m_ui->chromiumSupport->isChecked());
settings.setFirefoxSupport(m_ui->firefoxSupport->isChecked()); settings->setFirefoxSupport(m_ui->firefoxSupport->isChecked());
settings.setVivaldiSupport(m_ui->vivaldiSupport->isChecked()); settings->setVivaldiSupport(m_ui->vivaldiSupport->isChecked());
} }
void BrowserOptionDialog::showProxyLocationFileDialog() void BrowserOptionDialog::showProxyLocationFileDialog()

View File

@ -34,7 +34,6 @@
#include "core/PasswordGenerator.h" #include "core/PasswordGenerator.h"
#include "gui/MainWindow.h" #include "gui/MainWindow.h"
static const QUuid KEEPASSXCBROWSER_UUID = QUuid::fromRfc4122(QByteArray::fromHex("de887cc3036343b8974b5911b8816224"));
static const char KEEPASSXCBROWSER_NAME[] = "KeePassXC-Browser Settings"; static const char KEEPASSXCBROWSER_NAME[] = "KeePassXC-Browser Settings";
static const char ASSOCIATE_KEY_PREFIX[] = "Public Key: "; static const char ASSOCIATE_KEY_PREFIX[] = "Public Key: ";
static const char KEEPASSXCBROWSER_GROUP_NAME[] = "KeePassXC-Browser Passwords"; static const char KEEPASSXCBROWSER_GROUP_NAME[] = "KeePassXC-Browser Passwords";
@ -44,6 +43,7 @@ BrowserService::BrowserService(DatabaseTabWidget* parent)
: m_dbTabWidget(parent) : m_dbTabWidget(parent)
, m_dialogActive(false) , m_dialogActive(false)
, m_bringToFrontRequested(false) , m_bringToFrontRequested(false)
, m_keepassBrowserUUID(QUuid::fromRfc4122(QByteArray::fromHex("de887cc3036343b8974b5911b8816224")))
{ {
connect(m_dbTabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), this, SLOT(databaseLocked(DatabaseWidget*))); connect(m_dbTabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), this, SLOT(databaseLocked(DatabaseWidget*)));
connect(m_dbTabWidget, SIGNAL(databaseUnlocked(DatabaseWidget*)), this, SLOT(databaseUnlocked(DatabaseWidget*))); connect(m_dbTabWidget, SIGNAL(databaseUnlocked(DatabaseWidget*)), this, SLOT(databaseUnlocked(DatabaseWidget*)));
@ -65,7 +65,7 @@ bool BrowserService::isDatabaseOpened() const
bool BrowserService::openDatabase(bool triggerUnlock) bool BrowserService::openDatabase(bool triggerUnlock)
{ {
if (!BrowserSettings::unlockDatabase()) { if (!browserSettings()->unlockDatabase()) {
return false; return false;
} }
@ -139,11 +139,11 @@ Entry* BrowserService::getConfigEntry(bool create)
return nullptr; return nullptr;
} }
entry = db->resolveEntry(KEEPASSXCBROWSER_UUID); entry = db->resolveEntry(m_keepassBrowserUUID);
if (!entry && create) { if (!entry && create) {
entry = new Entry(); entry = new Entry();
entry->setTitle(QLatin1String(KEEPASSXCBROWSER_NAME)); entry->setTitle(QLatin1String(KEEPASSXCBROWSER_NAME));
entry->setUuid(KEEPASSXCBROWSER_UUID); entry->setUuid(m_keepassBrowserUUID);
entry->setAutoTypeEnabled(false); entry->setAutoTypeEnabled(false);
entry->setGroup(db->rootGroup()); entry->setGroup(db->rootGroup());
return entry; return entry;
@ -243,7 +243,7 @@ QJsonArray BrowserService::findMatchingEntries(const QString& id,
return result; return result;
} }
const bool alwaysAllowAccess = BrowserSettings::alwaysAllowAccess(); const bool alwaysAllowAccess = browserSettings()->alwaysAllowAccess();
const QString host = QUrl(url).host(); const QString host = QUrl(url).host();
const QString submitHost = QUrl(submitUrl).host(); const QString submitHost = QUrl(submitUrl).host();
@ -358,7 +358,7 @@ void BrowserService::updateEntry(const QString& id,
if (username.compare(login, Qt::CaseSensitive) != 0 || entry->password().compare(password, Qt::CaseSensitive) != 0) { if (username.compare(login, Qt::CaseSensitive) != 0 || entry->password().compare(password, Qt::CaseSensitive) != 0) {
int dialogResult = QMessageBox::No; int dialogResult = QMessageBox::No;
if (!BrowserSettings::alwaysAllowUpdate()) { if (!browserSettings()->alwaysAllowUpdate()) {
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setWindowTitle(tr("KeePassXC: Update Entry")); msgBox.setWindowTitle(tr("KeePassXC: Update Entry"));
msgBox.setText(tr("Do you want to update the information in %1 - %2?").arg(QUrl(url).host()).arg(username)); msgBox.setText(tr("Do you want to update the information in %1 - %2?").arg(QUrl(url).host()).arg(username));
@ -371,7 +371,7 @@ void BrowserService::updateEntry(const QString& id,
dialogResult = msgBox.exec(); dialogResult = msgBox.exec();
} }
if (BrowserSettings::alwaysAllowUpdate() || dialogResult == QMessageBox::Yes) { if (browserSettings()->alwaysAllowUpdate() || dialogResult == QMessageBox::Yes) {
entry->beginUpdate(); entry->beginUpdate();
entry->setUsername(login); entry->setUsername(login);
entry->setPassword(password); entry->setPassword(password);
@ -396,7 +396,7 @@ QList<Entry*> BrowserService::searchEntries(Database* db, const QString& hostnam
// Ignore entry if port or scheme defined in the URL doesn't match // Ignore entry if port or scheme defined in the URL doesn't match
if ((entryQUrl.port() > 0 && entryQUrl.port() != qUrl.port()) || if ((entryQUrl.port() > 0 && entryQUrl.port() != qUrl.port()) ||
(BrowserSettings::matchUrlScheme() && entryScheme.compare(qUrl.scheme()) != 0)) { (browserSettings()->matchUrlScheme() && entryScheme.compare(qUrl.scheme()) != 0)) {
continue; continue;
} }
@ -414,14 +414,14 @@ QList<Entry*> BrowserService::searchEntries(const QString& url, const StringPair
{ {
// Get the list of databases to search // Get the list of databases to search
QList<Database*> databases; QList<Database*> databases;
if (BrowserSettings::searchInAllDatabases()) { if (browserSettings()->searchInAllDatabases()) {
const int count = m_dbTabWidget->count(); const int count = m_dbTabWidget->count();
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
if (DatabaseWidget* dbWidget = qobject_cast<DatabaseWidget*>(m_dbTabWidget->widget(i))) { if (DatabaseWidget* dbWidget = qobject_cast<DatabaseWidget*>(m_dbTabWidget->widget(i))) {
if (Database* db = dbWidget->database()) { if (Database* db = dbWidget->database()) {
// Check if database is connected with KeePassXC-Browser // Check if database is connected with KeePassXC-Browser
for (const StringPair keyPair : keyList) { for (const StringPair keyPair : keyList) {
Entry* entry = db->resolveEntry(KEEPASSXCBROWSER_UUID); Entry* entry = db->resolveEntry(m_keepassBrowserUUID);
if (entry) { if (entry) {
QString key = entry->attributes()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + keyPair.first); QString key = entry->attributes()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + keyPair.first);
if (!key.isEmpty() && keyPair.second == key) { if (!key.isEmpty() && keyPair.second == key) {
@ -564,18 +564,18 @@ QList<Entry*> BrowserService::sortEntries(QList<Entry*>& pwEntries, const QStrin
} }
QList<Entry*> results; QList<Entry*> results;
QString field = BrowserSettings::sortByTitle() ? "Title" : "UserName"; QString field = browserSettings()->sortByTitle() ? "Title" : "UserName";
for (int i = 100; i >= 0; i -= 5) { for (int i = 100; i >= 0; i -= 5) {
if (priorities.count(i) > 0) { if (priorities.count(i) > 0) {
// Sort same priority entries by Title or UserName // Sort same priority entries by Title or UserName
auto entries = priorities.values(i); auto entries = priorities.values(i);
std::sort(entries.begin(), entries.end(), [&priorities, &field](Entry* left, Entry* right) { std::sort(entries.begin(), entries.end(), [&field](Entry* left, Entry* right) {
return (QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) < 0) || return (QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) < 0) ||
((QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) == 0) && ((QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) == 0) &&
(QString::localeAwareCompare(left->attributes()->value("UserName"), right->attributes()->value("UserName")) < 0)); (QString::localeAwareCompare(left->attributes()->value("UserName"), right->attributes()->value("UserName")) < 0));
}); });
results << entries; results << entries;
if (BrowserSettings::bestMatchOnly() && !pwEntries.isEmpty()) { if (browserSettings()->bestMatchOnly() && !pwEntries.isEmpty()) {
// Early out once we find the highest batch of matches // Early out once we find the highest batch of matches
break; break;
} }
@ -642,7 +642,7 @@ QJsonObject BrowserService::prepareEntry(const Entry* entry)
res["totp"] = entry->totp(); res["totp"] = entry->totp();
} }
if (BrowserSettings::supportKphFields()) { if (browserSettings()->supportKphFields()) {
const EntryAttributes* attr = entry->attributes(); const EntryAttributes* attr = entry->attributes();
QJsonArray stringFields; QJsonArray stringFields;
for (const QString& key : attr->keys()) { for (const QString& key : attr->keys()) {

View File

@ -107,6 +107,7 @@ private:
DatabaseTabWidget* const m_dbTabWidget; DatabaseTabWidget* const m_dbTabWidget;
bool m_dialogActive; bool m_dialogActive;
bool m_bringToFrontRequested; bool m_bringToFrontRequested;
QUuid m_keepassBrowserUUID;
}; };
#endif // BROWSERSERVICE_H #endif // BROWSERSERVICE_H

View File

@ -20,9 +20,16 @@
#include "BrowserSettings.h" #include "BrowserSettings.h"
#include "core/Config.h" #include "core/Config.h"
PasswordGenerator BrowserSettings::m_passwordGenerator; BrowserSettings* BrowserSettings::m_instance(nullptr);
PassphraseGenerator BrowserSettings::m_passPhraseGenerator;
HostInstaller BrowserSettings::m_hostInstaller; BrowserSettings* BrowserSettings::instance()
{
if (!m_instance) {
m_instance = new BrowserSettings();
}
return m_instance;
}
bool BrowserSettings::isEnabled() bool BrowserSettings::isEnabled()
{ {
@ -185,7 +192,7 @@ bool BrowserSettings::chromeSupport()
void BrowserSettings::setChromeSupport(bool enabled) void BrowserSettings::setChromeSupport(bool enabled)
{ {
m_hostInstaller.installBrowser( m_hostInstaller.installBrowser(
HostInstaller::SupportedBrowsers::CHROME, enabled, supportBrowserProxy(), customProxyLocation()); HostInstaller::SupportedBrowsers::CHROME, enabled, supportBrowserProxy(), customProxyLocation());
} }
bool BrowserSettings::chromiumSupport() bool BrowserSettings::chromiumSupport()
@ -196,7 +203,7 @@ bool BrowserSettings::chromiumSupport()
void BrowserSettings::setChromiumSupport(bool enabled) void BrowserSettings::setChromiumSupport(bool enabled)
{ {
m_hostInstaller.installBrowser( m_hostInstaller.installBrowser(
HostInstaller::SupportedBrowsers::CHROMIUM, enabled, supportBrowserProxy(), customProxyLocation()); HostInstaller::SupportedBrowsers::CHROMIUM, enabled, supportBrowserProxy(), customProxyLocation());
} }
bool BrowserSettings::firefoxSupport() bool BrowserSettings::firefoxSupport()
@ -207,7 +214,7 @@ bool BrowserSettings::firefoxSupport()
void BrowserSettings::setFirefoxSupport(bool enabled) void BrowserSettings::setFirefoxSupport(bool enabled)
{ {
m_hostInstaller.installBrowser( m_hostInstaller.installBrowser(
HostInstaller::SupportedBrowsers::FIREFOX, enabled, supportBrowserProxy(), customProxyLocation()); HostInstaller::SupportedBrowsers::FIREFOX, enabled, supportBrowserProxy(), customProxyLocation());
} }
bool BrowserSettings::vivaldiSupport() bool BrowserSettings::vivaldiSupport()
@ -218,7 +225,7 @@ bool BrowserSettings::vivaldiSupport()
void BrowserSettings::setVivaldiSupport(bool enabled) void BrowserSettings::setVivaldiSupport(bool enabled)
{ {
m_hostInstaller.installBrowser( m_hostInstaller.installBrowser(
HostInstaller::SupportedBrowsers::VIVALDI, enabled, supportBrowserProxy(), customProxyLocation()); HostInstaller::SupportedBrowsers::VIVALDI, enabled, supportBrowserProxy(), customProxyLocation());
} }
bool BrowserSettings::passwordUseNumbers() bool BrowserSettings::passwordUseNumbers()

View File

@ -27,95 +27,105 @@
class BrowserSettings class BrowserSettings
{ {
public: public:
static bool isEnabled(); explicit BrowserSettings() = default;
static void setEnabled(bool enabled); static BrowserSettings* instance();
static bool showNotification(); // TODO!! bool isEnabled();
static void setShowNotification(bool showNotification); void setEnabled(bool enabled);
static bool bestMatchOnly();
static void setBestMatchOnly(bool bestMatchOnly);
static bool unlockDatabase();
static void setUnlockDatabase(bool unlockDatabase);
static bool matchUrlScheme();
static void setMatchUrlScheme(bool matchUrlScheme);
static bool sortByUsername();
static void setSortByUsername(bool sortByUsername = true);
static bool sortByTitle();
static void setSortByTitle(bool sortByUsertitle = true);
static bool alwaysAllowAccess();
static void setAlwaysAllowAccess(bool alwaysAllowAccess);
static bool alwaysAllowUpdate();
static void setAlwaysAllowUpdate(bool alwaysAllowUpdate);
static bool searchInAllDatabases();
static void setSearchInAllDatabases(bool searchInAllDatabases);
static bool supportKphFields();
static void setSupportKphFields(bool supportKphFields);
static bool supportBrowserProxy(); bool showNotification(); // TODO!!
static void setSupportBrowserProxy(bool enabled); void setShowNotification(bool showNotification);
static bool useCustomProxy(); bool bestMatchOnly();
static void setUseCustomProxy(bool enabled); void setBestMatchOnly(bool bestMatchOnly);
static QString customProxyLocation(); bool unlockDatabase();
static void setCustomProxyLocation(QString location); void setUnlockDatabase(bool unlockDatabase);
static bool updateBinaryPath(); bool matchUrlScheme();
static void setUpdateBinaryPath(bool enabled); void setMatchUrlScheme(bool matchUrlScheme);
static bool chromeSupport(); bool sortByUsername();
static void setChromeSupport(bool enabled); void setSortByUsername(bool sortByUsername = true);
static bool chromiumSupport(); bool sortByTitle();
static void setChromiumSupport(bool enabled); void setSortByTitle(bool sortByUsertitle = true);
static bool firefoxSupport(); bool alwaysAllowAccess();
static void setFirefoxSupport(bool enabled); void setAlwaysAllowAccess(bool alwaysAllowAccess);
static bool vivaldiSupport(); bool alwaysAllowUpdate();
static void setVivaldiSupport(bool enabled); void setAlwaysAllowUpdate(bool alwaysAllowUpdate);
bool searchInAllDatabases();
void setSearchInAllDatabases(bool searchInAllDatabases);
bool supportKphFields();
void setSupportKphFields(bool supportKphFields);
static bool passwordUseNumbers(); bool supportBrowserProxy();
static void setPasswordUseNumbers(bool useNumbers); void setSupportBrowserProxy(bool enabled);
static bool passwordUseLowercase(); bool useCustomProxy();
static void setPasswordUseLowercase(bool useLowercase); void setUseCustomProxy(bool enabled);
static bool passwordUseUppercase(); QString customProxyLocation();
static void setPasswordUseUppercase(bool useUppercase); void setCustomProxyLocation(QString location);
static bool passwordUseSpecial(); bool updateBinaryPath();
static void setPasswordUseSpecial(bool useSpecial); void setUpdateBinaryPath(bool enabled);
static bool passwordUseBraces(); bool chromeSupport();
static void setPasswordUseBraces(bool useBraces); void setChromeSupport(bool enabled);
static bool passwordUsePunctuation(); bool chromiumSupport();
static void setPasswordUsePunctuation(bool usePunctuation); void setChromiumSupport(bool enabled);
static bool passwordUseQuotes(); bool firefoxSupport();
static void setPasswordUseQuotes(bool useQuotes); void setFirefoxSupport(bool enabled);
static bool passwordUseDashes(); bool vivaldiSupport();
static void setPasswordUseDashes(bool useDashes); void setVivaldiSupport(bool enabled);
static bool passwordUseMath();
static void setPasswordUseMath(bool useMath); bool passwordUseNumbers();
static bool passwordUseLogograms(); void setPasswordUseNumbers(bool useNumbers);
static void setPasswordUseLogograms(bool useLogograms); bool passwordUseLowercase();
static bool passwordUseEASCII(); void setPasswordUseLowercase(bool useLowercase);
static void setPasswordUseEASCII(bool useEASCII); bool passwordUseUppercase();
static bool advancedMode(); void setPasswordUseUppercase(bool useUppercase);
static void setAdvancedMode(bool advancedMode); bool passwordUseSpecial();
static QString passwordExcludedChars(); void setPasswordUseSpecial(bool useSpecial);
static void setPasswordExcludedChars(QString chars); bool passwordUseBraces();
static int passPhraseWordCount(); void setPasswordUseBraces(bool useBraces);
static void setPassPhraseWordCount(int wordCount); bool passwordUsePunctuation();
static QString passPhraseWordSeparator(); void setPasswordUsePunctuation(bool usePunctuation);
static void setPassPhraseWordSeparator(QString separator); bool passwordUseQuotes();
static int generatorType(); void setPasswordUseQuotes(bool useQuotes);
static void setGeneratorType(int type); bool passwordUseDashes();
static bool passwordEveryGroup(); void setPasswordUseDashes(bool useDashes);
static void setPasswordEveryGroup(bool everyGroup); bool passwordUseMath();
static bool passwordExcludeAlike(); void setPasswordUseMath(bool useMath);
static void setPasswordExcludeAlike(bool excludeAlike); bool passwordUseLogograms();
static int passwordLength(); void setPasswordUseLogograms(bool useLogograms);
static void setPasswordLength(int length); bool passwordUseEASCII();
static PasswordGenerator::CharClasses passwordCharClasses(); void setPasswordUseEASCII(bool useEASCII);
static PasswordGenerator::GeneratorFlags passwordGeneratorFlags(); bool advancedMode();
static QString generatePassword(); void setAdvancedMode(bool advancedMode);
static int getbits(); QString passwordExcludedChars();
static void updateBinaryPaths(QString customProxyLocation = QString()); void setPasswordExcludedChars(QString chars);
int passPhraseWordCount();
void setPassPhraseWordCount(int wordCount);
QString passPhraseWordSeparator();
void setPassPhraseWordSeparator(QString separator);
int generatorType();
void setGeneratorType(int type);
bool passwordEveryGroup();
void setPasswordEveryGroup(bool everyGroup);
bool passwordExcludeAlike();
void setPasswordExcludeAlike(bool excludeAlike);
int passwordLength();
void setPasswordLength(int length);
PasswordGenerator::CharClasses passwordCharClasses();
PasswordGenerator::GeneratorFlags passwordGeneratorFlags();
QString generatePassword();
int getbits();
void updateBinaryPaths(QString customProxyLocation = QString());
private: private:
static PasswordGenerator m_passwordGenerator; static BrowserSettings* m_instance;
static PassphraseGenerator m_passPhraseGenerator;
static HostInstaller m_hostInstaller; PasswordGenerator m_passwordGenerator;
PassphraseGenerator m_passPhraseGenerator;
HostInstaller m_hostInstaller;
}; };
inline BrowserSettings* browserSettings()
{
return BrowserSettings::instance();
}
#endif // BROWSERSETTINGS_H #endif // BROWSERSETTINGS_H

View File

@ -18,6 +18,7 @@
#include "HostInstaller.h" #include "HostInstaller.h"
#include "config-keepassx.h" #include "config-keepassx.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
@ -27,35 +28,27 @@
#include <QProcessEnvironment> #include <QProcessEnvironment>
#include <QStandardPaths> #include <QStandardPaths>
const QString HostInstaller::HOST_NAME = "org.keepassxc.keepassxc_browser";
const QStringList HostInstaller::ALLOWED_ORIGINS = QStringList()
<< "chrome-extension://iopaggbpplllidnfmcghoonnokmjoicf/"
<< "chrome-extension://oboonakemofpalcgghocfoadofidjkkk/";
const QStringList HostInstaller::ALLOWED_EXTENSIONS = QStringList() << "keepassxc-browser@keepassxc.org";
#if defined(Q_OS_OSX)
const QString HostInstaller::TARGET_DIR_CHROME = "/Library/Application Support/Google/Chrome/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_CHROMIUM = "/Library/Application Support/Chromium/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_FIREFOX = "/Library/Application Support/Mozilla/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_VIVALDI = "/Library/Application Support/Vivaldi/NativeMessagingHosts";
#elif defined(Q_OS_LINUX)
const QString HostInstaller::TARGET_DIR_CHROME = "/.config/google-chrome/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_CHROMIUM = "/.config/chromium/NativeMessagingHosts";
const QString HostInstaller::TARGET_DIR_FIREFOX = "/.mozilla/native-messaging-hosts";
const QString HostInstaller::TARGET_DIR_VIVALDI = "/.config/vivaldi/NativeMessagingHosts";
#elif defined(Q_OS_WIN)
const QString HostInstaller::TARGET_DIR_CHROME =
"HKEY_CURRENT_USER\\Software\\Google\\Chrome\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME;
const QString HostInstaller::TARGET_DIR_CHROMIUM =
"HKEY_CURRENT_USER\\Software\\Chromium\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME;
const QString HostInstaller::TARGET_DIR_FIREFOX =
"HKEY_CURRENT_USER\\Software\\Mozilla\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME;
const QString HostInstaller::TARGET_DIR_VIVALDI =
"HKEY_CURRENT_USER\\Software\\Vivaldi\\NativeMessagingHosts\\" + HostInstaller::HOST_NAME;
#endif
HostInstaller::HostInstaller() HostInstaller::HostInstaller()
: HOST_NAME("org.keepassxc.keepassxc_browser")
, ALLOWED_EXTENSIONS(QStringList() << "keepassxc-browser@keepassxc.org")
, ALLOWED_ORIGINS(QStringList() << "chrome-extension://iopaggbpplllidnfmcghoonnokmjoicf/"
<< "chrome-extension://oboonakemofpalcgghocfoadofidjkkk/")
#if defined(Q_OS_OSX)
, TARGET_DIR_CHROME("/Library/Application Support/Google/Chrome/NativeMessagingHosts")
, TARGET_DIR_CHROMIUM("/Library/Application Support/Chromium/NativeMessagingHosts")
, TARGET_DIR_FIREFOX("/Library/Application Support/Mozilla/NativeMessagingHosts")
, TARGET_DIR_VIVALDI("/Library/Application Support/Vivaldi/NativeMessagingHosts")
#elif defined(Q_OS_LINUX)
, TARGET_DIR_CHROME("/.config/google-chrome/NativeMessagingHosts")
, TARGET_DIR_CHROMIUM("/.config/chromium/NativeMessagingHosts")
, TARGET_DIR_FIREFOX("/.mozilla/native-messaging-hosts")
, TARGET_DIR_VIVALDI("/.config/vivaldi/NativeMessagingHosts")
#elif defined(Q_OS_WIN)
, TARGET_DIR_CHROME("HKEY_CURRENT_USER\\Software\\Google\\Chrome\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
, TARGET_DIR_CHROMIUM("HKEY_CURRENT_USER\\Software\\Chromium\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
, TARGET_DIR_FIREFOX("HKEY_CURRENT_USER\\Software\\Mozilla\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
, TARGET_DIR_VIVALDI("HKEY_CURRENT_USER\\Software\\Vivaldi\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser")
#endif
{ {
} }
@ -118,13 +111,13 @@ QString HostInstaller::getTargetPath(SupportedBrowsers browser) const
{ {
switch (browser) { switch (browser) {
case SupportedBrowsers::CHROME: case SupportedBrowsers::CHROME:
return HostInstaller::TARGET_DIR_CHROME; return TARGET_DIR_CHROME;
case SupportedBrowsers::CHROMIUM: case SupportedBrowsers::CHROMIUM:
return HostInstaller::TARGET_DIR_CHROMIUM; return TARGET_DIR_CHROMIUM;
case SupportedBrowsers::FIREFOX: case SupportedBrowsers::FIREFOX:
return HostInstaller::TARGET_DIR_FIREFOX; return TARGET_DIR_FIREFOX;
case SupportedBrowsers::VIVALDI: case SupportedBrowsers::VIVALDI:
return HostInstaller::TARGET_DIR_VIVALDI; return TARGET_DIR_VIVALDI;
default: default:
return QString(); return QString();
} }
@ -158,12 +151,12 @@ QString HostInstaller::getPath(SupportedBrowsers browser) const
userPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); userPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
} }
QString winPath = QString("%1/%2_%3.json").arg(userPath, HostInstaller::HOST_NAME, getBrowserName(browser)); QString winPath = QString("%1/%2_%3.json").arg(userPath, HOST_NAME, getBrowserName(browser));
winPath.replace("/", "\\"); winPath.replace("/", "\\");
return winPath; return winPath;
#else #else
QString path = getTargetPath(browser); QString path = getTargetPath(browser);
return QString("%1%2/%3.json").arg(QDir::homePath(), path, HostInstaller::HOST_NAME); return QString("%1%2/%3.json").arg(QDir::homePath(), path, HOST_NAME);
#endif #endif
} }
@ -207,19 +200,19 @@ QJsonObject HostInstaller::constructFile(SupportedBrowsers browser, const bool&
#endif // #ifdef KEEPASSXC_DIST_APPIMAGE #endif // #ifdef KEEPASSXC_DIST_APPIMAGE
QJsonObject script; QJsonObject script;
script["name"] = HostInstaller::HOST_NAME; script["name"] = HOST_NAME;
script["description"] = "KeePassXC integration with native messaging support"; script["description"] = "KeePassXC integration with native messaging support";
script["path"] = path; script["path"] = path;
script["type"] = "stdio"; script["type"] = "stdio";
QJsonArray arr; QJsonArray arr;
if (browser == SupportedBrowsers::FIREFOX) { if (browser == SupportedBrowsers::FIREFOX) {
for (const QString extension : HostInstaller::ALLOWED_EXTENSIONS) { for (const QString& extension : ALLOWED_EXTENSIONS) {
arr.append(extension); arr.append(extension);
} }
script["allowed_extensions"] = arr; script["allowed_extensions"] = arr;
} else { } else {
for (const QString origin : HostInstaller::ALLOWED_ORIGINS) { for (const QString& origin : ALLOWED_ORIGINS) {
arr.append(origin); arr.append(origin);
} }
script["allowed_origins"] = arr; script["allowed_origins"] = arr;
@ -248,10 +241,5 @@ bool HostInstaller::saveFile(SupportedBrowsers browser, const QJsonObject& scrip
} }
QJsonDocument doc(script); QJsonDocument doc(script);
qint64 bytesWritten = scriptFile.write(doc.toJson()); return scriptFile.write(doc.toJson()) >= 0;
if (bytesWritten < 0) {
return false;
}
return true;
} }

View File

@ -55,13 +55,13 @@ private:
bool saveFile(SupportedBrowsers browser, const QJsonObject& script); bool saveFile(SupportedBrowsers browser, const QJsonObject& script);
private: private:
static const QString HOST_NAME; const QString HOST_NAME;
static const QStringList ALLOWED_EXTENSIONS; const QStringList ALLOWED_EXTENSIONS;
static const QStringList ALLOWED_ORIGINS; const QStringList ALLOWED_ORIGINS;
static const QString TARGET_DIR_CHROME; const QString TARGET_DIR_CHROME;
static const QString TARGET_DIR_CHROMIUM; const QString TARGET_DIR_CHROMIUM;
static const QString TARGET_DIR_FIREFOX; const QString TARGET_DIR_FIREFOX;
static const QString TARGET_DIR_VIVALDI; const QString TARGET_DIR_VIVALDI;
}; };
#endif // HOSTINSTALLER_H #endif // HOSTINSTALLER_H

View File

@ -30,14 +30,14 @@
NativeMessagingHost::NativeMessagingHost(DatabaseTabWidget* parent, const bool enabled) NativeMessagingHost::NativeMessagingHost(DatabaseTabWidget* parent, const bool enabled)
: NativeMessagingBase(enabled) : NativeMessagingBase(enabled)
, m_mutex(QMutex::Recursive) , m_mutex(QMutex::Recursive)
, m_browserClients(m_browserService)
, m_browserService(parent) , m_browserService(parent)
, m_browserClients(m_browserService)
{ {
m_localServer.reset(new QLocalServer(this)); m_localServer.reset(new QLocalServer(this));
m_localServer->setSocketOptions(QLocalServer::UserAccessOption); m_localServer->setSocketOptions(QLocalServer::UserAccessOption);
m_running.store(false); m_running.store(false);
if (BrowserSettings::isEnabled() && !m_running) { if (browserSettings()->isEnabled() && !m_running) {
run(); run();
} }
@ -64,8 +64,8 @@ void NativeMessagingHost::run()
} }
// Update KeePassXC/keepassxc-proxy binary paths to Native Messaging scripts // Update KeePassXC/keepassxc-proxy binary paths to Native Messaging scripts
if (BrowserSettings::updateBinaryPath()) { if (browserSettings()->updateBinaryPath()) {
BrowserSettings::updateBinaryPaths(BrowserSettings::useCustomProxy() ? BrowserSettings::customProxyLocation() browserSettings()->updateBinaryPaths(browserSettings()->useCustomProxy() ? browserSettings()->customProxyLocation()
: ""); : "");
} }
@ -75,7 +75,7 @@ void NativeMessagingHost::run()
QtConcurrent::run(this, static_cast<void (NativeMessagingHost::*)()>(&NativeMessagingHost::readNativeMessages)); QtConcurrent::run(this, static_cast<void (NativeMessagingHost::*)()>(&NativeMessagingHost::readNativeMessages));
#endif #endif
if (BrowserSettings::supportBrowserProxy()) { if (browserSettings()->supportBrowserProxy()) {
QString serverPath = getLocalServerPath(); QString serverPath = getLocalServerPath();
QFile::remove(serverPath); QFile::remove(serverPath);

View File

@ -58,8 +58,8 @@ private slots:
private: private:
QMutex m_mutex; QMutex m_mutex;
BrowserClients m_browserClients;
BrowserService m_browserService; BrowserService m_browserService;
BrowserClients m_browserClients;
QSharedPointer<QLocalServer> m_localServer; QSharedPointer<QLocalServer> m_localServer;
SocketList m_socketList; SocketList m_socketList;
}; };

View File

@ -66,7 +66,7 @@ class BrowserPlugin : public ISettingsPage
public: public:
BrowserPlugin(DatabaseTabWidget* tabWidget) BrowserPlugin(DatabaseTabWidget* tabWidget)
{ {
m_nativeMessagingHost = QSharedPointer<NativeMessagingHost>(new NativeMessagingHost(tabWidget, BrowserSettings::isEnabled())); m_nativeMessagingHost = QSharedPointer<NativeMessagingHost>(new NativeMessagingHost(tabWidget, browserSettings()->isEnabled()));
} }
~BrowserPlugin() ~BrowserPlugin()
@ -103,7 +103,7 @@ public:
void saveSettings(QWidget* widget) override void saveSettings(QWidget* widget) override
{ {
qobject_cast<BrowserOptionDialog*>(widget)->saveSettings(); qobject_cast<BrowserOptionDialog*>(widget)->saveSettings();
if (BrowserSettings::isEnabled()) { if (browserSettings()->isEnabled()) {
m_nativeMessagingHost->run(); m_nativeMessagingHost->run();
} else { } else {
m_nativeMessagingHost->stop(); m_nativeMessagingHost->stop();