How to Convert Mail Attachments Received in TNEF Format

Email messages sent with Microsoft Outlook sometimes use the Rich Text format, or TNEF format. Such messages, when read using other email clients, contain a single attachment named winmail.dat, and any files that the sender may have attached to the message cannot be opened. This article describes how to integrate Axigen with MIMEDefang with the purpose to convert such attachments to a readable format.

Solution

Email messages sent with Microsoft Outlook sometimes use the Rich Text format, or TNEF format. Such messages, when read using other email clients, contain a single attachment named winmail.dat, and any files that the sender may have attached to the message cannot be opened. This article describes how to integrate Axigen with MIMEDefang with the purpose to convert such attachments to a readable format.

The configuration described in this article was tested on CentOS 6 and on Ubuntu 12.04.


1. Install MIMEDefang

On CentOS 6, the mimedefang package is not available in the default repositories. It can be installed by enabling the EPEL repository. Instructions about enabling the EPEL repositories are available at:

https://fedoraproject.org/wiki/EPEL

After enabling EPEL, install MIMEDefang with the command:

yum install mimedefang
On Ubuntu 12.04, the command to install the package is:

apt-get install mimedefang
2. Configure MIMEDefang to listen on the required TCP port

Edit the folowing file:

- On CentOS 6: /etc/sysconfig/mimedefang

- On Ubuntu 12.04: /etc/default/mimedefang

and add the line:

SOCKET=inet:10084
The port used in this example is 10084 but a different available port can be chosen.


3. Edit the /etc/mail/mimedefang-filter file and add the following minimal configuration:


#---cut here---

# -*- Perl -*-
#***********************************************************************
#
# mimedefang-filter
#
# Suggested minimum-protection filter for Microsoft Windows clients, plus
# SpamAssassin checks if SpamAssassin is installed.
#
# Copyright (C) 2002 Roaring Penguin Software Inc.
#
# This program may be distributed under the terms of the GNU General
# Public License, Version 2, or (at your option) any later version.
#
# $Id$
#***********************************************************************

#***********************************************************************
# Set administrator's e-mail address here.  The administrator receives
# quarantine messages and is listed as the contact for site-wide
# MIMEDefang policy.  A good example would be 'defang-admin@mydomain.com'
#***********************************************************************
$AdminAddress = 'postmaster@localhost';
$AdminName = "MIMEDefang Administrator's Full Name";

#***********************************************************************
# Set the e-mail address from which MIMEDefang quarantine warnings and
# user notifications appear to come.  A good example would be
# 'mimedefang@mydomain.com'.  Make sure to have an alias for this
# address if you want replies to it to work.
#***********************************************************************
$DaemonAddress = 'mimedefang@localhost';

#***********************************************************************
# If you set $AddWarningsInline to 1, then MIMEDefang tries *very* hard
# to add warnings directly in the message body (text or html) rather
# than adding a separate "WARNING.TXT" MIME part.  If the message
# has no text or html part, then a separate MIME part is still used.
#***********************************************************************
$AddWarningsInline = 0;

#***********************************************************************
# To enable syslogging of virus and spam activity, add the following
# to the filter:
# md_graphdefang_log_enable();
# You may optionally provide a syslogging facility by passing an
# argument such as:  md_graphdefang_log_enable('local4');  If you do this, be
# sure to setup the new syslog facility (probably in /etc/syslog.conf).
# An optional second argument causes a line of output to be produced
# for each recipient (if it is 1), or only a single summary line
# for all recipients (if it is 0.)  The default is 1.
# Comment this line out to disable logging.
#***********************************************************************
md_graphdefang_log_enable('mail', 1);

#***********************************************************************
# Uncomment this to block messages with more than 50 parts.  This will
# *NOT* work unless you're using Roaring Penguin's patched version
# of MIME tools, version MIME-tools-5.411a-RP-Patched-02 or later.
#
# WARNING: DO NOT SET THIS VARIABLE unless you're using at least
# MIME-tools-5.411a-RP-Patched-02; otherwise, your filter will fail.
#***********************************************************************
# $MaxMIMEParts = 50;

#***********************************************************************
# Set various stupid things your mail client does below.
#***********************************************************************

# Set the next one if your mail client cannot handle multiple "inline"
# parts.
$Stupidity{"NoMultipleInlines"} = 0;

# Detect and load Perl modules
detect_and_load_perl_modules();


