diff options
author | Kevin McCarthy <kevin@8t8.us> | 2021-03-05 18:52:48 -0800 |
---|---|---|
committer | Kevin McCarthy <kevin@8t8.us> | 2021-03-08 14:19:06 -0800 |
commit | 191b0513b43d5e603f99292faa5f8ebcc1be3823 (patch) | |
tree | 835573e952f10cc4912cff6b72b518b7f30f3fc1 /mutt_ssl.c | |
parent | fcc6299184208e9a38890979ebb9f1c1356c18eb (diff) |
Fix $ssl_client_cert usage with SMTP.
The ssl and gnutls client-cert setup code was calling
mutt_account_getuser(). This caused two problems. First, it's not
necessarily the case that there will be a username. Second,
populating the user would cause smtp_open() to check for AUTH
capabilities and call smtp_auth - even if the user is already
authenticated by the cert. The server won't advertize AUTH if they
already authenticated, causing a connection abort.
Remove prompt for mutt_account_getuser() in the ssl and gnutls client
certificate connection code. The SASL code has callbacks, so I don't
understand why it would need this. Let's take it out and see if
anyone screams 8-P. If necessary, we can add a mutt_account_getuser()
call to the very beginning of imap_auth_sasl().
Revamp the openssl ssl_passwd_cb() prompt. From the man pages, it
appears to be used for the cert decryption. There's no need to call
mutt_account_getuser() and use the generic mutt_account_getpass() just
to read a password in. Instead create a callback function version to
customize the prompt for a client cert with just the host.
Change the SMTP authentication test to check if the AUTH capabilities
are set, instead of if the user field is set before calling
smtp_auth().
Diffstat (limited to 'mutt_ssl.c')
-rw-r--r-- | mutt_ssl.c | 32 |
1 files changed, 27 insertions, 5 deletions
@@ -1399,22 +1399,44 @@ static void ssl_get_client_cert(sslsockdata *ssldata, CONNECTION *conn) SSL_CTX_use_certificate_file(ssldata->ctx, SslClientCert, SSL_FILETYPE_PEM); SSL_CTX_use_PrivateKey_file(ssldata->ctx, SslClientCert, SSL_FILETYPE_PEM); +#if 0 + /* This interferes with SMTP client-cert authentication that doesn't + * use AUTH EXTERNAL. (see gitlab #336) + * + * The mutt_sasl.c code sets up callbacks to get the login or + * user, and it looks like the Cyrus SASL external code calls + * those. + * + * Brendan doesn't recall if this really was necessary at one time, so + * I'm disabling it. + */ + /* if we are using a client cert, SASL may expect an external auth name */ mutt_account_getuser (&conn->account); +#endif } } +static void client_cert_prompt (char *prompt, size_t prompt_size, ACCOUNT *account) +{ + /* L10N: + When using a $ssl_client_cert, OpenSSL may prompt for the password + to decrypt the cert. %s is the hostname. + */ + snprintf (prompt, prompt_size, _("Password for %s client cert: "), + account->host); +} + static int ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata) { - ACCOUNT *account = (ACCOUNT*)userdata; + ACCOUNT *account; - if (mutt_account_getuser (account)) + if (!buf || size <= 0 || !userdata) return 0; - dprint (2, (debugfile, "ssl_passwd_cb: getting password for %s@%s:%u\n", - account->user, account->host, account->port)); + account = (ACCOUNT *) userdata; - if (mutt_account_getpass (account)) + if (_mutt_account_getpass (account, client_cert_prompt)) return 0; return snprintf(buf, size, "%s", account->pass); |