You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@spamassassin.apache.org by Justin Mason <jm...@jmason.org> on 2005/08/08 23:15:19 UTC
Re: [SPAM] RE: GeoCities Link-only spam
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
awesome! any chance you could put this on the wiki, linked from
CustomPlugins?
- --j.
Derek Harding writes:
> On Mon, 2005-08-08 at 15:53 -0500, salist@floridacpu.com wrote:
> > >
> > > It allows rules such as:
> > > uricountry URICOUNTRY_CN CN
> > > header URICOUNTRY_CN eval:check_uricountry('URICOUNTRY_CN')
> > > describe URICOUNTRY_CN Contains a URI hosted in China
> > > tflags URICOUNTRY_CN net
> > > score URICOUNTRY_CN 2.0
> > >
> > > Derek
> >
> >
> > Oh yes, that type code would be very nice to have indeed for people like
> > me who can't outright RBL them. Do you also have code for Korea even? But
> > dare I ask too much. :-) I could give it a score of 4 or so... and up it
> > even more when spammer simpletons start thinking they are on to the latest
> > greatest China spam idea. :-)
>
> The code will work for any country. Just write a rule for that country.
>
> Here's what's needed in your local.cf
>
> loadplugin Mail::SpamAssassin::Plugin::URICountry
>
> uricountry URICOUNTRY_CN CN
> header URICOUNTRY_CN eval:check_uricountry('URICOUNTRY_CN')
> describe URICOUNTRY_CN Contains a URI hosted in China
> tflags URICOUNTRY_CN net
> score URICOUNTRY_CN 2.0
>
> uricountry URICOUNTRY_KR KR
> header URICOUNTRY_KR eval:check_uricountry('URICOUNTRY_KR')
> describe URICOUNTRY_KR Contains a URI hosted in Korea
> tflags URICOUNTRY_KR net
> score URICOUNTRY_KR 2.0
>
> uricountry URICOUNTRY_BR BR
> header URICOUNTRY_BR eval:check_uricountry('URICOUNTRY_BR')
> describe URICOUNTRY_BR Contains a URI hosted in Brazil
> tflags URICOUNTRY_BR net
> score URICOUNTRY_BR 2.0
>
> Derek
>
> -- code for the plugin follows --
> =head1 NAME
>
> URICountry - add message metadata indicating the country code of each
> relay
>
> =head1 SYNOPSIS
>
> loadplugin Mail::SpamAssassin::Plugin::URICountry
>
> =head1 REQUIREMENT
>
> This plugin requires the IP::Country::Fast module from CPAN.
>
> =cut
>
> package Mail::SpamAssassin::Plugin::URICountry;
>
> use Mail::SpamAssassin::Plugin;
> use strict;
> use bytes;
>
> use vars qw(@ISA);
> @ISA = qw(Mail::SpamAssassin::Plugin);
>
> # constructor: register the eval rule
> sub new {
> my $class = shift;
> my $mailsaobject = shift;
>
> # some boilerplate...
> $class = ref($class) || $class;
> my $self = $class->SUPER::new($mailsaobject);
> bless ($self, $class);
>
> $self->register_eval_rule ("check_uricountry");
>
> return $self;
> }
>
> # this is just a placeholder; in fact the results are dealt with later
> sub check_uricountry {
> my ($self, $permsgstatus, $rulename) = @_;
> return 0;
> }
>
> # and the eval rule itself
> sub parsed_metadata {
> my ($self, $opts) = @_;
> my $scanner = $opts->{permsgstatus};
>
> my $reg;
>
> eval {
> require IP::Country::Fast;
> $reg = IP::Country::Fast->new();
> };
> if ($@) {
> dbg ("failed to load 'IP::Country::Fast', skipping");
> return 1;
> }
>
> my %domlist = ();
> foreach my $uri ($scanner->get_uri_list()) {
> my $dom = my_uri_to_domain($uri);
> dbg("debug: URICountry $uri in $dom");
> if ($dom) {
> $domlist{$dom} = 1;
> }
> }
>
> # Build a list of the countries for URIs in the message.
> my %countries = ();
> foreach my $dom (keys(%domlist)) {
> my $cc = $reg->inet_atocc($dom) || "XX";
> dbg("debug: URICountry $dom in $cc");
> $countries{lc($cc)} = 1;
> }
>
> # Now check if any match any defined rules.
> foreach my $rule (keys(%{$scanner->{conf}->{uricountry}})) {
> my $country = lc($scanner->{conf}->{uricountry}->{$rule});
> if($countries{$country}) {
> dbg ("debug: URICountry hit rule: $country");
> $scanner->got_hit($rule, "");
> }
> }
>
> return 1;
> }
>
> sub parse_config {
> my ($self, $opts) = @_;
>
> my $key = $opts->{key};
>
> if ($key eq 'uricountry') {
> if ($opts->{value} =~ /^(\S+)\s+(\S+)\s*$/) {
> my $rulename = $1;
> my $country = $2;
>
> dbg("debug: URICountry: registering $rulename");
> $opts->{conf}->{uricountry}->{$rulename} = $country;
> $self->inhibit_further_callbacks(); return 1;
> }
> }
>
> return 0;
> }
>
> # Taken from the one in Util.pm but we don't want to drop the hostname
> doing so
> # often leaves us with no A record.
> sub my_uri_to_domain {
> my ($uri) = @_;
>
> # Javascript is not going to help us, so return.
> return if ($uri =~ /^javascript:/i);
>
> $uri =~ s,#.*$,,gs; # drop fragment
> $uri =~ s#^[a-z]+:/{0,2}##gsi; # drop the protocol
> $uri =~ s,^[^/]*\@,,gs; # username/passwd
> $uri =~ s,[/\?\&].*$,,gs; # path/cgi params
> $uri =~ s,:\d+$,,gs; # port
>
> return if $uri =~ /\%/; # skip undecoded URIs.
> # we'll see the decoded version as well
>
> # keep IPs intact
> if ($uri !~ /^\d+\.\d+\.\d+\.\d+$/) {
> # get rid of hostname part of domain, understanding delegation
> #$uri Mail::SpamAssassin::Util::RegistrarBoundaries::trim_domain($uri);
>
> # ignore invalid domains
> return unless
>
> (Mail::SpamAssassin::Util::RegistrarBoundaries::is_domain_valid($uri));
> }
>
> # $uri is now the domain only
> return lc $uri;
> }
>
> sub dbg { Mail::SpamAssassin::dbg (@_); }
>
> 1;
> -- end code --
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Exmh CVS
iD8DBQFC98tnMJF5cimLx9ARAopMAJwPUfRwleBHQAJlNDpHLaJOyPpuHACfQ3Sy
JiuVQJF2cDbW8JrjhfcZRFU=
=K+Sc
-----END PGP SIGNATURE-----