diff -Nur -x '*.orig' -x '*.rej' smeserver-qpsmtpd-1.2.1/root/etc/e-smith/templates/var/service/qpsmtpd/config/plugins/62tnef2mime mezzanine_patched_smeserver-qpsmtpd-1.2.1/root/etc/e-smith/templates/var/service/qpsmtpd/config/plugins/62tnef2mime --- smeserver-qpsmtpd-1.2.1/root/etc/e-smith/templates/var/service/qpsmtpd/config/plugins/62tnef2mime 1970-01-01 10:00:00.000000000 +1000 +++ mezzanine_patched_smeserver-qpsmtpd-1.2.1/root/etc/e-smith/templates/var/service/qpsmtpd/config/plugins/62tnef2mime 2006-11-22 16:11:58.296578417 +1100 @@ -0,0 +1,6 @@ +{ + return "# tnef to mime conversion disabled" + unless ($smtpd{tnef2mime} eq "enabled"); + return "tnef2mime"; +} + diff -Nur -x '*.orig' -x '*.rej' smeserver-qpsmtpd-1.2.1/root/usr/share/qpsmtpd/plugins/tnef2mime mezzanine_patched_smeserver-qpsmtpd-1.2.1/root/usr/share/qpsmtpd/plugins/tnef2mime --- smeserver-qpsmtpd-1.2.1/root/usr/share/qpsmtpd/plugins/tnef2mime 1970-01-01 10:00:00.000000000 +1000 +++ mezzanine_patched_smeserver-qpsmtpd-1.2.1/root/usr/share/qpsmtpd/plugins/tnef2mime 2006-11-22 16:12:46.971100622 +1100 @@ -0,0 +1,160 @@ +#!/usr/bin/perl -wT +=head1 NAME + +tnef2mime + +=head1 DESCRIPTION + +Plugin that converts ms-tnef attachments (winmail.dat) and uuencoded attachments to MIME. + +perl-Convert-TNEF, perl-IO-stringy, perl-File-MMagic and perl-MIME-tools are required. + +=head1 AUTHOR + +Michael Weinberger, neddix Stuttgart, 2005 + +=head1 LICENSE + +GNU GPL (GNU General Public License) + + +=cut + + +use MIME::Parser; +use MIME::Entity; +use MIME::Head; +use File::MMagic; +use Convert::TNEF; + +my $parser; +my $ent; +my $tmpdir='/var/spool/qpsmtpd'; +my $count=0; +my $foundtnef=0; +my (@attachments, @blocked, @tnefs); + + +sub register { + my ($self, $qp, %arg) = @_; + $self->register_hook("data_post", "tnef2mime"); +} + +# for future use +sub kill_part ($) + { + my $part=$_; + #my $path = defined $part->bodyhandle ? $part->bodyhandle->path : ""; + #my $filename = $part->head->recommended_filename || ""; + return $part; + } + +sub keep_part ($$) + { + my ($self,$part)=@_; + my $mm = new File::MMagic; + + # when a ms-tnef attachment was sent uuencoded, its MIME type becomes application/octet-stream + # after the conversion. Therefore all application/octet-stream attachments are assumed to + # be a ms-tnef + + my $path = $part->bodyhandle ? $part->bodyhandle->path : ""; + + if( $part->mime_type =~ /ms-tnef/i || $part->mime_type =~ /application\/octet-stream/i ) + { + # convert tnef attachments and write to files + my $tnef = Convert::TNEF->read_ent($part,{output_dir=>$tmpdir,output_to_core=>"NONE"}); + + # if $tnef is undefined here, the application/octet-stream was not a ms-tnef and we are done. + return 1 if( ! defined $tnef ); + + for ($tnef->attachments) + { + next if !defined $_->datahandle; + my $mimetype = $mm->checktype_filename( $_->datahandle->path ); + $attachments[$count] = MIME::Entity->build( + Path=>$_->datahandle->path, + Filename=>$_->longname, + Encoding=>"base64", + Type=>$mimetype ); + $self->log(LOGDEBUG, + sprintf "converted attachment #%i: %s (%s, %ld bytes)", $count+1, $_->longname, $mimetype, $_->size ); + $count++; + } + push( @tnefs, $tnef ); # remind for cleanup + $foundtnef=1; + return 0; + } + return 1; + } + + +sub tnef2mime ( $$ ) + { + my ($self, $transaction) = @_; + # new Parser Object + $parser = new MIME::Parser; + # temp output directory + $parser->output_under( $tmpdir ); + $parser->extract_uuencode(1); + + # read message body + open BFN, $transaction->body_filename(); + $ent = $parser->parse(\*BFN); + my @keep = grep { keep_part($self, $_) } $ent->parts; # @keep now holds all non-tnef attachments + close BFN; + + my $founduu = $ent->parts && !$transaction->header->get('MIME-Version'); + + if( $foundtnef || $founduu ) + { + my @allatt; + @allatt = map { kill_part($_) } ( @keep, @attachments ); + $ent->parts(\@allatt); + # if message is a multipart type, but has MIME version tag, then add + # MIME version. PHP imap_fetchstructure() depends on that! + my $xac; + if( $founduu ) + { + $transaction->header->add('MIME-Version', "1.0" ); + $xac = "UUENCODE -> MIME"; + $self->log(LOGDEBUG, "uuencoded attachment converted to MIME" ); + } + # delete the X-MS-TNEF-Correlator header line + if( $foundtnef ) + { + $xac .= ( defined $xac ? ", " : "" ) . "MS-TNEF -> MIME"; + $transaction->header->delete('X-MS-TNEF-Correlator' ); + } + # add own X header + if( defined $xac ) + { + $transaction->header->add('X-TNEF2MIME-Plugin', $xac ); + } + # write converted message body + open BFN, ">" . $transaction->body_filename(); + $ent->print(\*BFN); + close BFN; + } + + # cleaning up + for( my $i=0; $i<@tnefs; $i++ ) + { + $tnefs[$i]->purge(); + } + + my $output_dir = $parser->output_dir; + + opendir( DIR, $output_dir ) or die "Could not open temporary output dir $output_dir: $!\n"; + while( defined( my $file = readdir( DIR ) ) ) + { + next if $file =~ /^\.\.?$/; + $file =~ s/(^.*$)//; + $file = $1; + unlink( "$output_dir/$file" ); + } + closedir( DIR ); + rmdir( $output_dir ); + + return DECLINED; + }