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!