1

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!

stackleit
  • 264
  • 4
  • 13
  • 1
    For Office 365 (and most other SMTP servers), you must use `Port=587` with `UseTLS=utUseExplicitTLS` (otherwuse, you can use `Port=993` with `UseTLS=utUseImplicitTLS`). And `ValidateAuthLoginCapability` is used only with `AuthType=satDefault`, not with `AuthType=satSASL`. And you should be using the IOHandler's `SSLOptions.SSLVersion` instead of its `SSLOptions.Method`, and you should enable TLS 1.1 (`sslvTLSv1_1`) and TLS 1.2 (`sslvTLSv1_2`) in it. – Remy Lebeau Jun 02 '20 at 19:46
  • Regarding the server's reported capabilities, what you showed are the server's pre-`STARTTLS` capabilities. Once a `STARTTLS` command has been issued and the connection is secured, the capabilities will change accordingly (the client is required to send a new `EHLO` command after `STARTTLS` is successful), which will include new `AUTH` schemes appearing, and the `STARTTLS` capability disappearing. When `TIdSMTP` attempts to authenticate with the server, it will first issue the `STARTTLS` and `EHLO` commands for you (when using `UseTLS=utUseExplicitTLS`) before logging in. – Remy Lebeau Jun 02 '20 at 19:57

0 Answers0