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-----