Hi,

It seems that there is an issue with the submission service when the SMTP 
server advertises chunking (I use Exim v4.91). I tried this with Dovecot v2.3.3 
and current master and could reproduce it with both versions.
My setup is that dovecot submission proxies to Exim on port 10025. The first 
mail gets through without any issues, but the second email will not get send. I 
had this issue at first with Apple Mail (it just sends a QUIT and shows an 
error) and could reproduce it with the OpenDMARC report perl script.

You can find a little Perl script attached to reproduce it. It seems to me that 
Dovecot sends an (unexpected or mixed up) second answer to the client. If I add 
a “$smtp->getline();” (line 110) sending multiple emails works again.

Another workaround is to disable CHUNKING in Exim (in this case only on the 
“proxy port”):

chunking_advertise_hosts = ${if eq{$received_port}{10025}{}{*}}

Thanks,
Paul

#!/usr/bin/env perl

use strict;
use warnings;

use File::Basename;
use Net::Domain qw(hostfqdn);
use Net::SMTP;

my $progname      = basename($0);
my $repdom        = "example.com";
my $sender        = 'sen...@example.com';
my $recipient     = 'u...@example.com';
my $smtp_server   = 'mail.example.com';
my $smtp_user     = 'sen...@example.com';
my $smtp_pass     = 'sender-password';
my $smtp_port     = 587;
my $smtp_use_tls  = 1;

my $verbose       = 1;
my $smtp;
my $smtp_sasl;
my $smtp_mech;
my $answer;
my $mailout;
my $domain;
my $smtpstatus;
my $smtpfail;

$smtp = Net::SMTP->new($smtp_server,
                       'Port' => $smtp_port,
                       'Hello' => hostfqdn(),
                       'Debug' => $verbose ? 1 : 0);
if (!defined($smtp))
{
  print STDERR "$progname: open SMTP server $smtp_server:$smtp_port failed\n";
  exit(1);
}

if ($smtp_use_tls)
{
  if (!$smtp->starttls(SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE))
  {
    print STDERR "$progname: SMTP starttls failed.\n";
    exit(1);
  }
}

if ($smtp_user && $smtp_pass)
{
  if ($smtp_mech)
  {
    $smtp_sasl = Authen::SASL->new(
      mechanism => $smtp_mech,
      callback  => {
        user => $smtp_user,
        pass => $smtp_pass,
        #authname => $smtp_user
      });
    if (!$smtp->auth($smtp_sasl))
    {
      print STDERR "$progname: SMTP AUTH failed.\n";
      exit(1);
    }
  }
  else
  {
    if (!$smtp->auth($smtp_user, $smtp_pass))
    {
      print STDERR "$progname: SMTP AUTH failed.\n";
      exit(1);
    }
  }
}

my @mails = (1, 2);
foreach (@mails) {
  $mailout  = "To: $recipient\n";
  $mailout .= "From: $sender\n";
  $mailout .= "Subject: Chunking Test $_\n";
  $mailout .= "\n";
  $mailout .= "Chunking Test...\n";
  $mailout .= "\n";

  $smtpstatus = "sent";
  $smtpfail = 0;
  if (!$smtp->mail($sender) ||
      !$smtp->to($recipient) ||
      !$smtp->data() ||
      !$smtp->datasend($mailout) ||
      !$smtp->dataend())
  {
    $smtpfail = 1;
    $smtpstatus = "failed to send";
  }

  if ($verbose || $smtpfail)
  {
    # now perl voodoo:
    $answer = ${${*$smtp}{'net_cmd_resp'}}[1] || $smtp->message() || 'unknown error';
    $answer =~ s/\r|\n//g;
    print STDERR "$progname: $smtpstatus mail sent to to $recipient ($answer )\n";
  }

  $smtp->reset();
  
  ########################################################
  # this is the line that fixed it if chunking on the mail server is supported
  # does not work if the server does NOT support chunking!
  # $smtp->getline();
}

$smtp->quit();

if ($verbose)
{
  print STDERR "$progname: terminating at " . localtime() . "\n";
}

exit(0);

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to