SMTP authentication does not fall back to AUTH LOGIN after another advertised mechanism returns 535
I did this
I am testing SMTP authentication against a server which advertises:
250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5 GSSAPI 250-STARTTLS
The server accepts my username/password using AUTH LOGIN.
I can reproduce a successful authentication with another SMTP client. The relevant SMTP exchange is:
C: EHLO DESKTOP-8QF1ECR S: 250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5 GSSAPI S: 250-STARTTLS
C: AUTH GSSAPI ... S: 535 5.7.8 Authentication credentials invalid
C: AUTH LOGIN S: 334 UGFzc3dvcmQ6
C: S: 235 2.0.0 Authentication successful
The same credentials therefore successfully authenticate with AUTH LOGIN.
With curl 8.13.0 on Windows, however, curl selects another authentication mechanism. For example:
curl 8.13.0 (Windows) libcurl/8.13.0 Schannel zlib/1.3.1 WinIDN
The server advertises the same mechanisms, but curl attempts AUTH PLAIN / CRAM-MD5 / DIGEST-MD5 depending on the negotiation and stops when the server returns:
535 5.7.8 Authentication credentials invalid
Curl then exits with:
curl: (67) Login denied
It does not attempt AUTH LOGIN afterwards.
I expected the following
For comparison, the other SMTP client continues after the 535 response and successfully authenticates using AUTH LOGIN.
I understand from issue #7156 that curl intentionally does not fall back to another authentication mechanism after a server reports an authentication failure, partly because repeated authentication attempts could lock an account.
However, this creates a practical interoperability problem when a server advertises several mechanisms but accepts the credentials only for one of them.
Would it be possible to provide an explicit opt-in mechanism allowing the caller to specify an ordered authentication fallback, for example:
AUTH=GSSAPI;AUTH=LOGIN
or perhaps:
--login-options "AUTH=GSSAPI,LOGIN"
with semantics such as:
GSSAPI -> 535 -> LOGIN -> authentication successful
The important point would be that fallback is explicitly requested by the caller, rather than being automatic.
This would avoid the security concern of silently retrying credentials against multiple mechanisms while still allowing applications to deal with SMTP servers exhibiting this behavior.
As a workaround, I can explicitly force:
--login-options "AUTH=LOGIN"
which works with this server.
When explicitly requested, curl could try the mechanisms in the caller-specified order and continue to the next mechanism when an authentication mechanism is rejected.
curl/libcurl version
curl 8.13.0 (Windows) libcurl 8.13.0
operating system
Windows
Source: curl/curl