Delphi: Using Indy 10 SMTP with SSL and office365 - delphi

This is a follow up question to Using INDY 10 SMTP with Office365 and Cannot use secure SMTP connection to Office365 with Delphi 2010 and Indy 10.5.5.
I have the following routine, incorporating points made in both threads (specifically, I set IdSMTP.AuthType := satSASL, provide the most common SASL mechanisms for TIdSMTP to choose from and I use Explicit TLS and sslvTLSv1):
procedure TEmailAlertSuite.AddSslHandler(const Username, Password: string);
var
SASLAnonymous: TIdSASLAnonymous;
SASLDigest: TIdSASLDigest;
SASLLogin: TIdSASLLogin;
SASLOTP: TIdSASLOTP;
SASLMD5: TIdSASLCRAMMD5;
SASLPlain: TIdSASLPlain;
SASLSHA1: TIdSASLCRAMSHA1;
SASLSkey: TIdSASLSKey;
UserPassProvider: TIdUserPassProvider;
begin
FSmtp.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(FSmtp);
TIdSSLIOHandlerSocketOpenSSL(FSmtp.IOHandler).SSLOptions.Method := sslvTLSv1;
FSmtp.UseTLS := utUseExplicitTLS;
// When we explicitly assign the port, we just get connection timeouts...
// FSmtp.Port := 587;
// This needs to be true, so that TIdSMTP can decide which SASL to use,
// from the ones provided below.
// (https://stackoverflow.com/questions/17734414/using-indy-10-smtp-with-office365)
FSmtp.UseEhlo := True;
FSmtp.Username := Username;
FSmtp.Password := Password;
FSmtp.AuthType := satSASL;
UserPassProvider := TIdUserPassProvider.Create;
UserPassProvider.Username := Username;
UserPassProvider.Password := Password;
// SASL mechanisms are declared and added in descending order of security
// (as far as that can be known -- not all units give a value for FSecurityLevel).
SASLOTP := TIdSASLOTP.Create(FSmtp);
SASLOTP.UserPassProvider := UserPassProvider;
FSmtp.SASLMechanisms.Add.SASL := SASLOTP;
SASLSkey := TIdSASLSKey.Create(FSmtp);
SASLSkey.UserPassProvider := UserPassProvider;
FSmtp.SASLMechanisms.Add.SASL := SASLSKey;
SASLSHA1 := TIdSASLCRAMSHA1.Create(FSmtp);
SASLSHA1.UserPassProvider := UserPassProvider;
FSmtp.SASLMechanisms.Add.SASL := SASLSHA1;
SASLMD5 := TIdSASLCRAMMD5.Create(FSmtp);
SASLMD5.UserPassProvider := UserPassProvider;
FSmtp.SASLMechanisms.Add.SASL := SASLMD5;
SASLLogin := TIdSASLLogin.Create(FSmtp);
SASLLogin.UserPassProvider := UserPassProvider;
FSmtp.SASLMechanisms.Add.SASL := SASLLogin;
SASLDigest := TIdSASLDigest.Create(FSmtp);
SASLDigest.UserPassProvider := UserPassProvider;
FSmtp.SASLMechanisms.Add.SASL := SASLDigest;
SASLPlain := TIdSASLPlain.Create(FSmtp);
SASLPlain.UserPassProvider := UserPassProvider;
FSmtp.SASLMechanisms.Add.SASL := SASLPlain;
// (least secure)
SASLAnonymous := TIdSASLAnonymous.Create(FSmtp);
FSmtp.SASLMechanisms.Add.SASL := SASLAnonymous;
FSmtp.ValidateAuthLoginCapability := False;
end;
I set FSmtp.ValidateAuthLoginCapability := False; and FSmtp.UseEhlo := True;, so that TIdSMTP would decide for itself which SASL mechanism to use.
Notice, too, that I had to comment out the explicit assignment of the port. This is because we would get a socket timeout, when assigning it. This is despite following the advice in Send email using indy component delphi xe2 SSL negotiation faild, and making the assignment after setting UseTLS to utUseExplicitTLS.
When I run this on my O365 tenant, I get the following log output, which shows the capabilities of the tenant and an exception:
FSmtp.Capabilities:
SIZE 157286400
PIPELINING
DSN
ENHANCEDSTATUSCODES
STARTTLS
8BITMIME
BINARYMIME
CHUNKING
SMTPUTF8
2020-06-02 10:12:46.232 - Doesn't support AUTH or the specified SASL handlers!!
Notice there is no announced value for AUTH.
I'm not sure what to try next. At this point, I expected TIdSMTP to be able to determine the correct mechanism to use and to successfully connect and send email. Any thoughts?
Thanks!

