Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 76 | magnus | 1 | Description: Add IPv6 support to the Greylisting SpamAssassin plugin. |
| 2 | The greylistfourthbyte option, for IPv6 addresses, means that all |
||
| 3 | addresses in the same /64 get whitelisted as a group. |
||
| 4 | Bug: https://bugs.debian.org/508161 |
||
| 5 | |||
| 6 | --- a/Greylisting.pm |
||
| 7 | +++ b/Greylisting.pm |
||
| 8 | @@ -21,6 +21,8 @@ package Greylisting; |
||
| 9 | |||
| 10 | use strict; |
||
| 11 | use Mail::SpamAssassin::Plugin; |
||
| 12 | +use NetAddr::IP; |
||
| 13 | +use File::Path qw(mkpath); |
||
| 14 | our @ISA = qw(Mail::SpamAssassin::Plugin); |
||
| 15 | |||
| 16 | sub new |
||
| 17 | @@ -104,8 +106,12 @@ sub greylisting |
||
| 18 | } |
||
| 19 | chomp($connectip); |
||
| 20 | # Clean up input (for security, if you use files/dirs) |
||
| 21 | - $connectip =~ /([\d.:]+)/; |
||
| 22 | - $connectip = ($1 or ""); |
||
| 23 | + |
||
| 24 | + $connectip = NetAddr::IP->new($connectip); |
||
| 25 | + if (not defined $connectip) { |
||
| 26 | + warn "Can only handle IPv4 and IPv6 addresses; skipping greylisting call for message $mesgid\n"; |
||
| 27 | + return 0; |
||
| 28 | + } |
||
| 29 | |||
| 30 | # Account for a null envelope from |
||
| 31 | if (not defined ($envfrom = $permsgstatus->get($option{'envfromhdr'}))) |
||
| 32 | @@ -172,26 +178,27 @@ sub greylisting |
||
| 33 | |||
| 34 | # connectip is supposed to be untainted now, but I was still getting |
||
| 35 | # some insecure dependecy error messages sometimes (perl 5.8 problem apparently) |
||
| 36 | - $connectip =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/; |
||
| 37 | - my ($ipbyte1, $ipbyte2, $ipbyte3, $ipbyte4) = ($1, $2, $3, $4); |
||
| 38 | - my $ipdir1 = "$option{'dir'}/$ipbyte1"; |
||
| 39 | - my $ipdir2 = "$ipdir1/$ipbyte2"; |
||
| 40 | - my $ipdir3 = "$ipdir2/$ipbyte3"; |
||
| 41 | - my $ipdir4; |
||
| 42 | - my $tupletdir; |
||
| 43 | - |
||
| 44 | - $ipdir4 = "$ipdir3"; |
||
| 45 | - $ipdir4 .= "/$ipbyte4" if ($option{'greylistfourthbyte'}); |
||
| 46 | - $tupletdir = "$ipdir4/$envfrom"; |
||
| 47 | - |
||
| 48 | + my $ipdir; |
||
| 49 | + if ($connectip->version == 6) { |
||
| 50 | + my @components = split ':', $connectip->full, 5; |
||
| 51 | + if ($option{'greylistfourthbyte'}) { |
||
| 52 | + $ipdir = join '/', @components; |
||
| 53 | + } else { |
||
| 54 | + $ipdir = join '/', @components[0..3]; |
||
| 55 | + } |
||
| 56 | + } else { |
||
| 57 | + my @components = split '\.', $connectip->addr; |
||
| 58 | + if ($option{'greylistfourthbyte'}) { |
||
| 59 | + $ipdir = join '/', @components; |
||
| 60 | + } else { |
||
| 61 | + $ipdir = join '/', @components[0..2]; |
||
| 62 | + } |
||
| 63 | + } |
||
| 64 | + my $tupletdir = "$option{'dir'}/$ipdir/$envfrom"; |
||
| 65 | $tuplet = "$tupletdir/$rcptto"; |
||
| 66 | |||
| 67 | # make directory whether it's there or not (faster than test and set) |
||
| 68 | - mkdir $ipdir1; |
||
| 69 | - mkdir $ipdir2; |
||
| 70 | - mkdir $ipdir3; |
||
| 71 | - mkdir $ipdir4; |
||
| 72 | - mkdir $tupletdir; |
||
| 73 | + mkpath $tupletdir; |
||
| 74 | |||
| 75 | if (not -e $tuplet) |
||
| 76 | { |