From 8aa51012b330dbbcaf67e096ef0b4f09badfdeb2 Mon Sep 17 00:00:00 2001 From: Shawn Iverson Date: Wed, 27 Dec 2023 08:57:30 -0500 Subject: [PATCH] Support new Exim Message-ID format (#673) --- common/etc/MailScanner/MailScanner.conf | 5 +++ common/usr/sbin/MailScanner | 31 ++++++++++++++ .../perl/MailScanner/ConfigDefs.pl | 3 +- .../perl/MailScanner/EximDiskStore.pm | 40 +++++++++++++++---- 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/common/etc/MailScanner/MailScanner.conf b/common/etc/MailScanner/MailScanner.conf index aaf1f89e..1072f5c4 100644 --- a/common/etc/MailScanner/MailScanner.conf +++ b/common/etc/MailScanner/MailScanner.conf @@ -291,6 +291,11 @@ Sendmail = /usr/lib/sendmail #Sendmail2 = /usr/sbin/sendmail -C /etc/exim/exim_send.conf Sendmail2 = /usr/lib/sendmail +# Path to Exim binary, used to check version for proper Message-ID +# handling. Will try to look for exim automatically if not set. Set this to +# the the exim command full path if necessary. +Exim Command = + # # Incoming Work Dir Settings # -------------------------- diff --git a/common/usr/sbin/MailScanner b/common/usr/sbin/MailScanner index 5470d76d..fef3fff2 100644 --- a/common/usr/sbin/MailScanner +++ b/common/usr/sbin/MailScanner @@ -373,6 +373,37 @@ my($MTAmod, $MTADSmod); $_=MailScanner::Config::QuickPeek($ConfFile, 'mta'); $_='sendmail' if $WantLintOnly || $WantLintLiteOnly || $WantRuleCheck; if (/exim/i) { + # Check for version >= 4.97 + my $eximcommand = MailScanner::Config::QuickPeek($ConfFile, 'eximcommand'); + if ($eximcommand eq "") { + # try to find exim + eval { + $eximcommand = `which exim`; + } + if ($@ || $eximcommand eq "") { + print STDERR "Exim binary not found. Please supply the full path to Exim Command in MailScanner.conf"; + exit 1; + } + } + # Get exim version + my @out; + my @line; + my $ver; + eval { + @out = `$eximcommand -bV`; + @line = split(/ /, $out[0]); + $ver = $line[2]; + $ver =~ /\d+\.\d+/; + } + if ($@) { + print STDERR "Unable to obtain version of Exim. Please check the path to Exim Command in MailScanner.conf"; + exit 1; + } + if ($ver >= 4.97) { + MailScanner::Config::SetValue('eximlongids',1); + } else { + MailSCanner::Config::SetValue('eximlongids',0); + } $MTAmod = 'Exim.pm'; $MTADSmod = 'EximDiskStore.pm'; } elsif(/zmailer/i) { diff --git a/common/usr/share/MailScanner/perl/MailScanner/ConfigDefs.pl b/common/usr/share/MailScanner/perl/MailScanner/ConfigDefs.pl index 62579345..53f88ed8 100644 --- a/common/usr/share/MailScanner/perl/MailScanner/ConfigDefs.pl +++ b/common/usr/share/MailScanner/perl/MailScanner/ConfigDefs.pl @@ -278,6 +278,7 @@ msmaildeliverymethod = MSMailDeliveryMethod msmailsockettype = MSMailSocketType msmailsocketdir = MSMailSocketDir +eximcommand = EximCommand # # Simple variables which can only have a single value, no rules allowed. @@ -319,7 +320,6 @@ stilldeliverunscannable 0 no 0 yes 1 retrybatchscanner 1 no 0 yes 1 - # These should be checked for dir existence [Simple,Dir] incomingworkdir /var/spool/MailScanner/incoming @@ -457,6 +457,7 @@ KseSocket /var/run/kse/kse.sock FsecureSocket /tmp/.fsav-0 SAVIDSocket /var/lib/savdid/savdid.sock +EximCommand # # These variables match on any rule matching From:, else anything for To: diff --git a/common/usr/share/MailScanner/perl/MailScanner/EximDiskStore.pm b/common/usr/share/MailScanner/perl/MailScanner/EximDiskStore.pm index 0b171f53..a6b557d6 100644 --- a/common/usr/share/MailScanner/perl/MailScanner/EximDiskStore.pm +++ b/common/usr/share/MailScanner/perl/MailScanner/EximDiskStore.pm @@ -1,6 +1,6 @@ # # MailScanner - SMTP Email Processor -# Copyright (C) 2002 Julian Field +# Copyright (C) 2023 MailScanner Project # # $Id: EximDiskStore.pm 4446 2008-05-08 19:15:02Z sysjkf $ # @@ -208,9 +208,16 @@ sub DoPendingDeletes { # whether the spool is split or not. sub OutQDir { my $name = shift; + my $offset; + + if (MailScanner::Config::Value('eximlongids') =~ /1/) { + $offset = -20; + } else { + $offset = -13; + } if (MailScanner::Config::Value('spliteximspool')) { - return '/' . substr($name,-13,1) . '/'; + return '/' . substr($name,$offset,1) . '/'; } else { return '/'; } @@ -433,9 +440,18 @@ sub WriteEntireMessage { # We have to strip the message-ID off the beginning of the file # using sysread since that is what File::Copy uses and it doesn't # play nicely with stdio operations such as $body->getline. The - # magic number 19 is from the length of NNNNNN-NNNNNN-NN-D\n. + # magic number 19 or 26 is from the length of message-ID in file\n. my $discard; - sysread($body, $discard, 19); + + my $offset; + + if (MailScanner::Config::Value('eximlongids') =~ /1/) { + $offset = 26; + } else { + $offset = 19; + } + + sysread($body, $discard, $offset); copy($body, $handle); @@ -509,17 +525,25 @@ sub ReadMessageHandle { # We have to strip the message-ID off the beginning of the file # using sysread since that is what File::Copy uses and it doesn't # play nicely with stdio operations such as $body->getline. The - # magic number 19 is from the length of NNNNNN-NNNNNN-NN-D\n. + # magic number 19 or 26 is from the length of message-ID in file\n. my $from_h = \do { local *FH1 }; open($from_h, "< $dhandle"); binmode $from_h or die "($!,$^E)"; - sysseek($from_h, 19, 0); + my $offset; + + if (MailScanner::Config::Value('eximlongids') =~ /1/) { + $offset = 26; + } else { + $offset = 19; + } + + sysseek($from_h, $offset, 0); my $size; my $buf = ""; my $lasteol = ' '; - my $dlength = -s $dhandle; # Catch case where -D file is 0 (ie 19) bytes + my $dlength = -s $dhandle; # Catch case where -D file is 0 (ie 19 or 26) bytes $size = $dlength; $size = 1024 if ($size < 512); $size = 1024*1024*2 if $size > 1024*1024*2; @@ -538,7 +562,7 @@ sub ReadMessageHandle { # Need to ensure the end of the file is and new-line character, # unless it's a 0 length file. - if ($lasteol !~ /[\n\r]/s && $dlength>19) { + if ($lasteol !~ /[\n\r]/s && $dlength>$offset) { $lasteol = "\n"; syswrite($to_h, $lasteol); }