【问题标题】:SMTP Implicit TLS and Explicit TLS using Indy 10.6.2.5341 in Delphi在 Delphi 中使用 Indy 10.6.2.5341 的 SMTP 隐式 TLS 和显式 TLS
【发布时间】:2017-09-14 05:11:51
【问题描述】:

这里有点奇怪,当将“UseTLS”设置为 utUseExplicitTLS 然后在其隐式 TLS 端口上连接到邮件服务器时,第一次尝试允许连接并发送电子邮件,随后在该端口上的尝试正确失败。

只是想知道是否有人对如何避免初始连接和发送时的误报有任何想法。

检查是为了处理非标准端口可能被用于用户的邮件服务器。我见过的几乎所有示例都假定始终提供正确的信息。

以下是处理它的代码部分(不包括错误记录):

function SendTestEmail(EmailAddress: String): Boolean;
var
  EmailMessage: TidMessage;
begin
  IdSMTPEmail.AuthType := satDefault
  IdSMTPEmail.Username := ...;
  IdSMTPEmail.Password := ...;
  IdSMTPEmail.Port := 465;

  IdSMTPEmail.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTPEmail);
  IdSMTPEmail.UseTLS := utUseExplicitTLS;
  TIdSSLIOHandlerSocketOpenSSL(IdSMTPEmail.IOHandler).SSLOptions.Method := sslvTLSv1_2;
  try
    // Connect
    IdSMTPEmail.Connect('smtp.gmail.com');

    try
      // Create
      EmailMessage := TidMessage.Create(nil);

      try
        // Set values
        EmailMessage.Body.Add('Test Email');
        EmailMessage.Subject := 'Test Email';

        // Set sender details
        EmailMessage.From.Address := 'test@test.com';
        EmailMessage.From.Name := 'SSL Test';

        // Set recipient
        EmailMessage.Recipients.Add.Address := EmailAddress;

        try
          // Send message
          IdSMTPEmail.Send(EmailMessage);

        except
          // Exception
          on E: EIdSMTPReplyError do
          begin
            // Result
            Result := False;
          end;
        end;

      finally
        // Free email
        EmailMessage.Free;
      end;

    finally
      // Disconnect
      IdSMTPEmail.Disconnect;
    end;

  except
    // Exception
    on E: Exception do
    begin
      IdSMTPEmail.Disconnect;
      // Result
      Result := False;
    end;
  end;
end;

【问题讨论】:

  • 你描述的不可能。隐式 TLS 端口要求在连接后立即启动 TLS 握手,并在发送 SMTP 问候语之前完全完成。 utUseExplicitTLS 在连接时不发送握手,因此Connect() 将阻止等待从未发送过的问候,直到服务器断开连接或ReadTimeout 过去,以先发生者为准。无论哪种方式,调用代码都无法发送任何电子邮件。
  • @RemyLebeau 你所说的是我所期待的行为,当上述第一次尝试时我感到震惊。作为检查,我同时运行了 Wireshark,它在第一次尝试时显示成功(也收到了电子邮件),但随后的尝试将超时,Wireshark 没有收到任何内容。
  • 你所说的在 implicit TLS 端口上根本不可能。 TLS 握手是必需的。您很可能在第一次尝试时连接到一个非隐式 端口,然后在随后的尝试中连接到一个隐式 端口。使用 Wireshark 验证每个连接上使用的端口。
  • @RemyLebeau 我直到现在才看到你的回复,但我会发布似乎已经修复它的答案。

标签: delphi indy


【解决方案1】:

使用下面的代码,尝试通过电子邮件发送到端口 465 的所有尝试均正确失败。

我什至不假装理解为什么会这样,但我的原版却没有。

function SendTestEmail(EmailAddress: String): Boolean;
var
  EmailMessage: TidMessage;
  IdSSLHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  IdSMTPEmail.AuthType := satDefault;

  IdSSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create;
  IdSSLHandler.SSLOptions.Method := sslvTLSv1_2;

  IdSMTPEmail.IOHandler := IdSSLHandler;
  IdSMTPEmail.UseTLS := utUseExplicitTLS;

  IdSMTPEmail.Username := ...;
  IdSMTPEmail.Password := ...;
  IdSMTPEmail.Port := 465;

  try
    // Connect
    IdSMTPEmail.Connect('smtp.gmail.com');

    try
      // Create
      EmailMessage := TidMessage.Create(nil);

      try
        // Set values
        EmailMessage.Body.Add('Test Email');
        EmailMessage.Subject := 'Test Email';

        // Set sender details
        EmailMessage.From.Address := 'test@test.com';
        EmailMessage.From.Name := 'SSL Test';

        // Set recipient
        EmailMessage.Recipients.Add.Address := EmailAddress;

        try
          // Send message
          IdSMTPEmail.Send(EmailMessage);

        except
          // Exception
          on E: EIdSMTPReplyError do
          begin
            // Result
            Result := False;
          end;
        end;

      finally
        // Free email
        EmailMessage.Free;
      end;

    finally
      // Disconnect
      IdSMTPEmail.Disconnect;
    end;

  except
    // Exception
    on E: Exception do
    begin
      IdSMTPEmail.Disconnect;
      // Result
      Result := False;
    end;
  end;
end;

【讨论】:

    猜你喜欢
    • 2011-10-25
    • 2022-01-01
    • 2021-05-03
    • 2012-12-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-05-02
    相关资源
    最近更新 更多