Delphi XE + Indy 10.6.2.0:TLS v1.2 在 IdSMTP.Connect 上挂起;

And*_*bel 1 delphi indy indy10 delphi-xe

当尝试使用 TLS v1.2 方法并使用端口 465 连接到 SMTP 服务器时,我的程序无限挂起。我在 mail.org 上创建了一个测试邮件帐户(TLS 1.2 强制)并尝试使用提供的数据。

环境:Delphi XE、Indy 10.6.2、OpenSSL 1.0.2u 程序文件夹中的DLL 文件。

源代码:

try
   IdSMTPReport.IOHandler := FormMain.IdSSLIOHandlerSocketMail;
   IdSMTPReport.UseTLS := utUseExplicitTLS;
   IdSSLIOHandlerSocketMail.SSLOptions.Method := sslvTLSv1_2;

   IdSMTPReport.Host := ###;
   IdSMTPReport.Username := ###;
   IdSMTPReport.Password := ###;
   IdSMTPReport.Port := 465;

   IdMessageReport.ContentType := 'text/plain; charset=UTF-8';
   IdMessageReport.Sender.Address := IdMessageReport.From.Address;
   IdMessageReport.Sender.Name := IdMessageReport.From.Name;
   IdMessageReport.Recipients.Clear;
   IdMessageReport.Recipients.EMailAddresses := ###;
   IdMessageReport.Subject := 'Test';
   IdMessageReport.Body.Clear;
   IdMessageReport.Body := MailReport;
   IdSMTPReport.Connect;
   IdSMTPReport.Send(IdMessageReport);
   IdSMTPReport.Disconnect;
except
   try
      IdSMTPReport.Disconnect;
   except
   end;
end;
Run Code Online (Sandbox Code Playgroud)

对象检查器中的 IdSSLIOHandlerSocketMail 设置

图像

它在将任何状态文本/信息消息发送到OnStatus/OnStatusInfo事件之前挂起。

SMTP 服务器使用给定的凭据可以正常工作。如果我尝试使用 TLS 1.2 和端口 587 的另一台服务器(1und1,德国 ISP),它工作正常。如果我更改为端口 465,则 10000 毫秒的超时(即使具有更高的超时)会生效,但不会发送邮件:

状态信息:

try
   IdSMTPReport.IOHandler := FormMain.IdSSLIOHandlerSocketMail;
   IdSMTPReport.UseTLS := utUseExplicitTLS;
   IdSSLIOHandlerSocketMail.SSLOptions.Method := sslvTLSv1_2;

   IdSMTPReport.Host := ###;
   IdSMTPReport.Username := ###;
   IdSMTPReport.Password := ###;
   IdSMTPReport.Port := 465;

   IdMessageReport.ContentType := 'text/plain; charset=UTF-8';
   IdMessageReport.Sender.Address := IdMessageReport.From.Address;
   IdMessageReport.Sender.Name := IdMessageReport.From.Name;
   IdMessageReport.Recipients.Clear;
   IdMessageReport.Recipients.EMailAddresses := ###;
   IdMessageReport.Subject := 'Test';
   IdMessageReport.Body.Clear;
   IdMessageReport.Body := MailReport;
   IdSMTPReport.Connect;
   IdSMTPReport.Send(IdMessageReport);
   IdSMTPReport.Disconnect;
except
   try
      IdSMTPReport.Disconnect;
   except
   end;
end;
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Rem*_*eau 6

您正在将该TIdSMTP.UseTLS属性设置为utUseExplicitTLS。这意味着TIdSMTP将以最初未加密的状态连接到服务器,读取服务器的问候语和功能,然后发送命令STARTTLS以请求发送 TLS 握手的权限以启动新的加密会话。

但是,端口 465 是 SMTP 的隐式TLS 端口。这意味着服务器将期望客户端在连接后立即执行 TLS 握手,然后再交换任何 SMTP 数据,包括服务器的问候语。

因此,由于使用了错误的配置,您陷入了第 22 条军规的境地。通过使用utUseExplicitTLS,TIdSMTP正在等待服务器未加密的问候语。但是,通过使用端口 465,服务器正在等待客户端的 TLS 握手。因此双方都没有满足另一方的等待条件,因此超时。

SMTP 的显式TLS 端口是 587。所以,你需要:

  • utUseImplicitTLS在端口 465 上使用。

  • utUseExplicitTLS在端口 587 上使用。

除非服务器配置不同。