From 5f2ee86d72946d2449d90c62bf20eaf017ac2ae9 Mon Sep 17 00:00:00 2001 From: James Carroll Date: Wed, 19 Jun 2024 20:49:30 +0100 Subject: [PATCH] Snap: Improve Web-browser Native Messaging host functionality (#10906) * Snap: Improve Web-browser Native Messaging host functionality This commit allows for the snap distribution of KeepassXC to self-manage native messaging manifests This is done by making the binary aware of the snapd environment changes that currently prevent this. Furthermore, the snap sandbox is expanded to the bare minimum needed to access these privileged files. Please note if running a self-compiled / untrusted KeepassXC snap build (I.E, installed with --dangerous) that you must manually run `sudo snap connect keepassxc:browser-native-messaging` to grant permissions. This will work on all distributions that expose `/snap/bin/` - such as Ubuntu, Debian, etc. For systems which don't provide `/snap/`, such as Fedora, follow instructions for enabling "Classic" snaps. e.g., `sudo ln -s /var/lib/snapd/snap /snap` --------- Co-authored-by: Jonathan White --- share/translations/keepassxc_en.ts | 16 ++++------------ snap/snapcraft.yaml | 14 +++++++++++++- src/browser/BrowserSettingsWidget.cpp | 19 ++----------------- src/browser/NativeMessageInstaller.cpp | 12 ++++++++++++ 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 91467de501..c482142158 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -1186,18 +1186,6 @@ Do you want to overwrite the passkey in %1 - %2? Custom extension ID - - Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - - - - KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2 and %3. %4 - - - - Please see special instructions for browser extension use below - - Executable Files @@ -1246,6 +1234,10 @@ Do you want to overwrite the passkey in %1 - %2? Allow using localhost with passkeys + + KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2 and %3. + + CloneDialog diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 435bf725bf..d03f0e1c1e 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -10,7 +10,7 @@ apps: command: usr/bin/keepassxc common-id: org.keepassxc.KeePassXC.desktop extensions: [kde-neon] - plugs: [home, unity7, network, network-bind, removable-media, raw-usb, password-manager-service] + plugs: [home, unity7, network, network-bind, removable-media, raw-usb, password-manager-service, browser-native-messaging] autostart: org.keepassxc.KeePassXC.desktop cli: command: usr/bin/keepassxc-cli @@ -21,6 +21,18 @@ apps: extensions: [kde-neon] plugs: [home] +plugs: + browser-native-messaging: + interface: personal-files + write: + - $HOME/.mozilla/native-messaging-hosts/org.keepassxc.keepassxc_browser.json + - $HOME/.config/chromium/NativeMessagingHosts/org.keepassxc.keepassxc_browser.json + - $HOME/.config/google-chrome/NativeMessagingHosts/org.keepassxc.keepassxc_browser.json + - $HOME/.config/microsoft-edge/NativeMessagingHosts/org.keepassxc.keepassxc_browser.json + - $HOME/.config/vivaldi/NativeMessagingHosts/org.keepassxc.keepassxc_browser.json + - $HOME/.config/BraveSoftware/Brave-Browser/NativeMessagingHosts/org.keepassxc.keepassxc_browser.json + - $HOME/.local/share/torbrowser/tbb/x86_64/tor-browser_en-US/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts/org.keepassxc.keepassxc_browser.json + slots: session-dbus-interface: interface: dbus diff --git a/src/browser/BrowserSettingsWidget.cpp b/src/browser/BrowserSettingsWidget.cpp index 3190fddbe0..3e2679e799 100644 --- a/src/browser/BrowserSettingsWidget.cpp +++ b/src/browser/BrowserSettingsWidget.cpp @@ -31,23 +31,13 @@ BrowserSettingsWidget::BrowserSettingsWidget(QWidget* parent) m_ui->setupUi(this); // clang-format off - QString snapInstructions; -#if defined(KEEPASSXC_DIST_SNAP) - snapInstructions = "

" + - tr("Due to Snap sandboxing, you must run a script to enable browser integration." - "
" - "You can obtain this script from %1") - .arg("https://keepassxc.org"); -#endif - m_ui->extensionLabel->setOpenExternalLinks(true); m_ui->extensionLabel->setText( - tr("KeePassXC-Browser is needed for the browser integration to work.
Download it for %1 and %2 and %3. %4") + tr("KeePassXC-Browser is needed for the browser integration to work.
Download it for %1 and %2 and %3.") .arg("Firefox", "" "Google Chrome / Chromium / Vivaldi / Brave", - "Microsoft Edge", - snapInstructions)); + "Microsoft Edge")); // clang-format on m_ui->tabWidget->setEnabled(m_ui->enableBrowserSupport->isChecked()); @@ -149,16 +139,11 @@ void BrowserSettingsWidget::loadSettings() m_ui->useCustomProxy->setVisible(false); m_ui->customProxyLocation->setVisible(false); m_ui->customProxyLocationBrowseButton->setVisible(false); - m_ui->browsersGroupBox->setVisible(false); - m_ui->browsersGroupBox->setEnabled(false); m_ui->updateBinaryPath->setChecked(false); m_ui->updateBinaryPath->setVisible(false); // No custom browser for snaps m_ui->customBrowserSupport->setVisible(false); m_ui->customBrowserGroupBox->setVisible(false); - // Show notice to user - m_ui->messageWidget->showMessage(tr("Please see special instructions for browser extension use below"), - MessageWidget::Warning); #endif #ifdef KEEPASSXC_DIST_FLATPAK // The sandbox makes custom proxy locations very unintuitive diff --git a/src/browser/NativeMessageInstaller.cpp b/src/browser/NativeMessageInstaller.cpp index 92b5db2913..7e637a64cc 100644 --- a/src/browser/NativeMessageInstaller.cpp +++ b/src/browser/NativeMessageInstaller.cpp @@ -226,6 +226,16 @@ QString NativeMessageInstaller::getNativeMessagePath(SupportedBrowsers browser) } else { basePath = QDir::homePath() + "/.config"; } +#elif defined(KEEPASSXC_DIST_SNAP) + // Same as Flatpak above, with the exception that Snap also redefines $HOME + // Therefore we must explicitly reference $SNAP_REAL_HOME + if (browser == SupportedBrowsers::TOR_BROWSER) { + basePath = qEnvironmentVariable("SNAP_REAL_HOME") + "/.local/share"; + } else if (browser == SupportedBrowsers::FIREFOX) { + basePath = qEnvironmentVariable("SNAP_REAL_HOME"); + } else { + basePath = qEnvironmentVariable("SNAP_REAL_HOME") + "/.config"; + } #elif defined(Q_OS_LINUX) || (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) if (browser == SupportedBrowsers::TOR_BROWSER) { basePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); @@ -296,6 +306,8 @@ QString NativeMessageInstaller::getInstalledProxyPath() const path = QProcessEnvironment::systemEnvironment().value("APPIMAGE"); #elif defined(KEEPASSXC_DIST_FLATPAK) path = constructFlatpakPath(); +#elif defined(KEEPASSXC_DIST_SNAP) + path = "/snap/bin/keepassxc.proxy"; #else path = QCoreApplication::applicationDirPath() + QStringLiteral("/keepassxc-proxy"); #ifdef Q_OS_WIN