Skip to content

Commit

Permalink
Use XDG Desktop Portal to autostart the flatpak v2
Browse files Browse the repository at this point in the history
  • Loading branch information
moriol42 committed Apr 18, 2024
1 parent 194409a commit 66f0ef5
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 24 deletions.
3 changes: 3 additions & 0 deletions src/core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::GUI_HidePreviewPanel, {QS("GUI/HidePreviewPanel"), Roaming, false}},
{Config::GUI_AlwaysOnTop, {QS("GUI/GUI_AlwaysOnTop"), Local, false}},
{Config::GUI_ToolButtonStyle, {QS("GUI/ToolButtonStyle"), Roaming, Qt::ToolButtonIconOnly}},
#ifdef KEEPASSXC_DIST_FLATPAK
{Config::GUI_LaunchAtStartup, {QS("GUI/LaunchAtStartup"), Roaming, false}},
#endif
{Config::GUI_ShowTrayIcon, {QS("GUI/ShowTrayIcon"), Roaming, false}},
{Config::GUI_TrayIconAppearance, {QS("GUI/TrayIconAppearance"), Roaming, {}}},
{Config::GUI_MinimizeToTray, {QS("GUI/MinimizeToTray"), Roaming, false}},
Expand Down
3 changes: 3 additions & 0 deletions src/core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ class Config : public QObject
GUI_HidePreviewPanel,
GUI_AlwaysOnTop,
GUI_ToolButtonStyle,
#ifdef KEEPASSXC_DIST_FLATPAK
GUI_LaunchAtStartup,
#endif
GUI_ShowTrayIcon,
GUI_TrayIconAppearance,
GUI_MinimizeToTray,
Expand Down
19 changes: 16 additions & 3 deletions src/core/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@ bool Database::performSave(const QString& filePath, SaveAction action, const QSt

bool Database::writeDatabase(QIODevice* device, QString* error)
{
Q_ASSERT(m_data.key);
Q_ASSERT(m_data.transformedDatabaseKey);

PasswordKey oldTransformedKey;
if (m_data.key->isEmpty()) {
oldTransformedKey.setRawKey(m_data.transformedDatabaseKey->rawKey());
Expand Down Expand Up @@ -767,18 +770,29 @@ Database::CompressionAlgorithm Database::compressionAlgorithm() const

QByteArray Database::transformedDatabaseKey() const
{
Q_ASSERT(m_data.transformedDatabaseKey);
if (!m_data.transformedDatabaseKey) {
return {};
}
return m_data.transformedDatabaseKey->rawKey();
}

QByteArray Database::challengeResponseKey() const
{
Q_ASSERT(m_data.challengeResponseKey);
if (!m_data.challengeResponseKey) {
return {};
}
return m_data.challengeResponseKey->rawKey();
}

bool Database::challengeMasterSeed(const QByteArray& masterSeed)
{
Q_ASSERT(m_data.key);
Q_ASSERT(m_data.masterSeed);

m_keyError.clear();
if (m_data.key) {
if (m_data.key && m_data.masterSeed) {
m_data.masterSeed->setRawKey(masterSeed);
QByteArray response;
bool ok = m_data.key->challenge(masterSeed, response, &m_keyError);
Expand Down Expand Up @@ -824,8 +838,7 @@ bool Database::setKey(const QSharedPointer<const CompositeKey>& key,
m_keyError.clear();

if (!key) {
m_data.key.reset();
m_data.transformedDatabaseKey.reset(new PasswordKey());
m_data.resetKeys();
return true;
}

Expand Down
23 changes: 13 additions & 10 deletions src/core/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,30 +188,33 @@ public slots:
QScopedPointer<PasswordKey> challengeResponseKey;

QSharedPointer<const CompositeKey> key;
QSharedPointer<Kdf> kdf = QSharedPointer<AesKdf>::create(true);
QSharedPointer<Kdf> kdf;

QVariantMap publicCustomData;

DatabaseData()
: masterSeed(new PasswordKey())
, transformedDatabaseKey(new PasswordKey())
, challengeResponseKey(new PasswordKey())
{
kdf->randomizeSeed();
clear();
}

void clear()
{
resetKeys();
filePath.clear();
publicCustomData.clear();
}

masterSeed.reset();
transformedDatabaseKey.reset();
challengeResponseKey.reset();
void resetKeys()
{
masterSeed.reset(new PasswordKey());
transformedDatabaseKey.reset(new PasswordKey());
challengeResponseKey.reset(new PasswordKey());

key.reset();
kdf.reset();

publicCustomData.clear();
// Default to AES KDF, KDBX4 databases overwrite this
kdf.reset(new AesKdf(true));
kdf->randomizeSeed();
}
};

Expand Down
4 changes: 1 addition & 3 deletions src/gui/DatabaseOpenWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,7 @@ void DatabaseOpenWidget::clearForms()
m_ui->hardwareKeyCombo->clear();
toggleQuickUnlockScreen();

QString error;
m_db.reset(new Database());
m_db->open(m_filename, nullptr, &error);
m_db.reset(new Database(m_filename));
}

QSharedPointer<Database> DatabaseOpenWidget::database()
Expand Down
2 changes: 1 addition & 1 deletion src/gui/csvImport/CsvImportWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace

auto nameList = groupPath.split("/", QString::SkipEmptyParts);
// Skip over first group name if root
if (nameList.first().compare("root", Qt::CaseInsensitive)) {
if (nameList.first().compare("root", Qt::CaseInsensitive) == 0) {
nameList.removeFirst();
}

Expand Down
11 changes: 6 additions & 5 deletions src/gui/dbsettings/DatabaseSettingsWidgetEncryption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,23 @@ void DatabaseSettingsWidgetEncryption::initialize()
}

auto version = KDBX4;
if (m_db->kdf()) {
if (m_db->key() && m_db->kdf()) {
version = (m_db->kdf()->uuid() == KeePass2::KDF_AES_KDBX3) ? KDBX3 : KDBX4;
}
m_ui->compatibilitySelection->setCurrentIndex(version);

bool isNewDatabase = false;

if (!m_db->kdf()) {
m_db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D));
isNewDatabase = true;
}
if (!m_db->key()) {
m_db->setKey(QSharedPointer<CompositeKey>::create(), true, false, false);
m_db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D));
m_db->setCipher(KeePass2::CIPHER_AES256);
isNewDatabase = true;
} else if (!m_db->kdf()) {
m_db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D));
isNewDatabase = true;
}

