Introduction

Sending email from Windows, Android and iOS Delphi applications over public SMTP servers requires an encrypted connection. Internet Direct (Indy) configuration for SSL/TLS connections is shown in this example source code.

Disclaimer

This code is mostly based on code posted in the Embarcadero forum and here.

Example usage

[sourcecode language=”Delphi”]
procedure TFormMailDemo.ButtonSendClick(Sender: TObject);
var
Mail: TSSLEmail;
begin
if EditToEmail.Text <> ” then
begin
Mail := TSSLEmail.Create(‘mail.example.com’, 465,
‘me@example.com’, ‘***’);

try
Mail.edSenderName := ‘ABC Inc.’;
Mail.edSenderEmail := ‘abc@example.com’;
Mail.edToEmail := EditToEmail.Text;
Mail.edSubject := EditSubject.Text;
Mail.edBody := MemoBody.Lines;

Mail.SendEmail;

EditToEmail.Text:=”;
EditSubject.Text:=”;
MemoBody.Clear;
finally
Mail.Free;
end;
end;
end;
[/sourcecode]

Requirements

The code requires Internet Direct (Indy) version 10.6.
Note that the application needs the SSL dynamic link libraries, which can be found at indy.fulgan.com/SSL.

Supported platforms

The code has been tested with Delphi 2009 on Windows. The original code in the linked article reportedly works with Android.
For iOS, please also read this article.

Feedback and support

Feedback is welcome, please visit Habarisoft web page to find contact information. The source code is unsupported example code, use it at your own risk.

Source code

The source code for the SSL mail unit is shown below.

[sourcecode language=”Delphi”]
unit IndySecureMailClient;

interface

uses
IdMessage, Classes, IdSMTP;

const
SMTP_PORT_EXPLICIT_TLS = 587;

type
TSSLEmail = class(TObject)
private
IdMessage: TIdMessage;
SMTP: TIdSMTP;

FedBody: TStrings;
FedSMTPPort: Integer;
FedToEmail: string;
FedSubject: string;
FedSMTPServer: string;
FedCCEmail: string;
FedPassword: string;
FedBCCEmail: string;
FedSenderName: string;
FedUserName: string;
FedPriority: TIdMessagePriority;
FedSenderEmail: string;
FedSSLConnection: Boolean;

// Getter / Setter
procedure SetBody(const Value: TStrings);

procedure Init;
procedure InitMailMessage;
procedure InitSASL;
procedure AddSSLHandler;

public
constructor Create; overload;
constructor Create(const ASMTPServer: string;
const ASMTPPort: Integer;
const AUserName, APassword: string); overload;

destructor Destroy; override;

procedure SendEmail;

// Properties
property edBCCEmail: string read FedBCCEmail write FedBCCEmail;
property edBody: TStrings read FedBody write SetBody;
property edCCEmail: string read FedCCEmail write FedCCEmail;
property edPassword: string read FedPassword write FedPassword;
property edPriority: TIdMessagePriority read FedPriority write FedPriority;
property edSenderEmail: string read FedSenderEmail write FedSenderEmail;
property edSenderName: string read FedSenderName write FedSenderName;
property edSMTPServer: string read FedSMTPServer write FedSMTPServer;
property edSMTPPort: Integer read FedSMTPPort write FedSMTPPort;
property edSSLConnection: Boolean read FedSSLConnection write FedSSLConnection;
property edToEmail: string read FedToEmail write FedToEmail;
property edUserName: string read FedUserName write FedUserName;
property edSubject: string read FedSubject write FedSubject;

end;

implementation

uses
IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase,
IdMessageClient, IdSMTPBase, IdBaseComponent, IdIOHandler,
IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdSASLLogin,
IdSASL_CRAM_SHA1, IdSASL, IdSASLUserPass, IdSASL_CRAMBase, IdSASL_CRAM_MD5,
IdSASLSKey, IdSASLPlain, IdSASLOTP, IdSASLExternal, IdSASLDigest,
IdSASLAnonymous, IdUserPassProvider;

constructor TSSLEmail.Create;
begin
inherited;

Init;

FedBody := TStringList.Create;
end;

procedure TSSLEmail.Init;
begin
edSSLConnection := True;
edPriority := TIdMessagePriority.mpNormal;
end;

constructor TSSLEmail.Create(const ASMTPServer: string;
const ASMTPPort: Integer; const AUserName, APassword: string);
begin
Create;

edSMTPServer := ASMTPServer;
edSMTPPort := ASMTPPort;
edUserName := AUserName;
edPassword := APassword;
end;

destructor TSSLEmail.Destroy;
begin
edBody.Free;

inherited;
end;

// Setter / Getter ———————————————————–

procedure TSSLEmail.SetBody(const Value: TStrings);
begin
FedBody.Assign(Value);
end;

// Send the mail ————————————————————-

