(kubuntu, but trying to remain platform independent in my approaches.)
Either of conceptual explanations or necessary steps are appreciated.
I'm reading through the documentation, and tried to get gpg-agent to work once, but am getting discouraged as each attempt will require a reboot, and I don't really understand how it works in the first place (just cutting and pasting code).
I want to use gpg-agent so that I can try out GNUS without entering passphrase on .authinfo.gpg every time I open GNUS.
I'd like to understand more about the process before I dig into the problem more.
Is a gpg --gen-key necessary before using gpg-agent for .authinfo.gpg?
Are the config lines mentioning SSH necessary for my minimal use of gpg?
Is .authinfo.gpg to take position on some keychain? Does that keychain itself need a master key?
Please correct me on the imagined flow of the process. (Is an absent key needed?). I regret that it is very sparse.
After boot, initialization turns on the gpg daemon, and other related settings are made.
When GNUS accesses .authinfo.gpg, it caches something with gpg-agent.
Here are some more details I consider.
The following variables are set
GPG_AGENT_INFO ${HOME}/.gpg-agent-info
GPG_TTY $(TTY)
In ~/.gnupg/gpg.conf, we need to see use-agent. I leave the dummy #default-key ******** commented out, as I believe it's only needed if you have more than one key.
In ~/.gnupg/gpg-agent.conf, we need to see
pinentry-program /usr/bin/pinentry-qt4
no-grab
default-cache-ttl 1800
(Though, pinentry-qt4 might be replaced with other present versions, such as pinentry-curses.)
There may be some redundancies, but I've also seen lines for I assume .bashrc, such as eval $(gpg-agent --daemon), or
gpg-agent --daemon \
--write-env-file "${HOME}/.gpg-agent-info"
(I've omitted lines regarding SSH, as I assume I don't need this for now.)
I've seen a troubleshooting command
echo "test" | gpg -ase -r 0xMYKEYID | gpg
but since I wasn't sure if I needed a key in the first place, I didn't go further with this.
Here is my very amateur tutorial in reply to my own question.
To check if gpg-agent is already enabled, try
ps aux | grep gpg
I find
iam#heeere:/e$ ps aux | grep gpg
iam 1490 0.0 0.0 16728 900 ? Ss 17:25 0:00 gpg-agent --daemon --sh
iam 2611 0.0 0.0 11748 912 pts/0 S+ 17:33 0:00 grep --color=auto gpg
This together with
(setq epg-gpg-program "/usr/bin/gpg2")
seemed to solve my problem. As Jens Erat pointed out, gpg-agent is associated with gpg2, not gpg.
In fact, I deleted all the modifications I had made from
GnuPG and EasyPG Assistant Configuration - Emacs auth-source Library,
and it still worked perfectly. That is, no eval $(gpg-agent --daemon), no gpg-agent.conf needed. Though, I may add some back, for instance default-cache-ttl. And while pinentry-curses looks appealing, I think greater minds than mine have struggled with preventing gpg-agent using pop-up from Emacs, so I'll leave that alone.
Related
I am writing a bash script on a machine without expect.
The script automates the build of a helm (v2.9.1) chart.
I've got to the part in the script where it runs a
helm package --sign --key 'mykey' --keyring 'path/to/keyring' -d chartdir chart
and because helm prompts for the passphrase of the gpg key I created in order to use provenance files (a requirement), I cannot script around the soliciting of the passphrase, which I would like to prompt for separately as the script is part of a CI/CD build chain.
I have tried using
yes $promptedPassPhrase | helm package --sign...
and I got
xrealloc: cannot allocate 18446744071562067968 bytes (237568 bytes allocated)
I also tried plain old
echo $promptedPassPhrase | helm package --sign...
and I got
Error: inappropriate ioctl for device
I also tried script and got the same response. As I do not have expect on the server, I cannot expect my way round it, so I'm stumped as to how to automate the helm package command and am not going to use a key without a passphrase as it is bad practice.
I don't know how long this has been the case, or exactly which versions this works on, but this doc page says:
If your PGP private key has a passphrase, [...] You can set the HELM_KEY_PASSPHRASE environment variable to that passphrase in case you don't want to be prompted to enter the passphrase.
This works for me on v2.13.1. It looks like it was added in October of 2018, so my guess is that it was first available in v2.12.0-rc.1.
Although this doesn't directly answer the OP's question (since they asked about v2.9.1), it will hopefully help anyone who ends up here because they (like me the first time round) missed that line in the doc.
I do sign commits with git, and it's a big problem that I can't enter gpg key passphprase from anywhere except CLI. If I'll do commit in vscode for example, it will fail. So I've came up with idea to just simply input passphrase from CLI, and cache it for some period of time.
I'm using fish shell in here so here's a config:
set -x GPG_TTY (tty)
eval (gpg-agent --daemon --allow-preset-passphrase --default-cache-ttl 43200)
As I understand I need to enable to preset the passhprase for the agent. So now what's next?
I've tried to preset a key like this, but it fails:
$ echo mypassphrase | /usr/lib/gnupg2/gpg-preset-passphrase -c E2AB66331DA5CA780B7B1FA5D4BF11DA1E39EDFF
gpg-preset-passphrase: caching passphrase failed: Not supported
I've googled everything I could, but no one is answering this question anywhere. Would be nice to have something like ssh-add, you just add a private key, and enter password, wonder why gpg-agent haven't adopted this nice design.
Seems to be solved. There's a need to add couple of things to ~/.gnupg/gpg-agent.conf:
default-cache-ttl 46000
pinentry-program /usr/bin/pinentry-gtk-2
allow-preset-passphrase
Reload gpg-agent
gpg-connect-agent reloadagent /bye
I'm automating my Docker installation. Something like this:
if apt-key fingerprint 0EBFCD88 | grep "Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88" > /dev/null
then
# proceed
fi
This worked fine in older versions of apt-key, but recent versions have two issues:
A different output format: I can hack around that
A warning:
Warning: apt-key output should not be parsed (stdout is not a terminal)
Clearly, I can hack around this as well, just redirect stderr to /dev/null. It just made me curious:
How do these fine folks suggest I verify my key fingerprints? Or am I getting this fundamentally wrong by wanting to automate it, does that defeat the point? (I think not, since I still manually lifted the expected fingerprint from the website, but feel free to tell me otherwise...)
From apt-key sources, you can set APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE to a non-empty value to disable this warning.
You can also use "grep -q" so you don't need to redirect stdout in /dev/null either.
To reply to the part "am I getting this fundamentally wrong":
I believe that possibly yes. That's the reason of the warning.
You don't write what you do exactly, but one thing to realize is:
The keys do have some expiration so after some time the fingerprint in your script will become obsolete and possibly it will not behave as expected anymore.
Once the repository and its key is installed so the system somehow upgrades the key automatically but when the repository is initially added so an up-to-date key has to be provided. In my scripts automating the installation I do not test whether a key was already added but I test whether the repository was already added. If the repository was not added, so I add it together with an up-to-date key that I download always from its URL.
I'm modifying the command itself to use batch mode so it will not complain about stdout. For the bigger apt-key this will work, quickly tested on debian:
sed -i "s%{GPG_EXE}\")' --%{GPG_EXE}\")' --batch --%g" /usr/bin/apt-key
While for the smaller apt-key this could work (untested as I can't recall exactly where I have seen this simpler variant):
sed -i 's%GPG_CMD="gpg %GPG_CMD="gpg --batch %g' /usr/bin/apt-key
You need privileges to write to the /usr/bin/apt-key so either run as root or use sudo
This works
apt-key exportall > test.key 2>/dev/null
or
apt-key exportall 2>&1 | grep -v '^Warning' > test.key
Say there's an encrypted file file.txt
In order to update its content the file must be decrypted first, then run through the desired processing and afterwards it must be encrypted again.
(1) What would be the most straight forward way to do so in bash scripting using gpg2? The operation should request the user only once for a password to decrypt. It should use the same password for the final encryption afterwards.
Here is a most likely extremely unsecure, but working example of what I try to archieve:
function update-encrypted-file() {
read pass_tmp;
local pass=$pass_tmp;
unset pass_tmp;
local file="file.txt";
local tmp_result=$(cat $file | gpg2 --batch --passphrase $pass | update);
echo $tmp_result | gpg2 -c --batch --passphrase $pass > $file;
}
whereas update might be sth. like this: alias update="tr -d X" (delete all X's)
(2) What exactly could make the above example insecure? I guess using read itself is a no-go, but it would be interesting to see why. Not having the variable set locally causes the password to be inside the global space for some short time. Could that possibly be fetched? I could not figure out how to use pinentry-tty in this case (see this post)
(3) Apart from that, the gpg2 documentation remarks regarding the --passphrase option: "Obviously, this is of very questionable security on a multi-user system. Don't use this option if you can avoid it."
Is this only the case when manually used inside a terminal, since the commands are logged? Or would there also be concerns when using e.g. inside a function with the password having saved in only this function scope.
I'm not answering your individual questions directly, but have a slight discussion of password management and GnuPG, but for the third question: the command line of all processes from all users running on the machine are available to anybody. To confirm, just run a simple ps ax as an unprivileged user. Never pass secrets as parameters!
Obviously, the most secure option will be to never get hold of the passphrase at all. If you don't have it, you can't mess with it. With GnuPG 2.1, this was even applied to the actual GnuPG binary (gpg/gpg2): The most critical secret key operations (involving handling the passphrase) are performed by the small gpg-agent (thus having smaller attack surface), the rather large and complicated GnuPG binary neither gets direcct access to the key nor the passphrase.
This is also what I'd go for: instead of handling the passphrase, rely on gpg-agent doing so instead. It is available (and since GnuPG 2.1, also required) anyway. If configured properly (and this is the default), gpg-agent will cache the passphrase for a while. If the user configured something else, he decided he does not want cached passphrases, which you also should respect with your application.
As soon as required, the gpg-agent will query the user for the passphrase through the configured method -- if you're running a graphical user interface, this will likely be a window popping up.
If you mess with the GnuPG configuration (for example, your own configuration files, starting your own gpg-agent, ...), it's your job of course to take care of this. To start your own instance of gpg-agent to have full control over caching and other options, take advantage of the --options, --homedir and --no-use-standard-socket as required by your individual use case.
Finally, you're storing an intermediate result of the contents, which you echo:
local tmp_result=$(cat $file | gpg2 --batch --passphrase $pass | update);
echo $tmp_result | gpg2 -c --batch --passphrase $pass > $file;
Don't do this for the same reasons discussed for passphrases! Instead, directly pipe the result into the encryption process (and there is no need for cat here):
< $file gpg2 --batch --passphrase $pass | update | gpg2 -c --batch --passphrase $pass > $file;
I have installed msysgit: Git-1.7.8-preview20111206.exe from http://code.google.com/p/msysgit/downloads/list (Edit: I have also installed msysGit-fullinstall-1.7.8-preview20111206.exe, which conveniently installs to a different directory, and I am seeing the same problems with that instance).
And I am having a problem with ssh-agent, where ssh-add always reports: "Could not open a connection to your authentication agent."
Unfortunately, ssh-add does not give me any further details on the error it encountered. It feels like it is timing out when it tries to connect to a socket, but it does not actually admit that this is the issue, and ssh-agent acts like it is running normally. Thinking about this combination makes me suspect a permissions issue, but I have no idea where I would look to investigate that kind of problem (and I do no see anything that I recognize as significant in windows event log).
This error message baffles me: I have reason to believe that I could get this error message if my environmental variables were not set up properly, but I have reason to believe that I have my environmental variables set properly. I have reason to believe that I could get this error message if my environmental variables refer to an instance of ssh-agent which is not running, but I have exactly one instance of ssh-agent running and it matches what I see in the environmental variables. And this is repeatable. I have started (and eventually shut down) dozens of instances of ssh-agent, using techniques like ssh-agent > ~/.ssh/environment; . ~/.ssh/environment, and eval `ssh-agent` and ssh-agent bash and so on... and I cannot get msys ssh-add to connect to msys ssh-agent.
bash-3.1$ ps | grep ssh-agent
10304 1 10304 10304 ? 500 09:01:24 /bin/ssh-agent
bash-3.1$ bash -c 'set | grep SSH_A'
BASH_EXECUTION_STRING='set | grep SSH_A'
SSH_AGENT_PID=10304
SSH_AUTH_SOCK=/tmp/ssh-oAFwa11048/agent.11048
bash-3.1$ time ssh-add -L
Could not open a connection to your authentication agent.
real 0m10.730s
user 0m0.000s
sys 0m0.015s
bash-3.1$ wc /tmp/ssh-oAFwa11048/agent.11048
0 3 52 /tmp/ssh-oAFwa11048/agent.11048
bash-3.1$ cat /tmp/ssh-oAFwa11048/agent.11048; echo
!<socket >59261 060A4541-9831B739-519220DE-57936738
bash-3.1$
I am not concerned with scripting anything, just yet -- I believe that if I can get ssh-add working from the command line that I can script it...
And note also that the 10 seconds of real time that ssh-add uses happens before it issues the "Could not open..." message.
And, I am using a current version of windows 7, here. And, I also have cygwin installed, but it's not in my path when I am using msys. Task manager shows me that I only have one instance of ssh-agent running. The ssh-agent which is running is the msys ssh-agent, and was started from msysgit's bash prompt (without anything from cygwin in path). The ssh key was generated using cygwin's ssh-keygen, but superficial testing shows me that msys ssh utilities have no problem with the file. ssh-agent does not give me any error messages or warnings.
I can use cygwin's ssh-agent, but mixing cygwin and msys introduces other complexities (and you can see some of that just from my description of this issue), and I am trying to get msys working without anything from cygwin.
What do I need to do to find out why the msys ssh-add does not work? (Or: what do I need to do to get that ssh-add to work properly?)
I can't tell you much about the why's and how's, but I can tell you what I tried and what finally solved it.
In git bash:
exec ssh-agent bash
Then (in the changed shell):
ssh-add
That worked to a degree, I only had to type the passphrase once, but I lost the normal look. After some more searching I found a .bashrc script on this Github help page.