How it works
This plugin checks if a mail has been delivered directly from a dialup-IP. It simply uses the last trusted received-line for the IP and the DNS-Names and tries to find out if the IP-Number is somehow coded into the DNS.
Requirements
none.
Installation
Save the two files below in your local configuration directory.
Remarks
- Note that this is my first SA plugin, so any feedback is welcome
- This Plugin can only be a hint about spam, so don't set the score to high.
– Author: Lars Uffmann, lu at cachescrubber dot org, converted to a module by Cord Beermann, cord@Wunder-Nett.org
Code
relayed_by_dialup.cf
loadplugin RelayedByDialup /etc/spamassassin/relayed_by_dialup.pm header RELAYED_BY_DIALUP eval:relayed_by_dialup() describe RELAYED_BY_DIALUP Sent directly from dynamic IP address score RELAYED_BY_DIALUP 1
relayed_by_dialup.pm
# written by Lars Uffmann <lu -at- cachescrubber -dot- org> # converted to a SA-module by Cord Beermann <cord@Wunder-Nett.org> # Licence: same as Spamassassin package RelayedByDialup; use Mail::SpamAssassin; use Mail::SpamAssassin::Plugin; use List::Util qw(sum); our @ISA = qw(Mail::SpamAssassin::Plugin); $dbg_text = 'dynamic_relay: '; sub new { my ($class, $mailsa) = @_; $class = ref($class) || $class; my $self = $class->SUPER::new($mailsa); bless ($self, $class); $self->register_eval_rule ("relayed_by_dialup"); return $self; } sub relayed_by_dialup { my ($self, $permsgstatus) = @_; my $match = 0; # we need the reveived header from _our_ first MX. # we can only match this if we have at least 1 untrusted header Mail::SpamAssassin::Plugin::dbg("dynamic_relay: starting"); unless ($permsgstatus->{num_relays_untrusted} > 0) { Mail::SpamAssassin::Plugin::dbg("dynamic_relay: num_relays_untrusted undefined"); return 0; } else { my $relay = $permsgstatus->{relays_untrusted}->[0]; Mail::SpamAssassin::Plugin::dbg ("dynamic_relay: mx=" . $relay->{by}); if ($relay->{no_reverse_dns} || $relay->{rdns} eq '' ) { Mail::SpamAssassin::Plugin::dbg($dbg_text . "cannot perform, no rDNS"); return 0; } if (_is_dynamic_ip($relay->{ip}, $relay->{rdns})) { Mail::SpamAssassin::Plugin::dbg($dbg_text . "match: " . $relay->{ip} . "=" . $relay->{rdns}); return 1; } Mail::SpamAssassin::Plugin::dbg($dbg_text . "tried: " . $relay->{ip} . "=" . $relay->{rdns}); return 0; } } sub _is_dynamic_ip { my @ip = split(/\./, $_[0]); my $name = $_[1]; return 0 unless $name; # convert addresses in hex to dotted decimal notation. $name =~ s/\b([a-f0-9]{8})\b/join(".", unpack("C*", pack("H8", $1)))/eg; # try shorter suffixes of $IP return 1 if _is_rr_dynamic_ip(join(".",@ip), $name); shift(@ip); return 1 if _is_rr_dynamic_ip(join(".",@ip), $name); return 0; # will lead to false positives ... shift(@ip); return 1 if _is_rr_dynamic_ip(join(".",@ip), $name); return 0; } sub _is_rr_dynamic_ip { my $ip = $_[0]; my $is_ip = $_[1]; # remove anything but digits > 0 $is_ip =~ s/[^1-9]//g; # normalize the ip my $ip_test = $ip; # remove anything but digits > 0 $ip_test =~ s/[0.]//g; my $diff = length($is_ip) - length($ip_test); return 0 if $diff < 0; my $offset = 0; my $ip_test_sum = sum(0, split("", $ip_test)); do { my $test = substr($is_ip, $offset++, length($ip_test)); my $is_ip_sum = sum(0, split("", $test)); return 1 if $is_ip_sum == $ip_test_sum; } while ($diff--); return 0; } 1;