X-Git-Url: http://git.ipfire.org/?p=people%2Fstevee%2Fguardian.git;a=blobdiff_plain;f=modules%2FEvents.pm;h=c451914da5b34aa63a9d877887cede3e829ccdd5;hp=b70bbb58c2908d2a30436e6a17c28e2650eac928;hb=8a79df70921e2a0da6a31d32f4f3a3ff5ecdf08b;hpb=7121d8cdb77ebae6f775890a6a38c0ffe448b0bf diff --git a/modules/Events.pm b/modules/Events.pm index b70bbb5..c451914 100644 --- a/modules/Events.pm +++ b/modules/Events.pm @@ -13,6 +13,8 @@ my %commands = ( 'unblock' => \&CallUnblock, 'flush' => \&CallFlush, 'reload' => \&main::Reload, + 'reload-ignore-list' => \&main::ReloadIgnoreList, + 'logrotate' => \&main::Logrotate, ); # Hash to store addresses and their current count. @@ -23,9 +25,14 @@ my %counthash = (); my %blockhash = (); # Hash to store user-defined IP addresses and/or subnets which should be -# ignored in case any events should be repored for them. +# ignored in case any events should be repored for them. my %ignorehash = (); +# Array to store localhost related IP addresses. +# They are always white-listed to prevent guardian from blocking +# any local traffic. +my @localhost_addresses = ("127.0.0.1", "::1"); + # This object will contain the reference to the logger object after calling Init. my $logger; @@ -64,12 +71,43 @@ sub Init (%) { if (exists($self->{IgnoreFile})) { # Call function to handle the ignore mechanism. &GenerateIgnoreList($self->{IgnoreFile}); + } else { + # Whitelist local addresses. + %ignorehash = &_whitelist_localhost(); } # Return the class object. return $self; } +# +## The "Update" Block settings function. +# +## This object based function is called to update various class settings. +# +sub Update (\%) { + my $self = shift; + + # Dereference the given hash-ref and store + # the values into a new temporary hash. + my %settings = %{ $_[0] }; + + # Skip settings update if some essential settings are missing. + unless ((exists($settings{BlockCount})) && (exists($settings{BlockTime}))) { + $logger->Log("err", "Values for BlockCount or BlockTime are missing, keeping previously configured settings."); + + # Return unmodified class object. + return $self; + } + + # Change settings. + $self->{BlockCount} = $settings{BlockCount}; + $self->{BlockTime} = $settings{BlockTime}; + + # Return modified class object. + return $self; +} + # ## The main "CheckAction" function. # @@ -282,6 +320,44 @@ sub CallUnblock ($) { # Drop address from blockhash. delete ($blockhash{$address}); + # Drop address from counthash if the address has been unblocked + # by the user. This happens when the called module is "Socket". + if ($module eq "Socket") { + delete ($counthash{$address}); + } + + # Everything worked well, return nothing. + return undef; +} + +# +## CallFlush function. +# +## This function is responsible for calling the used firewall +## engine to do a flush of the used firewall chain. This will +## clean the entire firewall chain. +# +sub CallFlush ($) { + my $self = shift; + + # Log the call for flushing. + $logger->Log("info", "Flush has been called..."); + + # Call flush. + my $error = &DoFlush(); + + # If an error message is returned, something went wrong. + if ($error) { + # Exit function and return the error message. + return $error; + } else { + # Flush successfully has been performed. + $logger->Log("debug", "Flush successfully has been performed..."); + } + + # Flush blockhash. + %blockhash = (); + # Everything worked well, return nothing. return undef; } @@ -295,6 +371,11 @@ sub CallUnblock ($) { # sub GenerateIgnoreList($) { my $file = shift; + my @include_files; + + # Reset current ignore hash and add + # localhost related IP addresses. + %ignorehash = &_whitelist_localhost(); # Check if the given IgnoreFile could be opened. unless(-e $file) { @@ -302,7 +383,7 @@ sub GenerateIgnoreList($) { return; } - # Open the given IgnoreFile. + # Open the given IgnoreFile. open (IGNORE, $file); # Read-in the file line by line. @@ -316,28 +397,106 @@ sub GenerateIgnoreList($) { # Remove any newlines. chomp; - # Check if the line contains a valid single address or network and - # convert it into binary format. Store the result/start and - # end values in a temporary array. - my @values = &Guardian::Base::IPOrNet2Int($_); + # Check for an include instruction. + if ($_ =~ /^Include_File = (.*)/) { + my $include_file = $1; - # If the function returned any values, the line contained a valid - # single address or network which successfully has been converted into - # binary format. - if (@values) { - # Assign the array as value to the ignorehash. - $ignorehash{$_} = [@values]; - } else { - # Log invalid entry. - $logger->Log("err", "IgnoreFile contains an invalid address/network: $_"); + # Check if the parsed include file exists and is read-able. + if (-e $include_file) { + # Add file to the array of files wich will be included. + push(@include_files, $include_file); - # Skip line. - next; + # Write out log message. + $logger->Log("debug", "Addresses from $include_file will be included..."); + } else { + # Log missing file. + $logger->Log("err", "$include_file will not be included. File does not exist!"); + } + } else { + # Check if the line contains a valid single address or network and + # convert it into binary format. Store the result/start and + # end values in a temporary array. + my @values = &Guardian::Base::IPOrNet2Int($_); + + # If the function returned any values, the line contained a valid + # single address or network which successfully has been converted into + # binary format. + if (@values) { + # Assign the array as value to the ignorehash. + $ignorehash{$_} = [@values]; + } else { + # Log invalid entry. + $logger->Log("err", "IgnoreFile contains an invalid address/network: $_"); + + # Skip line. + next; + } } } # Close filehandle for the IgnoreFile. close (IGNORE); + + # Check if any files should be included. + if (@include_files) { + # Loop through the array of files which should be included. + foreach my $file (@include_files) { + # Open the file. + open(INCLUDE, $file); + + # Read-in file line by line. + while() { + # Skip any comments. + next if (/\#/); + + # Skip any blank lines. + next if (/^\s*$/); + + # Chomp any newlines. + chomp; + + # Check if the line contains a valid single address or network and + # convert it into binary format. Store the result/start and + # end values in a temporary array. + my @values = &Guardian::Base::IPOrNet2Int($_); + + # If the function returned any values, the line contained a valid + # single address or network which successfully has been converted into + # binary format. + if (@values) { + # Assign the array as value to the ignorehash. + $ignorehash{$_} = [@values]; + } else { + # Log invalid entry. + $logger->Log("err", "$file contains an invalid address/network: $_"); + + # Skip line. + next; + } + } + + # Close filehandle. + close(INCLUDE); + } + } + + # Get amount of current elements in hash. + my $amount = scalar(keys(%ignorehash)); + + # Write out log message. + $logger->Log("debug", "Ignore list currently contains $amount entries:"); + + # Sort the ignore hash. + my @sorted_addresses = &Guardian::Base::SortAddressHash(\%ignorehash); + + # Loop through the entire array. + foreach my $address (@sorted_addresses) { + # Log the ignored address. + $logger->Log("debug", "\- $address"); + } + + # Finished return nothing. + return; } # @@ -405,4 +564,30 @@ sub _IsOnIgnoreList ($) { return; } +# +## The _whitelist_localhost function. +# +## This tiny private function simple generates and returns a hash which contains +## the clear and binary converted addresses for all array-stored +## (@localhost_addresses) in an ignorelist compatible format. +# +sub _whitelist_localhost () { + my %temphash; + + # Loop through the array of localhost related addresses. + foreach my $address (@localhost_addresses) { + # Validate and convert the addresss into binary format. + my @values = &Guardian::Base::IPOrNet2Int($address); + + # Check if any values are returned. + if (@values) { + # Store the converted binary values in the temporary hash. + $temphash{$address} = [@values]; + } + } + + # Return the temporary hash. + return %temphash; +} + 1;