Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

split-gpg2 client exits non-zero when importing public keys on alternate gpg homedir #9534

Open
ben-grande opened this issue Oct 24, 2024 · 11 comments · May be fixed by QubesOS/qubes-app-linux-split-gpg2#18
Assignees
Labels
affects-4.2 This issue affects Qubes OS 4.2. C: split-gpg2 split-gpg version 2 diagnosed Technical diagnosis has been performed (see issue comments). P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. pr submitted A pull request has been submitted for this issue. T: bug Type: bug report. A problem or defect resulting in unintended behavior in something that exists.

Comments

@ben-grande
Copy link

Qubes OS release

R4.2

Brief summary

When import a public key for the first time to a split-gpg2 client, it has a delay as the agent doesn't respond, imports the key but exits non zero. What I am currently doing to overcome the error exit code:

  • Checking if the regex ^\[GNUPG:\] IMPORT_OK appears in stderr
  • Overriding agent with --agent-program="$(gpgconf --list-components | awk -F: '/^gpg-agent:/{print $3}')"

Steps to reproduce

Add a new public key (not previously imported) to the client keyring.

Expected behavior

Import happens successfully and exits with code zero. The /usr/share/split-gpg2/gpg-agent-placeholder should reply with something useful when importing a key, not only exit zero.

Actual behavior

Import happens successfully, but it has a delay and exits with code non-zero.

gpg --status-fd=2 --homedir=/tmp/tmp.mWSPrpSXoW --import salt/qubes-builder/files/client/qusal/keys/DF3834875B65758713D92E91A475969DE4E371E3.asc
[GNUPG:] KEY_CONSIDERED DF3834875B65758713D92E91A475969DE4E371E3 0
gpg: key A475969DE4E371E3: public key "Ben Grande (Code signing key) <[email protected]>" imported
[GNUPG:] IMPORTED A475969DE4E371E3 Ben Grande (Code signing key) <[email protected]>
[GNUPG:] IMPORT_OK 1 DF3834875B65758713D92E91A475969DE4E371E3
gpg: can't connect to the agent: IPC connect call failed
gpg: Total number processed: 1
gpg:               imported: 1
[GNUPG:] IMPORT_RES 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
[GNUPG:] KEY_CONSIDERED DF3834875B65758713D92E91A475969DE4E371E3 0
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
zsh: exit 2     gpg --homedir=/tmp/tmp.kre9T3wViO --import
@ben-grande ben-grande added P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. T: bug Type: bug report. A problem or defect resulting in unintended behavior in something that exists. labels Oct 24, 2024
@marmarek
Copy link
Member

What does it do with the agent? Agent is responsible for handling only secret keys... Maybe it tries to check if it has secret part for this key? Can you enabled debugging in the split-gpg2 and see what it tries to do? See debug_log option in the config: https://github.com/QubesOS/qubes-app-linux-split-gpg2/blob/main/qubes-split-gpg2.conf.example

@marmarek
Copy link
Member

Or maybe just journalctl/.xsession-errors in the backend will have that info already?

@ben-grande
Copy link
Author

What does it do with the agent? Agent is responsible for handling only secret keys... Maybe it tries to check if it has secret part for this key?

Possibly tries to check if there is a secret part.

Can you enabled debugging in the split-gpg2 and see what it tries to do?

Checked the dom0 logs now and it never calls the split-gpg2 backend, nothing logged to the journal of qubes-qrexec-policy-daemon.

@marmarek
Copy link
Member

hmm, does it mean split-gpg2 isn't working for you there at all? maybe the client part fails to start or such?

@ben-grande
Copy link
Author

split-gpg2 works fine, I can list secret keys only available in the backend.

@andrewdavidwong andrewdavidwong added C: split-gpg2 split-gpg version 2 affects-4.2 This issue affects Qubes OS 4.2. needs diagnosis Requires technical diagnosis from developer. Replace with "diagnosed" or remove if otherwise closed. labels Oct 25, 2024
@Euwiiwueir
Copy link

split-gpg2 works fine, I can list secret keys only available in the backend.

Can you also sign or encrypt with them?

@ben-grande
Copy link
Author

ben-grande commented Oct 26, 2024 via email

@ben-grande
Copy link
Author

ben-grande commented Oct 28, 2024

Example to demonstrate the problem:

#!/bin/sh
set -eu

key_url="https://keys.openpgp.org/vks/v1/by-fingerprint/86BA6E93318FBA446642A90ADB8FD31CCAD7D72C"
gnupg_homedir="$(mktemp -d)"
trap 'rm -rf - "${gnupg_homedir}"' EXIT INT HUP QUIT ABRT
cd "${gnupg_homedir}" || exit 1
curl -o key.asc "${key_url}"
gpg --homedir . --import key.asc
user@disp8589:~$ sudo touch /var/run/qubes-service/split-gpg2-client

user@disp8589:~$ sudo apt install -y split-gpg2

