Skip to content
mobius1qwe edited this page Nov 13, 2026 · 1 revision

Home > E-mail > Receber

Receber e-mail

Important

Em desenvolvimento (2.0). Ainda não está numa versão lançada e pode mudar.

Nível: intermediário

Em uma frase: TRALSMTPServer faz da sua aplicação um servidor SMTP: recebe mensagens de outros servidores (porta 25) e dos seus usuários (587 e 465, com login), e entrega cada uma ao seu código num evento.

Você vai precisar: o pacote RALModuleMailPackage (e-mail); para TLS, um certificado (arquivo PEM, ou o certificado automático) e a OpenSSL ao lado do executável. Para receber de fora, o registro MX do domínio apontando para a máquina e a porta 25 liberada.

Um servidor

uses RALSMTPServer;

  FServidor := TRALSMTPServer.Create(Self);
  FServidor.HostName := 'mx.minhaempresa.com.br';
  FServidor.SSL.CertFile := 'C:\MeuApp\cert.pem';
  FServidor.SSL.KeyFile := 'C:\MeuApp\key.pem';
  FServidor.SSL.Enabled := True;
  FServidor.Users.Add('vendas=senha');            // login de quem envia pela 587/465
  FServidor.OnRcptTo := ConferirDestinatario;
  FServidor.OnMessage := MensagemChegou;
  FServidor.Active := True;

procedure TForm1.ConferirDestinatario(Sender: TObject; ASession: TRALSMTPSession;
  const AAddress: StringRAL; var ACode: IntegerRAL; var AReply: StringRAL);
begin
  // na porta 25, só os domínios que são seus: senão você vira um "open relay"
  if (Pos('@minhaempresa.com.br', LowerCase(AAddress)) = 0) and not ASession.Authenticated then
  begin
    ACode := 550;
    AReply := '5.7.1 relay not permitted';
  end;
end;

procedure TForm1.MensagemChegou(Sender: TObject; ASession: TRALSMTPSession;
  AEnvelope: TRALSMTPEnvelope; AData: TStream; var ACode: IntegerRAL;
  var AReply: StringRAL);
var
  vMsg: TRALMailMessage;
begin
  vMsg := TRALMailMessage.Create;
  try
    vMsg.LoadFromStream(AData);
    // AEnvelope.From, AEnvelope.Recipients: o envelope; vMsg: a mensagem
    Gravar(AEnvelope, vMsg);
  finally
    vMsg.Free;
  end;
end;
  • Portas: Port (25) recebe de outros servidores; SubmissionPort (587, STARTTLS) e TLSPort (465, TLS desde o início, aberta só com SSL.Enabled) recebem dos seus usuários e exigem login. 0 fecha a porta.
  • Os eventos rodam na thread da conexão. Um OnMessage demorado segura as outras conexões daquela thread: grave e responda; o trabalho pesado vai para uma fila de jobs.
  • AData traz a mensagem com o cabeçalho Received do seu servidor na frente; até MemoryLimit (4 MB) fica na memória, acima disso num arquivo temporário. É liberada depois do evento: copie o que precisar.
  • Um ACode 4xx no OnMessage diz ao remetente "tente depois"; 5xx recusa.
  • Sem OnRcptTo todo destinatário é aceito: certo na 587 e na 465 (só quem fez login), um open relay na 25. Confira os domínios.
  • MaxMessageSize (25 MB) vai no SIZE do EHLO; MaxRecipients (100) e MaxConnections (1000) limitam o resto. A mensagem passa por blocos de 16 KB: uma de 100 MB não ocupa 100 MB de memória.

Login

Sem plugin de autenticação, o login confere Users (nome=senha). Com um plugin de autenticação ligado ao servidor (Authentication), o login passa por ele: TRALServerBasicAuth, ou um JWT como senha (PasswordIsToken). Os plugins de segurança também valem: lista de endereços, força bruta e inundação recusam como recusariam um pedido HTTP. Cada conexão nova passa pela lista de endereços e pela inundação antes da saudação.

mecanismo (AuthMethods) quando
ssaScramSHA256 sempre (a senha não atravessa a rede); usa Users ou OnSCRAMCredential
ssaPlain, ssaLogin só depois do TLS (AllowPlainAuthWithoutTLS só para testes)
ssaXOAuth2, ssaOAuthBearer o token vai ao plugin de autenticação como Bearer

RequireTLS exige STARTTLS antes do MAIL em todas as portas; RequireAuth exige login também na 25.

O verbo "Testar portas" (clique direito no componente) diz se as portas abrem e se o certificado carrega.

O que o servidor já cuida

  • PIPELINING, CHUNKING (BDAT), 8BITMIME, SMTPUTF8, SIZE, ENHANCEDSTATUSCODES.
  • Um comando enviado junto do STARTTLS é descartado (não roda dentro do TLS).
  • "SMTP smuggling": o fim da mensagem só vale como CRLF.CRLF; um LF.LF solto é conteúdo.
  • Linha longa demais, comandos inválidos em série e conexão parada (CommandTimeout, 5 minutos) fecham a conexão.

DKIM

TRALDKIMVerifier confere as assinaturas DKIM de uma mensagem recebida. A chave pública vem do DNS: responda OnKeyLookup com o TXT de seletor._domainkey.dominio.

  vResultados := TList.Create;
  try
    AData.Position := 0;
    if FVerificador.Verify(AData, vResultados) then
      ... // ao menos uma assinatura confere
    // cada TRALDKIMResult: Domain, Selector, Verdict (dkvPass, dkvFail...), Reason
  finally
    ...
  end;

Erros comuns

sintoma causa o que fazer
ninguém de fora consegue entregar porta 25 bloqueada (provedor, firewall) ou MX errado libere a 25; confira o MX
530 5.7.0 authentication required na 587 a submissão exige login Users ou um plugin de autenticação
538 5.7.11 no AUTH PLAIN PLAIN sem TLS STARTTLS antes, ou SCRAM
o servidor vira fonte de spam OnRcptTo não confere os domínios na 25 recuse destinatários de fora a quem não fez login
Active := True dá erro de porta outra aplicação na 25/587/465, ou porta < 1024 sem permissão no Linux "Testar portas"; outra porta atrás de redirecionamento

Veja também

Começar

Servidor

MQTT 🚧

E-mail 🚧

Cliente

Motores

Avançado

Ajuda

🚧 = em desenvolvimento, pode mudar

Clone this wiki locally