Page MenuHome GnuPG

Kleopatra configuration files in wrong places
Open, NormalPublic

Description

Edit: It was decided that GNUPGHOME gets a subfolder kleopatra, where all these config files should go

+++

Noticed when checking out where to find the settings for the new notifications mentioned here https://dev.gnupg.org/T6766#177906 :
On Windows there is no section [Notification Messages] in the kleopatrarc.
Instead the choice to not show a notification message again is written to %LOCALAPPDTA%kleopatra/kleopatra.kmessagebox
At least for the notifications regarding certifications.

According to Ingo there are two implementations of KMessageBoxDontAskAgainInterface. In KWidgetsAddons and in frameworks integration. On Windows it seems an other implementation is used than on Linux. This should be unified.

Additionally the kleopatrarc on a new system is saved without subdirectory to AppData/Local instead of Appdata/Roaming/kleopatra, where it belongs.
And the kleopatragroupsrc will still be created there, too, instead of in Appdata/Roaming/kleopatra.
In T6669 this was already documented but it was not acted upon.

The following screenshot are from a quite new VM, on older ones where several versions have been installed, there will be two kleopatrarc s.


Details

Version
VS-Desktop-3.1.90.258-Beta

Event Timeline

ebo triaged this task as High priority.Nov 7 2023, 3:02 PM
ebo created this task.

When I created the GnuPG VS-Desktop MSI Package I messed up and forgot about a file that Gpg4win writes where to place the config files.

So GnuPG VS-Desktop from the beginning placed its files into localappdata / seemingly random locations (https://doc.qt.io/qt-5/qstandardpaths.html) because we also do not properly set the organization in the QApplication. So this is not a regression. The files are in the same places as they always were in GnuPG VS-Desktop / Gpg4win respectively.

While by contrast Gpg4win neatly places its files into %APPDATA%\kleopatra thanks to a patch to Qt and a qt.conf: https://dev.gnupg.org/source/gpg4win/browse/master/src/inst-qtbase.nsi$44

Now the problem is, when I realized what was going on we already had widely deployed GnuPG VS-Desktop, and we cannot simply change that because then users will loose all their settings if we do not write a proper migrator that moves the config files around.

So I think the priority is mistaken because Gpg4win tests were in the mix. E.g. if you create a Group with Gpg4win it will not show up in GnuPG VS-Desktop. But If you create a Group with GnuPG VS-Desktop 3.1.26 it will show up in GnuPG VS-Desktop 3.2.0. If that is not the case then the priority here is indeed high.

We discussed this problem in Erkrath once and we think the only proper solution is for Kleopatra to place all its config files into gpgconf --homedir but this would mean to a) Patch Qt some more maybe even have Qt depend on GPGME (so that the gpgconf call is at least cached and does not slow down the startup more) and b) write a migrator for the existing config files.

aheinecke lowered the priority of this task from High to Normal.Nov 7 2023, 3:26 PM

This will definitely not be changed for 3.2 it will be a very invasive patch with a big regression risk and which does not make real sense to do before we switch to Qt6 since it involves patching Qt.

Also this the behavior we have in GnuPG VSD since the very first release. And more importantly is that all these additional config files are not settable through the Windows Registry.

