Matthew.van.Eerde wrote:
> Philip Prindeville wrote:
>> 
>> my %badnetworks = {
>>     '58.71.0.0/17'      => 'REJECT',
>>     '62.117.127.0/25'   => 'REJECT',
> ...
>>     '222.136.0.0/11'    => 'REJECT',
>>     # local mail
>>     '127.0.0.1/32'      => 'ACCEPT',
>>     '192.168.1.0/24'    => 'ACCEPT',
>>     # wildcard action
>>     '0.0.0.0/0'         => 'ACCEPT',
>> };
>> 
> ...
>>     while (my ($lhs, $action) = each %badnetworks) {
>>         my ($net, $length) = split('/', $lhs);
> 
> Umm... note that each %hash returns the key/value pairs in hash
> order.  This is NOT NECESSARILY THE SAME as the order you entered
> them into the hash.  If you happen to hit 0.0.0.0/0 => ACCEPT as the
> first entry none of your blacklists will take effect.   
> 
> You could fix this by using two arrays:
> 
> my @badnetworks = ( '58.71.0.0/17', ...);
> my @goodnetworks = ( '127.0.0.1/32', ... );
> 
> and iterating over each separately.

If you want to have a full-on layered permissions scheme (where the action 
applies to the smallest containing subnet) you could store a more complicated 
hash...

sub compile_subnet_policies();

my %subnet_policies =
(
        '0.0.0.0/0' => "ACCEPT",
        '127.0.0.1/32' => "ACCEPT",
        ...
        '58.71.0.0/17' => "REJECT",
        ...
)

my @compiled_subnet_policies;

compile_subnet_policies(); # run this once

sub compile_subnet_policy()
{
        my %temp = ();

        for my $subnet (keys %subnet_policies)
        {
                my ($neta, $length) = split("/", $subnet);
                my $net = inet_aton($neta);
                my $mask = (0xffffffff << (32 - $length)) & 0xffffffff;

                $temp{$subnet} = {
                        subnet => $subnet,
                        length => $length,
                        net => $net,
                        mask => $mask,
                        action => $subnet_policies{$subnet},
                };
        }

        # sort /32's first, /0's at the end
        @compiled_subnet_policies = @temp{ sort { $b{length} <=> $a{length} } 
keys %temp };
}

Then your hard work is done at slave startup and your filter can look like:

sub filter_relay($$) {
    my ($hostname, $hostip) = @_;

    $hostip = inet_aton($hostip);

    # note policies are applied in /32 to /0 order
    for my $policy (@compiled_subnet_policies) {

        if (($hostip & $policy{mask}) == $policy{net}) {
            my $msg = ($policy{action} eq 'ACCEPT') ? 'OK'
                       : "This network is blacklisted";

            return ($action, $msg);
        }
    }

    ...

-- 
Matthew.van.Eerde (at) hbinc.com               805.964.4554 x902
Hispanic Business Inc./HireDiversity.com       Software Engineer

_______________________________________________
NOTE: If there is a disclaimer or other legal boilerplate in the above
message, it is NULL AND VOID.  You may ignore it.

Visit http://www.mimedefang.org and http://www.roaringpenguin.com
MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com
http://lists.roaringpenguin.com/mailman/listinfo/mimedefang

Reply via email to