user@disp8589:~$ sh -x ./imp.sh
+ set -eu
+ key_url=https://keys.openpgp.org/vks/v1/by-fingerprint/86BA6E93318FBA446642A90ADB8FD31CCAD7D72C
+ mktemp -d
+ gnupg_homedir=/tmp/tmp.axcQxkaPH3
+ trap rm -rf - "${gnupg_homedir}" EXIT INT HUP QUIT ABRT
+ cd /tmp/tmp.axcQxkaPH3
+ curl -o key.asc https://keys.openpgp.org/vks/v1/by-fingerprint/86BA6E93318FBA446642A90ADB8FD31CCAD7D72C
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  4426  100  4426    0     0  25248      0 --:--:-- --:--:-- --:--:-- 25291
+ gpg --homedir . --import key.asc
gpg: keybox '/tmp/tmp.axcQxkaPH3/pubring.kbx' created
gpg: key DB8FD31CCAD7D72C: 1 signature not checked due to a missing key
gpg: /tmp/tmp.axcQxkaPH3/trustdb.gpg: trustdb created
gpg: key DB8FD31CCAD7D72C: public key "Marek Marczykowski-Górecki <[email protected]>" imported
gpg: can't connect to the agent: IPC connect call failed
gpg: Total number processed: 1
gpg:               imported: 1
gpg: no ultimately trusted keys found
+ rm -rf - /tmp/tmp.axcQxkaPH3
user@disp8589:~$ sudo rm -f /var/run/qubes-service/split-gpg2-client

user@disp8589:~$ sh -x ./imp.sh
+ set -eu
+ key_url=https://keys.openpgp.org/vks/v1/by-fingerprint/86BA6E93318FBA446642A90ADB8FD31CCAD7D72C
+ mktemp -d
+ gnupg_homedir=/tmp/tmp.VFGlryM71C
+ trap rm -rf - "${gnupg_homedir}" EXIT INT HUP QUIT ABRT
+ cd /tmp/tmp.VFGlryM71C
+ curl -o key.asc https://keys.openpgp.org/vks/v1/by-fingerprint/86BA6E93318FBA446642A90ADB8FD31CCAD7D72C
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  4426  100  4426    0     0  23739      0 --:--:-- --:--:-- --:--:-- 23795
+ gpg --homedir . --import key.asc
gpg: keybox '/tmp/tmp.VFGlryM71C/pubring.kbx' created
gpg: key DB8FD31CCAD7D72C: 1 signature not checked due to a missing key
gpg: /tmp/tmp.VFGlryM71C/trustdb.gpg: trustdb created
gpg: key DB8FD31CCAD7D72C: public key "Marek Marczykowski-Górecki <[email protected]>" imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: no ultimately trusted keys found
+ rm -rf - /tmp/tmp.VFGlryM71C

@marmarek
Copy link
Member

I think it's not related to the import operation, but to a changed homedir. split-gpg2 listens only on the primary (default) socket. I guess the solution would be to change gpg-agent-placeholder to check also for changed home dir (option and/or env variable) and don't intercept those calls. Alternative would be to start listening on those extra sockets, but IMO that would be confusing - you use alternative gpg homedir usually to not have other keys there.

@ben-grande
Copy link
Author

Good point. It is not always passed to the environment variable but always as parameter, $@ contains: --homedir /tmp/tmp.un8FBXDKRM --use-standard-socket --daemon. Setting GNUPGHOME or --homedir option on the command line, results in the positional parameter --homedir being passed to the agent in the end.

/usr/share/split-gpg2/gpg-agent-placeholder:

#!/bin/bash

set -eo pipefail

printf '%s\n' "GNUPGHOME=${GNUPGHOME:-}" | tee -- /tmp/log >/dev/null
printf '%s\n' "$@" | tee -a -- /tmp/log >/dev/null
gpgconf --list-dirs | grep -e -socket -e homedir | tee -a -- /tmp/log >/dev/null

# prevent starting real gpg-agent locally if it's redirected via split-gpg2
if [ -e /run/qubes-service/split-gpg2-client ]; then
    exit 0
fi
# otherwise, launch gpg-agent
gpgagent=$(gpgconf --list-components | grep ^gpg-agent: | cut -d ':' -f 3)
exec "$gpgagent" "$@"

imp.sh:

#!/bin/sh
set -eu