sub filter {
    my($entity, $fname, $ext, $type) = @_;
 
    ### Convert TNEF winmail.dat format
    ### Note: You must install Convert::TNEF and File::Type from CPAN before using this script
    if (lc($type) eq "application/ms-tnef" or lc($fname) eq "winmail.dat" ) {
        use Convert::TNEF;
        use File::Type;
        use File::Temp qw(tempfile tempdir);
 
        # Create a unique temporary directory under "/tmp"
        my $tnefdir = tempdir(CLEANUP => 1, DIR => "/tmp");
        if (not $tnefdir) {
                md_graphdefang_log('tnef_fail',"Unable to create temporary directory");
                return action_accept();
        }
 
        # If we can't Convert the TNEF file for some reason, just accept the attachment and log the error
        my $tnef = Convert::TNEF->read_ent($entity,{output_dir=>"$tnefdir"});
        if (not $tnef) {
                md_graphdefang_log('tnef_fail',$Convert::TNEF::errstr);
                return action_accept();
        }
 
        my $ft = File::Type->new();
 
        # Append attachments contained in the winmail.dat file to the message.
        for ($tnef->attachments) {
             # Determine the mime-type of the file
             my $mimetype = $ft->mime_type($_->data);
 
                # File::Type doesn't detect text files well, this is a workaround
             if ($mimetype eq "application/octet-stream") {
                  #Set the mime-type to text/plain if the first 1024 characters are printable
                  $text_check = substr($_->data,0,1024);
                  $mimetype = "text/plain" unless $text_check =~ /[^[:print:]s]/;
             }
 
             my $tnef_entity = action_add_part($entity, "$mimetype", "base64", $_->data, $_->longname, "attachment");
             md_graphdefang_log('tnef_ext', "File: " . $_->longname . " Type: $mimetype");
 
             # Run each new TNEF-sourced MIME part back through the filter again, this ensures that bad filenames etc.
             # cannot sneak through by being contained in winmail.dat files
 
             filter ($tnef_entity, $_->longname, "", "$mimetype");
        }
 
        # Deletes working files
        $tnef->purge;

 
        # Remark this if you want still want to keep the original winmail.dat file
        return action_drop();
    }
 
    # Keep the attachment
    return action_accept();
}

# DO NOT delete the next line, or Perl will complain.
1;


#---cut here---

4. The Convert::TNEF and File::Type Perl modules need to be installed.


On CentOS 6:

- the Convert::TNEF module was installed with the command:

yum install perl-Convert-TNEF.noarch
- the File::Type module was not found in the repositories enabled on the test machine. It was downloaded from the link:

http://pkgs.org/centos-6/repoforge-i386/perl-File-Type-0.22-1.el6.rf.noarch.rpm.html

and then installed with the command:

yum install perl-File-Type-0.22-1.el6.rf.noarch.rpm
On Ubuntu 12.04, the two modules were installed with the commands:

apt-get install libconvert-tnef-perl
apt-get install libfile-type-perl

Alternatively, the modules can be installed using CPAN.


5. Verify the syntax of the mimedefang-filter file:

# perl -c /etc/mail/mimedefang-filter
6. Start MIMEDefang:

/etc/init.d/mimedefang restart
Check that the process runs and that it listens on the defined TCP port:

# netstat -tlpn | grep 10084
tcp        0      0 0.0.0.0:10084           0.0.0.0:*               LISTEN      7401/mimedefang
#



Axigen Configuration

Open the Axigen Webadmin interface and navigate to the following section:

Security & Filtering -> Acceptance & Routing -> Advanced Settings

Add the below two rules for using the mimedefang filter:

Rule 1:

- press the 'Add Acceptance/Routing Rule' Button

- Type a suggestive Rule name such as 'mimedefang_define'

- Unless otherwise required, leave the Conditions section unmodified as the default policies will apply to all SMTP connections

- From the Actions section, making use of the drop-down box select Filters -> Add Filter and click the '+Add Action' button. You should next define a corresponding name for this filter (for example, mimedefang). Note that this name can be used for tracking the filter entries in the Axigen log entries. Also fill the Address field with the connection address of the MIMEDefang's MILTER listener.


Example:

Name: mimedefang
Address: inet://127.0.0.1:10084


By selecting to Save Configuration the new filter details will be saved.



Rule 2:
In order to activate the filter, from the same Advanced Settings context you will create a second rule that will ensure the filter execution.

- press the 'Add Acceptance/Routing Rule' Button

- type a suggestive Rule name such as 'mimedefang_execute'

- leave the Conditions section unmodified

- in the Actions section select the 'Execute filters' option from the Filters category and press the '+ Add Action' button. Fill the 'Name pattern' field with the name of the previously defined filter, in our case 'mimedefang'.

Finally, press the Save configuration button in order to activate this rule.



After this point, all the server's traffic will be will be processed by this filter.
OS: LinuxWindowsFreeBSDMACOpenBSDNetBSDSolaris
Distros: DEB based distros amd64RPM based distros x64DEB based distros amd64