Skip to content

Commit

Permalink
Merge branch 'develop' into feature/healthcheck
Browse files Browse the repository at this point in the history
  • Loading branch information
wolframroesler authored Dec 29, 2019
2 parents 5ecaa44 + 2fab4d5 commit 3233f27
Show file tree
Hide file tree
Showing 56 changed files with 1,543 additions and 613 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ endif (CCACHE_FOUND)

# Support Visual Studio Code
include(CMakeToolsHelpers OPTIONAL)
include(FeatureSummary)

include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
Expand Down Expand Up @@ -465,8 +466,6 @@ endif()

include_directories(SYSTEM ${GCRYPT_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})

include(FeatureSummary)

add_subdirectory(src)
add_subdirectory(share)
if(WITH_TESTS)
Expand Down
5 changes: 5 additions & 0 deletions COPYING
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,8 @@ Comment: from Freedesktop.org website

Files: share/icons/application/32x32/actions/statistics.png
Copyright: Icon made by Freepik from https://www.flaticon.com/free-icon/bars-chart_265733

Files: share/icons/application/scalable/actions/object-locked.svg
share/icons/application/scalable/actions/object-unlocked.svg
License: LGPL-3
Comment: from Breeze icon theme (https://github.com/KDE/breeze-icons)
2 changes: 1 addition & 1 deletion share/docs/man/keepassxc-cli.1
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Displays the program version.
.IP "-d, --dry-run <path>"
Prints the changes detected by the merge operation without making any changes to the database.

.IP "-f, --key-file-from <path>"
.IP "--key-file-from <path>"
Sets the path of the key file for the second database.

.IP "--no-password-from"
Expand Down
14 changes: 14 additions & 0 deletions share/icons/application/scalable/actions/object-locked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions share/icons/application/scalable/actions/object-unlocked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ set(keepassx_SOURCES
gui/TotpDialog.cpp
gui/TotpExportSettingsDialog.cpp
gui/DatabaseOpenDialog.cpp
gui/URLEdit.cpp
gui/WelcomeWidget.cpp
gui/csvImport/CsvImportWidget.cpp
gui/csvImport/CsvImportWizard.cpp
Expand Down
6 changes: 3 additions & 3 deletions src/browser/BrowserAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ QJsonObject BrowserAction::readResponse(const QJsonObject& json)

bool triggerUnlock = false;
const QString trigger = json.value("triggerUnlock").toString();
if (!trigger.isEmpty() && trigger.compare("true", Qt::CaseSensitive) == 0) {
if (!trigger.isEmpty() && trigger.compare(TRUE_STR, Qt::CaseSensitive) == 0) {
triggerUnlock = true;
}

Expand Down Expand Up @@ -268,7 +268,7 @@ QJsonObject BrowserAction::handleGetLogins(const QJsonObject& json, const QStrin
const QString id = decrypted.value("id").toString();
const QString submit = decrypted.value("submitUrl").toString();
const QString auth = decrypted.value("httpAuth").toString();
const bool httpAuth = auth.compare("true", Qt::CaseSensitive) == 0 ? true : false;
const bool httpAuth = auth.compare(TRUE_STR, Qt::CaseSensitive) == 0 ? true : false;
const QJsonArray users = m_browserService.findMatchingEntries(id, url, submit, "", keyList, httpAuth);

if (users.isEmpty()) {
Expand Down Expand Up @@ -469,7 +469,7 @@ QJsonObject BrowserAction::buildMessage(const QString& nonce) const
{
QJsonObject message;
message["version"] = KEEPASSXC_VERSION;
message["success"] = "true";
message["success"] = TRUE_STR;
message["nonce"] = nonce;
return message;
}
Expand Down
4 changes: 4 additions & 0 deletions src/browser/BrowserOptionDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ BrowserOptionDialog::BrowserOptionDialog(QWidget* parent)
connect(m_ui->useCustomProxy, SIGNAL(toggled(bool)), m_ui->customProxyLocationBrowseButton, SLOT(setEnabled(bool)));
connect(m_ui->customProxyLocationBrowseButton, SIGNAL(clicked()), this, SLOT(showProxyLocationFileDialog()));

#ifndef Q_OS_LINUX
m_ui->snapWarningLabel->setVisible(false);
#endif

#ifdef Q_OS_WIN
// Brave uses Chrome's registry settings
m_ui->braveSupport->setHidden(true);
Expand Down
2 changes: 1 addition & 1 deletion src/browser/BrowserOptionDialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<widget class="QLabel" name="snapWarningLabel">
<property name="text">
<string>Browsers installed as snaps are currently not supported.</string>
</property>
Expand Down
52 changes: 29 additions & 23 deletions src/browser/BrowserService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static const QString KEEPASSHTTP_GROUP_NAME = QStringLiteral("KeePassHttp Passwo
// Extra entry related options saved in custom data
const QString BrowserService::OPTION_SKIP_AUTO_SUBMIT = QStringLiteral("BrowserSkipAutoSubmit");
const QString BrowserService::OPTION_HIDE_ENTRY = QStringLiteral("BrowserHideEntry");
const QString BrowserService::OPTION_ONLY_HTTP_AUTH = QStringLiteral("BrowserOnlyHttpAuth");
// Multiple URL's
const QString BrowserService::ADDITIONAL_URL = QStringLiteral("KP2A_URL");

Expand Down Expand Up @@ -380,9 +381,14 @@ QJsonArray BrowserService::findMatchingEntries(const QString& id,
// Check entries for authorization
QList<Entry*> pwEntriesToConfirm;
QList<Entry*> pwEntries;
for (auto* entry : searchEntries(url, keyList)) {
for (auto* entry : searchEntries(url, submitUrl, keyList)) {
if (entry->customData()->contains(BrowserService::OPTION_HIDE_ENTRY)
&& entry->customData()->value(BrowserService::OPTION_HIDE_ENTRY) == "true") {
&& entry->customData()->value(BrowserService::OPTION_HIDE_ENTRY) == TRUE_STR) {
continue;
}

if (!httpAuth && entry->customData()->contains(BrowserService::OPTION_ONLY_HTTP_AUTH)
&& entry->customData()->value(BrowserService::OPTION_ONLY_HTTP_AUTH) == TRUE_STR) {
continue;
}

Expand Down Expand Up @@ -583,7 +589,7 @@ BrowserService::ReturnValue BrowserService::updateEntry(const QString& id,
}

QList<Entry*>
BrowserService::searchEntries(const QSharedPointer<Database>& db, const QString& hostname, const QString& url)
BrowserService::searchEntries(const QSharedPointer<Database>& db, const QString& url, const QString& submitUrl)
{
QList<Entry*> entries;
auto* rootGroup = db->rootGroup();
Expand All @@ -601,19 +607,15 @@ BrowserService::searchEntries(const QSharedPointer<Database>& db, const QString&
continue;
}

auto domain = baseDomain(hostname);

// Search for additional URL's starting with KP2A_URL
if (entry->attributes()->keys().contains(ADDITIONAL_URL)) {
for (const auto& key : entry->attributes()->keys()) {
if (key.startsWith(ADDITIONAL_URL) && handleURL(entry->attributes()->value(key), domain, url)) {
entries.append(entry);
continue;
}
for (const auto& key : entry->attributes()->keys()) {
if (key.startsWith(ADDITIONAL_URL) && handleURL(entry->attributes()->value(key), url, submitUrl)) {
entries.append(entry);
continue;
}
}

if (!handleURL(entry->url(), domain, url)) {
if (!handleURL(entry->url(), url, submitUrl)) {
continue;
}

Expand All @@ -624,7 +626,7 @@ BrowserService::searchEntries(const QSharedPointer<Database>& db, const QString&
return entries;
}

QList<Entry*> BrowserService::searchEntries(const QString& url, const StringPairList& keyList)
QList<Entry*> BrowserService::searchEntries(const QString& url, const QString& submitUrl, const StringPairList& keyList)
{
// Check if database is connected with KeePassXC-Browser
auto databaseConnected = [&](const QSharedPointer<Database>& db) {
Expand Down Expand Up @@ -661,7 +663,7 @@ QList<Entry*> BrowserService::searchEntries(const QString& url, const StringPair
QList<Entry*> entries;
do {
for (const auto& db : databases) {
entries << searchEntries(db, hostname, url);
entries << searchEntries(db, url, submitUrl);
}
} while (entries.isEmpty() && removeFirstDomain(hostname));

Expand Down Expand Up @@ -854,7 +856,7 @@ QJsonObject BrowserService::prepareEntry(const Entry* entry)
}

if (entry->isExpired()) {
res["expired"] = "true";
res["expired"] = TRUE_STR;
}

if (entry->customData()->contains(BrowserService::OPTION_SKIP_AUTO_SUBMIT)) {
Expand Down Expand Up @@ -999,7 +1001,7 @@ bool BrowserService::removeFirstDomain(QString& hostname)
return false;
}

bool BrowserService::handleURL(const QString& entryUrl, const QString& hostname, const QString& url)
bool BrowserService::handleURL(const QString& entryUrl, const QString& url, const QString& submitUrl)
{
if (entryUrl.isEmpty()) {
return false;
Expand All @@ -1016,32 +1018,36 @@ bool BrowserService::handleURL(const QString& entryUrl, const QString& hostname,
}
}

// Make a direct compare if a local file is used
if (url.contains("file://")) {
return entryUrl == submitUrl;
}

// URL host validation fails
if (browserSettings()->matchUrlScheme() && entryQUrl.host().isEmpty()) {
if (entryQUrl.host().isEmpty()) {
return false;
}

// Match port, if used
QUrl qUrl(url);
if (entryQUrl.port() > 0 && entryQUrl.port() != qUrl.port()) {
QUrl siteQUrl(url);
if (entryQUrl.port() > 0 && entryQUrl.port() != siteQUrl.port()) {
return false;
}

// Match scheme
if (browserSettings()->matchUrlScheme() && !entryQUrl.scheme().isEmpty()
&& entryQUrl.scheme().compare(qUrl.scheme()) != 0) {
&& entryQUrl.scheme().compare(siteQUrl.scheme()) != 0) {
return false;
}

// Check for illegal characters
QRegularExpression re("[<>\\^`{|}]");
auto match = re.match(entryUrl);
if (match.hasMatch()) {
if (re.match(entryUrl).hasMatch()) {
return false;
}

// Filter to match hostname in URL field
if (entryQUrl.host().endsWith(hostname)) {
if (siteQUrl.host().endsWith(entryQUrl.host())) {
return true;
}

Expand Down
7 changes: 4 additions & 3 deletions src/browser/BrowserService.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ class BrowserService : public QObject
const QString& group,
const QString& groupUuid,
const QSharedPointer<Database>& selectedDb = {});
QList<Entry*> searchEntries(const QSharedPointer<Database>& db, const QString& hostname, const QString& url);
QList<Entry*> searchEntries(const QString& url, const StringPairList& keyList);
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 = {});

public:
Expand All @@ -74,6 +74,7 @@ class BrowserService : public QObject
static const QString LEGACY_ASSOCIATE_KEY_PREFIX;
static const QString OPTION_SKIP_AUTO_SUBMIT;
static const QString OPTION_HIDE_ENTRY;
static const QString OPTION_ONLY_HTTP_AUTH;
static const QString ADDITIONAL_URL;

public slots:
Expand Down Expand Up @@ -130,7 +131,7 @@ public slots:
sortPriority(const Entry* entry, const QString& host, const QString& submitUrl, const QString& baseSubmitUrl) const;
bool schemeFound(const QString& url);
bool removeFirstDomain(QString& hostname);
bool handleURL(const QString& entryUrl, const QString& hostname, const QString& url);
bool handleURL(const QString& entryUrl, const QString& url, const QString& submitUrl);
QString baseDomain(const QString& hostname) const;
QSharedPointer<Database> getDatabase();
QSharedPointer<Database> selectedDatabase();
Expand Down
3 changes: 1 addition & 2 deletions src/cli/Merge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ const QCommandLineOption Merge::SameCredentialsOption =
QObject::tr("Use the same credentials for both database files."));

const QCommandLineOption Merge::KeyFileFromOption =
QCommandLineOption(QStringList() << "k"
<< "key-file-from",
QCommandLineOption(QStringList() << "key-file-from",
QObject::tr("Key file of the database to merge from."),
QObject::tr("path"));

Expand Down
10 changes: 6 additions & 4 deletions src/cli/keepassxc-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ void enterInteractiveMode(const QStringList& arguments)
prompt += "> ";
command = reader->readLine(prompt);
if (reader->isFinished()) {
currentDatabase->releaseData();
return;
break;
}

QStringList args = Utils::splitCommandString(command);
Expand All @@ -163,14 +162,17 @@ void enterInteractiveMode(const QStringList& arguments)
errorTextStream << QObject::tr("Unknown command %1").arg(args[0]) << "\n";
continue;
} else if (cmd->name == "quit" || cmd->name == "exit") {
currentDatabase->releaseData();
return;
break;
}

cmd->currentDatabase = currentDatabase;
cmd->execute(args);
currentDatabase = cmd->currentDatabase;
}

if (currentDatabase) {
currentDatabase->releaseData();
}
}

int main(int argc, char** argv)
Expand Down
4 changes: 4 additions & 0 deletions src/core/Bootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ namespace Bootstrap
{
// start minimized if configured
if (config()->get("GUI/MinimizeOnStartup").toBool()) {
#ifdef Q_OS_WIN
mainWindow.showMinimized();
#else
mainWindow.hideWindow();
#endif
} else {
mainWindow.bringToFront();
}
Expand Down
Loading

0 comments on commit 3233f27

Please sign in to comment.