key_url="https://keys.openpgp.org/vks/v1/by-fingerprint/86BA6E93318FBA446642A90ADB8FD31CCAD7D72C"
gnupg_homedir="$(mktemp -d)"
trap 'rm -rf - "${gnupg_homedir}"' EXIT INT HUP QUIT ABRT
cd "${gnupg_homedir}" || exit 1
curl -o key.asc "${key_url}"
#gpg --import key.asc
gpg --homedir . --import key.asc
#GNUPGHOME=. gpg --import key.asc
#GNUPGHOME="${gnupg_homedir}" gpg --import key.asc
$ GNUPGHOME="${gnupg_homedir}" gpg --import key.asc
> GNUPGHOME=/tmp/tmp.gQzeYPoncU
> --homedir /tmp/tmp.gQzeYPoncU --use-standard-socket --daemon
> dirmngr-socket:/run/user/1000/gnupg/d.7e941cr5w3kz9fjxqp48yqfe/S.dirmngr
> agent-ssh-socket:/run/user/1000/gnupg/d.7e941cr5w3kz9fjxqp48yqfe/S.gpg-agent.ssh
> agent-extra-socket:/run/user/1000/gnupg/d.7e941cr5w3kz9fjxqp48yqfe/S.gpg-agent.extra
> agent-browser-socket:/run/user/1000/gnupg/d.7e941cr5w3kz9fjxqp48yqfe/S.gpg-> agent.browser
> agent-socket:/run/user/1000/gnupg/d.7e941cr5w3kz9fjxqp48yqfe/S.gpg-agent
> homedir:/tmp/tmp.gQzeYPoncU
$ GNUPGHOME=. gpg --import key.asc
> GNUPGHOME=.
> --homedir /tmp/tmp.vC3JfJwgpM --use-standard-socket --daemon
> dirmngr-socket:/run/user/1000/gnupg/d.qsn8stftdyd1o57odsjuedkc/S.dirmngr
> agent-ssh-socket:/run/user/1000/gnupg/d.qsn8stftdyd1o57odsjuedkc/S.gpg-agent.ssh
> agent-extra-socket:/run/user/1000/gnupg/d.qsn8stftdyd1o57odsjuedkc/S.gpg-agent.extra
> agent-browser-socket:/run/user/1000/gnupg/d.qsn8stftdyd1o57odsjuedkc/S.gpg-agent.browser
> agent-socket:/run/user/1000/gnupg/d.qsn8stftdyd1o57odsjuedkc/S.gpg-agent
> homedir:/tmp/tmp.vC3JfJwgpM
$ gpg --homedir . --import key.asc
> GNUPGHOME=
> --homedir /tmp/tmp.M2QRZOmkxv --use-standard-socket --daemon
> dirmngr-socket:/run/user/1000/gnupg/S.dirmngr
> agent-ssh-socket:/run/user/1000/gnupg/S.gpg-agent.ssh
> agent-extra-socket:/run/user/1000/gnupg/S.gpg-agent.extra
> agent-browser-socket:/run/user/1000/gnupg/S.gpg-agent.browser
> agent-socket:/run/user/1000/gnupg/S.gpg-agent
> homedir:/home/user/.gnupg

The last one is quite problematic as the homedir on the command line and CWD changed, but gpgconf reports the default homedir and GNUPGHOME reports emtpy.

What happens when I try to list secret with the default homedir:

$ gpg -K
> GNUPGHOME=
> --homedir /home/user/.gnupg --use-standard-socket --daemon
> dirmngr-socket:/run/user/1000/gnupg/S.dirmngr
> agent-ssh-socket:/run/user/1000/gnupg/S.gpg-agent.ssh
> agent-extra-socket:/run/user/1000/gnupg/S.gpg-agent.extra
> agent-browser-socket:/run/user/1000/gnupg/S.gpg-agent.browser
> agent-socket:/run/user/1000/gnupg/S.gpg-agent
> homedir:/home/user/.gnupg

From my tests, --homedir is always passed. I finished with the gpg-agent-placeholder like this:

#!/bin/sh
set -euo pipefail

# prevent starting real gpg-agent locally if it's redirected via split-gpg2
if [ -e /run/qubes-service/split-gpg2-client ]; then
    case "$@" in
        *"--homedir $HOME/.gnupg "*)
            exit 0
            ;;
    esac
    # Another option
    #if printf '%s\n' "$@" | grep -q -- "--homedir $HOME/.gnupg "; then
    #  exit 0
    #fi
fi

# otherwise, launch gpg-agent
gpgagent="$(gpgconf --list-components | awk -F: '/^gpg-agent:/{print $3}')"
exec "$gpgagent" "$@"

ben-grande added a commit to ben-grande/qubes-app-linux-split-gpg2 that referenced this issue Oct 29, 2024
@ben-grande
Copy link
Author

PR submitted.

@ben-grande ben-grande changed the title split-gpg2 client exits non-zero when importing public keys split-gpg2 client exits non-zero when importing public keys on alternate gpg homedir Oct 29, 2024
@andrewdavidwong andrewdavidwong added diagnosed Technical diagnosis has been performed (see issue comments). pr submitted A pull request has been submitted for this issue. and removed needs diagnosis Requires technical diagnosis from developer. Replace with "diagnosed" or remove if otherwise closed. labels Oct 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects-4.2 This issue affects Qubes OS 4.2. C: split-gpg2 split-gpg version 2 diagnosed Technical diagnosis has been performed (see issue comments). P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. pr submitted A pull request has been submitted for this issue. T: bug Type: bug report. A problem or defect resulting in unintended behavior in something that exists.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants