Bluehost.com Web Hosting $6.95

[AMaViS-user] [patch] replace banned attachments

This is a discussion on [AMaViS-user] [patch] replace banned attachments within the Amavis User forums, part of the Anti-Spam and Anti-Virus Related Forums category; Hello, here is a patch to replace banned attachments with a text notice. Guess a lot of people are going ...


Go Back   Usenet Forums > Anti-Spam and Anti-Virus Related Forums > Amavis User

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 11-07-2005
Thomas Jarosch
 
Posts: n/a
Default [AMaViS-user] [patch] replace banned attachments

Hello,

here is a patch to replace banned attachments with a text notice.
Guess a lot of people are going to be happy :-)

Features:
* Replace banned attachments with notice of your choice
* Bans root/source attachment for compressed archives
* Original message gets quarantined for later reinjection
* Doesn't alter the email if no banned attachments are found
* Works on nested messages

Limitations:
* Doesn't work on a per recipient basis, if a banned attachment
is found for one recipient, it get's banned for all.
* All original files need to be retained (needed for reconstructing the email),
so effectivly compressed archives get passed twice to the virus scanner.

How to use it:
* Apply the inlined patch to amavisd-new-2.3.3 or get it from here:

http://www.intra2net.com/opensource/...tachment.patch

* Set the new configuration variables:

$banned_replace_attachment = 1;
$banned_replace_attachment_filename = "File %F was replaced.txt";
$banned_replace_attachment_content_type = "text/plain";
$banned_replace_attachment_text = "The file %F was replaced.\n\n
Please contact your administrator for further details.";

Modify this existing variable to retain all attachments:
@keep_decoded_original_maps = (new_RE( qr '.' ));

Mark: Maybe this step can be automatated or even modified that all files
are kept on disc, but not passed to the virus scanner.

* Restart amavisd and enjoy.


I gave the patch extensive testing for several hours, so far it's not causing
any trouble. As simple as the patch may look now, it took more than 20 hours
to cook this one up. Please test it before putting it in productive usage.

Cheers,
Thomas

diff -u -r amavisd-new-2.3.3/amavisd amavisd-new.banned/amavisd
--- amavisd-new-2.3.3/amavisd 2005-08-22 01:46:15.000000000 +0200
+++ amavisd-new.banned/amavisd 2005-11-07 13:28:37.902497471 +0100
@@ -215,6 +215,10 @@
$per_recip_whitelist_sender_lookup_tables
$per_recip_blacklist_sender_lookup_tables

+ $banned_replace_attachment $banned_replace_attachment_filename
+ $banned_replace_attachment_content_type
+ $banned_replace_attachment_text
+
%sql_clause

@local_domains_maps @mynetworks_maps
@@ -3547,6 +3551,8 @@
{ my($self)=shift; !@_ ? $$self[13] : ($$self[13]=shift) }
sub banned_rhs # right-hand side of matching rules (a ref to a list)
{ my($self)=shift; !@_ ? $$self[14] : ($$self[14]=shift) }
+sub banned_parts_obj # corresponding amavis part object
+ { my($self)=shift; !@_ ? $$self[15] : ($$self[15]=shift) }

sub recip_final_addr { # return recip_addr_modified if set, else recip_addr
my($self)=shift;
@@ -5114,6 +5120,8 @@
{ my($self)=shift; !@_ ? $self->{children}||[] : ($self->{children}=shift) };
sub mime_placement # part location within a MIME tree, e.g. "1/1/3"
{ my($self)=shift; !@_ ? $self->{place} : ($self->{place}=shift) };
+sub mime_entity # original MIME entity, needed by banned attachment replacing
+ { my($self)=shift; !@_ ? $self->{entity} : ($self->{entity}=shift) };
sub type_short # string or a ref to a list of strings
{ my($self)=shift; !@_ ? $self->{ty_short} : ($self->{ty_short}=shift) };
sub type_long
@@ -5417,9 +5425,11 @@
push(@$a,$matchingkey); $r->banned_keys($a);
$a = $r->banned_rhs; $a = [] if !defined($a);
push(@$a,$result); $r->banned_rhs($a);
+ $a = $r->banned_parts_obj; $a = [] if !defined($a);
+ push(@$a,$part); $r->banned_parts_obj($a);
}
}
- last if !grep {!$_->{result}} @recip_tables; # stop if all recips true
+ last if !c('banned_replace_attachment') && !grep {!$_->{result}} @recip_tables; # stop if all recips true and attachment replacment is disabled
} # endfor: message tree traversal
} # endif: doing parts checking
}
@@ -5436,7 +5446,7 @@
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
$VERSION = '2.043';
@ISA = qw(Exporter);
- @EXPORT_OK = qw(&mime_decode);
+ @EXPORT_OK = qw(&mime_decode &banned_replace_attachment);
}
use Errno qw(ENOENT EACCES);
use IO::File qw(O_CREAT O_EXCL O_WRONLY);
@@ -5532,6 +5542,7 @@
}
if (defined $part) {
$part->mime_placement($placement);
+ $part->mime_entity($entity); # Save entity object for attachment banning
$part->type_declared($mt eq $et ? $mt : [$mt, $et]);
my(@rn); # recommended file names, both raw and RFC 2047 decoded
my($val, $val_decoded);
@@ -5594,6 +5605,45 @@
($entity, $mime_err);
}

