Delphi: использование Indy 10 SMTP с SSL и office365

Это дополнительный вопрос к использованию INDY 10 SMTP с Office365 и Невозможно использовать безопасный SMTP подключение к Office365 с Delphi 2010 и Indy 10.5.5.

У меня есть следующая процедура, включающая точки, сделанные в обоих потоках (в частности, я устанавливаю IdSMTP.AuthType := satSASL, предоставляю наиболее распространенные механизмы SASL для TIdSMTP на выбор и использую Explicit TLS и 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;

Я поставил FSmtp.ValidateAuthLoginCapability := False; и FSmtp.UseEhlo := True;, чтобы TIdSMTP сам решал, какой механизм SASL использовать.

Заметьте также, что мне пришлось закомментировать явное назначение порта. Это потому, что мы получим тайм-аут сокета при его назначении. Это происходит, несмотря на то, что вы следуете совету в Отправить электронную почту с использованием компонента indy. Ошибка согласования SSL delphi xe2, и выполнение назначения после установки UseTLS на utUseExplicitTLS.

Когда я запускаю это на своем клиенте O365, я получаю следующий вывод журнала, который показывает возможности клиента и исключение:

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!!

Обратите внимание, что для AUTH нет объявленного значения.

Я не уверен, что попробовать дальше. На данный момент я ожидал, что TIdSMTP сможет определить правильный механизм для использования и успешного подключения и отправки электронной почты. Есть предположения?

Спасибо!


person stackleit    schedule 02.06.2020    source источник
comment
Для Office 365 (и большинства других SMTP-серверов) необходимо использовать Port=587 с UseTLS=utUseExplicitTLS (в противном случае можно использовать Port=993 с UseTLS=utUseImplicitTLS). И ValidateAuthLoginCapability используется только с AuthType=satDefault, а не с AuthType=satSASL. И вы должны использовать SSLOptions.SSLVersion IOHandler вместо его SSLOptions.Method, и вы должны включить в нем TLS 1.1 (sslvTLSv1_1) и TLS 1.2 (sslvTLSv1_2).   -  person Remy Lebeau    schedule 02.06.2020
comment
Что касается заявленных возможностей сервера, вы показали возможности сервера до STARTTLS. Как только будет выполнена команда STARTTLS и соединение будет защищено, возможности изменятся соответствующим образом (клиент должен отправить новую команду EHLO после успешного выполнения STARTTLS), что будет включать появление новых схем AUTH и исчезновение возможностей STARTTLS. Когда TIdSMTP пытается аутентифицироваться на сервере, он сначала выдает для вас команды STARTTLS и EHLO (при использовании UseTLS=utUseExplicitTLS) перед входом в систему.   -  person Remy Lebeau    schedule 02.06.2020