1
votes

I have an IMAP4 client that works fine connected to RackSpace, but the client is moving to Amazon work mail.

Per Amazon published instructions:

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

The only operation I have coded is IMAPClient.Connect();

It returns a status of "Connected", but the program hangs after that. I have followed the thread through the component source and found it is waiting for a return from Amazon in the function TIdIMAP4.GetResponse: string; It just hangs there for a very long time and then throws a "Connection Gracefully Closed" exception.

Delphi 10.2

Indy 10.6.2.5366

What am I missing?

My settings are:

var
  IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;

with IMAPClient do
begin
  Name := 'IMAPClient';
  OnStatus := IMAPClientStatus;
  IOHandler := IdSSLIOHandlerSocketOpenSSL1;
  OnDisconnected := IMAPClientDisconnected;
  OnConnected := IMAPClientConnected;
  Password := 'EmailTest1236';
  Port := 993;
  Username := '[email protected]';
  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;

The email account and password are bogus. I can not give out a real one.

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.
1

1 Answers

1
votes

You need to change the TIdImap4.UseTLS property from utUseRequireTLS to utUseImplicitTLS. IMAP port 993 expects the client to send an SSL/TLS handshake as soon as the socket is connected, before the server can send the IMAP greeting (encrypted) to the client. utUseRequireTLS does not do that handshake, utUseImplicitTLS does. Your client is freezing because it is not sending the handshake, and is trying to read an (unencrypted) greeting that the server is not sending.

On a side note, you should not be setting most of the SSLIOHandler's properties that you are currently setting. The only properties you should be setting manually are Name (optional), SSLOptions, and desired event handlers. The rest of the properties are handled by Indy internally for you (primarily by Connect()), so you don't need to mess around with them.