I don't like to have username and passwords lying around unencrypted on my hard drive. But I also don't like to have to keep entering in the same information over and over.
A great example of this problem can be found in the Emacs Gnus Mail
Reader. Gnus lets you store your username and password information in
a file called .authinfo
. This way you don't have to enter a
password every time you connect to your news or email servers. Of
course the file isn't encrypted. EasyPG to the rescue. EasyPG allows
you to have any file named *.gpg
and it will then use gpg
to
decrypt the file. One little problem, every time Gnus needs to read
info from the .authinfo
file it prompts for the gpg password. So
although you don't have to remember the passwords for the accounts you
have to keep entering your gpg password. Ugghhh.
One way to fix this is to use gpg-agent
. gpg-agent
is a daemon to
manage gpg private keys independently of any protocol. So with this
you can configure how long to cache an entry (like a passphrase) so
you don't have to enter it again. By default gpg-agent
has a
cache-ttl of 600 seconds. With this working Gnus can read the
encrypted .authinfo file for 5 minutes and only prompts you for a
password on the first read. Pretty sweet.
Of course setting up gpg-agent
on OS X so that it interacts nicely
with GUI apps like Emacs.app as well as command line utilities isn't
perfectly straightforward but hopefully this entry will help.
Getting the software
I'm a big fan of MacPort so I'll use that in the examples. But you could download and compile your self.
sudo port install pinentry +gtk2 gpg-agent gnupg2
You need to add one of the variants to pinentry to get a GUI client that works on OS X. Your choices are: gtk1, gtk2, qt3 or qt4. I used gtk2 because I have other ports that depend on it but you can pick your favorite GUI toolkit. If you don't select a variant you will get a pinentry application that can only be run from a terminal.
Setup Emacs to use EasyPG and gpg-agents
The first step is to get Emacs to use EasyPG on files that end in
.gpg
. More info can be found on the
Emacs Wiki.
Add the following to your Emacs.app start-up file
(require 'epa-file) (epa-file-enable)
Next you need to teach EasyPG to use gpg2
instead of gpg
as the
name of the gpg executable. This is because MacPorts installs the gpg
executable as gpg2
for the gnupg2 port. There is a gnupg port that
installs the gpg
executable but that is version 1.4 and doesn't work
by default with gpg-agent
.
Add the following to your Emacs.app start-up file
(setq epg-gpg-program "gpg2")
Lastly you need to teach Emacs how to talk to gpg-agent
.
Add the following to your Emacs.app start-up file
(setenv "GPG_AGENT_INFO" "~/.gnupg/S.gpg-agent")
Getting gpg-agent to start at Login
Now that Emacs.app is configured to use gpg
and gpg-agent
you have
to configure it so gpg-agent
is started when you login. There are
several ways to do this. I think the easiest and most "Macish" is to
add a new Login Item in the Users Preference Pane. But to do that it
has to be an Application. Luckily, AppleScript makes it easy to make
Applications out of simple scripts.
A script to start gpg-agent
First lets write a simple Bash script to start gpg-agent
#!/bin/bash GPG_AGENT=/opt/local/bin/gpg-agent GPG_ARGS="--daemon --use-standard-socket" GPG_SOCKET="~/.gnupg/S.gpg-agent" if [[ -e ${GPG_SOCKET} ]] then rm ${GPG_SOCKET} fi if [[ -x ${GPG_AGENT} ]] then ${GPG_AGENT} ${GPG_ARGS} fi
Save this to a file named gpg_agent_start.sh
in your bin
directory and make it executable.
chmod 755 ~/bin/gpg_agent_start.sh
Applescript to make an Application
Next start "AppleScriptEditor" it can be found in your
/Applications/Utilities
folder. Make a new script with the
following:
do shell script "~/bin/gpg_agent_start.sh"
And then do a "Save As …", be sure to select "Application" as the File Format and name it "gpg_agent_Application".
Set as Login Item
- Launch System Preferences
- Select Accounts
- Select Login Items
-
Use the "+" to add
gpg_agent_Application
- Close System Preferences
- Logout and back in
You should see gpg-agent
as a running process.
At this point you should be able to open any encrypted file named *.gpg and get prompted for the password with the pinentry application. Then any access to that file in the next 5 minutes won't require entering a password.