10 апреля 2010 г.

Отправка почты с SSL шифрование (Indy 10 + Open SSL)

Такие почтовые сервера как Google, Yahoo или MSN требуют при авторизации на своих SMTP серверах  использовать шифрование SSL.
В данном посте я расскажу как отправлять почту из программ написанных на Delphi используя шифрование SSL.
Нам понадобится:
  • Indy версии 10, поскольку в нем добавлена возможность использования Open SSL (9 версия не подойдет). Я использовал версию 10.0.52 (взять можно тут)
  • Пакет Open SSL, у меня стабильно заработал с версией 0.9.8h

Устанавливаем Indy 10.

Перед установкой необходимо удалить предыдущую версию Indy. Для этого идем по меню Component-Install Packages и удалем все со словом Indy.
Следующим шагом распаковываем архив скачанный с сайта Indy
 Теперь необходимо добавить пути Library path. Для этого переходим по пункту Tools-Environment Options-Library и добавляем Library path пути к следующим папкам
  1. System
  2. Core
  3. Protocols
  4. Super Core 

Теперь открываем и компилируем пакеты в следующем порядке:
  1. пакет IndySystemX0.dpk (где X – это версия Delphi) (папка System)
  2. пакет IndyCoreX0.dpk (где X- это версия Delphi) (папка Core)
  3. пакет IndyProtocolsX0.dpk (где X – это ваша версия Delphi) (папка Protocols).
  4. пакет IndySuperCore70.dpk  (для Delphi 7) (папка Super Core)

Далее открываем и устанавливаем:
  1. пакет dclIndyCoreX0.dpk (папка Core)
  2. пакет dclIndySuperCore70.dpk   (папка Super Core) только для Delphi 7
  3. пакет dclIndyProtocolsX0.dpk (папка Protocols)

Установка Indy завершена.


Установка Open SSL.

Установка  Open SSL не требуется. Все что необходимо, распаковать DLL библиотеки в каталог с проектом.


Собственно отправка почты.

Кидаем на форму следующие компоненты:
idMessage, idSMTP, IdSSLIOHandlerSocketOpenSSL

Теперь пишем вот такой код:
{формируем тело сообщения}
IdMessage1 := TIdMessage.Create;
IdMessage1.From.Address := Fromadres.Text;
IdMessage1.Recipients.EMailAddresses := Toadres.Text;
IdMessage1.Subject := UTF8Encode(subject.Text);
IdMessage1.Date:= now;

{настройка компонентов перед отправкой}
IdSMTP := TIdSMTP.Create(nil);

IdSMTP.Host:=ed_smtpserver.Text;
IdSMTP.Port:=ed_port.text; // обычно при использование ssl 495, 587 или стандартный 25
IdSMTP.Username:=login.Text;
IdSMTP.Password:=ed_.pass.Text;
IdSMTP.AuthType:=atDefault;

{это необходимо использовать для SSL}
IdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
IdSSLIOHandlerSocketOpenSSL.Destination := IdSMTP.Host+':'+IntToStr(IdSMTP.Port);
IdSSLIOHandlerSocketOpenSSL.Host := IdSMTP.Host;
IdSSLIOHandlerSocketOpenSSL.Port := IdSMTP.Port;
IdSSLIOHandlerSocketOpenSSL.DefaultPort := 0;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.Method := sslvTLSv1;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.Mode := sslmUnassigned;

IdSMTP.IOHandler := IdSSLIOHandlerSocketOpenSSL;
IdSMTP.UseTLS := utUseExplicitTLS;

{отправляем письмо}
IdSMTP.Connect();
except
MessageBox(handle,pchar('ОШИБКА!!! Подключение к SMTP серверу не удалось'+#10+#13+
'Проверьте настройки программы, а так же не блокируется ли'+#10#13+
'порт SMTP сервера антивирусом или файреволом(брандмауэром)'), pchar(Mail.Caption), 48);
exit;
end;
IdSMTP.Send(IdMessage1);
Application.ProcessMessages;
IdSMTP.Disconnect;
на событие OnClose вешаем следующее:
{очищаем память}
idMessage1.Free;
IdSSLIOHandlerSocketOpenSSL.Free;
idSMTP.Free;
Вот собственно и все. Жду ваших комментариев.

10 комментариев:

  1. Скачал отсюда 10 indy. Установил. Скомпилировал проект. И тут же Avira детектировал в exe-шке троян. Нужен другой исходник Indy

    ОтветитьУдалить
  2. это ложное срабатывание скорее всего. Ссылка дана на официальный дистрибутив. Проверил файл на virustotal.com ни один из 43 антивирусов не нашел вирус. Попробуйте обновить свой антивирус до последней версии (как базы, так и сам антивирус).
    Вот отчет с virustotal.com
    http://www.virustotal.com/file-scan/report.html?id=7ffa33d2589a5b6b96554e025a5f02dfb969fd68bff6eacbd6c286938fac139f-1283411100

    ОтветитьУдалить
  3. Перепробовал кучу версий Indy 10 в Delphi 7, всё равно Avira срабатывает (обновляется каждый день). Поставил CodeGear™ Delphi® 2009, - пример скомпилировался без проблем.
    Вообще у Indy всегда была не совместимость в низ. Поэтому разумно устанавливать несколько версий Delphi не трогая компонентов.

    З.Ы. Как проверю работу с yandex и gmail отпишусь

    ОтветитьУдалить
  4. Спасибо очень понятно все расписали.
    Вот только почему то ругается на библиотеку libeaY32.dll
    "Порядковый номер 4540 не найден в библиотеке DLL Libeay32.dll"

    Ошибку закрываешь и письмо отправлено. Если повторно отправить письмо, то ошибки нет. Странно...
    Пробовал менять dll на другие версии, менялись только номера ошибок. Пробовал удалять dll c system32, результата нет.
    Indy 10.
    Пробовал отправку на smtp.gmail.com

    ОтветитьУдалить
  5. ХА, уже думал Synapse попробовать, читал тему, там указали скачать Openssl-0.9.8d-Win32
    Скачал и на моё удивление заработало без ошибок. (хотя я точно помню что качал такую же версию openssl)
    Мораль такова "Не все библиотеки одинаково полезны!", пробуйте разные.

    ОтветитьУдалить
  6. Установил Indy 10.0.52, скомпилил пример, при попытке отправки ругается на 'Could not open ssl library' или что-то в этом духе. Нашел дллки, подкинул в папку с exe, эффекта ноль. Скачал и установил Win32OpenSSL_Light-1_0_1c.exe, при отправке так же ругается и не отправляет. В чем может быть трабл?

    ОтветитьУдалить
    Ответы
    1. тоже самое.
      компоненты установлены.
      ссл пробывал разных версий.
      ошибка таже.

      Удалить
  7. Попробовал - получилось. Было у меня правда через яндекс по 25 порту, добавил компонент IdSSLIOHandlerSocketOpenSSL, поменял порт, хост и там по мелочи, да, еденичку к компоненту дорисовал:) Все работает и через гугловский джмаил теперь. Спасибо!

    ОтветитьУдалить
  8. спасибо огромное за статью,очень долго искал,и вот она,единственная полезная и рабочая статья.с отправкой почты с использованием ssl

    ОтветитьУдалить
  9. Спасибо! Очень хорошая статья, было интересно!

    ОтветитьУдалить