HOWTO remove attachements from a mail and make them available through the Web (via URL)

This feature bases on the function action_replace_with_url and patches by Jeremy Mates (http://lists.roaringpenguin.com/pipermail/mimedefang/2003-June/014908.html). You'll need a server capable of serving files, usually a Webserver, but a FTP server will do as well. MIMEDefang and the server must share a directory, into which MIMEDefang will write and the server will read from.

I will proceed assuming you use a Web-Server :-).

The security implications are such:
MIMEDefang will remove the attachment from the mail and save it into a file named «sha1_from_content».«original_extension». That means:
a) that the original filename except the extension is lost (but can be preserved, see below), and
b) that it is unlikely that someones can guess the filename unless he already got hold of the content. That's why there is no strong need to protect the shared file except for:

  1. First, create a directory into which the MIMEDefang user can write and the Webserver can read from, e.g.:
    drwxr-x---    2 mdefang  www-data     8192 Jun 16 12:16 /var/spool/MIMEDefang_Captured_Files
    The directory is owned by the mimedefang user, which can read and write it, the webserver can read its content, all others are denied.
    These permissions will cover the first security consideration above.
  2. Setup the server to serve the files in this directory, e.g. for the Apache, you can add this section:
    # MIME Defang captured files
    Alias /captured_mailfiles/        /var/spool/MIMEDefang_Captured_Files/
    
    <Directory "/var/spool/MIMEDefang_Captured_Files">
            AddDefaultCharset Off
            DefaultType application/octet-stream
            Options None
            AllowOverride None
            Order allow,deny
            Allow from all
    </Directory>
    Note: It is strongly advisable to not allow directory indexing, otherwise you might leak information, because anyone can easily read any file your server recieved and you've ordered MIMEDefang to capture.
    All two security considerations above are covered now.

    Surf to http://url_server/captured_mailfiles/, you should see a denial error.

    Then create a test file there, e.g. named test, and try to access it, it must work.

  3. Setup MIMEDefang to actually put some files there.

    Attachments are available in the function filter only. Hence, you'll have to wind up some logic to decide which attachements are entitled for distributing via Web rather than email. My filter contains this code: Note: $entity is the first argument of the sub filter, $lcType is the lc() of the forth argument (the supposed content type), $friendlyName is a humanized and securified version of the file name (the second argument), all other variables are computed by the filter.

       # We are a leaf, replace non-text/* MIME Attachments
    if($oneRcptIsLargeList || $oneRcptIsList && !$isAuthed) {
    	 if($lcType eq 'message/delivery-status') {
    		 md_graphdefang_log('dsn_to_list', $lcType, '');
    		 return action_bounce("Protect list against wrongly routed DSNs - rejected");
    	 }
    	if($lcType =~ /^text\// || $lcType eq 'application/x-pkcs7-signature') {
    		skahead "Keeping MIME attachment '$friendlyName' of $lcType";
    	} else {
    		my $size = (stat($entity->bodyhandle->path))[7];
    		if($size >= 10*1024) {          # larger than 10KB
    			if($size > 1024) {
    				$size = int($size / 1024);
    				if($size > 1024) {
    					$size = int($size / 1024);
    					$size .= 'MB';
    				} else {
    					$size .= 'KB';
    				}
    			} else {
    				$size .= "B";
    			}
    			skahead "Replace $lcType '$friendlyName' ($size) with URL";
    			return action_replace_with_url($entity,
    				"/var/spool/MIMEDefang_Captured_Files",
    				"http://url_server/captured_mailfiles",
    "Der Anhang '$friendlyName' wurde aufgrund seiner Groesse aus dieser
    Nachricht entfernt, kann jedoch ueber folgende URL abgerufen werden:\n
    The attachment '$friendlyName' was removed from this mail, but
    may be accessed at this URL (approx. $size):\n" .
    			"\t_URL_\n"
    			, "$lcType $friendlyName\n", $skaCfg{urlsalt});
    		} else {
    			skahead "Keeping MIME attachment '$friendlyName' of $lcType size: $size";
    		}
    	}
    }
    What's all this about?
Now send a test mail you are sure about triggering the condition to replace an attachement.

Check out the mail, the spool directory and if you can access the link. Note: Because of the 5th argument you ought to find a hidden file with the same name (well, and the dot of course) in the directory.
E.g. use: wget http://url_server/captured_mailfiles/XYZ.ext


HOWTO preserve the original filename

Again, this neat feature has been brought to you by Jeremy Mates (http://lists.roaringpenguin.com/pipermail/mimedefang/2003-June/014908.html).

The fifth argument of the action_replace_with_url function instructs MIMEDefang to store arbitary data into a file named .«sha1_from_content».«original_extension» (with the leading dot!!) into the same directory as the captured file, /var/spool/MIMEDefang_Captured_Files in my case. I decided to store the original content type as well as the original filename.

Now you have to configure the Webserver to pass this information back to the client, which then has to decide what to do with it. Normally the user gets this filename, when he tries to save the file.

Jeremy implemented a perl script callable by mod_perl, I took it and added some extra stuff for my needs.