So should we at the moment only change our backup/migration recommendations? Add %LOCALAPPDATA%/kleopatra and %LOCALAPPDATA%/*rc to the backup?

To be honest, the only backup worthy settings file of kleopatra is the kleopatragroupsrc right now. Most other settings are pretty much only for convenience I would not even bother to back them up. When something important is configured by the administration that should go through the registry. As we recently noticed, through talking to people at froscon and with the BSI the most common case was that our kleopatra settings were actually never updated or only saved by accident.

ok, then I'll add the tag for the VSD release after the upcoming one. It is of course relevant for Gpg4win also, but we do not have a dedicated workboard for that (at least not yet)

Well in Gpg4win it actually works better :) At least there the configuration files are all in one place (or mostly, or should be). Anyway a difficult issue which I am only planning to touch when we do the migration to Qt6 since this is heavily Qt releated. But the current plan (which might change) is to do that for the GnuPG VSD summer release which will be the next feature release after 3.2.

What is the status here? Werners opinion is that only the kleopatragroupsrc needs to be migrated.

Alternatively to patching QStandardPaths we could probably patch KConfig (e.g. make KConfigPrivate::changeFileName use a path set by us instead of QStandardPaths::writableLocation(resourceType)). In any case, I see no other solution than patching the base libraries.

Let me remark, that we don't need a general migrator. We only need to make sure that the kleogroups are somehow migrated. Maybe we should do this along with the change of these group files (signing, v5 fingerprints). In any case it is important to get this into vsd33

Another remark: It's very easy to change the location of the kleopatragroupsrc because we have full control over its usage and can simply specify an absolute path for the file. If the file isn't found we can simply look in the old location, i.e. migration is also trivial (as long as we can reliably determine the old location).

Changing the general location of all config files is much harder because some config files are accessed/created by KDE Frameworks libraries outside of kleopatra's and libkleo's control.

The first part, getting the KMessageBox don't remind me checkbox to store the config at the same places as the rest of Kleopatra is handled by https://invent.kde.org/pim/kleopatra/-/merge_requests/193 .

I also made the whole thing more future proof (but also less backportable to Qt5) by moving the KConfig storage plugin to KConfigWidgets instead of FrameworkIntegration with https://invent.kde.org/frameworks/kwidgetsaddons/-/merge_requests/247 https://invent.kde.org/frameworks/frameworkintegration/-/merge_requests/40 and https://invent.kde.org/frameworks/kconfigwidgets/-/merge_requests/243

I have a proof of concept for the second part, for reading config from ~/.gnupg/kleopatra/kleopatrarc (while still supporting the legacy ~/.config/kleopatrarc) at https://invent.kde.org/pim/kleopatra/-/merge_requests/199

Advantage is that it doesn't require any patches in Qt or KConfig and works the same on all platforms, disadvantage is that we need to replace KSharedConfig::openConfig with Kleo::SharedConfig::openConfig which might not be a so bad thing as it gives us back control on how to load the config instead of using the KDE default.

Problem is that this approach doesn't work for settings that are read/written by KF, e.g. the language settings if people change the application language. I also don't particular like the Krita approach of forking everything. On the other hand, patching Qt is also suboptimal and doesn't even work for builds we don't control. Maybe KConfig needs a way to override the default config location retrieved from Qt.

Problem is that this approach doesn't work for settings that are read/written by KF, e.g. the language settings if people change the application language. I also don't particular like the Krita approach of forking everything. n the other hand, patching Qt is also suboptimal and doesn't even work for builds we don't control.

Right, also for KConfigXT generated config object, there is no way with the current api to provide a custom KSharedConfig even thought KConfigSketeton does :(

Maybe KConfig needs a way to override the default config location retrieved from Qt.

This was my first idea too, I just couldn't come up with a good API as we still want to read from ~/.config/kleopatrarc as legacy fallback but maybe something like this could work:

// main.cpp
KConfig::setConfigBaseDirectory(".~/gnupg/kleopatra/", QStandardPaths::AppLocalDataLocation);
KConfig::addFallbackConfigBaseDirectory("~/.config", QStandardPaths::AppLocalDataLocation);

I don't think we need a fallback. For the group configuration we can manually look in the old location. And for everything else it's okay to lose the configuration.

Alternatively, I would look into copying the configuration files from old to new location with the installer.

I don't think we need a fallback. For the group configuration we can manually look in the old location. And for everything else it's okay to lose the configuration.

It is really okay to lose the configuration. I would expect it to be okay for stuff like dialog sizes or even the don't remember me dialogs, but not so okay for the stuff in ~/.config/kleopatrarc.

In any cases, here are some merge requests which ensure config are loaded from ~/.gnupg/kleopatra and the group config are migrated:

ikloecker changed the task status from Open to Testing.Aug 20 2024, 4:27 PM
ikloecker moved this task from Restricted Project Column to Restricted Project Column on the Restricted Project board.

Should work (if correct path is set in qt.conf).

Should also work in VSD 3.3

ebo moved this task from Restricted Project Column to Restricted Project Column on the Restricted Project board.Oct 1 2024, 3:55 PM
ebo moved this task from Restricted Project Column to Restricted Project Column on the Restricted Project board.Oct 1 2024, 4:52 PM

with gpg4win-Beta-50 on a new (not upgraded) installation I see kleopatrarc in the folder %APPDATA%\kleopatra and kleopatragroupsrc in %APPDATA%\gnupg\kleopatra. And no kleopatra files in the base directory of %LOCALAPPDATA%.

I believe this is it was intended and implemented.

aheinecke changed the task status from Testing to Open.Oct 7 2024, 11:52 AM
aheinecke removed CarlSchwan as the assignee of this task.
aheinecke added a subscriber: CarlSchwan.

I see no commits that change the behaviour or do the migration. Then this is not fixed. To clarify. For me this issue is about General config files of KDE / Qt. Not only about the kleopatragroupsrc Since the kleopatragroupsrc was fixed in the last release already.
In the state I left it for VSD 3.3 (master) qt.conf is only written for Gpg4win. And not for VS-Desktop. So testing with Gpg4win has different results. This was the underlying reason since qt.conf was written with FileWrite and not packaged. I only changed that in Gpg4win master.

The confusion is here that instead of opening a different task this was hijacked to only relate to kleopatragroupsrc mudding things up.

So to clarify I reopen this issue as this is the issue to fix it properly for KF6 in Gpg4win and Kleopatra master.

I have already changed the packaging so that qt.conf is now a gpg4win source file and lies under gpg4win/src/qt.conf in there the contents are:

[StandardPaths]
AppLocalDataLocation=%GNUPGHOME%/kleopatra
AppDataLocation=%GNUPGHOME%/kleopatra
CacheLocation=%GNUPGHOME%/kleopatra
StateLocation=%GNUPGHOME%/kleopatra
GenericConfigLocation=%GNUPGHOME%/kleopatra
GenericDataLocation=%GNUPGHOME%/kleopatra
GenericStateLocation=%GNUPGHOME%/kleopatra
GenericCacheLocation=%GNUPGHOME%/kleopatra

With the corresponding patch to Qtbase modified so that it expands environment variables. But if an environment variable is not set, then it returns the path as an unpatched qt would return it. This allows to obtain the "old" path:

+    QScopedPointer<const QSettings> settings(findConfiguration());
+    if (!settings.isNull()) {
+        QString key = QLatin1String(standardPathsSection);
+        key += QLatin1Char('/');
+        key += locations[type];
+        const QString value = settings->value(key).toString();
+#ifdef Q_OS_WIN
+        if (value.isEmpty())
+#endif
+          return value;
+#ifdef Q_OS_WIN
+        wchar_t expandedPath[MAX_PATH] = {0};
+        if (ExpandEnvironmentStrings((wchar_t*)value.utf16(), expandedPath, MAX_PATH)) {
+            const auto expanded = QString::fromWCharArray(expandedPath).replace("\\", "/");
+            if (expanded.contains(QLatin1Char('%'))) {
+                OutputDebugString(L"Not all environment variables could be expanded.");
+                return QString();
+            }
+            return expanded;
+        }
+        return value;
+#endif

To close this issue it is needed that very early on in Kleopatras main or in any main that wants to use this. GNUPGHOME needs to be set.

The idea was to add a migrator that copies the files by obtaining the old path to the file by calling QStandardPaths without a set GNUPGHOME. Copies them to the path that GPGME returns as the GNUPGHOME path.

So this needs to be added I just have not done it yet:

  1. Call gpgme to get the homedir
  2. Check if the migrator was exectued once or not. If not call it.
  3. For each config file we can think of (and here I would need a bit testing to catch all):
    • Unset GNUPGHOME
    • Call QStandardPaths with the correct type to check if the file exists
    • Set GNUPGHOME to the homedir obtained in the first step.
    • Call QStandardPaths again to obtain the new location.
    • Move the file from old to new.
  4. After the code line with the migration then always set GNUPGHOME to the path obtained in the first step.

This will not work for Gpg4win though, since in Gpg4win the files were already place in non standard location (%APPDATA%\kleopatra) and the code does not handle this.

For Gpg4win I wold have additionally checked in the migrator if %APPDATA%/kleopatra exists. If so and GNUPGHOME\kleoptra does not exists, then copy %APPDATA%\kleopatra to GNUPGHOME\kleopatra and remove %APPDATA%\kleopatra .Please remember that QDir::rename does not work accross directories and having GNUPGHOME on a different drive is probably very common.

Andre, didn't we conclude that there's nothing worth migrating except the groups configuration (which is migrated)?

Regardless of the migration. At least we need to set GNUPGHOME early in Kleopatras main to the value returned by GpgME so that the qt.conf patch works in KF6.

This issue for me was (see the first comment) about generally solving this with KF6, but in between it was said that kleopatragroupsrc needed to be moved ASAP (3.3) with more priorty. I already talked to ebo about this and that part should have been its own issue ideally.

Thus the rule is that all our Qt applications except for pinentry need to fist initialize gpgme to get the actually used GNUPGEHOME. gpgconf either takes this from the GNUPGHOME envvar or from its default or via its gpgconf.ctl file.
The latter can eventually be used to move the default homedir to %APPDATA%\gnupg-vsd so to allow using different versions of the gnupg engine.

ebo edited projects, added gpd5x; removed vsd33, Restricted Project.Tue, Oct 29, 9:42 AM