

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
4 messages in net.sourceforge.lists.courier-usersRe: [courier-users] scanning for spam...| From | Sent On | Attachments |
|---|---|---|
| Hari Kurup | Apr 27, 2005 7:58 am | |
| Ben Kennedy | Apr 27, 2005 8:20 am | .txt |
| Hari Kurup | Apr 27, 2005 11:34 pm | |
| Ben Kennedy | Apr 28, 2005 8:34 am | .txt |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | Re: [courier-users] scanning for spam on relay server | Actions... |
|---|---|---|
| From: | Ben Kennedy (be...@zygoat.ca) | |
| Date: | Apr 27, 2005 8:20:34 am | |
| List: | net.sourceforge.lists.courier-users | |
| Attachments: | ||
Hari Kurup wrote at 5:54 pm (+0300) on Wed 27 Apr 2005:
I want to have spamassassin called at smtp level as part of the clamav-perlfilter, without having to run amavis-ng or anything like that. Has anyone done such an implementation?
Sounds exactly what I've been doing myself. Attached is my modified version of clamav-perlfilter. It does a number of additional things:
- filters through clamav (of course), rejects if virus - filters through spamc, rejects if high score (hard-coded currently to 4.0) - rejects if missing a From: header in the message - skips the clamav/spamc filtering if coming from an authenticated session.
I've only added the latter logic in the last week or so (following consultation on this list). I should point out that in the last couple of days, I've found two situations where courier is answering on SMTP but no dialog happens; my cpu load is way up and there are two dozen invocations of perlfilter running. This was not happening before so I suspect there might be some new fault I've introduced, but I'm not sure.
-ben
-- Ben Kennedy, chief magician zygoat creative technical services 613-228-3392 | 1-866-466-4628 http://www.zygoat.ca
# ClamAV and etc filter for Courier perlfitler. See the perlfilter-example that # comes with Courier for the comments.
# Installed by BRK on 07 July 2004 from http://karmak.org/2004/courier-clamav/
# BRK also altered return status from 500 to 577 which seems more consistent
with rfc1893.
# 05 Nov 2004: BRK modified to first scan the incoming message and reject if
# there is no From: header provided. Seems there are spammy things getting
through
# with no header, so by virtue of maildrop etc. it ends up misleadingly with the
# recipient user's own address.
# 13 Dec 2004: BRK modified again to also call spamc and check for an egregious
spam score
# following a successful virus check. This is an effort to cull out the most
obvious
# crap before it even gets to the maildrop process.
# 20 Apr 2005: BRK modified; we now check the first Received: header to see
whether the
# message came from an authenticated session. If so, we bypass the virus and
spam checks.
use IO::File;
my $filedesc=shift @ARGV; my $socket=new IO::File "+<&$filedesc"; die "$!" unless defined $socket;
my $line; my $first=1; my $errmsg="200 Ok";
while (defined ($line=<$socket>)) { my $msg; chomp $line; last unless $line; if ($first) { $msg=filterdata($line); } else { $msg=filtercontrol($line); } $first=0; $errmsg=$msg if $msg; }
$errmsg .= "\n" unless $errmsg =~ /\n$/; print $socket $errmsg;
$socket->close;
sub filterdata { my $filename=shift;
# BRK: First scan the input file to ensure there is a From: header.
my $goodfrom = 0; # whether we have found presence of a From: header
my $received = 0; # whether we have encountered the first Received: header yet
my $authenticated = 0; # whether the message originated via an authenticated
SMTP session
# The line-reading loop that follows is slightly more complicated than just a
while(<FILE>)... loop
# because we need to collapse multi-line headers into one (particularly
Received:).
open(FILE, "<${filename}"); my $nextline = <FILE>; # fetch first line while(1) { my $p = $nextline; # start with this line
while (<FILE>) # fetch a line { if (/^\s+/) # if it starts with whitespace { $p .= $_; } # append to the accumulating line else { $nextline = $_; # cache for the next iteration last; # abort loop and start to parse } }
# If this is a From header, make note of its presence. if ($p =~ /^From\: /) { $goodfrom = 1; }
# If this is the first Received header, check it for authentication. elsif ($p =~ /^Received\: / && $received == 0) { $received = 1; if ($p =~ /^Received: from .*\s+\(.*\)\s+\((.* )?AUTH\:\ /) { $authenticated = 1; } }
# If this is the end of the headers, or if we've found the first Received and
a From,
# no need to continue parsing.
if ($p eq '' || ($goodfrom && $received))
{ last; }
}
close FILE;
if (!$goodfrom) # If no From: header existed, barf up with the error. { return '550 Please provide a From: header in the message.'; }
# We passed; now see if it smells like fish.
# diag: dump env. #open(E, '>/tmp/msg.env'); #my $key; #foreach $key (sort(keys %ENV)) # { print E, $key . ' = ' . $ENV{$key} . "\n"; } #close E;
# Suppress checking if the message originated from an authenticated user.
if ($authenticated == 0)
{
open(SPAMOUT, "cat ${filename} | spamc -c -U /var/run/spamd.sock |");
my $result = <SPAMOUT>;
close(SPAMOUT);
# Fetch result which will be "score/threshold", e.g. "6.9/4.0".
$result =~ m/^([0-9.]+)/; # Extract the score.
$result = $1;
# Fail if the score is reasonably large.
if ($result > 4.9)
{
return "571 Identified spam ($result). Contact postmaster\@zygoat.ca if this
is in error.";
}
# Now, carry on with the original CLAMAV scanning.
open(CLAMOUT, "cat ${filename} | clamdscan --stdout - |"); my $result = <CLAMOUT>; close(CLAMOUT); if ( $result =~ m/ FOUND$/ ) { $result =~ s/.*stream: (.*) FOUND/$1/; chomp $result; # strip trailing newline (?) return "577 Virus detected (${result})."; } }
# Otherwise all looks good, so return usual.
return ""; }
sub filtercontrol { my $filename=shift; return ""; }








.txt