User authentication

User authentication is among common awkward things about computing: there's a lot of incompatible methods, and every user has to deal with those.

There is plenty of APIs (SASL, GSSAPI, etc), specialised protocols (Kerberos, RADIUS, SRP, etc), protocols that can be used for that (e.g., TLS, SSH, IPsec), occasional additional authentication (sudo), various protocol-specific ones, and people keep making custom ones (that's most popular on the web, I guess). It's nice that there is a choice, and a vulnerability in one protocol (or in its commonly used implementation) wouldn't compromise about everything, but it's also quite a mess.

Users can't remember and enter all the passwords all the time (be that for password-based authentication or for encrypted keys), so for them there are netrc and secret service API, with the former taking bits of private data for search (as does that newer pass thing), and the latter being another bloated and awkward dbus-based freedesktop thing. There also are ssh-agent and gpg-agent, just encrypted (or plain text in many cases, I guess) files, various password managers (which may or may not use the standard methods), rather esoteric things like plan 9's factotum, and weird custom stuff around the web again (in-browser password managers, web-based ones, cookies, etc).

This is without counting distributed systems, access delegation, multi-factor authentication, and use of multiple devices with synchronisation of credentials between them.

I don't see any apparent and realistic solution without drawbacks to this: choosing key-based authentication over password-based one whenever possible should be helpful, and it's both secure and handy, but that's the same thing I thought of a while ago, and it doesn't seem to help that much even for personal use and when you control both server and client: even when protocols support that, software doesn't, or at least it's rather painful to set.

Update (2018-01-05): After recent Meltdown and Spectre attacks, it seems rather important to use at least something like SCRAM with passwords stored in a hashing scheme specific to an authentication mechanism, even with mandatory TLS (end-to-end encryption and dedicated hardware would also help, but those are not about user authentication). It's pretty easy to set with a regular dovecot + postfix setup (where postfix uses dovecot's SASL), similar to dovecot's CRAM-MD5 HowTo. Just don't forget to set the password database file owner to dovecot, to set userdb, and to generate hashes with doveadm pw -s scram-sha-1. E.g.:

auth_mechanisms = scram-sha-1

passdb { 
  driver = passwd-file
  args = scheme=scram-sha-1 /etc/dovecot/scram-sha-1.pwd

userdb {
  driver = passwd

Though the best emacs's smtpmail library can do is CRAM-MD5, so there's that, or using a local MTA for this, or perhaps hacking smtpmail.el to use sasl.el. And in general, as mentioned above, software support for these things is incomplete and awkward. Here's a bit of configuration that I've added into the default postfix configuration on CentOS to relay messages through a remote server (though a password is stored in plain text locally with this setup):

# http://www.postfix.org/SASL_README.html#client_sasl
smtp_sasl_auth_enable = yes
smtp_tls_security_level = encrypt
smtp_sasl_tls_security_options = noanonymous
relayhost = [uberspace.net]
# Alternative form:
# relayhost = [mail.isp.example]:submission
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

And mbsync supports SCRAM-SHA-1 on its own.

Though a better approach may be to just use doveadm-sync, synchronizing mail over SSH; it appears to drop the SSH_AUTH_SOCK environment variable (used by ssh-agent) here, but here's a workaround:

doveadm sync sh -c "SSH_AUTH_SOCK=$SSH_AUTH_SOCK ssh uberspace.net doveadm dsync-server"

Sending can be organized in a similar way (e.g., ssh host sendmail instead of sendmail), eliminating all the mail-specific authentication.