+# Build mime entity for attachment replacement
+sub banned_create_replacement_entity($); # prototype
+sub banned_create_replacement_entity($) {
+ my($filename) = @_;
+
+ my($entity_filename) = c('banned_replace_attachment_filename');
+ $entity_filename =~ s/%F/$filename/g;
+ my($entity_data) = c('banned_replace_attachment_text');
+ $entity_data =~ s/%F/$filename/g;
+
+ # TODO: What about encoding of special chars?
+ my($new_entity) = MIME::Entity->build(Type => c('banned_replace_attachment_content_type'),
+ Filename => $entity_filename,
+ Data => $entity_data,
+ Disposition => "attachment",
+ 'X-Mailer' => undef);
+ return $new_entity;
+}
+
+sub banned_replace_attachment($$$); # prototype
+sub banned_replace_attachment($$$) {
+ my($entity, $filename, $replace_entity) = @_;
+
+ # recursive descent all child parts
+ # note: don't have to check ourselves as we are a child of the root pseudo-part
+ if ($entity->parts) {
+ my(@done_parts);
+ for my $e ($entity->parts) {
+ if ($e == $replace_entity) {
+ push(@done_parts, banned_create_replacement_entity($filename));
+ } else {
+ banned_replace_attachment($e, $filename, $replace_entity);
+ push(@done_parts, $e);
+ }
+ }
+ $entity->parts(\@done_parts);
+ }
+}
+
1;

#
@@ -6071,7 +6121,7 @@
first_received_from);
import Amavis::Unpackers::Validity qw(
check_header_validity check_for_banned_names);
- import Amavis::Unpackers::MIME qw(mime_decode);
+ import Amavis::Unpackers::MIME qw(mime_decode banned_replace_attachment);
import Amavis::Expand qw(expand);
import Amavis::Notify qw(delivery_status_notification delivery_short_report
string_to_mime_entity defanged_mime_entity);
@@ -7328,7 +7378,14 @@
? "250 2.7.1 Ok, discarded"
: "550 5.7.1 Message content rejected") .
", id=$am_id - $reason");
- $r->recip_done(1);
+
+ # don't mark as delivered if we want to send
+ # a version with replaced banned attachments
+ if (!$r->infected && defined($r->banned_parts) && @{$r->banned_parts}
+ && c('banned_replace_attachment')) {
+ } else {
+ $r->recip_done(1);
+ }
# note that 5xx status rejects may later be converted to bounces or
# discards, according to $*_destiny setting
}
@@ -7338,6 +7395,48 @@
# send notifications, quarantine it
do_virus($conn, $msginfo, $virus_dejavu);

+ # Replace attachments if neccessary (if it's no virus)
+ if ($banned_filename_any && !@virusname && c('banned_replace_attachment')) {
+ $which_section = "banned_replace_attachment";
+ do_log(1, "Replacing banned attachments");
+ ensure_mime_entity($msginfo, $fh, $tempdir, \@virusname, $parts_root);
+
+ # Replace banned attachments for all recipients
+ for my $r (@{$msginfo->per_recip_data}) {
+ if (defined($r->banned_parts_obj)) {
+ for my $bp (@{$r->banned_parts_obj}) {
+ # Search for (parent) MIME entity
+ my($check_part) = $bp;
+ my($banned_filename) = undef;
+ my($replace_entity) = undef;
+ while(defined($check_part) && !defined($replace_entity)) {
+ ll(5) && do_log(5, "Replace banned attachments: Looking for original MIME entity in part ".$check_part->number);
+ $banned_filename = $check_part->name_declared;
+ $replace_entity = $check_part->mime_entity;
+ defined($replace_entity) && ll(5) && do_log(5, "Replace banned attachments: Found original MIME entity in part "
+ .$check_part->number. " - ".$banned_filename);
+ $check_part = $check_part->parent;
+ }
+
+ if (!defined($replace_entity)) {
+ do_log(-1, "Replace banned attachments: WARNING: Original banned attachment not found in MIME entities");
+ } else {
+ banned_replace_attachment($msginfo->mime_entity, $banned_filename, $replace_entity);
+ }
+ }
+ }
+ }
+
+ # Remove message id as quarantined (full) email got the same ID
+ my($hdr_edits) = $msginfo->header_edits;
+ $hdr_edits = Amavis::Out::EditHeader->new if !$hdr_edits;
+ $hdr_edits->delete_header("Message-ID");
+ $msginfo->header_edits($hdr_edits);
+
+ # Replace mail with rewritten version
+ $msginfo->mail_text($msginfo->mime_entity);
+ $msginfo->mail_text_fn(undef); # remove filename information
+ }
} else { # perhaps some recips consider it spam?
# spaminess is an individual matter, we must compare spam level
# with each recipient setting, there is no single global criterium
@@ -13297,9 +13396,6 @@
do_log(4, "flatten_and_tidy_dir: NONREGULAR FILE \"$fname\"");
$cnt_u++; $newpart_obj->attributes_add('S');
unlink($fname) or die "Can't remove nonregular file \"$fname\": $!";
- } elsif (-z _) {
- $cnt_u++;
- unlink($fname) or die "Can't remove empty file \"$fname\": $!";
} else {
chmod(0750, $fname)
or die "Can't change protection of file \"$fname\": $!";
@@ -13414,11 +13510,6 @@
$part->exists(0);
$part->type_short(-l _ ? 'symlink' : -d _ ? 'dir' : 'special')
if !defined $part->type_short;
- } elsif (-z _) { # empty file
- unlink($fname) or die "Can't remove \"$fname\": $!";
- $part->exists(0);
- $part->type_short('empty') if !defined $part->type_short;
- $part->type_long('empty') if !defined $part->type_long;
} else {
$part->exists(1);
}


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
AMaViS-user mailing list
AMaViS-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/...fo/amavis-user
AMaViS-FAQ:http://www.amavis.org/amavis-faq.php3
AMaViS-HowTos:http://www.amavis.org/howto/
Reply With Quote
Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT +1. The time now is 08:42 AM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.0.0