diff -Nur --no-dereference smeserver-qpsmtpd-2.7.0.old/root/usr/share/qpsmtpd/plugins/tnef2mime smeserver-qpsmtpd-2.7.0/root/usr/share/qpsmtpd/plugins/tnef2mime --- smeserver-qpsmtpd-2.7.0.old/root/usr/share/qpsmtpd/plugins/tnef2mime 2008-10-07 11:05:17.000000000 -0400 +++ smeserver-qpsmtpd-2.7.0/root/usr/share/qpsmtpd/plugins/tnef2mime 2021-09-17 00:33:10.776000000 -0400 @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -w =head1 NAME tnef2mime @@ -19,9 +19,56 @@ =cut - - use MIME::Parser; +{ +# this is a dirty fix regarding this bug https://rt.cpan.org/Ticket/Display.html?id=97886 +# this way we can keep on usinhg this plugin waiting for the upstream fix +# the no warnings avoid message in qpsmtpd log on every mails saying we override the sub. +no warnings; +*MIME::Parser::Filer::output_path = sub { + my ($self, $head) = @_; + + ### Get the output directory: + my $dir = $self->output_dir($head); + + ### Get the output filename as UTF-8 + my $fname = $head->recommended_filename; + + ### Can we use it: + if (!defined($fname)) { + $self->debug("no filename recommended: synthesizing our own"); + $fname = $self->output_filename($head); + } + elsif ($self->ignore_filename) { + $self->debug("ignoring all external filenames: synthesizing our own"); + $fname = $self->output_filename($head); + } + elsif ($self->evil_filename($fname)) { + + ### Can we save it by just taking the last element? + my $ex = $self->exorcise_filename($fname); + if (defined($ex) and !$self->evil_filename($ex)) { + $self->whine("Provided filename '$fname' is regarded as evil, ", + "but I was able to exorcise it and get something ", + "usable."); + $fname = $ex; + } + else { + $self->whine("Provided filename '$fname' is regarded as evil; ", + "I'm ignoring it and supplying my own."); + $fname = $self->output_filename($head); + } + } + $self->debug("planning to use '$fname'"); + + #untaint dir and fname + $self->debug("it is our own"); + $fname = ($fname =~ m/^([ \w_.:%-]+)$/ig) ? $1 : $self->output_filename($head); + ### Resolve collisions and return final path: + return $self->find_unused_path($dir, $fname); +}; +} + use MIME::Entity; use MIME::Head; use File::MMagic; @@ -117,13 +164,18 @@ my ($self, $transaction) = @_; # new Parser Object $parser = new MIME::Parser; + # if you want to debug the Parser : + #use MIME::Tools; MIME::Tools->debugging(1); # temp output directory $parser->output_under( $tmpdir ); $parser->extract_uuencode(1); + #untainted filename + $transaction->body_filename() =~ /^([:\-\/\w]+)\z/ or die "Disallowed characters in filename ".$transaction->body_filename(); + my $bdfilename = $1; # read message body - open BFN, $transaction->body_filename(); - $ent = $parser->parse(\*BFN); + open BFN, "<", $bdfilename ;#$transaction->body_filename(); + $ent = $parser->parse(\*BFN); my @keep = grep { keep_part($self, $_) } $ent->parts; # @keep now holds all non-tnef attachments close BFN; @@ -155,7 +207,7 @@ $transaction->header->add('X-TNEF2MIME-Plugin', $xac ); } # write converted message body - open BFN, ">" . $transaction->body_filename(); + open BFN, ">" , $bdfilename;#$transaction->body_filename(); $ent->print(\*BFN); close BFN; } @@ -166,7 +218,9 @@ $tnefs[$i]->purge(); } - my $output_dir = $parser->output_dir; + #untainted filename + $parser->output_dir =~ /^([:\-\/\w]+)\z/ or die "Disallowed characters in output dir ".$parser->output_dir; + my $output_dir = $1; opendir( DIR, $output_dir ) or die "Could not open temporary output dir $output_dir: $!\n"; while( defined( my $file = readdir( DIR ) ) )