Closed mcmeel closed 3 years ago
If you use the gpg
command on your system to sign a file using that same key, what exactly does it output when prompting for the passphrase?
I tried to sign the file that contains the passphrase for example:
gpg --sign .usermin/gnupg/pass.2E3F4FD2
outputs:
You need a passphrase to unlock the secret key for
user: "Test User <testuser@testdomain.com>"
2048-bit RSA key, ID 2E3F4FD2, created 2021-05-05
gpg: cancelled by user
gpg: no default secret key: Operation cancelled
gpg: signing failed: Operation cancelled
I was not prompted for any input, it just output the above.
Was that run via SSH?
Yes, it was run in a shell via SSH as the user that owns the mailbox.
In an attempt to recreate with a different set of conditions I attempted this with Ubuntu 20.04 as the OS and Usermin version 1.823.
It fails still, but differently (of course).
In this case the correct passphrase is stored in ~/.usermin/gpupg/pass.\<key ID> as before, but the error in miniserv.error is:
Error: Failed to sign message : gpg: using "F7D9344DD2C91485B7BF7DE6F91C50BFF2F8C87E" as default secret key for signing
gpg: signing failed
(F7D9344DD2C91485B7BF7DE6F91C50BFF2F8C87E is the key ID)
When attempting to sign a file on the CLI, pinentry-curses prompts me for the passphrase and the signing works properly. A second attempt to send a signed email in Usermin now works properly.
I made the following observations:
There are differences in versions of gpg and pinentry between the two hosts as well.
CentOS gpg/pinentry = 2.0.22/0.8.1
Ubuntu gpg/pinentry = 2.2.19/1.1.0
If I kill the gpg-agent process on the Ubuntu host the mail fails to sign again until I sign again in the shell gpg command and the gpg-agent process starts back up. Killing the gpg-agent process on the CentOS host has no effect on the mail signing or shell gpg command signing.
Interesting, so it looks like when you enter the passphrase, it's being kept in the gpg-agent
so that Usermin's attempt to sign now works.
What if you supply the phrase to the gpg
command with the --passphrase
command line flag?
Short story, I wasn't able to supply the passphrase via the --passphrase command line flag no matter what I tried. When attempting to do so the same error messages were presented.
While looking at why that wasn't working I found information regarding the way pinentry tries to find the tty to prompt for the passphrase. Since this user is an email only type user, they didn't have a valid shell. I was running these commands with a combination of sudo -u directly with gpg, and /bin/bash for an interactive shell. All of these were still using my same tty owned by the user I logged in with.
To get around this I started /bin/bash in screen running as the user which allocated a tty. At this point pinentry prompts me for the passphrase. Once entered gpg signs successfully on the command line, and a gpg-agent process is started. At this point I tried to sign an email in Usermin but it failed with the same error as before, even with the gpg-agent still running.
Digging some more I found to the following command to provide the passphrase to gpg: --passphrase-fd
From the man page:
--passphrase-fd n
Read the passphrase from file descriptor n. If you use 0 for n, the passphrase will be read from stdin. This can only be used if only one passphrase is supplied. Don't use this option if you can avoid it.
--batch
Use batch mode. Never ask, do not allow interactive commands.
Using this I was able to use the ~/.usermin/gnupg/pass.\<key ID> file to sign on the command line without the need for a tty or pinentry by passing the contents of that file to the gpg command on STDIN (combination of --batch and --passphrase-fd 0).
cat ~/.usermin/gnupg/pass.2E3F4FD2 | gpg --batch --passphrase-fd 0 --sign ~/.usermin/gnupg/pass.2E3F4FD2
Although even after success there, Usermin is unable to sign emails using that key with or without the gpg-agent running (same errors are present in usermin.error).
Looking at the command in gnupg-lib.pl that is called as a result of sign_data:
$cmd = "$gpgpath --armor --output $dstfile --default-key $_[2]->{'key'} --detach-sig $srcfile";
I recreated that on the command line, adding --batch and --passphrase-fd 0, and passing the contents of the passphrase file via STDIN and it created a signature.
cat ~/.usermin/gnupg/pass.2E3F4FD2 | gpg --batch --armor --output foo.asc --default-key 2E3F4FD2 --passphrase-fd 0
--detach-sig foo.sh
But then I am lost.
Did that final command with the passphrase being supplied as input work as expected? If so, it seems like I need to update Usermin to use that --passphrase-fd
flag.
Yes, it worked as expected.
Ok, I have implemented fixes for this issue which will be included in the next Usermin release.
When attempting to GPG sign a message with a key that has a passphrase the following error is presented after clicking send:
The key was created using the Usermin GPG setup screen, and a file is present at ~/.usermin/gnupg/ named "pass.\<key ID>" with the correct passphrase. A private key created without a passphrase works without error.
OS: CentOS 7.9.2009 Usermin: 1.823
/var/usermin/miniserv.error: