Page MenuHome GnuPG

gpg does create socketdir after every operation
Closed, ResolvedPublic

Description

I need to locate my gpg sockets under GNUPGHOME, but gpg always re-creates them under /run/user/UID/gnupg.

Details

Version
2.2.41

Event Timeline

What is your problem with socket below /run/user ? In fact you will need it anyway if your socket file name is longer than something like 104 characters.

Note that there are gpgconf --create-socketdir and --remove-socketdir helper commands in case you need to create them before any operation.

exactly, as soon as I need a socketdir other than GNUPGHOME I would use gpgconf --create-socketdir and remove it afterwards via gpgconf --remove-socketdir. But it seems that the socketdir /run/user/UID/gnupg is created by default.

My specific case is that I have to sign files within fakeroot environment. So I export GNUPGHOME of my actual user into it. Now I have to do gpgconf --remove-socketdir before the first gpg operation inside fakeroot. gpg-agent falls back to GNUPGHOME once. Otherwise gpg-agent cannot connect IPC to /run/user/0/gnupg. But before the second gpg operation I would have to do gpgconf --remove-socketdir again.

So IMHO gpg should not create the sockets under /run/user/UID/gnupg by default. Now it somehow "feels" like a logical bug in certain cases.

That is convenience. Before we did this people were complaining that they first need to create a directory for the sockets. You should not need to use --create-socketdir unless you want to start something like watchgnupg on a socket in just this directory (using the shortcut socket://).

The problems with NFS file systems and other remotely mounted GNUPGHOME are another reason why the old way of having the sockets in GNUPGHOME are deprecated.

I see that fakeroot is problematic here. I have not tried but /run/user/0/gnupg wrong permissions my force a fallback to $GNUPGHOME. We have this check

if (sb.st_uid != getuid ())
    {
      *r_info |= 4; /* Not owned by the user.  */
      if (!skip_checks)
        goto leave;
    }

Which seems not to kick in because fakeroot creates a mismatch between stat and getuid?

if nothing else works implementing an override might be possible by extending the gpgconf.ctl file, which can be used to runtime switch the sysconfdir and such.

exactly this UID comparison is not enough within fakeroot environment! thanks for redirecting me to homedir.c!

I guess an additional check like

struct dirent *entry;

if (sb.st_uid != getuid () || !(entry = readdir(prefix))
 {
      *r_info |= 4; /* Not owned by the user.  */
      if (!skip_checks)
        goto leave;
 }

should do.

Btw I did not understand what you mean by
"extending the gpgconf.ctl file, which can be used to runtime switch the sysconfdir and such"
I think there is no configuration option to set the socket directory, it's hardcoded in homedir.c

I think there is no configuration option to set the socket directory, it's hardcoded in homedir.c

Right,. we could add an option to gpgconf.ctl to allow a different socket dir. gpgconf.ctl is currently used for the the regresion test and for the (deprecated) portable version on Windows. For example see gnupg/tests/gpgconf.ctl.in.

werner triaged this task as Normal priority.Nov 13 2023, 4:18 PM
werner edited projects, added gnupg24, Feature Request; removed Bug Report.
werner changed the task status from Open to Testing.Jan 5 2024, 11:39 AM
werner moved this task from Backlog to QA on the gnupg24 board.

With rG239c1fdc28dcd0dc7aa5341be7c966da2231642a we now have a socketdir keyword for gpgconf.ctl. man gpgconf and look for that file. Will be released with 2.4.4.

thats great news! I will test the keyword with Archlinux's Builds System (and Fakeroot) as soon as possible!

PS: meanwhile I found a workaround using unshare and mount --bind /run/user/UID/gnupg /run/user/0/gnupg inside a fakeroot-wrapper script, which is pretty cumbersome IMHO.

werner claimed this task.

Tested during development.