Related

How to response to digest access authentication with Indy

I'm trying to send response back to servers requesting digest access authentication
....
FResponseHeader.Text := FResponseText;// received header.
FResponseHeader.ProcessHeaders;
....
WriteLn(FResponseHeader.WWWAuthenticate); //WWW-Authenticate: Digest realm="xxxx.com", nonce="fq1uvocyzvr17e6a5syproazd5phwdvhvlc5", stale=false, algorithm=MD5, qop="auth"
LIdAuthentication := TIdDigestAuthentication.Create;
try
LIdAuthentication.Username := FUser;
LIdAuthentication.Password := FPass;
LIdAuthentication.Uri := FURI;
LIdAuthentication.Method := GetMsgTypeString(FResponseHeader.RequestMethods);
LIdAuthentication.Params.Values['Authorization'] := FResponseHeader.WWWAuthenticate;
LIdAuthentication.AuthParams.AddValue('Digest', FResponseHeader.WWWAuthenticate);
for I := 0 to LIdAuthentication.Steps do
LIdAuthentication.Next;
Result := LIdAuthentication.Authentication;
finally
LIdAuthentication.Free;
end;
I got 401 from the server.
What is the correct way to create the Authorization Header ?
TIdDigestAuthentication (and other TIdAuthentication-derived classes) are intended to be used with TIdHTTP, not standalone.
If you are using TIdHTTP to communicate with a server, you do not need to manage Digest authentication manually at all. If the server requests Digest in its WWW-Authenticate header, and if IdAuthenticationDigest (or IdAllAuthentications) is in your uses clause, then TIdHTTP will automatically send a Digest response for you. The only thing you have to concern yourself with doing is:
set the TIdHTTP.Request.Username and TIdHTTP.Request.Password properties for the initial authentication attempt.
set a TIdHTTP.OnAuthorization event handler to handle the possibility of the server rejecting the current Username/Password so you can supply new values for retry, optionally after prompting the user.
optionally set a TIdHTTP.OnSelectProxyAuthorization event handler to choose which authentication scheme to use if multiple schemes are requested by the server, and/or if you want to control which scheme takes priority over others.
For example:
uses
..., IdHTTP, IdAuthenticationDigest;
...
IdHTTP1.OnAuthorization := AuthRequested;
IdHTTP1.Request.Username := ...; // initial username
IdHTTP1.Request.Password := ...; // initial password
IdHTTP1.Get(...);
...
procedure TMyClass.AuthRequested(Sender: TObject; Authentication: TIdAuthentication; var Handled: Boolean);
begin
if (new credentials are available) then
begin
Authentication.Username := ...; // new username
Authentication.Password := ...; // new password
Handled := True;
end else
Handled := False;
end;
That being said, if you want to use TIdDigestAuthentication standalone, then you should use it similarly to how TIdHTTP uses it, eg:
LIdAuthentication := TIdDigestAuthentication.Create;
try
LIdAuthentication.SetRequest(FGetMsgTypeString(FResponseHeader.RequestMethods), FURI);
LIdAuthentication.Username := FUser;
LIdAuthentication.Password := FPass;
LIdAuthentication.Params.Values['Authorization'] := LIdAuthentication.Authentication;
LIdAuthentication.AuthParams := FResponseHeader.WWWAuthenticate; // assuming WWWAuthenticate is a TIdHeaderList...
repeat
case LIdAuthentication.Next of
wnAskTheProgram:
begin
// set LIdAuthentication.Username and LIdAuthentication.Password to new credentials to retry...
end;
wnDoRequest:
begin
// send new request with LIdAuthentication.Authentication in the 'Authorization' header...
Result := LIdAuthentication.Authentication;
Exit;
end;
wnFail:
begin
// error handling ...
Result := '';
Exit;
end;
end;
until False;
finally
LIdAuthentication.Free;
end;

Send email using indy component delphi xe2 SSL negotiation faild

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

Delphi XE2 Indy 10.5.92 GMail SMTP error "Username and Password not accepted"

