Integrating password-store with Emacs ∞
Pass might be the perfect password manager.
It's been around for a while. What you might not be aware of how well it
can work with Emacs as a backend for auth-sources.
The classic way of storing your username and password in a way that Emacs can
understand is to maintain a list of credentials in ~/.authinfo{,.gpg}1 or
~/.netrc. This becomes a pain if you use a password manager though, because
now you have to update your password in two places when you change it.
Fortunately there is a library
auth-password-store
that connects auth-source (used by gnus and tramp, among others) with
the Emacs library provided by pass. It's not very well documented at the
moment though, so I'll share my experiences here. Note that these entries in
the password store don't have to be in the root folder. Mine are all in a
directory auth-sources, but you can organise them however you like.
auth-password-store imposes a specific organisation on the files themselves,
apparently based on the
organisation scheme used by the
authors of pass. It looks for the keys host, port, and user. The
password is taken to be the first line in the file. You don't need to specify
port if some port is passed to auth-pass-backend by the program requesting
the secret. For instance, gnus will send port 993 if you've set it up to use
an IMAPS server, and smtp-send-it will use port 587 (only useful if the named
server is also listening on 587).
For use with tramp:
∞
You need a file with the same user@host format that you would supply to
find-file. For instance: /sudo:root@localhost:/etc/file-owned-by-root.
In this case the pass entry will have the form:
$ pass ls auth-sources/root@localhost <password> host: localhost user: root
Even though the it says the user is root, the password here should be your
user's sudo password. In the case of a remote server there's no need to allow
SSH login as root for this to work, your user just needs to have sudo
privileges.
For use with gnus and a local IMAP server:
∞
On my machines I use something like
this,
but with mbsync instead of offlineimap.
You need a file with the same user@host format you would supply to
gnus-select-method. For instance:
(eval-after-load "gnus" '(setq gnus-select-method ;; there should be a pass entry eqyiel@localhost '(nnimap "eqyiel@localhost" (nnimap-address "localhost") (nnimap-stream network))))
In this case the pass entry will have the form:
$ pass ls auth-sources/eqyiel@localhost <password> host: localhost user: eqyiel
If it's not working be sure to check what port you've configured gnus to use
and what port your server is listening on.
For use with gnus and a remote IMAP server:
∞
You need a file with the format user@imap-server. Be sure to use the same
imap-server as the first argument to nnimap. For instance:
(eval-after-load "gnus" '(setq gnus-select-method '(nnimap "rkm.id.au" (nnimap-address "rkm.id.au") (nnimap-server-port 993) (nnimap-stream ssl)) gnus-secondary-select-methods '((nnimap "imap.gmail.com" (nnimap-address "imap.gmail.com") (nnimap-server-port 993) (nnimap-stream ssl)) (nnimap "outlook.office365.com" (nnimap-address "outlook.office365.com") (nnimap-server-port 993) (nnimap-stream ssl)))))
In this case the pass entry will look like this:
$ pass ls auth-sources/eqyiel@imap.gmail.com <password> host: imap.gmail.com user: eqyiel@gmail.com
For use with smtpmail:
∞
You need a file with the format user@smtp-server. Note that the SMTP and IMAP
servers may be running on different hosts. For instance, Microsoft Exchange
uses smtp.office365.com and outlook.office365.com (IMAP), and Google uses
smtp.gmail.com and imap.gmail.com. Fortunately both outlook.office365.com
and imap.google.com listen on port 587 so in this case you don't need to
maintain two files, but if your server is rejecting your mail as unauthenticated
be sure to check this. For an Exchange server (used by my university), the
pass entry will look like this:
$ pass ls auth-sources/mahe0054@outlook.office365.com <password> host: outlook.office365.com user: mahe0054@uni.flinders.edu.au
And for Gmail:
$ pass edit auth-sources/eqyiel@imap.gmail.com <password> host: imap.gmail.com user: eqyiel@gmail.com
If you're using this
advice from emacswiki the smtp-server and
host field must match the third argument to an account in smtp-accounts.
For example:
(defvar smtp-accounts '((ssl "eqyiel@gmail.com" "imap.gmail.com" 587 "eqyiel@gmail.com" nil) (ssl "mahe0054@uni.flinders.edu.au" "outlook.office365.com" 587 "mahe0054@uni.flinders.edu.au" nil)))
It's great being able to manage these all in one place. Now, if only all web services had a standard API for changing passwords!