procedure TSSLEmail.SendEmail;
begin
IdMessage := TIdMessage.Create;
try
InitMailMessage;

SMTP := TIdSMTP.Create;
try
if edSSLConnection then
begin
AddSSLHandler;

if edSMTPPort = SMTP_PORT_EXPLICIT_TLS then
SMTP.UseTLS := utUseExplicitTLS
else
SMTP.UseTLS := utUseImplicitTLS;
end;

if (edUserName<>”) or (edPassword<>”) then
begin
SMTP.AuthType := satSASL;
InitSASL;
end
else
begin
SMTP.AuthType := satNone;
end;

SMTP.Host := edSMTPServer;
SMTP.Port := edSMTPPort;
SMTP.ConnectTimeout := 30000;
SMTP.UseEHLO := True;
SMTP.Connect;

try
SMTP.Send(IdMessage);
finally
SMTP.Disconnect;
end;
finally
SMTP.Free;
end;
finally
IdMessage.Free;
end;
end;

// Prepare the mail ———————————————————-

procedure TSSLEmail.InitMailMessage;
begin
IdMessage.ContentType := ‘text/plain’;
IdMessage.Charset := ‘UTF-8’;
IdMessage.Body := edBody;
IdMessage.Sender.Text := edSenderEMail;
IdMessage.From.Name := edSenderName;
IdMessage.From.Address := edSenderEMail;
IdMessage.ReplyTo.EMailAddresses := edSenderEmail;
IdMessage.Recipients.EMailAddresses := edToEmail;
IdMessage.Subject := edSubject;
IdMessage.Priority := edPriority;
IdMessage.CCList.EMailAddresses := edCCEMail;
IdMessage.ReceiptRecipient.Text := ”;
IdMessage.BccList.EMailAddresses := edBCCEMail;
end;

procedure TSSLEmail.AddSSLHandler;
var
SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(SMTP);
// SSL/TLS handshake determines the highest available SSL/TLS version dynamically
SSLHandler.SSLOptions.Method := sslvSSLv23;
SSLHandler.SSLOptions.Mode := sslmClient;
SSLHandler.SSLOptions.VerifyMode := [];
SSLHandler.SSLOptions.VerifyDepth := 0;
SMTP.IOHandler := SSLHandler;
end;

procedure TSSLEmail.InitSASL;
var
IdUserPassProvider: TIdUserPassProvider;
IdSASLCRAMMD5: TIdSASLCRAMMD5;
IdSASLCRAMSHA1: TIdSASLCRAMSHA1;
IdSASLPlain: TIdSASLPlain;
IdSASLLogin: TIdSASLLogin;
IdSASLSKey: TIdSASLSKey;
IdSASLOTP: TIdSASLOTP;
IdSASLAnonymous: TIdSASLAnonymous;
IdSASLExternal: TIdSASLExternal;
begin
IdUserPassProvider := TIdUserPassProvider.Create(SMTP);
IdUserPassProvider.Username := edUserName;
IdUserPassProvider.Password:= edPassword;

IdSASLCRAMSHA1 := TIdSASLCRAMSHA1.Create(SMTP);
IdSASLCRAMSHA1.UserPassProvider := IdUserPassProvider;
IdSASLCRAMMD5 := TIdSASLCRAMMD5.Create(SMTP);
IdSASLCRAMMD5.UserPassProvider := IdUserPassProvider;
IdSASLSKey := TIdSASLSKey.Create(SMTP);
IdSASLSKey.UserPassProvider := IdUserPassProvider;
IdSASLOTP := TIdSASLOTP.Create(SMTP);
IdSASLOTP.UserPassProvider := IdUserPassProvider;
IdSASLAnonymous := TIdSASLAnonymous.Create(SMTP);
IdSASLExternal := TIdSASLExternal.Create(SMTP);
IdSASLLogin := TIdSASLLogin.Create(SMTP);
IdSASLLogin.UserPassProvider := IdUserPassProvider;
IdSASLPlain := TIdSASLPlain.Create(SMTP);
IdSASLPlain.UserPassProvider := IdUserPassProvider;

SMTP.SASLMechanisms.Add.SASL := IdSASLCRAMSHA1;
SMTP.SASLMechanisms.Add.SASL := IdSASLCRAMMD5;
SMTP.SASLMechanisms.Add.SASL := IdSASLSKey;
SMTP.SASLMechanisms.Add.SASL := IdSASLOTP;
SMTP.SASLMechanisms.Add.SASL := IdSASLAnonymous;
SMTP.SASLMechanisms.Add.SASL := IdSASLExternal;
SMTP.SASLMechanisms.Add.SASL := IdSASLLogin;
SMTP.SASLMechanisms.Add.SASL := IdSASLPlain;
end;

end.

[/sourcecode]


Discover more from Habarisoft Blog

Subscribe to get the latest posts sent to your email.