From 996fed89967a1fd4d8665a10fd73b9612aeb1606 Mon Sep 17 00:00:00 2001 From: Dirk Koopman Date: Mon, 9 Jan 2023 15:21:04 +0000 Subject: [PATCH] store local and base badips in separate files --- cmd/load/badip.pl | 2 +- cmd/set/badip.pl | 12 ++++-- perl/DXCIDR.pm | 107 +++++++++++++++++++++++++++++++--------------- 3 files changed, 82 insertions(+), 39 deletions(-) diff --git a/cmd/load/badip.pl b/cmd/load/badip.pl index 22967cd7..3cf4212d 100644 --- a/cmd/load/badip.pl +++ b/cmd/load/badip.pl @@ -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"; diff --git a/cmd/set/badip.pl b/cmd/set/badip.pl index b5376356..3c4578ba 100644 --- a/cmd/set/badip.pl +++ b/cmd/set/badip.pl @@ -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); diff --git a/perl/DXCIDR.pm b/perl/DXCIDR.pm index 7cb13df0..88a26d5c 100644 --- a/perl/DXCIDR.pm +++ b/perl/DXCIDR.pm @@ -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 -- 2.43.0