Ошибка STARTTLS при отправке электронной почты с помощью Indy в Delphi XE

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

  Var
  MailMessage : TIdMessage;
  SMTP        : TIdSMTP
   .
   .
   .
 //setup SMTP
 SMTP.Host := 'smtp.gmail.com';
 SMTP.Port := 25;
 //setup mail message
 MailMessage.From.Address := '[email protected]';
 MailMessage.Recipients.EMailAddresses := '[email protected]';
 MailMessage.Subject := 'Test';
 MailMessage.Body.Text := 'Hello, It is Just for test';

 SMTP.Connect;
 SMTP.Send(MailMessage);

Когда я запускаю его, он генерирует следующую ошибку

**ERROR: Must issue a STARTTLS command first. i29sm34080394wbp.22**

Как я могу это решить?


person ae1080    schedule 10.10.2011    source источник
comment
Вам следует ознакомиться с STARTTLS: en.wikipedia.org/wiki/STARTTLS и fastmail.fm/help/technology_ssl_vs_tls_starttls.html полезны.   -  person james.garriss    schedule 18.01.2013


Ответы (3)


Собрав ответы, вы получите следующий код. Не забывайте, как упоминалось в Nathanial Woolls _ 2_, чтобы поместить библиотеки libeay32.dll и ssleay32.dll, например, из _ 5_ в папку проекта или по пути из _ 6_.

uses
  IdMessage, IdSMTP, IdSSLOpenSSL, IdGlobal, IdExplicitTLSClientServerBase;

procedure SendEmail(const Recipients: string; const Subject: string; const Body: string);
var
  SMTP: TIdSMTP;
  Email: TIdMessage;
  SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  SMTP := TIdSMTP.Create(nil);
  Email := TIdMessage.Create(nil);
  SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);

  try
    SSLHandler.MaxLineAction := maException;
    SSLHandler.SSLOptions.Method := sslvTLSv1;
    SSLHandler.SSLOptions.Mode := sslmUnassigned;
    SSLHandler.SSLOptions.VerifyMode := [];
    SSLHandler.SSLOptions.VerifyDepth := 0;

    SMTP.IOHandler := SSLHandler;
    SMTP.Host := 'smtp.gmail.com';
    SMTP.Port := 587;
    SMTP.Username := '[email protected]';
    SMTP.Password := 'yourpassword';
    SMTP.UseTLS := utUseExplicitTLS;

    Email.From.Address := '[email protected]';
    Email.Recipients.EmailAddresses := Recipients;
    Email.Subject := Subject;
    Email.Body.Text := Body;

    SMTP.Connect;
    SMTP.Send(Email);
    SMTP.Disconnect;

  finally
    SMTP.Free;
    Email.Free;
    SSLHandler.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SendEmail('[email protected]', 'Subject', 'Body');
end;

Надеюсь на эту помощь

person TLama    schedule 10.10.2011
comment
Избавьтесь от присвоений свойствам SSLHandler.Destination, SSLHandler.Host и SSLHandler.Port. Эти свойства автоматически заполняются Connect(). - person Remy Lebeau; 11.10.2011

smtp.gmail.com заставляет вас использовать зашифрованное соединение с помощью STARTTLS.

Indy 9 не поддерживает STARTTLS напрямую, но indy 10 поддерживает.

В Indy 10 перед подключением к серверу вы должны назначить IOHandler с поддержкой SSL, например TIdSSLIOHandlerSocketOpenSSL,

См .: http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdSSLIOHandlerSocketOpenSSL.html

Добавьте следующий код:

var
...
SSLHandler: TIdSSLIOHandlerSocketOpenSSL;

SSLHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(Form1);
SMTP.IOHandler:= SSLHandler;
SMTP.UseTLS:= utUseExplicitTLS;
SMTP.Username:= 'username';
SMTP.Password:= 'password';
SMTP.Port:= 587; 

Если вы просто используете SMTP для незашифрованного SMTP-обработчика (SMTP вашего интернет-провайдера), у вас не возникнет этой проблемы.

person Johan    schedule 10.10.2011
comment
@Johna: сказать, что Indy 9 не поддерживает это, неверно. Indy 9 поддерживает шифрование SSL, но не поддерживает команду STARTTLS, которая требуется SMTP-серверу GMail. Однако вы можете отправить команду STARTTLS вручную, добавив несколько дополнительных строк кода. Что касается события OnGetPassword, это применимо только в том случае, если используется защищенный паролем сертификат SSL (что не относится к GMail). - person Remy Lebeau; 11.10.2011
comment
@ RemyLebeau-TeamB, спасибо, что указали на это, я давно не использовал Indy. - person Johan; 11.10.2011
comment
@RemyLebeau Можно ли отправить STARTTLS вручную с помощью Indy 8? У меня есть приложение, использующее Indy 8. Я могу отправлять электронные письма с использованием SSL-соединения, но только если сервер использует неявный TLS. Хочу добавить поддержку STARTTLS. Если возможно, скажите, пожалуйста, как - person CITBL; 21.07.2013

Ошибка связана с тем, что Gmail использует SSL и TLS. Вам нужно будет использовать обработчик ввода-вывода SSL от Indy, а также соответствующий OpenSSL DLL для вашей версии Indy.

Учебное пособие по получению этого рабочего здесь.

person Nathanial Woolls    schedule 10.10.2011