Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: TIdSMTP + Exchange (TLS) not notifying unknow recipient



Permlink Replies: 3 - Last Post: Dec 4, 2014 10:44 AM Last Post By: Remy Lebeau (Te...
Ronald Hoek

Posts: 22
Registered: 7/1/01
TIdSMTP + Exchange (TLS) not notifying unknow recipient
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 28, 2014 8:00 AM
Hello,

We use TIdSMTP to send mailnotifications. We connect to our internal Exchange mail server (Windows 2008R2) with TLS authentication.

We use the following code to initialize the SMTP component (aConfig.HostAuth = haUserNameTLS)

procedure InitEmailSettings(aSMTP: TIdSMTP; aConfig: ISSMailConfigSection);
begin
  aSMTP.Host := aConfig.Host;
  aSMTP.UseTLS := utNoTLSSupport; // default no TLS
 
  if aConfig.HostAuth > haNone then
  begin
    aSMTP.Username := aConfig.HostUsername;
    aSMTP.Password := aConfig.HostPassword;
 
    // use  TLS?
    if aConfig.HostAuth = haUsernameTLS then
    begin
      // test SSL capabilities
      TIdSSLContext.Create.Free; // Raises an error when SSL cannot be used
 
      // Check current IOHandler
      if aSMTP.IOHandler = nil then
        aSMTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(aSMTP)
      else if not(aSMTP.IOHandler is TIdSSLIOHandlerSocketBase) then
        raise Exception.Create('TLS not possible: no SSL IO Handler assigned');
 
      // set TLS settings
      aSMTP.UseTLS := utUseExplicitTLS;
    end;
  end;
end;


We send the E-mail using the following code:

NOTE: aRecipients = 'jantje at fhhfyyehyr1234545 dot nl'

class procedure SSDataImportMailing.InternalSend(const aConfig
  : ISSMailConfigSection; const aRecipients, aSubject, aBody,
  aAttachment: string);
var
  LSMTP: TIdSMTP;
  LMsg: TIdMessage;
  LAtt: TIdAttachmentFile;
begin
  LSMTP := TIdSMTP.Create(nil);
  try
    InitEmailSettings(LSMTP, aConfig);
 
    LMsg := TIdMessage.Create(LSMTP);
    try
      LMsg.Subject := aSubject;
      LMsg.Recipients.EMailAddresses := aRecipients;
      LMsg.From.Text := aConfig.Sender;
      LMsg.Body.Text := aBody;
 
      LAtt := nil;
      if FileExists(aAttachment) then
        begin
          LAtt := TIdAttachmentFile.Create(LMsg.MessageParts, aAttachment);
          LAtt.StoredPathName := aAttachment;
        end;
 
      LSMTP.Connect;
      try;
        LSMTP.Send(LMsg);
      finally
        LSMTP.Disconnect;
      end;
    finally
      FreeAndNil(LAtt);
      FreeAndNil(LMsg);
    end;
  finally
    FreeAndNil(LSMTP);
  end;
end;


The problem is, that we don't get an exaception from TIdSMTP, that the mail cannot be send AND we don't get an 'unable to deliver' notification in the mailbox of the 'aConfig.Sender;' - which is a valid user/E-mail in the Exchange server environment.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: TIdSMTP + Exchange (TLS) not notifying unknow recipient
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 28, 2014 9:50 AM   in response to: Ronald Hoek in response to: Ronald Hoek
Ronald wrote:

// test SSL capabilities
TIdSSLContext.Create.Free; // Raises an error when SSL cannot be used

Do not manually create and destroy a TIdSSLContext object. If you want to
load OpenSSL manually, call the IdSSLOpenSSL.LoadOpenSSLLibrary() function
instead.

LAtt.StoredPathName := aAttachment;

You do not need that. The TIdAttachmentFile constructor handles that for
you.

try;
LSMTP.Send(LMsg);

You have an errorneous semicolon. after the 'try'.

FreeAndNil(LAtt);

You don't need that. The TIdMessage.MessageParts collection owns the TIdAttachmentFile
object, it will be freed when the collection itself is freed, when the TIdMessage
is freed.

FreeAndNil(LMsg);

That is redundant, since you assigned the TIdSMTP object as the Owner for
the TIdMessage object, so the TIdMessage will be freed when the TIdSMTP is
freed.

The problem is, that we don't get an exaception from TIdSMTP, that
the mail cannot be send

That means Exchange is not reporting any error to TIdSMTP. If you are sending
an email to a mailbox that is outside of the Exchange's system, it does not
know during your SMTP session whether the recipient can be reached or not,
so it has to accept the email from you and put it into a queue so it can
send it to the recipient in the background, long after your SMTP session
has ended. It will retry sending it peridoically until a fatal error is
received or a timeout elapses (which is usually in days). That is perfectly
normal behavior for SMTP servers. There is nothing TIdSMTP can do to control
that. Once Exchange (or any other SMTP server you connect to) accepts the
email, it is out of your hands.

AND we don't get an 'unable to deliver' notification in the mailbox of
the 'aConfig.Sender;'

Such notifications might take days to be delivered, if ever. There is no
guarantee. All you can do is provide a valid Sender, and hope the email
(or the notification) does not get lost in transit as it passes through other
systems.

--
Remy Lebeau (TeamB)
Ronald Hoek

Posts: 22
Registered: 7/1/01
Re: TIdSMTP + Exchange (TLS) not notifying unknow recipient
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 4, 2014 6:26 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks for the info Remy,

Most of it is some typos while removing some of the non-needed code in the sample (for example try;)

// test SSL capabilities
TIdSSLContext.Create.Free; // Raises an error when SSL cannot be used

Do not manually create and destroy a TIdSSLContext object. If you want to
load OpenSSL manually, call the IdSSLOpenSSL.LoadOpenSSLLibrary() function
instead.

I've noticed there are some circomstances that will result into a deadlock of the application,
which are a result of a failure to create the TIdSSLContext a some point, but are
not covered by querying the result of IdSSLOpenSSL.LoadOpenSSLLibrary().

AND we don't get an 'unable to deliver' notification in the mailbox of
the 'aConfig.Sender;'

Such notifications might take days to be delivered, if ever. There is no
guarantee. All you can do is provide a valid Sender, and hope the email
(or the notification) does not get lost in transit as it passes through other
systems.

I was hoping this would not be the answer, but it was the one I expected (sadly enough)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: TIdSMTP + Exchange (TLS) not notifying unknow recipient
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 4, 2014 10:44 AM   in response to: Ronald Hoek in response to: Ronald Hoek
Ronald wrote:

I've noticed there are some circomstances that will result into a
deadlock of the application, which are a result of a failure to create
the TIdSSLContext a some point, but are not covered by querying
the result of IdSSLOpenSSL.LoadOpenSSLLibrary().

If you look at the TIdSSLContext constructor, all it does is calls LoadOpenSSLLibrary()
and intializes the fVerifyMode, fMode, and fSessionId members, nothing else.
So there is no way that calling LoadOpenSSLLibrary() directly would deadlock
but constructing a TIdSSLContext instead would not deadlock. However, ignoring
the result of LoadOpenSSLLibrary() might cause deadlocks, as LoadOpenSSLLibrary()
does initialize OpenSSL's thread-locking callbacks. So if LoadOpenSSLLibrary()
fails, there is no guarantee that the callbacks are in place when performing
OpenSSL operations (which you should not be doing at all if LoadOpenSSLLibrary()
fails).

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02