Por causa dessa modificação simples, muitos programas que antes conseguiam enviar email tranquilamente através do GMail falharam. Para piorar, a versão 9 do Indy não implementa nativamente o tratamento do TLS - isso só aconteceu a partir da versão 10. Ou seja, programas Delphi ou C++ Builder construídos com o Indy 9 não tinham uma solução fácil à mão para essa questão.
Na versão 10 do Indy, a solução é extremamente simples : basta configurar a propriedade UseTLS da instância de IdSMTP e manter as demais configurações:
IdSMTP1.UseTLS := utUseExplicitTLS;
Manter as demais configurações significa que o servidor deve continuar sendo smtp.gmail.com, a porta 587, com autenticação de usuário e senha. Também é obrigatório atribuir um handler para tratar a comunicação SSL/TLS. Para mais informações sobre isso e outros aspectos das configurações básicas, veja este post.
Embora não seja um processo tão direto, é possível trabalhar com TLS em Indy 9. Basicamente, é preciso enviar ao servidor de email um comando STARTTLS logo após o SMTP ter se conectado. O trecho abaixo é um código genérico que testa configurações internas para determinar se a conexão é segura. Em caso positivo, um handler é destacado para fazer o tratamento da conexão. Neste ponto, o SMTP já foi preparado com as configurações básicas necessárias.
if (TipoSeguranca = SEGURANCA_SSL) Or (TipoSeguranca = SEGURANCA_TLS) then
begin
IdSMTP.IOHandler := IdSSLIOHandlerSocket;
if (TipoSeguranca = SEGURANCA_TLS) then
begin
IdSSLIOHandlerSocket.SSLOptions.Method := sslvTLSv1;
IdSSLIOHandlerSocket.PassThrough := true;
end;
end;
{ Tenta conectar no servidor com 1 minuto de timeout }
IdSMTP.Connect (60000);
{ Emula o comportamento do TLS }
if (TipoSeguranca = SEGURANCA_TLS) then
begin
IdSMTP.SendCmd('STARTTLS', 220);
IdSSLIOHandlerSocket.PassThrough := false;
end;
if (Autentica And (not IdSMTP.Authenticate () ) then
Raise Exception.Create ('Falha na autenticação do usuário');
begin
IdSMTP.IOHandler := IdSSLIOHandlerSocket;
if (TipoSeguranca = SEGURANCA_TLS) then
begin
IdSSLIOHandlerSocket.SSLOptions.Method := sslvTLSv1;
IdSSLIOHandlerSocket.PassThrough := true;
end;
end;
{ Tenta conectar no servidor com 1 minuto de timeout }
IdSMTP.Connect (60000);
{ Emula o comportamento do TLS }
if (TipoSeguranca = SEGURANCA_TLS) then
begin
IdSMTP.SendCmd('STARTTLS', 220);
IdSSLIOHandlerSocket.PassThrough := false;
end;
if (Autentica And (not IdSMTP.Authenticate () ) then
Raise Exception.Create ('Falha na autenticação do usuário');
Ao detectar que a conexão segura exige TLS, alguns ajustes precisam ser feitos. Primeiro, mudo o método de segurança do handler para que adote o padrão para TLS. Depois, instruo o handler a codificar os comandos trocados entre ele e o servidor. Só então, podemos estabelecer a conexão.
Uma vez que a conexão está estabelecida, enviamos ao servidor o comando STARTTLS para ativar a comunicação segura na mesma porta. Por causa disso, o PassThrough que forçamos antes da conexão já pode ser desligado.
Autenticar manualmente o usuário e a senha é um preciosismo pois o método Send para envio da mensagem o fará por nós. Aqui no exemplo foi feita a autenticação explícita pra mostrar que é possível interceptar um erro de usuário/senha inválido antes de se tentar enviar a mensagem.
Agora, é só preparar uma instância do idMessage com os dados da mensagem (destinatários, assunto, corpo da mensagem, etc.) e enviá-la com o SMTP.
As considerações tecidas neste post também são válidas para quem usa o Hotmail como serviço para envio de email em suas aplicações. Há apenas duas diferenças importantes : o servidor de email, claro, é outro (smtp.live.com); também a forma de se especificar o usuário do serviço difere. No GMail, deve ser usado como nome do usuário somente o texto que vem antes do arroba (@) do endereço de email, enquanto no Hotmail o nome do usuário é o endereço completo.


