使用 Rust lettre 库从 Exchange SMTP 获取 "Client was not authenticated to send anonymous mail during MAIL FROM" 错误
Getting "Client was not authenticated to send anonymous mail during MAIL FROM" error from Exchange SMTP using Rust lettre library
我正在编写一个 Rust 应用程序,它将通过启用了 SMTP 功能的 Exchange 服务器发送电子邮件。根据Microsoft's webpage,需要的设置是:
- 服务器地址smtp.office365.com
- 端口 587
- 已启用 StartTLS
- 邮件帐户登录凭据
网络邮件服务的 POP/IMAP 设置证实了这些。
这是我的代码(经过一些审查):
extern crate lettre;
use self::lettre::email::EmailBuilder;
use self::lettre::transport::smtp::{SecurityLevel, SmtpTransportBuilder, SUBMISSION_PORT};
use self::lettre::transport::smtp::authentication::Mechanism;
use self::lettre::transport::EmailTransport;
pub fn send_mail() {
let email = EmailBuilder::new()
.from("my email")
.to("destination email")
.body("testing")
.subject("testing")
.build()
.unwrap();
// Connect to SMTP server
let mut transport = SmtpTransportBuilder::new(("smtp.office365.com", SUBMISSION_PORT))
.expect("Failed to create email transport")
.encrypt()
.smtp_utf8(true)
.credentials("my email", "my password")
.authentication_mechanism(Mechanism::Login)
.build();
println!("Mail transport built");
println!("{:?}", transport.send(email.clone()));
}
当我编译 运行 代码时,它给我这个错误:
Err(Permanent(Response { code: Code { severity:
PermanentNegativeCompletion, category: Unspecified3, detail: 0 },
message: ["5.7.57 SMTP; Client was not authenticated to send anonymous
mail during MAIL FROM [SYXPR01CA0106.ausprd01.prod.outlook.com]"] }))
为什么会这样?
我研究中最接近的问题是 GitHub 与不支持 Login
身份验证机制(Office 365 使用)的字母库相关的问题;但是,代码库已更新以支持 Login
,并且我直接从 GitHub 使用 master 分支,因此理论上我的应用程序应该支持 Login
机制。
编辑:忘记提及我尝试向服务器发送 EHLO,但它返回了一个 (Client:(Connection closed)) 错误。
我使用 telnet 和 openssl 尝试直接连接到我的 SMTP 服务器,我发现 AUTH LOGIN 需要 3 个命令;一个发送 AUTH LOGIN 代码,一个发送用户名,另一个发送密码。我发现 lettre 库将其所有 AUTH 命令实现为单个命令,因此这不适用于服务器。我下载了该库的源代码,更改了发送函数以执行三个单独的命令,重新编译了我的代码,一切正常:)
我对字母代码的补充:
if (accepted_mechanisms[0] == Mechanism::Login) &&
(accepted_mechanisms.capacity() == 1) {
try_smtp!(self.client.command("AUTH LOGIN"), self);
try_smtp!(self.client.command(base64::encode_config(
&username.as_bytes(),
base64::STANDARD).as_str()), self);
try_smtp!(self.client.command(base64::encode_config(
&password.as_bytes(),
base64::STANDARD).as_str()), self);
我正在编写一个 Rust 应用程序,它将通过启用了 SMTP 功能的 Exchange 服务器发送电子邮件。根据Microsoft's webpage,需要的设置是:
- 服务器地址smtp.office365.com
- 端口 587
- 已启用 StartTLS
- 邮件帐户登录凭据
网络邮件服务的 POP/IMAP 设置证实了这些。
这是我的代码(经过一些审查):
extern crate lettre;
use self::lettre::email::EmailBuilder;
use self::lettre::transport::smtp::{SecurityLevel, SmtpTransportBuilder, SUBMISSION_PORT};
use self::lettre::transport::smtp::authentication::Mechanism;
use self::lettre::transport::EmailTransport;
pub fn send_mail() {
let email = EmailBuilder::new()
.from("my email")
.to("destination email")
.body("testing")
.subject("testing")
.build()
.unwrap();
// Connect to SMTP server
let mut transport = SmtpTransportBuilder::new(("smtp.office365.com", SUBMISSION_PORT))
.expect("Failed to create email transport")
.encrypt()
.smtp_utf8(true)
.credentials("my email", "my password")
.authentication_mechanism(Mechanism::Login)
.build();
println!("Mail transport built");
println!("{:?}", transport.send(email.clone()));
}
当我编译 运行 代码时,它给我这个错误:
Err(Permanent(Response { code: Code { severity: PermanentNegativeCompletion, category: Unspecified3, detail: 0 }, message: ["5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM [SYXPR01CA0106.ausprd01.prod.outlook.com]"] }))
为什么会这样?
我研究中最接近的问题是 GitHub 与不支持 Login
身份验证机制(Office 365 使用)的字母库相关的问题;但是,代码库已更新以支持 Login
,并且我直接从 GitHub 使用 master 分支,因此理论上我的应用程序应该支持 Login
机制。
编辑:忘记提及我尝试向服务器发送 EHLO,但它返回了一个 (Client:(Connection closed)) 错误。
我使用 telnet 和 openssl 尝试直接连接到我的 SMTP 服务器,我发现 AUTH LOGIN 需要 3 个命令;一个发送 AUTH LOGIN 代码,一个发送用户名,另一个发送密码。我发现 lettre 库将其所有 AUTH 命令实现为单个命令,因此这不适用于服务器。我下载了该库的源代码,更改了发送函数以执行三个单独的命令,重新编译了我的代码,一切正常:)
我对字母代码的补充:
if (accepted_mechanisms[0] == Mechanism::Login) &&
(accepted_mechanisms.capacity() == 1) {
try_smtp!(self.client.command("AUTH LOGIN"), self);
try_smtp!(self.client.command(base64::encode_config(
&username.as_bytes(),
base64::STANDARD).as_str()), self);
try_smtp!(self.client.command(base64::encode_config(
&password.as_bytes(),
base64::STANDARD).as_str()), self);