Home IdSMTP fail to send email when executed inside a vps computer
Reply: 1

IdSMTP fail to send email when executed inside a vps computer

coyote
1#
coyote Published in 2018-02-08 16:17:17Z

I want send a email Hotmail > Gmail, that contain a attach file and i mounted this code below and works fine when executed on my own computer, already when is executed inside a vps computer not sends any message.

////////////////////////////////////////////////

What is wrong with this code?


uses
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase,
  IdMessageClient, IdSMTPBase, IdSMTP, IdMessage, IdAttachmentFile,
  IdSSLOpenSSL, IdGlobal;

procedure SendEmail(const Attach, Recipients: string; const Subject: string; const Body: string);
var
  SMTP: TIdSMTP;
  Email: TIdMessage;
  SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
begin

  try

    SMTP := TIdSMTP.Create(nil);
    Email := TIdMessage.Create(nil);
    SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);

    SSLHandler.MaxLineAction := maException;
    SSLHandler.SSLOptions.Method := sslvTLSv1;
    SSLHandler.SSLOptions.Mode := sslmUnassigned;
    SSLHandler.SSLOptions.VerifyMode := [];
    SSLHandler.SSLOptions.VerifyDepth := 0;

    SMTP.AuthType := satDefault;
    SMTP.IOHandler := SSLHandler;
    SMTP.Host := 'smtp.live.com';
    SMTP.Port := 587;
    SMTP.Username := 'test@hotmail.com';
    SMTP.Password := 'test123';
    SMTP.UseTLS := utUseExplicitTLS;

    Email.From.Address := 'test@hotmail.com';
    Email.From.Name := 'TEST';
    Email.Recipients.EmailAddresses := Recipients;
    Email.Subject := Subject;
    Email.Body.Text := Body;

    if not FileExists(Attach) then
      Exit;

    TIdAttachmentFile.Create(Email.MessageParts, Attach);

    try

      SMTP.Connect;
      SMTP.Send(Email);
      SMTP.Disconnect;

    except
      Exit;
    end;

  finally
    SMTP.Free;
    Email.Free;
    SSLHandler.Free;
  end;
end;

SendEmail('c:\test.txt', 'recipient@gmail.com', 'Test SUBJECT', 'Test Body');

EDITION:

The error is:

Authentication unsuccessful

    try
      SMTP.Connect;
      SMTP.Authenticate;
    except
      on E:Exception do
      begin
        MessageDlg('' +
          E.Message, mtWarning, [mbOK], 0);
        Exit;
      end;
    end;

    try
      SMTP.Send(Email);
      MessageDlg('Sent!', mtInformation, [mbOK], 0);
    except
      On E:Exception do
      begin
        MessageDlg('' +
          E.Message, mtWarning, [mbOK], 0);
      end;
    end;

  finally
    SMTP.Disconnect;
    SMTP.Free;
    Email.Free;
    SSLHandler.Free;
  end;
Remy Lebeau
2#
Remy Lebeau Reply to 2018-02-08 20:26:28Z

It is clear from the error message that the server is rejecting your authentication attempt before sending the email.

Before I get into specifics for your issue, let me give you some information so you understand how TIdSMTP authentication works in general.

By default, the TIdSMTP.AuthType property is satDefault, and the TIdSMTP.ValidateAuthLoginCapability property is True. This means the TIdSMTP.Username and TIdSMTP.Password properties are sent using an unsecure AUTH LOGIN command (which most servers will not accept without an established SSL/TLS session), but only if the server's EHLO reply indicates that LOGIN is an acceptable authentication (which many servers do not report, even if they do accept it).

So, it is possible that TIdSMTP.Authenticate() (which you do not need to call manually, TIdSMTP.Send() calls it for you) may not even attempt to authenticate with a server when AuthType=satDefault, and then a subsequent call to TIdSMTP.Send() can fail with an authentication error (you can verify this by assigning one of Indy's TIdLog... components to the TIdSMTP.Intercept property and then look at the actual SMTP commands that TIdSMTP sends).

So, try setting TIdSMTP.ValidateAuthLoginCapability to False so TIdSMTP.Authenticate() will always send AUTH LOGIN when AuthType=satDefault, regardless of whether the server reports it is acceptable or not. If the server does not accept it, at least it will fail authentication at that stage, rather than at the Send() stage.

However, most SMTP servers nowadays accept/require stronger authentication schemes than LOGIN, such as CRAM-SHA1 or CRAM-MD5. So, you could set AuthType=satSASL instead, and then populate the TIdSMTP.SASLMechanisms collection with relevant TIdSASL-derived components (including TIdSASLLogin to handle AUTH LOGIN when supported), and link them to a TIdUserPassProvider to get the Username and Password (the TIdSMTP.Username and TIdSMTP.Password properties are not used during SASL authentications).

Now, that being said, I tested TIdSMTP with smtp.live.com, and it does, in fact, report support for LOGIN authentication after an SSL/TLS session is established, so ValidateAuthLoginCapability doesn't apply to that server. The AUTH LOGIN command gets sent when using AuthType=satDefault, or when using TIdSASLLogin with AuthType=satSASL.

But, the server rejects my login attempts with AUTH LOGIN when using my real Hotmail password, and this is because my account has 2-Step Verification enabled. So, in order for TIdSMTP to login correctly, I have to go into my Hotmail account using a web browser and create an App Password in the security settings, and then configure TIdSMTP to use that password instead of my real password. Then AUTH LOGIN is successful.

You will have to do the same, if you have 2-Step Verification enabled on your Hotmail account.

SMTP.AuthType := satDefault;
SMTP.IOHandler := SSLHandler;
SMTP.Host := 'smtp.live.com';
SMTP.Port := 587;
SMTP.Username := 'real hotmail email here';
SMTP.Password := 'app password here'; // <--
SMTP.UseTLS := utUseExplicitTLS;

Note that the only other authentication scheme that smtp.live.com supports is XOAUTH2*, which does not require an App Password be created. Indy does not currently implementation XOAUTH2. But there may be a 3rd party implementation floating around if you look around. Or, you can try implementing a custom TIdSASL-derived component for it yourself.

* FYI, Gmail also supports XOAUTH2 for SMTP and IMAP.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.317577 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO