From 7cd824ae1cdbcb71b665557afa48b7e785e78b75 Mon Sep 17 00:00:00 2001 From: louib Date: Mon, 4 Apr 2022 19:04:18 -0400 Subject: [PATCH] Upstream Flathub patches (#7728) --- CMakeLists.txt | 5 +- share/CMakeLists.txt | 46 ++++++++++++++---- .../linux/{keepassxc.xml => keepassxc.xml.in} | 2 +- .../linux/org.keepassxc.KeePassXC.appdata.xml | 2 +- ...top => org.keepassxc.KeePassXC.desktop.in} | 2 +- src/browser/BrowserSettingsWidget.cpp | 12 +++++ src/browser/BrowserShared.cpp | 3 ++ src/browser/NativeMessageInstaller.cpp | 45 +++++++++++++++-- src/config-keepassx.h.cmake | 1 + src/core/EntryAttachments.cpp | 7 ++- src/gui/Icons.cpp | 15 ++++-- src/gui/Icons.h | 1 + utils/keepassxc-flatpak-wrapper.sh | 48 +++++++++++++++++++ 13 files changed, 169 insertions(+), 20 deletions(-) rename share/linux/{keepassxc.xml => keepassxc.xml.in} (85%) rename share/linux/{org.keepassxc.KeePassXC.desktop => org.keepassxc.KeePassXC.desktop.in} (98%) create mode 100755 utils/keepassxc-flatpak-wrapper.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index db97debc3..382bcb7ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ cmake_minimum_required(VERSION 3.3.0) project(KeePassXC) +set(APP_ID "org.keepassxc.${PROJECT_NAME}") if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING @@ -158,11 +159,13 @@ message(STATUS "Setting up build for KeePassXC v${KEEPASSXC_VERSION}\n") # Distribution info set(KEEPASSXC_DIST ON) set(KEEPASSXC_DIST_TYPE "Other" CACHE STRING "KeePassXC Distribution Type") -set_property(CACHE KEEPASSXC_DIST_TYPE PROPERTY STRINGS Snap AppImage Other) +set_property(CACHE KEEPASSXC_DIST_TYPE PROPERTY STRINGS Snap AppImage Flatpak Other) if(KEEPASSXC_DIST_TYPE STREQUAL "Snap") set(KEEPASSXC_DIST_SNAP ON) elseif(KEEPASSXC_DIST_TYPE STREQUAL "AppImage") set(KEEPASSXC_DIST_APPIMAGE ON) +elseif(KEEPASSXC_DIST_TYPE STREQUAL "Flatpak") + set(KEEPASSXC_DIST_FLATPAK ON) elseif(KEEPASSXC_DIST_TYPE STREQUAL "Other") unset(KEEPASSXC_DIST) endif() diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 6d689df9e..34017e95c 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -23,15 +23,43 @@ install(FILES ${wordlists_files} DESTINATION ${DATA_INSTALL_DIR}/wordlists) file(COPY "wordlists" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) if(UNIX AND NOT APPLE AND NOT HAIKU) - install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor - FILES_MATCHING PATTERN "keepassx*.png" PATTERN "keepassx*.svg" - PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE) - install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor - FILES_MATCHING PATTERN "application-x-keepassxc.png" PATTERN "application-x-keepassxc.svg" - PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE) - install(FILES linux/org.keepassxc.KeePassXC.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) - install(FILES linux/org.keepassxc.KeePassXC.appdata.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo) - install(FILES linux/keepassxc.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages) + # Flatpak requires all host accessible files to use filenames based upon the app id + if(KEEPASSXC_DIST_FLATPAK) + set(APP_ICON_NAME "${APP_ID}") + set(MIME_ICON "${APP_ID}-application-x-keepassxc") + configure_file(linux/keepassxc.xml.in ${CMAKE_CURRENT_BINARY_DIR}/linux/${APP_ID}.xml @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/linux/${APP_ID}.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages) + + file(GLOB_RECURSE ICON_FILES LIST_DIRECTORIES false + "icons/application/*/keepassxc*.png" + "icons/application/*/*keepassxc*.svg") + foreach(icon_match ${ICON_FILES}) + get_filename_component(icon_name ${icon_match} NAME) + get_filename_component(icon_dir ${icon_match} DIRECTORY) + # Prefix all icons with application id: "org.keepassxc.KeePassXC" + string(REGEX REPLACE "^keepassxc(.*)?(\\.png|\\.svg)$" "${APP_ID}\\1\\2" icon_name ${icon_name}) + string(REGEX REPLACE "^(application-x-keepassxc\\.svg)$" "${APP_ID}-\\1" icon_name ${icon_name}) + # Find icon sub dir ex. "scalable/mimetypes/" + file(RELATIVE_PATH icon_subdir ${CMAKE_CURRENT_SOURCE_DIR}/icons/application ${icon_dir}) + install(FILES ${icon_match} DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/${icon_subdir} + RENAME ${icon_name}) + endforeach() + else() + set(APP_ICON_NAME "keepassxc") + set(MIME_ICON "application-x-keepassxc") + configure_file(linux/keepassxc.xml.in ${CMAKE_CURRENT_BINARY_DIR}/linux/keepassxc.xml @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/linux/keepassxc.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages) + + install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor + FILES_MATCHING PATTERN "keepassx*.png" PATTERN "keepassx*.svg" + PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE) + install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor + FILES_MATCHING PATTERN "application-x-keepassxc.svg" PATTERN "status" + EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE) + endif(KEEPASSXC_DIST_FLATPAK) + configure_file(linux/${APP_ID}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/linux/${APP_ID}.desktop @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/linux/${APP_ID}.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) + install(FILES linux/${APP_ID}.appdata.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo) endif(UNIX AND NOT APPLE AND NOT HAIKU) if(APPLE) diff --git a/share/linux/keepassxc.xml b/share/linux/keepassxc.xml.in similarity index 85% rename from share/linux/keepassxc.xml rename to share/linux/keepassxc.xml.in index b26b4db25..15ec11189 100644 --- a/share/linux/keepassxc.xml +++ b/share/linux/keepassxc.xml.in @@ -3,6 +3,6 @@ KeePass 2 Database - + diff --git a/share/linux/org.keepassxc.KeePassXC.appdata.xml b/share/linux/org.keepassxc.KeePassXC.appdata.xml index a3673da7e..1b74b2be3 100644 --- a/share/linux/org.keepassxc.KeePassXC.appdata.xml +++ b/share/linux/org.keepassxc.KeePassXC.appdata.xml @@ -94,7 +94,7 @@
  • FdoSecrets: Major Refactor and Code Consolidation [#5747][#5660][#7043][#6915]
  • FdoSecrets: Implement unlock before search [#6943]
  • Reports: Add browser statistics report [#7197]
  • -
  • Port crypto backend to [Botan](https://github.com/randombit/botan) [#6209]
  • +
  • Port crypto backend to Botan [#6209]
  • Improve attachment handling and security [#6606][#5034][#7083]
  • Allow selecting any open database in unlock dialog [#5427]
  • KeeShare: Remove checking signed container and QuaZip dependency [#7223]
  • diff --git a/share/linux/org.keepassxc.KeePassXC.desktop b/share/linux/org.keepassxc.KeePassXC.desktop.in similarity index 98% rename from share/linux/org.keepassxc.KeePassXC.desktop rename to share/linux/org.keepassxc.KeePassXC.desktop.in index e8d4dccf4..eef24fe7f 100644 --- a/share/linux/org.keepassxc.KeePassXC.desktop +++ b/share/linux/org.keepassxc.KeePassXC.desktop.in @@ -37,7 +37,7 @@ Comment[et]=Kogukonna arendatav port Windowsi programmist KeePass Password Safe Comment[ru]=Разработанный сообществом порт Windows-приложения KeePass Password Safe Exec=keepassxc %f TryExec=keepassxc -Icon=keepassxc +Icon=@APP_ICON_NAME@ StartupWMClass=keepassxc StartupNotify=true Terminal=false diff --git a/src/browser/BrowserSettingsWidget.cpp b/src/browser/BrowserSettingsWidget.cpp index d0f816151..8dd26d324 100644 --- a/src/browser/BrowserSettingsWidget.cpp +++ b/src/browser/BrowserSettingsWidget.cpp @@ -158,6 +158,18 @@ void BrowserSettingsWidget::loadSettings() m_ui->browserGlobalWarningWidget->setCloseButtonVisible(false); m_ui->browserGlobalWarningWidget->setAutoHideTimeout(-1); #endif +#ifdef KEEPASSXC_DIST_FLATPAK + // Guarantees proxy path works with different flatpak installations + m_ui->updateBinaryPath->setChecked(true); + m_ui->updateBinaryPath->setEnabled(false); + // The sandbox makes custom proxy locations very unintuitive + m_ui->useCustomProxy->setChecked(false); + m_ui->useCustomProxy->setEnabled(false); + m_ui->useCustomProxy->setVisible(false); + m_ui->customProxyLocation->setVisible(false); + // Won't work with xdg portals and executables that must be browser accessible + m_ui->customProxyLocationBrowseButton->setVisible(false); +#endif const auto customBrowserSet = settings->customBrowserSupport(); m_ui->customBrowserSupport->setChecked(customBrowserSet); diff --git a/src/browser/BrowserShared.cpp b/src/browser/BrowserShared.cpp index 22a507810..96d92e807 100644 --- a/src/browser/BrowserShared.cpp +++ b/src/browser/BrowserShared.cpp @@ -31,6 +31,9 @@ namespace BrowserShared const auto serverName = QStringLiteral("/org.keepassxc.KeePassXC.BrowserServer"); #if defined(KEEPASSXC_DIST_SNAP) return QProcessEnvironment::systemEnvironment().value("SNAP_USER_COMMON") + serverName; +#elif defined(KEEPASSXC_DIST_FLATPAK) + return QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) + "/app/" + "org.keepassxc.KeePassXC" + + serverName; #elif defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) // Use XDG_RUNTIME_DIR instead of /tmp if it's available QString path = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); diff --git a/src/browser/NativeMessageInstaller.cpp b/src/browser/NativeMessageInstaller.cpp index dbf6b9b31..f4876f4e8 100644 --- a/src/browser/NativeMessageInstaller.cpp +++ b/src/browser/NativeMessageInstaller.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -214,12 +215,20 @@ QString NativeMessageInstaller::getNativeMessagePath(SupportedBrowsers browser) basePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); } return QStringLiteral("%1/%2_%3.json").arg(basePath, HOST_NAME, getBrowserName(browser)); +#elif defined(KEEPASSXC_DIST_FLATPAK) + // Flatpak sandboxes do not have access to the XDG_DATA_HOME and XDG_CONFIG_HOME variables + // defined in the host, so we must hardcode them here. + if (browser == SupportedBrowsers::TOR_BROWSER) { + basePath = QDir::homePath() + "/.local/share"; + } else if (browser == SupportedBrowsers::FIREFOX) { + basePath = QDir::homePath(); + } else { + basePath = QDir::homePath() + "/.config"; + } #elif defined(Q_OS_LINUX) if (browser == SupportedBrowsers::TOR_BROWSER) { - // Tor Browser launcher stores its config in ~/.local/share/... basePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); } else if (browser == SupportedBrowsers::FIREFOX) { - // Firefox stores its config in ~/ basePath = QDir::homePath(); } else { basePath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); @@ -234,6 +243,34 @@ QString NativeMessageInstaller::getNativeMessagePath(SupportedBrowsers browser) return QStringLiteral("%1%2/%3.json").arg(basePath, getTargetPath(browser), HOST_NAME); } +#ifdef KEEPASSXC_DIST_FLATPAK +/** Constructs a host accessible proxy path for use with flatpak + * + * @return path Path to host accessible wrapper script (org.keepassxc.KeePassXC) + */ +QString constructFlatpakPath() +{ + // Find and extract the host flatpak data directory (in /var) + QString path; + QSettings settings("/.flatpak-info", QSettings::IniFormat); + settings.beginGroup("Instance"); + QString appPath = settings.value("app-path").toString(); + + QRegularExpression re("^((?:/[\\.\\w-]*)+)+/app"); + QRegularExpressionMatch match = re.match(appPath); + if (match.hasMatch()) { + // Construct a proxy path that should work with all flatpak installations + path = match.captured(1) + "/exports/bin/" + "org.keepassxc.KeePassXC"; + } else { + // Fallback to the most common and default flatpak installation path + path = "/var/lib/flatpak/exports/bin/org.keepassxc.KeePassXC"; + } + settings.endGroup(); + + return path; +} +#endif + /** * Gets the path to keepassxc-proxy binary * @@ -247,8 +284,10 @@ QString NativeMessageInstaller::getProxyPath() const } QString path; -#ifdef KEEPASSXC_DIST_APPIMAGE +#if defined(KEEPASSXC_DIST_APPIMAGE) path = QProcessEnvironment::systemEnvironment().value("APPIMAGE"); +#elif defined(KEEPASSXC_DIST_FLATPAK) + path = constructFlatpakPath(); #else path = QCoreApplication::applicationDirPath() + QStringLiteral("/keepassxc-proxy"); #ifdef Q_OS_WIN diff --git a/src/config-keepassx.h.cmake b/src/config-keepassx.h.cmake index 6b855c62b..6caa89d81 100644 --- a/src/config-keepassx.h.cmake +++ b/src/config-keepassx.h.cmake @@ -31,6 +31,7 @@ #cmakedefine KEEPASSXC_DIST_TYPE "@KEEPASSXC_DIST_TYPE@" #cmakedefine KEEPASSXC_DIST_SNAP #cmakedefine KEEPASSXC_DIST_APPIMAGE +#cmakedefine KEEPASSXC_DIST_FLATPAK #cmakedefine HAVE_PR_SET_DUMPABLE 1 #cmakedefine HAVE_RLIMIT_CORE 1 diff --git a/src/core/EntryAttachments.cpp b/src/core/EntryAttachments.cpp index eeeb6fb2c..c611f4413 100644 --- a/src/core/EntryAttachments.cpp +++ b/src/core/EntryAttachments.cpp @@ -17,6 +17,7 @@ #include "EntryAttachments.h" +#include "config-keepassx.h" #include "core/Global.h" #include "crypto/Random.h" @@ -218,9 +219,13 @@ bool EntryAttachments::openAttachment(const QString& key, QString* errorMessage) const QByteArray attachmentData = value(key); auto ext = key.contains(".") ? "." + key.split(".").last() : ""; -#ifdef KEEPASSXC_DIST_SNAP +#if defined(KEEPASSXC_DIST_SNAP) const QString tmpFileTemplate = QString("%1/XXXXXXXXXXXX%2").arg(QProcessEnvironment::systemEnvironment().value("SNAP_USER_DATA"), ext); +#elif defined(KEEPASSXC_DIST_FLATPAK) + const QString tmpFileTemplate = + QString("%1/app/%2/XXXXXX.%3") + .arg(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation), "org.keepassxc.KeePassXC", ext); #else const QString tmpFileTemplate = QDir::temp().absoluteFilePath(QString("XXXXXXXXXXXX").append(ext)); #endif diff --git a/src/gui/Icons.cpp b/src/gui/Icons.cpp index 0809e271b..b16c40f80 100644 --- a/src/gui/Icons.cpp +++ b/src/gui/Icons.cpp @@ -52,9 +52,18 @@ Icons::Icons() { } +QString Icons::applicationIconName() +{ +#ifdef KEEPASSXC_DIST_FLATPAK + return QString("org.keepassxc.KeePassXC"); +#else + return QString("keepassxc"); +#endif +} + QIcon Icons::applicationIcon() { - return icon("keepassxc", false); + return icon(applicationIconName(), false); } QString Icons::trayIconAppearance() const @@ -81,7 +90,7 @@ QIcon Icons::trayIcon(QString style) auto iconApperance = trayIconAppearance(); if (!iconApperance.startsWith("monochrome")) { - return icon(QString("keepassxc%1").arg(style), false); + return icon(QString("%1%2").arg(applicationIconName(), style), false); } QIcon i; @@ -92,7 +101,7 @@ QIcon Icons::trayIcon(QString style) i = icon(QString("keepassxc-monochrome-dark%1").arg(style), false); } #else - i = icon(QString("keepassxc-%1%2").arg(iconApperance, style), false); + i = icon(QString("%1-%2%3").arg(applicationIconName(), iconApperance, style), false); #endif #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) // Set as mask to allow the operating system to recolour the tray icon. This may look weird diff --git a/src/gui/Icons.h b/src/gui/Icons.h index 01af0b289..db342ae19 100644 --- a/src/gui/Icons.h +++ b/src/gui/Icons.h @@ -27,6 +27,7 @@ class Icons { public: + QString applicationIconName(); QIcon applicationIcon(); QIcon trayIcon(QString style = "unlocked"); QIcon trayIconLocked(); diff --git a/utils/keepassxc-flatpak-wrapper.sh b/utils/keepassxc-flatpak-wrapper.sh new file mode 100755 index 000000000..042acfb27 --- /dev/null +++ b/utils/keepassxc-flatpak-wrapper.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# +# Flatpak Multiple Commands Wrapper +# Copyright (C) 2022 KeePassXC team +# +# 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 +# the Free Software Foundation, either version 2 or (at your option) +# version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# This script is a workaround to the limitation of one command per Flatpak +# manifest. It solves this by redirecting stdio to keepassxc-proxy, as +# necessary, based upon matching command line arguments. + +# For format of parsed arguments, see "Connection-based messaging" at: +# https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Native_messaging + +readonly appId='org.keepassxc.KeePassXC' +# Chromium, Google Chrome, Vivaldi & Brave +readonly arg1='chrome-extension://oboonakemofpalcgghocfoadofidjkkk' +# Firefox & Tor Browser +readonly arg2='keepassxc-browser@keepassxc.org' + +# Browser integration is enabled if unix socket exists +if [[ -S "${XDG_RUNTIME_DIR}/app/${appId}/${appId}.BrowserServer" ]]; then + # Using the =~ operator is intended to allow small variations + # in the parameters, like and ending slash. + # shellcheck disable=2076 + if [[ "$1" =~ "${arg1}" ]] || [[ "$2" =~ "${arg2}" ]]; then + exec keepassxc-proxy "$@" + fi +fi + +# If the first argument is "cli", execute keepassxc-cli instead. +if [[ "$1" == "cli" ]]; then + exec keepassxc-cli "${@:2}" +fi + +# If no arguments are matched or browser integration is off, execute keepassxc +exec keepassxc "$@"