1

I tried with Indy component to send email in XE2, and it works fine on my laptop that I compiled my project on.

But if I take my exe project to another PC, it shows an error message

Connection closed gracefully

or, sometimes I get

SSL Negotiation failed

Actually I tried many times to solve my problem, but I can't.

This is my code - where is my mistake? I need a practical solution.

procedure Gmail(username, password, totarget, subject, body :string);
var
   DATA : TIdMessage;
   SMTP : TIdSMTP;
   SSL : TIdSSLIOHandlerSocketOpenSSL;
   result:Boolean;
begin
   try
      SMTP := TIdSMTP.Create(nil);
      DATA := TIdMessage.Create(nil);
      SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);

      SSL.Destination := 'smtp.gmail.com:587';
      SSL.Host := 'smtp.gmail.com';
      //  SSL.MaxLineAction.maException;
      SSL.Port:= 587;
      SSL.SSLOptions.Method := sslvTLSv1;
      SSL.SSLOptions.Mode := sslmUnassigned;
      SSL.SSLOptions.VerifyMode :=  [];
      SSL.SSLOptions.VerifyDepth := 0;

      DATA.From.Address := username;
      DATA.Recipients.EMailAddresses := totarget;
      DATA.Subject := subject;
      DATA.Body.Text := body;

      if FileExists('D:\Test1.txt') then
         TIdAttachmentFile.Create(DATA.MessageParts, 'D:\Test1.txt');

      SMTP.IOHandler := SSL;
      SMTP.Host := 'smtp.live.com';
      SMTP.Port := 587 ;
      SMTP.Username := username;
      SMTP.Password := password;
      //  SMTP.SASLMechanisms;
      SMTP.UseTLS := utUseExplicitTLS;

      try
         try
           SMTP.Connect;
           SMTP.Send(DATA);
           Result := True;
         except
           on E:Exception do
           begin
               ShowMessage('Cannot send E-Mail: ' + E.Message);
               Result := False;
           end;
         end;
      finally
         if SMTP.Connected then SMTP.Disconnect;
      end;
  except
    on E : Exception do
    begin
      ShowMessage('Error in the function SendEmailDelphi: ' + E.Message);
      Result := False;
    end;
  end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Enabled:= True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
mail_username := 'email@gmail.com';
mail_password := 'pass';
mail_to := 'email@gmail.com';
mail_subject := 'Text email from Delphi project';
mail_body := 'this is a test email sent from Delphi project, do not reply';

 try
   begin
     Gmail(mail_username, mail_password, mail_to , mail_subject, mail_body);
   end;
 finally

 end;
end;
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Adam
  • 78
  • 2
  • 11
  • Do you have the libeay32.dll and ssleay32.dll installed in the other PC? – Tom Brunberg Feb 06 '16 at 15:42
  • Possible duplicate of [Using Gmails Outgoing SMTP from DELPHI(Indy) using TLS](http://stackoverflow.com/questions/7037929/using-gmails-outgoing-smtp-from-delphiindy-using-tls) – Tom Brunberg Feb 06 '16 at 15:58
  • @tomBrunberg , I install the dll files in my project folder, and i copy the dll file to system files.. and the problem still not solved !! – Adam Feb 06 '16 at 18:19

1 Answers1

1

DO NOT set the SSL.Destination, SSL.Host, or SSL.Port properties manually! TIdTCPClient.Connect() handles that for you. Besides, don't you think it's odd that you are setting SSL.Destination/Host to smtp.gmail.com but are setting SMTP.Host to smtp.live.com instead? Gmail and Live are not the same service provider.

Also, SSL.SSLOptions.Mode should be set to sslmClient instead of sslmUnassigned. Not too important, TIdSSLIOHandlerSocketOpenSSL will simply flip it when it configures the connection. But you should do it anyway, since you know your code is acting as a client.

And lastly, try setting SMTP.UseTLS before setting SMTP.Port, as setting UseTLS may change the Port, so you want to make sure you are really connecting to the correct port you are expecting.

With that said, the SSL Negotiation failed error means the TLS handshake was started but failed part-way through the negotiation. Try assigning handlers to TIdSSLIOHandlerSocketOpenSSL's OnStatusInfo/Ex events to see how far the handshake is actually getting. And if you are using a relatively modern version of Indy 10, try looking at the raised exception's InnerException property, it might give you a clue as to what went wrong before the EIdTLSClientTLSHandShakeFailed exception was raised afterwards.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you so much , the problem solved, ................................ But , onther problem was raised to me !!! 'Could not load SSL Library' I copy dll files library32.dll & ssleay32.dll to my project folder, but this problem still show to me !! ............................. how I can solve it ? – Adam Feb 07 '16 at 12:55
  • Indy has a `WhichFailedToLoad()` function in the `IdSSLOpenSSLHeaders` unit that returns why OpenSSL could not be loaded. Either the DLLs themselves could not be loaded into memory, or you are using a version of the DLLs that is missing one or more exported functions that Indy deems "critical" for its use. – Remy Lebeau Feb 07 '16 at 18:20
  • I have a similar problem I have not been able to fix. The code is developed on a W7 Desktop top and it works fine there (and also on another Desktop W10). However, it fails on ReadTimeOut execption on a number of Laptops I have tried. Note. It used to work fine on a Laptop also, but there have been some recent change which has caused it stop working. I suspect Windows Update. I have tried the fixes suggested above, but the problem Still Persists. – x iHarpzZ Aug 25 '19 at 18:53