bool kdbx3Enabled = KeePass2Writer::kdbxVersionRequired(m_db.data(), true, true) <= KeePass2::FILE_VERSION_3_1;

// check if the DB's custom data has a decryption time setting stored
Expand Down
51 changes: 51 additions & 0 deletions src/gui/osutils/nixutils/NixUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
#include <QStandardPaths>
#include <QStyle>
#include <QTextStream>
#ifdef KEEPASSXC_DIST_FLATPAK
#include <QRandomGenerator>
#include "core/Config.h"
#endif
#ifdef WITH_XC_X11
#include <QX11Info>

Expand Down Expand Up @@ -123,12 +127,17 @@ QString NixUtils::getAutostartDesktopFilename(bool createDirs) const

bool NixUtils::isLaunchAtStartupEnabled() const
{
#if !defined(KEEPASSXC_DIST_FLATPAK)
return QFile::exists(getAutostartDesktopFilename());
;
#else
return config()->get(Config::GUI_LaunchAtStartup).toBool();
#endif
}

void NixUtils::setLaunchAtStartup(bool enable)
{
#if !defined(KEEPASSXC_DIST_FLATPAK)
if (enable) {
QFile desktopFile(getAutostartDesktopFilename(true));
if (!desktopFile.open(QIODevice::WriteOnly)) {
Expand Down Expand Up @@ -163,8 +172,50 @@ void NixUtils::setLaunchAtStartup(bool enable)
} else if (isLaunchAtStartupEnabled()) {
QFile::remove(getAutostartDesktopFilename());
}
#else
QDBusConnection sessionBus = QDBusConnection::sessionBus();
QDBusMessage msg = QDBusMessage::createMethodCall(
"org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", "org.freedesktop.portal.Background", "RequestBackground");

QMap<QString, QVariant> options;
options["autostart"] = QVariant(enable);
options["reason"] = QVariant("Launch KeePassXC at startup");
int token = QRandomGenerator::global()->bounded(1000, 9999);
options["handle_token"] = QVariant(QString("org/keepassxc/KeePassXC/%1").arg(token));

msg << "" << options;

QDBusMessage response = sessionBus.call(msg);

QDBusObjectPath handle = response.arguments().at(0).value<QDBusObjectPath>();

bool res = sessionBus.connect("org.freedesktop.portal.Desktop",
handle.path(),
"org.freedesktop.portal.Request",
"Response",
this,
SLOT(launchAtStartupRequested(uint, QVariantMap)));

if (!res) {
qDebug() << "Could not connect to org.freedesktop.portal.Request::Response signal";
}
#endif
}


void NixUtils::launchAtStartupRequested(uint response, const QVariantMap &results) {
if (response > 0) {
qDebug() << "The interection was cancelled";
return;
}
bool isLauchedAtStartup = results["autostart"].value<bool>();
qDebug() << "The autostart value is set to:" << isLauchedAtStartup;
#if defined(KEEPASSXC_DIST_FLATPAK)
config()->set(Config::GUI_LaunchAtStartup, isLauchedAtStartup);
#endif
}


bool NixUtils::isCapslockEnabled()
{
#ifdef WITH_XC_X11
Expand Down
1 change: 1 addition & 0 deletions src/gui/osutils/nixutils/NixUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class NixUtils : public OSUtilsBase, QAbstractNativeEventFilter
private slots:
void handleColorSchemeRead(QDBusVariant value);
void handleColorSchemeChanged(QString ns, QString key, QDBusVariant value);
void launchAtStartupRequested(uint response, const QVariantMap &results);

private:
explicit NixUtils(QObject* parent = nullptr);
Expand Down
8 changes: 6 additions & 2 deletions tests/TestKeePass2Format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,9 @@ void TestKeePass2Format::testKdbxKeyChange()

db->setKey(key1);
writeKdbx(&buffer, db.data(), hasError, errorString);
QVERIFY(!hasError);
if (hasError) {
QFAIL(qPrintable(QStringLiteral("Error while reading database: ").append(errorString)));
}

// read database
db = QSharedPointer<Database>::create();
Expand All @@ -599,7 +601,9 @@ void TestKeePass2Format::testKdbxKeyChange()
// write database
buffer.seek(0);
writeKdbx(&buffer, db.data(), hasError, errorString);
QVERIFY(!hasError);
if (hasError) {
QFAIL(qPrintable(QStringLiteral("Error while reading database: ").append(errorString)));
}

// read database
db = QSharedPointer<Database>::create();
Expand Down

0 comments on commit 66f0ef5

Please sign in to comment.