Gpg-agent socket binding

Hi all,

I am trying to run gpg and the gpg-agent inside of a snap but have been running into issues with the gpg-agent failing to bind to its standard Unix socket. I have been using the following as references (particularly jdstrand’s test-gnupg2 example).



My use case is a bit different than some of the other discussions I have seen on here where developers want to be able to access the gpg-agent running on the host machine. I specifically need gpg/gpg-agent to be separate from the versions of these applications running on the host. All keys used in the snap application are specified through configuration files or generated inside the snap so the application does not use the gpg-keys interface.

When attempting to run gpg-agent --daemon --debug-level guru inside the snap, I get the output

gpg-agent[7407]: enabled debug flags: mpi crypto memory cache memstat hashing ipc
gpg-agent[7407]: directory ‘/home/user/snap/raven-client/x1/.gnupg/private-keys-v1.d’ created
gpg-agent[7407]: error binding socket to ‘/run/user/1000/gnupg/S.gpg-agent’: Address already in use
gpg-agent[7407]: random usage: poolsize=600 mixed=0 polls=0/0 added=0/0
outmix=0 getlvl1=0/0 getlvl2=0/0
gpg-agent[7407]: rndjent stat: collector=0x0000000000000000 calls=0 bytes=0
gpg-agent[7407]: secmem usage: 0/65536 bytes in 0 blocks

My understanding of the issue is that the gpg-agent running on the host has already bound to that socket, preventing the gpg-agent inside of the snap from binding to that socket as well. Ideally, I would be able to use layouts to force the gpg-agent in snap to bind to a different socket, but layouts cannot be used on /run. The ability to use non-standard sockets was removed from the gpg-agent a version or two ago, although I am going to keep poking around to see if I am missing something on this gpg-agent front (this work around no longer seems to work for some reason https://dev.gnupg.org/T1752). I was curious if there are any snap-based solutions to this problem since being able to run a separate instance of the gpg-agent inside of snap does not seem like an unreasonable task.

At the end of the day, downgrading the gpg-agent to a version that allows the use of non-standard sockets is always an option, but I would prefer a more sustainable long-term solution for this problem. Any help is greatly appreciated!

I don’t think my snapcraft.yaml is relevant to the issue, but I have included it just in case:

name: client
base: core18
version: '0.1'
summary: python client
description: |
  client

grade: devel 
confinement: strict

parts:
  # python set up
  internal-python:
    plugin: python
    python-version: python3
    source: .
    python-packages:
      - protobuf
      - pycryptodome
      - python-gnupg
      - pyyaml
      - python-dateutil
      - ruamel.yaml	# needed for config_to_yaml

  # set up hooks in snap
  hook-setup:
    plugin: dump
    source: hooks
    organize:
      configure: snap/hooks/configure
      post-refresh: snap/hooks/post-refresh
      install: snap/hooks/install

  # install binaries we need that are not provided in core18
  binary-install:
    source: .
    plugin: nil
    stage-packages:
      - gpg
      - gpg-agent
      - gpgconf
      - gpgsm
      - gpgv
      - tree

  # load scripts into snap
  script-copy:
    source: client
    plugin: dump

plugs:
  home-all:
    interface: home
    read: all

hooks:
  configure:
    plugs:
    - home-all

layout:
  /usr/bin/gpg:
    bind-file: $SNAP/usr/bin/gpg
  /usr/bin/gpg-agent:
    bind-file: $SNAP/usr/bin/gpg-agent
  /usr/bin/gpg-connect-agent:
    bind-file: $SNAP/usr/bin/gpg-connect-agent
  /usr/bin/gpgconf:
    bind-file: $SNAP/usr/bin/gpgconf
  /usr/bin/gpgsm:
    bind-file: $SNAP/usr/bin/gpgsm
  /usr/bin/gpgv:
    bind-file: $SNAP/usr/bin/gpgv

apps:
  run:
    command: "$SNAP/run.sh"
    plugs:
      - network
      - network-bind
      - home-all
      - home