Hi,
My snap package wants to encrypt some data during «a hook» plug/slot connection. I know that «within snapcraft.yaml» you have to stage your hooks to get an environment, and it works perfectly with e.g uuid
etc. But…
To be simple;
I want to
- generate a key
- sign a file, and
- share a key,
- share a file
upon connection. It’s not important who,when, why, but a valid signature is is crucial to ensure that the connecting app doesn’t change.
However, I’ve tried to stage my «prepare» hook w/stage packages (gpg, gpg-client), but I’m still getting «/usr/bin/gpg-agent» = “Not found”.
If I log in to the running daemon (snap run --shell
), I can see that which gpg
and gpg-agent
shows $SNAP/usr/bin/gpg
and $SNAP/usr/bin/gpg-agent
. If I execute $SNAP/usr/bin/gpg-agent
- I’ll get gpg-agent[3326939]: gpg-agent running and available
Will I have to change to OpenSSL for this matter or can I use GPG?
You can try to use the Layouts snap feature to map certain paths to the location the program is expected to be in.
I don’t think that will help, as the location exist.
Running the following in the hook (preprare-slot-<name>
)
which gpg-agent
gpg-agent
$SNAP/usr/bin/gpg-agent
returns
/snap/<name>/x1/usr/bin/gpg-agent
gpg-agent[3771720]: no gpg-agent running in this session
gpg-agent[3771721]: no gpg-agent running in this session
So the it seems to exist, but it doesn’t run. (Note that it is running if I snap run --shell
).
I managed to solve this by creating a script that checks if the plug is set when the daemon starts, and then generate a GPG-key, which is OK as the plug requires a restart of the daemon anyway.
But I don’t understand what is missing (e.g en env.var) for it to run under a prepare-hook.
Do you need additional interfaces for the hook when it creates the key? What interfaces does your daemon use when it runs? Also note that hooks always run as root, not sure if that is relevant for your use case as well or not
Do you need additional interfaces for the hook when it creates the key?
Not that I’m aware of.
What interfaces does your daemon use when it runs?
- bluez
- network
- network-bind
- raw-usb
- physical-memory-control
Also note that hooks always run as root, not sure if that is relevant for your use case as well or not
I know, but that’s fine as the daemon also runs as root. 
Just out of curiosity; Tried setting the same plugs for the hook - without success.
So I’ve done some further investigations. It turns out that gpg-agent needs network
+ network-bind
plugs.
I moved the code to an post-refresh hook, as it’s easier to debug. It hangs on
Run post-refresh hook of "test-snap" snap if present
While it’s hanging on that hook, I’m able to shell into the daemon.
sudo snap run --shell test-snap.daemon
now issuing the command gpg --list-keys
outputs the newly generated key.
However the only way to end the «refresh» routine is to terminate the process (CTRL+C
) and the snap will roll back to the previous version.
This is the whole script
#!/usr/bin/env -S bash -ex
UUID_FILE="${SNAP_DATA}/.install-id"
if ! [[ -f "${UUID_FILE}" ]]; then
echo "Generate UUID"
uuid > "${UUID_FILE}"
echo "UUID `cat ${UUID_FILE}`"
fi
UUID=`cat "${UUID_FILE}"`
echo "UUID: ${UUID}"
KEY=`gpg --armor --export "${UUID}"`
echo "KEY: $KEY"
if [ -z "${KEY}" ]; then
gpg-agent --daemon &
gpg --batch --gen-key <<< "%no-protection
Key-Type: DSA
Key-Length: 2048
Name-Real: ${UUID}
Expire-Date: 0"
fi
KEY=`gpg --armor --export "${UUID}"`
echo "KEY: $KEY"
exit 0
I think the issue you are seeing with hanging is that you have a gpg-agent --daemon &
which forks, and snapd when running the hook will block waiting for that process to exit, so if you save the pid that is created when you start the agent in daemon mode, and kill it after the script is done, it should exit automatically.
Hi,
Maybe. But it hangs even if I exit 1
(with set -e
). It seems like nothing is executed after the gpg-agent --daemon
command.
However, I just found out that the following worked:
gpg-agent --server
gpg-agent --daemon
Why - I don’t understand.