My question is: why gmail gives me that error:
Username and Password not accepted. Learn more at
http://support.google.com/mail/bin/answer.py?answer=14257 lp8sm18275694wic.17 - gsmtp
I tried everything, whole bunch of options: SSL, TSL, SASL and still nothing. Somewhere I found that google demands some OAUTH2 SASL method wchich is to be done in Indy.
Of course on Delphi 6 and Indy 9 with proper eay dlls on port 465 with ssl works fine.
Anyone has some idea what to do with that?
O course I installed http://slproweb.com/products/Win32OpenSSL.html i anyone asked...
here is the code:
procedure send(Recipientemail, AccountName, Pass, EmailSMTP,EmailPortNo :string);
var
lTextPart: TIdText;
lImagePart: TIdAttachmentfile;
IdSMTP1: TIdSMTP;
IdMsg: TIdMessage;
SSLHandler:TIdSSLIOHandlerSocketOpenSSL;
IdUserPassProv1: TIdUserPassProvider;
IdSASLLogin1: TIdSASLLogin;
IdSASLCRAMMD5: TIdSASLCRAMMD5;
IdSASLCRAMSHA1: TIdSASLCRAMSHA1;
IdSASLPlain: TIdSASLPlain;
IdSASLLogin: TIdSASLLogin;
IdSASLSKey: TIdSASLSKey;
IdSASLOTP: TIdSASLOTP;
IdSASLAnonymous: TIdSASLAnonymous;
IdSASLExternal: TIdSASLExternal;
begin
IdSMTP1:=TIdSMTP.Create(nil);
IdMsg:=TIdMessage.Create(nil);
IdSMTP1.Host:=EmailSMTP;
IdSMTP1.Port:=EmailPortNo;
//IdSMTP1.Username:=trim(AccountName);//tried with or without
//IdSMTP1.Password:=trim(Pass);//tried with or without
TIdSSLContext.Create.Free;
SSLHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTP1);
SSLHandler.SSLOptions.Method := sslvSSLv3;
SSLHandler.SSLOptions.Mode := sslmClient;
IdSMTP1.IOHandler := SSLHandler;
if (IdSMTP1.port = 465) then
IdSMTP1.UseTLS := utUseImplicitTLS
else
IdSMTP1.UseTLS := utUseExplicitTLS;
IdSASLLogin1:=TIdSASLLogin.Create(IdSMTP1);
IdUserPassProv1:=TIdUserPassProvider.Create(IdSMTP1);
IdUserPassProv1.Password:=trim(EmailHasloKonta);
IdUserPassProv1.Username:=trim(EmailNazwaKonta);
IdSMTP1.AuthType:=satSASL;
IdSASLCRAMSHA1 := TIdSASLCRAMSHA1.Create(idSMTP1);
IdSASLCRAMSHA1.UserPassProvider := IdUserPassProv1;
IdSASLCRAMMD5 := TIdSASLCRAMMD5.Create(idSMTP1);
IdSASLCRAMMD5.UserPassProvider := IdUserPassProv1;
IdSASLSKey := TIdSASLSKey.Create(idSMTP1);
IdSASLSKey.UserPassProvider := IdUserPassProv1;
IdSASLOTP := TIdSASLOTP.Create(idSMTP1);
IdSASLOTP.UserPassProvider := IdUserPassProv1;
IdSASLAnonymous := TIdSASLAnonymous.Create(idSMTP1);
IdSASLExternal := TIdSASLExternal.Create(idSMTP1);
IdSASLLogin := TIdSASLLogin.Create(idSMTP1);
IdSASLLogin1.UserPassProvider:=IdUserPassProv1;
IdSASLPlain := TIdSASLPlain.Create(idSMTP1);
IdSASLPlain.UserPassProvider := IdUserPassProv1;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLCRAMSHA1;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLCRAMMD5;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLSKey;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLOTP;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLAnonymous;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLExternal;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLLogin1;
IdSMTP1.SASLMechanisms.Add.SASL := IdSASLPlain;
IdMsg.CharSet:=CmbEncod.Text;
IdMsg.From.Address:=EmailAdresNadawcy;
IdMsg.From.Name:=ToISO_8859_2(true, EmailNadawca);
IdMsg.Recipients.Add.Address:=email;
if EmailDoWiad<>'' then IdMsg.BccList.Add.Address:=EmailDoWiad;
IdMsg.ContentType:='multipart/relative';//; charset='+CmbEncod.Text;
IdMsg.Subject:=ifthen(TytulEmaila='',translate('Potwierdzenie rezerwacji'),TytulEmaila);
IdMsg.Body.Clear;
IdMsg.Body.Text:='';
lTextPart := TIdText.Create(IdMsg.MessageParts);
lTextPart.Body.text:='Some body text';
lTextPart.ContentType := 'text/plain';
try
IdSMTP1.Connect;
//IdSMTP1.Authenticate; //tried with or without
try
try
IdSMTP1.Send(IdMsg);
except
on e: exception do
MessageDlg('Sending error:'#13+
e.message,
mtinformation,[mbok],0);
end;
finally
IdSMTP1.Disconnect;
end;
finally
IdSMTP1.Disconnect;
IdUserPassProv1.free;
IdSASLLogin1.free;
IdSASLCRAMMD5.free;
IdSASLCRAMSHA1.free;
IdSASLPlain.free;
IdSASLLogin.free;
IdSASLSKey.free;
IdSASLOTP.free;
IdSASLAnonymous.free;
IdSASLExternal.free;
lTextPart.Free;
lImagePart.Free;
SSLHandler.free;
IdSMTP1.Free;
IdMsg.Free;
SSLHandler.Free;
end;
end;
Using the latest Indy version (10.6.1), I can successfully connect and authenticate TIdSMTP to Gmail using Indy's SASL components with both SSL (UseTLS=utUseImplicitTLS on port 465) and TLS (UseTLS=utUseExplicitTLS on port 587) using similar code to what you have shown. Despite popular belief, OAUTH2 is not required yet.
The fact that you are getting a human-readable authentication error means the SSL/TLS portion is working fine, so this is strictly a SASL issue.
If your Gmail account is using 2-step verification, make sure you have created an Application Password in your Gmail account settings, you cannot use your primary Gmail password. Read Gmail's documentation for more details:
Application-specific password required
Sign in using App Passwords
With that said, the only changes I would suggest you make to the code you have showed are:
setting the UseTLS property may change the Port property value, so you should set UseTLS first and then set the Port to the desired value afterwards:
if (EmailPortNo = 465) then
IdSMTP1.UseTLS := utUseImplicitTLS
else
IdSMTP1.UseTLS := utUseExplicitTLS;
IdSMTP1.Port := EmailPortNo;
you do not need to create and destroy a TIdSSLContext object, so get rid of that. The only reason to create a TIdSSLContext manually is so it can call the IdSSLOpenSSL.LoadOpenSSLLibrary() function, which is public so you can call it directly if needed (which you don't really need to in this situation).
multipart/relative is not a valid ContentType. Did you mean multipart/related instead? Your TIdMessage does not contain multiple parts so you should not be using multipart ContentType to begin with.
Most of your calls to Free() are redundant since you assigned the TIdSMTP as the Owner for everything except the TIdMessage. You don't need to free the SASL components manually, you can let TIdSMTP do that for you.
you are calling IdSMTP1.Disconnect() twice. You don't need that.
Here is the solution:
After all tries is seems to I have had the wrong version of two dlls libeay.dll and ssleay.dll.

Delphi XE2 - Unable to connect to Gmail smtp server via SSL

Using Delphi XE2, Indy 10 that ships with it and OpenSSL dll's version 1.0.1c.
We are in the final stages of converting our Delphi 6 project to Delphi XE2.
We have solved every show stopper so far but I am running into one trying to connect to Gmail smtp server.
Our Delphi 6 app works fine using SSL v2.3 and SSL v3 and Indy 9 components connecting to port 465 per Google's own documentation. Google Support
Our Delphi XE2 app does not connect at all. The call to connect goes into the ether and nothing happens for some 7 minutes until I get bored waiting for the thing to timeout and kill it off. I actually traced the program execution all the way to the IdWinsock2 funcion here:
function Stub_select(nfds: Integer; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): Integer; stdcall;
begin
#select := FixupStub(hWinSockDll, 'select'); {Do not Localize}
Result := select(nfds, readfds, writefds, exceptfds, timeout);//<-this line never returns and timeout is always nil
end;
I need to maintain the old SSL connectivity for existing users' configurations.
New users will be able to connect using TLS (to port 587) and that DOES work!?!?
I am at a loss as to why the non-TLS SSL options do not work and do not report any error and do not time out but just go off to Never-Never Land. Please help!
TJ
Here is the code:
SMTPClient.Host := trim(EditSMTPServer.Text);
SMTPClient.Port := EditSMTPServerPort.AsInteger;//<- value from custom edit box
SMTPClient.Username := trim(EditSMTPLogon.Text);
SMTPClient.Password := trim(EditSMTPPassword.Text);
SMTPClient.AuthType := satDefault;
if CheckBoxUseSSL.Checked then begin
SMTPClient.IOHandler := IdSSLIOHandlerSocket1;
IdSSLIOHandlerSocket1.ReadTimeout := 30000;//30 second timeout which does not appear to work
case ComboBoxSSLMode.ItemIndex of
0 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv2;
1 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23;
2 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv3;
3 : begin
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvTLsv1;
SMTPClient.UseTLS := utUseImplicitTLS;
end;
end;//case
IdSSLIOHandlerSocket2.SSLOptions.Method := IdSSLIOHandlerSocket1.SSLOptions.Method;
IdSSLIOHandlerSocket2.PassThrough := False;
end
else begin
SMTPClient.IOHandler := nil;
end;
try
SMTPClient.Connect;
if SMTPClient.Connected then begin
if SMTPClient.Authenticate then begin
... do some work ...
end;
end;
except
on e:Exception do begin
showmessage(e.message);
end;
end;
EDIT:
As usual, after I post a question I have stumbled across a workaround.
If I set the UsetTLS property to utUseImplicitTLS for all NON-SSL transactions and set it to utUseExplicitTLS for TLS transactions my connections appear to work in a timely manner.
Hopefully this helps someone out.
updated code:
if CheckBoxUseSSL.Checked then begin
SMTPClient.IOHandler := IdSSLIOHandlerSocket1;
SMTPClient.UseTLS := utUseImplicitTLS;
case ComboBoxSSLMode.ItemIndex of
0 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv2;
1 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23;
2 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv3;
3 : begin
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvTLsv1;
SMTPClient.UseTLS := utUseExplicitTLS;
end;
end;//case
IdSSLIOHandlerSocket2.SSLOptions.Method := IdSSLIOHandlerSocket1.SSLOptions.Method;
IdSSLIOHandlerSocket2.PassThrough := False;
end
else begin
SMTPClient.UseTLS := utNoTLSSupport;//reset TLS support flag
SMTPClient.IOHandler := nil;
end;
What you discovered is what you are supposed to be doing. SSL and TLS have different semantics, so you have to set UseTLS accordingly.
For SSL on port 465, the server expects your client to initiate an SSL handshake immediately upon connecting, before the server then sends an encrypted Greeting. UseTLS=utUseImplicitTLS does that, but UseTLS=utUseExplicitTLS does not. When UseTLS=utUseExplicitTLS, TIdSMTP will expect the server to send an unencrypted Greeting immediately, which would explain the hang in select() - the server is not sending any data!
For TLS on port 587, the server is expecting the client to connect initially unencrypted and then send an explicit STARTTLS command when it is ready to initiate encryption. UseTLS=utUseExplicitTLS does that, but UseTLS=utUseImplicitTLS does not.

Delphi Indy 10 Smtp Error "Unable to authenticate at present"

I am using this piece of code to mail a test message from delphi indy.
I have a TidSMTP,TIdMessage and IdSSLIOHandlerSocketOpenSSL;
In the belowe code if i set it up to use gmail with ssl it works fine, but as soon as i replace my the server details with my cpanel mail server detials it does not work error:
" unable to authenticate at present".
I used same details I would use to setup my account in outlook 2007. Here is the code
IdSSLIOHandlerSocketOpenSSL details.
method := sslvsslv3
mode := sslmUnassigned
//rest default values
procedure Tfrmnotification.btnSendClick(Sender: TObject);
var
IdMsg : TIdMessage;
begin
begin
IdMsg := TIdMessage.Create(nil);
try
with TIdSMTP.Create(nil) do
try
// UserName := 'something#gmail.com';
// Password := 'pass';
// Host := 'smtp.gmail.com';
// IOHandler := IdSSLIOHandlerSocketOpenSSL;
// Port := 587;
UserName := 'something#sasra.co.za';
Password := 'password';
Host := 'outgoing server detials';// same as outlooks
IOHandler := IdSSLIOHandlerSocketOpenSSL;
Port := 465;// this is correct port
UseTLS:= utUseExplicitTLS;
IdMsg.Body.Add('test');
IdMsg.Recipients.emailAddresses := 'something#gmail.com';
IdMsg.Subject := 'test';
IdMsg.From.Address := 'something#sasra.co.za';
IdMsg.From.Name := 'john';
Connect;
Send(IdMsg);
Disconnect;
finally
Free;
end;
finally
IdMsg.free;
end;
showmessage('done');
end;
Any help would be appricated.
Port 465 is used for SMTP over implicit SSL. You have set UseTLS to utUseExplicitTLS. The correct value should (most likely) be utUseImplicitTLS.

Resources