1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
|
# -*- Perl -*-
#***********************************************************************
#
# Test filter. Tests most MIMEDefang actions.
#
# Copyright (C) 2000 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 name 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'
#***********************************************************************
$Administrator = 'postmaster@localhost';
#***********************************************************************
# 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 = 'mailer-daemon@localhost';
#***********************************************************************
# Set various stupid things your mail client does below.
#***********************************************************************
# Set the next one if your mail client cannot handle nested multipart
# messages
$Stupidity{"flatten"} = 1;
# Set the next one if your mail client cannot handle multiple "inline"
# parts (*cough* Exchange *cough* Outlook)
$Stupidity{"NoMultipleInlines"} = 1;
sub filter_begin {
if (stream_by_domain()) {
return;
}
my($recip);
foreach $recip (@Recipients) {
if ($recip =~ /nosuchperson/) {
delete_recipient($recip);
add_recipient('dfs@roaringpenguin.com');
}
}
if ($SuspiciousCharsInHeaders) {
print STDERR "SUSPICIOUS CHARACTERS IN HEADERS\n";
}
action_rebuild();
print STDERR "This should be logged at debug level\n";
my($hits, $req, $names, $report) = spam_assassin_check();
$Boilerplate = "Boilerplate for domain: $Domain\nhits=$hits\nreq=$req\nnames=$names\nreport=$report\n";
}
#***********************************************************************
# %PROCEDURE: filter
# %ARGUMENTS:
# entity -- a Mime::Entity object (see MIME-tools documentation for details)
# fname -- the suggested filename, taken from the MIME Content-Disposition:
# header. If no filename was suggested, then fname is ""
# ext -- the file extension (everything from the last period in the name
# to the end of the name, including the period.)
# type -- the MIME type, taken from the Content-Type: header.
#
# NOTE: There are two likely and one unlikely place for a filename to
# appear in a MIME message: In Content-Disposition: filename, in
# Content-Type: name, and in Content-Description. If you are paranoid,
# you will use the re_match and re_match_ext functions, which return true
# if ANY of these possibilities match. re_match checks the whole name;
# re_match_ext checks the extension. See the sample filter below for usage.
# %RETURNS:
# Nothing
#***********************************************************************
sub filter {
my($entity, $fname, $ext, $type) = @_;
# For convenience, compute lower-case versions of filename and extension
my($lc_fname) = $fname;
my($lc_ext) = $ext;
my($head) = $entity->head;
my($junk);
$junk = $head->get('Content-type', 0);
print STDERR "get Content-type: $junk\n";
$junk = $head->get('Content-description', 0);
print STDERR "get Content-description: $junk\n";
$lc_fname =~ tr/A-Z/a-z/;
$lc_ext =~ tr/A-Z/a-z/;
####################################################################
# #
# Filter rules follow #
# #
####################################################################
print STDERR "Filter: fname='$fname', ext='$ext', type='$type'\n";
#-------------------------------------------------------------------
# Quarantine viruses
#-------------------------------------------------------------------
if (entity_contains_virus_filescan($entity)) {
return action_quarantine($entity, "Virus detected - $VirusScannerMessages");
}
#-------------------------------------------------------------------
# tests
#-------------------------------------------------------------------
if ($lc_fname =~ /action_accept_with_warning/) {
return action_accept_with_warning("accept with warning test");
}
if ($lc_fname =~ /action_resend/) {
# Resend only if original message was to dfs@shishi.roaringpenguin.com
if ($Recipients[0] eq '<dfs@shishi.roaringpenguin.com>') {
resend_message('dfs@roaringpenguin.com', 'webmaster@roaringpenguin.com');
return action_discard();
}
}
if ($lc_fname =~ /action_replace_with_url/) {
return action_replace_with_url($entity,
"/home/httpd/html/parts",
"http://localhost/parts",
"The part was too large. It was removed from this message, but is accessible\nat the following link:\n\n\t_URL_");
}
if ($lc_fname =~ /action_accept/) {
action_add_header("X-Added-Header", "I chose to accept you");
return action_accept();
}
if ($lc_fname =~ /action_drop_with_warning/) {
return action_drop_with_warning("drop with warning test");
}
# Ensure that multiplexor kills filter if it's too busy
if ($lc_fname =~ /test_busy_kill/) {
while(1) {
}
}
if ($lc_fname =~ /action_drop/) {
# Test action_notify_sender here.
action_notify_sender("The attachment '$fname' was dropped.\n");
return action_drop();
}
if ($lc_fname =~ /action_defang/) {
return action_defang($entity, "", "", "application/octet-stream");
}
if ($lc_fname =~ /action_quarantine/) {
action_add_header("X-Quarantined", "Because I don't like you");
action_quarantine_entire_message();
return action_quarantine($entity, "action_quarantine test");
}
if ($lc_fname =~ /action_bounce/) {
return action_bounce("Bounce test");
}
if ($lc_fname =~ /action_tempfail/) {
return action_tempfail("Test of tempfail action");
}
# Test that we tempfail a message if the filter dies
if ($lc_fname =~ /action_filterexit/) {
print STDERR "Deliberately exiting from filter to test tempfail\n";
# Pretend to multiplexor that everything's cool
if ($ServerMode) {
$| = 1;
print "ok\n";
$| = 0;
# Let MUX do its stuff before we exit...
sleep(4);
}
exit(32);
}
if ($lc_fname =~ /action_discard/) {
action_notify_administrator("Discarding message; admin should get this");
return action_discard();
}
if ($type eq "text/html") {
return anomy_clean_html($entity);
}
return action_accept();
}
#***********************************************************************
# %PROCEDURE: defang_warning
# %ARGUMENTS:
# oldfname -- the old file name of an attachment
# fname -- the new "defanged" name
# %RETURNS:
# A warning message
# %DESCRIPTION:
# This function customizes the warning message when an attachment
# is defanged.
#***********************************************************************
sub defang_warning {
my($oldfname, $fname) = @_;
return
"An attachment named '$oldfname' was converted to '$fname'.\n" .
"To recover the file, right-click on the attachment and Save As\n" .
"'$oldfname'\n";
}
sub filter_end {
my($entity) = @_;
append_boilerplate($entity, "$Boilerplate");
}
# Test host rejection
sub filter_relay {
my($hostip, $hostname) = @_;
if ($hostname eq "shishi.roaringpenguin.com") {
return (0, "Sorry, shishi, you are blacklisted");
}
return (1, "ok");
}
sub filter_sender {
my($sender) = @_;
if ($sender =~ /^<?blacklisted\@roaringpenguin.com>?$/i) {
return (0, 'Sorry, <blacklisted@roaringpenguin.com>, you are blacklisted');
}
return (1, "ok");
}
# DO NOT delete the next line, or Perl will complain.
1;
|