SSL 协商失败时 TIdSMTP/SSLIOHandler 应触发哪个事件?

问题描述 投票:0回答:1

我想做什么? 使 SSL“隐式/显式”(对于 SMTP)配置透明,并且为了做到这一点,我显然是通过事件触发来做到这一点。

我的想法是捕获 SSL/TLS 协商成功或失败,然后使用其他选项重试。

我在

TIdSMTP
TIdSSLIOHandlerSocketOpenSSL
上看到了一些事件,但它们似乎都没有触发正确性。

Indy 文档也无法在这里下载(DNS 损坏错误)。

我使用以下带有“

Sleep(1);
”的事件只是为了对它们进行断点。

TIdSMTP

OnTLSNotAvailable

OnTLSHandShakeFailed

OnTLSNegCmdFailed

OnFailedEHLO

TIdSSLIOHandlerSocketOpenSSL

OnStatus

OnStatusInfo

OnStatusInfoEx

我测试过的:

我使用 Outlook smtp.office365.com587 端口(在 Indy 中为 STARTTLS -

utUseExplicitTLS
)作为示例,但我故意将
TIdSMTP.UseTLS
更改为
utUseImlicitTLS
以模拟 SSL/TLS 协商失败。

在第一个

TIdSMTP.Connect
中,我得到了
EIdSocketError
异常(“Socket Error # 10060 Connection timed out”),而不是 SSL/TLS 协商失败消息/异常。在本次测试中,唯一触发的事件是
TIdSSLIOHandlerSocketOpenSSL.OnStatus
/
TIdSMTP.OnStatus

在第二次

TIdSMTP.Connect
中,我没有收到带有超时消息的
EIdSocketError
,除了第一次尝试时的事件之外,它还触发了
TIdSSLIOHandlerSocketOpenSSL.OnStatusInfo
TIdSSLIOHandlerSocketOpenSSL.OnStatusInfoEx
事件,处理SSL连接错误。

一些代码片段:

procedure Connect;
var
  LSMTP: TIdSMTP;
  LSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
  LSMTP:= TIdSMTP.Create(nil);
  LSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  
  {functions to be declared}
  LSMTP.OnTLSNotAvailable   := MyTLSNotAvailable;
  LSMTP.OnTLSHandShakeFailed:= MyTLSHandShakeFailed;
  LSMTP.OnTLSNegCmdFailed   := MyTLSNegCmdFailed;
  LSMTP.OnFailedEHLO        := MyFailedEHLO;

  LSSL.OnStatus      := MyOnStatus;
  LSSL.OnStatusInfo  := MySSLInfo;
  LSSL.OnStatusInfoEx:= MySSlInfoEx;
  LSSL.ConnectTimeout:= 1000000;
  LSSL.ReadTimeout   := 1000000;

  LSMTP.IOHandler       := FSSL;
  LSMTP.AuthType        := satDefault;
  LSMTP.UseTLS          := utUseExplicitTLS;
  LSSL.SSLOptions.Method:= sslvSSLv23;
  LSSL.SSLOptions.Mode  := sslmBoth;

  LSMTP.Host:= 'smtp.office365.com';
  LSMTP.Port:= '587';
  LSMTP.Username:= [email protected];
  LSMTP.Password:= password;
  LSMTP.From:= LSMTP.Username;

  try
    LSMTP.Connect;
  except
      raise Exception.Create(Format('Error during connect attempt: %s',[Exception(ExceptObject).Message]));
  end;

end;

所以,我有一些问题:

为什么

TIdSMTP.OnTLSNotAvailable
/
TIdSMTP.OnTLSHandShakeFailed
/
TIdSMTP.OnTLSNegCmdFailed
在这些情况下不会触发?

为什么

TIdSSLIOHandlerSocketOpenSSL.OnStatusInfo
TIdSSLIOHandlerSocketOpenSSL.OnStatusInfoEx
仅在第二次连接尝试时触发?

我错过了什么?

delphi ssl smtp indy
1个回答
0
投票

如果您在显式 tls 端口上使用

utUseImplicitTLS
,客户端将在建立 TCP 连接后立即发送 TLS 握手,然后当它将服务器未加密的 SMTP 问候错误解释为 TLS 握手回复时,连接将会失败。

如果在隐式 TLS 端口上使用

utUseExplicitTLS
,客户端将在建立 TCP 连接后超时,因为它将等待服务器从不发送的未加密 SMTP 问候语,因为服务器正在等待 TLS 握手客户从不发送。

© www.soinside.com 2019 - 2024. All rights reserved.