store local and base badips in separate files
authorDirk Koopman <djk@tobit.co.uk>
Mon, 9 Jan 2023 15:21:04 +0000 (15:21 +0000)
committerDirk Koopman <djk@tobit.co.uk>
Mon, 9 Jan 2023 15:21:04 +0000 (15:21 +0000)
cmd/load/badip.pl
cmd/set/badip.pl
perl/DXCIDR.pm

index 22967cd71d82e73e3ffb6cb745d7bff81ee17d8c..3cf4212d6eb0935036f57801430020a096699770 100644 (file)
@@ -12,7 +12,7 @@ return (1, $self->msg('e5')) if $self->priv < 6;
 my @out;
 
 my $count = 0;
-eval{ $count += DXCIDR::load(); };
+eval{ $count += DXCIDR::reload(); };
 return (1, "load/badip: $_ $@") if $@;
 
 push @out, "load/badip: added $count entries";
index b53763569127f2505be6d73f3afcb3ac27ca8a13..3c4578ba444caf8c59796c36ef253691a61e6006 100644 (file)
@@ -12,7 +12,11 @@ return (1, $self->msg('e5')) if $self->priv < 6;
 my @out;
 my @added;
 my @in = split /\s+/, $line;
-return (1, "set/badip: need IP, IP-IP or IP/24") unless @in;
+my $suffix = 'local';
+if ($in[0] =~ /^[_\d\w]+$/) {
+       $suffix = shift @in;
+}
+return (1, "set/badip: need [suffix (def: local])] IP, IP-IP or IP/24") unless @in;
 for my $ip (@in) {
        my $r;
        eval{ $r = DXCIDR::find($ip); };
@@ -21,12 +25,12 @@ for my $ip (@in) {
                push @out, "set/badip: $ip exists, not added";
                next;
        }
-       DXCIDR::add($ip);
+       DXCIDR::add($suffix, $ip);
        push @added, $ip;
 }
 my $count = @added;
 my $list = join ' ', @in;
 DXCIDR::clean_prep();
-DXCIDR::save();
-push @out, "set/badip: added $count entries: $list" if $count;
+DXCIDR::append($suffix, @added);
+push @out, "set/badip: added $count entries to badip.$suffix : $list" if $count;
 return (1, @out);
index 7cb13df0bf4ef7e7f870e99e1a785aa6dc0e0dc7..88a26d5c552631e4b66c173eb0c3262400e17d0d 100644 (file)
@@ -26,50 +26,44 @@ my $ipv6;
 my $count4 = 0;
 my $count6 = 0;
 
-# load the badip file
-sub load
-{
-       if ($active) {
-               _load();
-       }
-       LogDbg('DXProt', "DXCIDR: loaded $count4 IPV4 addresses and $count6 IPV6 addresses");
-       return $count4 + $count6;
-}
-
 sub _fn
 {
        return localdata($badipfn);
 }
 
-sub _load
+sub _read
 {
+       my $suffix = shift;
        my $fn = _fn();
+       $fn .= ".$suffix" if $suffix;
        my $fh = IO::File->new($fn);
-       my $count = 0;
+       my @out;
 
-       new();
-       
        if ($fh) {
                while (<$fh>) {
                        chomp;
                        next if /^\s*\#/;
                        next unless /[\.:]/;
-                       add($_);
-                       ++$count;
+                       push @out, $_;
                }
                $fh->close;
-       } elsif (-r $fn) {
-               LogDbg('err', "DXCIDR: $fn not found ($!)");
+       } else {
+               LogDbg('err', "DXCIDR: $fn read error ($!)");
        }
+       return @out;
+}
 
-       clean_prep();
-       
-       return $count;
+sub _load
+{
+       my $suffix = shift;
+       my @in = _read($suffix);
+       return scalar add(@in);
 }
 
 sub _put
 {
-       my $fn = _fn();
+       my $suffix = shift;
+       my $fn = _fn() . ".$suffix";
        my $r = rand;
        my $fh = IO::File->new (">$fn.$r");
        my $count = 0;
@@ -79,29 +73,54 @@ sub _put
                        ++$count;
                }
                move "$fn.$r", $fn;
+               LogDbg('cmd', "DXCIDR: put (re-)written $fn");
        } else {
                LogDbg('err', "DXCIDR: cannot write $fn.$r $!");
        }
        return $count;
 }
 
+sub append
+{
+       my $suffix = shift;
+       my @in = @_;
+       my @out;
+       
+       if ($suffix) {
+               my $fn = _fn() . ".$suffix";
+               my $r = rand;
+               my $fh = IO::File->new (">>$fn.$r");
+               if ($fh) {
+                       print $fh "$_\n" for @in;
+                       $fh->close;
+                       move "$fn.$r", $fn;
+               } else {
+                       LogDbg('err', "DXCIDR::append error appending to $fn.$r $!");
+               }
+       } else {
+               LogDbg('err', "DXCIDR::append require badip suffix");
+       }
+       return scalar @in;
+}
+
 sub add
 {
        my $count = 0;
        
        for my $ip (@_) {
                # protect against stupid or malicious
-               next if /^127\./;
-               next if /^::1$/;
-               if (/\./) {
+               next if $ip =~ /^127\./;
+               next if $ip =~ /^::1$/;
+               if ($ip =~ /\./) {
                        $ipv4->add_any($ip);
                        ++$count;
                        ++$count4;
-               } elsif (/:/) {
+               } elsif ($ip =~ /:/) {
                        $ipv6->add_any($ip);
                        ++$count;
                        ++$count6;
-                       LogDbg('DXProt', "DXCIDR: Added IPV6 $ip address");
+               } else {
+                       LogDbg('err', "DXCIDR::add non-ip address '$ip' read");
                }
        }
        return $count;
@@ -119,12 +138,6 @@ sub clean_prep
        }
 }
 
-sub save
-{
-       return 0 unless $active;
-       _put() if $count4 || $count6;
-}
-
 sub _sort
 {
        my @in;
@@ -166,9 +179,35 @@ sub init
        import Net::CIDR::Lite;
        $active = 1;
 
+       my $fn = _fn();
+       if (-e $fn) {
+               move $fn, "$fn.base";
+       }
+
+       _touch("$fn.local");
+       
+       reload();
+
+}
+
+sub _touch
+{
+       my $fn = shift;
+       my $now = time;
+       local (*TMP);
+       utime ($now, $now, $fn) || open (TMP, ">>$fn") || LogDbg('err', "DXCIDR::touch: Couldn't touch $fn: $!");
+}
+
+sub reload
+{
        new();
 
-       load();
+       my $count = _load('base');
+       $count += _load('local');
+
+       LogDbg('DXProt', "DXCIDR::reload $count ip addresses found (IPV4: $count4 IPV6: $count6)" );
+
+       return $count;
 }
 
 sub new