使用 Delphi 和 Indy 连接到 Amazon Work Mail

Connecting to Amazon Work Mail with Delphi and Indy

我有一个 IMAP4 客户端,连接到 RackSpace 后运行良好,但该客户端正在转移到 Amazon 工作邮件。

根据亚马逊发布的说明:

Connect to your IMAP Client Application

You can connect any IMAP-compatible client software to Amazon WorkMail by providing the following information: 

Type of account IMAP 
Protocol IMAPS 
Port 993 
Secure connection Required;SSL 
Incoming username Email address associated with your Amazon WorkMail account 
Incoming password Your password 
Incoming server The endpoint matching the region where your mailbox is located: • us-east-1 imap.mail.us-east-1.awsapps.com

我编码的唯一操作是IMAPClient.Connect();

它 return 的状态为 "Connected",但程序在那之后挂起。我已经通过组件源跟踪线程,发现它正在等待函数 TIdIMAP4.GetResponse: string; 中来自亚马逊的 return 它只是挂在那里很长时间然后抛出 "Connection Gracefully Closed" 异常.

Delphi10.2

印地 10.6.2.5366

我错过了什么?

我的设置是:

var
  IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;

with IMAPClient do
begin
  Name := 'IMAPClient';
  OnStatus := IMAPClientStatus;
  IOHandler := IdSSLIOHandlerSocketOpenSSL1;
  OnDisconnected := IMAPClientDisconnected;
  OnConnected := IMAPClientConnected;
  Password := 'EmailTest1236';
  Port := 993;
  Username := 'emailTest.1236@foo.bar.com';
  Host := 'imap.mail.us-east-1.awsapps.com';
  UseTLS := utUseRequireTLS;
  SASLMechanisms := <>;
  MilliSecsToWaitToClearBuffer := 10;
end;

IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(Self);

with IdSSLIOHandlerSocketOpenSSL1 do
begin
  Name := 'IdSSLIOHandlerSocketOpenSSL1';
  OnStatus := IdSSLIOHandlerSocketOpenSSL1Status;
  Destination := 'imap.mail.us-east-1.awsapps.com:993';
  Host := 'imap.mail.us-east-1.awsapps.com';
  MaxLineAction := maException;
  Port := 993;
  BoundPort := 993;
  DefaultPort := 0;
end;

邮箱账号和密码是假的。我不能给出一个真实的。

unit uMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdIOHandler, IdIOHandlerSocket,
  IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase, IdMessageClient,
  IdIMAP4, Vcl.StdCtrls;

type
  TForm4 = class(TForm)
    IMAPClient: TIdIMAP4;
    IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure IMAPClientStatus(ASender: TObject; const AStatus: TIdStatus;
      const AStatusText: string);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

procedure TForm4.Button1Click(Sender: TObject);
begin
  IMAPClient.Connect();
end;

procedure TForm4.IMAPClientStatus(ASender: TObject; const AStatus: TIdStatus;
  const AStatusText: string);
begin
  memo1.Lines.Add(AStatusText);
end;

end.

您需要将 TIdImap4.UseTLS 属性 从 utUseRequireTLS 更改为 utUseImplicitTLS。 IMAP 端口 993 希望客户端在套接字连接后立即发送 SSL/TLS 握手,然后服务器才能向客户端发送 IMAP 问候语(加密)。 utUseRequireTLS 不进行握手,utUseImplicitTLS 进行。您的客户端正在冻结,因为它没有发送握手,并且正在尝试读取服务器没有发送的(未加密的)问候语。

附带说明一下,您不应设置当前正在设置的大部分 SSLIOHandler 属性。您应该手动设置的唯一属性是 Name(可选)、SSLOptions 和所需的事件处理程序。其余的属性由 Indy 内部为您处理(主要由 Connect()),因此您无需对它们进行处理。