curl: (94) 身份验证函数在尝试执行 SMTP 诊断时返回错误

curl: (94) An authentication function returned an error when trying to perform SMTP diagnostics

我正在尝试使用 curl 执行 SMTP 诊断并收到此错误:“curl:(94) 身份验证功能 returned 一个错误”。谷歌搜索此错误并 return 除了一般错误列表和描述之外。

我在 Windows 10 上使用 Git 附带的 curl 客户端,并且已经在 Gitbash 和普通命令行中尝试了 运行。邮件服务器是海外总部的企业服务器,我们无法轻松访问配置或日志。它确实需要 SSL/TLS 进行连接。

我能够使用下面附加的 Powershell 脚本成功发送电子邮件。

卷曲错误:

$ curl -v smtp://mymailserver.com:587 --mail-from me@mydomain.com --mail-rcpt me@mydomain.com --user 'me@mydomain.com:mypassword'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying <obfuscarted-ip-address>:587...
* Connected to mymailserver.com (<obfuscarted-ip-address>) port 587 (#0)
< 220 <mymailserver.com> Microsoft ESMTP MAIL Service ready at Tue, 8 Mar 2022 08:12:55 +0100
> EHLO <mycomputername>
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0< 250-<mymailserver.com> Hello [<obfuscarted-ip-address>]
< 250-SIZE 20971520
< 250-PIPELINING
< 250-DSN
< 250-ENHANCEDSTATUSCODES
< 250-STARTTLS
< 250-AUTH GSSAPI NTLM
< 250-8BITMIME
< 250-BINARYMIME
< 250 CHUNKING
> AUTH GSSAPI
< 334 GSSAPI supported
  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0
* Closing connection 0
curl: (94) An authentication function returned an error

正在尝试使用 --ssl:

$ curl -v --ssl smtp://mymailserver:587 --mail-from me@mydomain.com --mail-rcpt me@mydomain.com --user 'me@mydomain.com:password'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying <ip>...
* Connected to mymailserver (<ip>) port 587 (#0)
< 220 mymailserver Microsoft ESMTP MAIL Service ready at Sat, 12 Mar 2022 01:14:23 +0100
> EHLO <pc>
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0< 250-mymailserver Hello [<ip>]
< 250-SIZE 20971520
< 250-PIPELINING
< 250-DSN
< 250-ENHANCEDSTATUSCODES
< 250-STARTTLS
< 250-AUTH GSSAPI NTLM
< 250-8BITMIME
< 250-BINARYMIME
< 250 CHUNKING
> STARTTLS
< 220 2.0.0 SMTP server ready
*  CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
*  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [85 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2933 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [365 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [102 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* Server certificate:
*  subject: C=<obfuscated>; ST=<obfuscated>; L=<obfuscated>; O=<obfuscated>; CN=<obfuscated>
*  start date: May 16 06:40:30 2021 GMT
*  expire date: Jun 17 06:40:30 2022 GMT
*  subjectAltName: host "<obfuscated>" matched cert's "<obfuscated>"
*  issuer: C=<obfuscated>; O=<obfuscated>; CN=<obfuscated>
*  SSL certificate verify ok.
} [5 bytes data]
> EHLO <obfuscated>
{ [5 bytes data]
< 250-mymailserver Hello [<ip>]
< 250-SIZE 20971520
< 250-PIPELINING
< 250-DSN
< 250-ENHANCEDSTATUSCODES
< 250-AUTH GSSAPI NTLM LOGIN
< 250-8BITMIME
< 250-BINARYMIME
< 250 CHUNKING
} [5 bytes data]
> AUTH GSSAPI
  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0{ [5 bytes data]
< 334 GSSAPI supported
  0     0    0     0    0     0      0      0 --:--:--  0:00:04 --:--:--     0
* Closing connection 0
} [5 bytes data]
* TLSv1.2 (OUT), TLS alert, close notify (256):
} [2 bytes data]
curl: (94) An authentication function returned an error

尝试使用 smtps 而不是 smtp:

$ curl -v smtps://mymailserver.com:587 --mail-from me@mydomain.com --mail-rcpt me@mydomain.com --user 'me@mydomain.com:password'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying <ip>:587...
* Connected to mymailserver.com (<ip>) port 587 (#0)
*  CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
*  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* error:1408F10B:SSL routines:ssl3_get_record:wrong version number
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Closing connection 0
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number

卷曲版本:

$ curl --version
curl 7.80.0 (x86_64-w64-mingw32) libcurl/7.80.0 OpenSSL/1.1.1l (Schannel) zlib/1.2.11 brotli/1.0.9 zstd/1.5.0 libidn2/2.3.1 libssh2/1.10.0 nghttp2/1.45.1
Release-Date: 2021-11-10
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL SSPI TLS-SRP zstd

与上面的 curl 命令不同,这个 powershell 脚本确实有效:

$Username = "me@mydomain.com";
$Password = "mypassword";

function Send-ToEmail([string]$email, [string]$attachmentpath){

    $message = new-object Net.Mail.MailMessage;
    $message.From = "me@mydomain.com";
    $message.To.Add($email);
    $message.Subject = "test";
    $message.Body = "body";

    $smtp = new-object Net.Mail.SmtpClient("mymailserver.com", "587");
    $smtp.EnableSSL = $true;
    $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
    $smtp.send($message);
    write-host "Mail Sent" ; 
 }
Send-ToEmail  -email "me@mydomain.com";

我对curl的SMTP特性不是很熟悉,但是对SMTP还是比较了解的。 curl 显然无法验证。我没有找到关于它支持哪些身份验证机制的文档,但 GSSAPI 似乎不是其中之一(至少不是您指定的选项)。 (我对 GSSAPI 也一无所知。)

我猜想出了什么问题是您没有将 TLS 与 curl 一起使用(STARTTLS 仍被列为受支持的扩展之一)。一旦启用 TLS,我从 this documentation is that you should either specify --ssl or --ssl-reqd, or change smtp to smtps (smtps://mymailserver.com), which switches from Explicit TLS to Implicit TLS. The list of supported authentication mechanisms often changes 中获取的内容可能会包括 PLAIN

感谢 Kaspar Etter 让我思考解决这个问题的正确途径。还有这个 post 用于建议“-T -”标志:https://bugzilla.redhat.com/show_bug.cgi?id=1502108.

关键是要求它使用 NTLM 而不是 GSSAPI 进行身份验证。线索是当服务器回复支持的身份验证方法时:

< 250-AUTH GSSAPI NTLM LOGIN

通过添加 --ntlm 选项,curl 将使用 NTLM 而不是 GSSAPI。还要感谢 post 提到不支持 GSSAPI:https://github.com/nextcloud/user_external/issues/153

同时按照 Kaspar Etter 的建议添加 --ssl 标志是关键的一步。

修复 GSSAPI 错误后,我在 curl 发送 VRFY 命令时遇到问题,可以使用奇怪的“-T -”选项修复。

所以最终的工作命令是:

$ curl -v --ssl smtp://mymailserver.com:587 --mail-from me@domain.com --mail-rcpt me@domain.com --user 'me@domain.com:password' --upload-file c:\temp\email.txt --ntlm -T -