From fc300fd811e56407d329a895e91e9dd84ca84297 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 3 Jan 2021 19:39:08 +0100 Subject: [PATCH] Set authentication id for the SASL EXTERNAL mechanism The SASL library will refuse to use the EXTERNAL module when no auth id is set a priori. Tested to work with Dovecot, using TLS client certificates for authentication. --- src/drv_imap.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/drv_imap.c b/src/drv_imap.c index 574f7cf..8d7c99b 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -2273,6 +2273,7 @@ imap_open_store_authenticate2( imap_store_t *ctx ) #ifdef HAVE_LIBSASL const char *saslavail; char saslmechs[1024], *saslend = saslmechs; + int want_external = 0; #endif // Ensure that there are no leftovers from previous runs. This is needed in case @@ -2308,6 +2309,9 @@ imap_open_store_authenticate2( imap_store_t *ctx ) *saslend++ = ' '; memcpy( saslend, cmech->string, len + 1 ); saslend += len; + + if (!strcasecmp( cmech->string, "EXTERNAL" )) + want_external = 1; #endif } } @@ -2343,6 +2347,18 @@ imap_open_store_authenticate2( imap_store_t *ctx ) goto bail; } + // The built-in EXTERNAL mechanism wants the authentication id to be set + // even before instantiation; consequently it won't prompt for it, either. + // While this clearly makes sense on the server side, it arguably does not + // on the client side. Ah, well ... + if (want_external && ensure_user( srvc )) { + rc = sasl_setprop( ctx->sasl, SASL_AUTH_EXTERNAL, srvc->user ); + if (rc != SASL_OK ) { + error( "Error setting SASL authentication id: %s\n", sasl_errdetail( ctx->sasl ) ); + goto bail; + } + } + rc = sasl_client_start( ctx->sasl, saslmechs + 1, &interact, CAP(SASLIR) ? &out : NULL, &out_len, &gotmech ); if (rc == SASL_NOMECH) goto notsasl;