]> git.ipfire.org Git - people/stevee/guardian.git/blobdiff - modules/Base.pm
Add functionality for whitelisting single addresses or network ranges.
[people/stevee/guardian.git] / modules / Base.pm
index e4ff8a0abed48f12f3d47f04fded1b5cf330b556..194cb9692a62cb115f44b22dfc8a905847706403 100644 (file)
@@ -4,49 +4,22 @@ use warnings;
 
 use Exporter qw(import);
 
-our @EXPORT_OK = qw(GenerateMonitoredFiles);
+our @EXPORT_OK = qw(GenerateMonitoredFiles FilePositions);
 
-#
-## Function for fileposition initialization.
-#
-## This function is used to get the cursor position of the end of file (EOF) of
-## a specified file.
-#
-## In order to prevent from permanently read and keep files opened, or dealing
-## with huge logfiles, at initialization time of the worker processes, the file will
-## be opened once and the cursor position of the end of file (EOF) get stored.
-#
-sub InitFileposition ($) {
-       my $file = $_[0];
-
-       # Open the file.
-       open(FILE, $file) or die "Could not open $file. $!\n";
-
-       # Just seek to the end of the file (EOF).
-       seek(FILE, 0, 2);
-
-       # Get and store the position.
-       my $position = tell(FILE),
-
-       # Close the file again.
-       close(FILE);
-
-       # Return the position.
-       return $position;
-}
+use Net::IP;
 
 #
 ## Function to generate a hash of monitored files and their file positions.
 #
 ## This function is responsible for creating the hash of which files should be
 ## monitored by guardian. In order to do this, all options from the given hash of
-## main settings will be parsed and all files to monitor extracted and stored into
-## a temporary hash.
+## main settings will be parsed and all files to monitor and their configured parsers
+## get extracted, validated and stored into a temporary hash.
 #
-## Next step will be to check if the the file allready is part of the existing hash
-## of monitored files and if true to use the stored value of the current cursor position.
-## If this check fails, the responsible function to initialize the cursor position of
-## EOF (end of file) will be called and stored.
+## Next step will be to cleanup files which have been monitored in the past but have been
+## requested for beeing unmonitored for now. To do this, a check if the the file name is
+## part of the existing hash of monitored files and if true to transfer the data into the
+## new temporary hash which get returned by the function.
 #
 sub GenerateMonitoredFiles (\%\%) {
        # Dereference the given hash-refs and store
@@ -57,14 +30,28 @@ sub GenerateMonitoredFiles (\%\%) {
        # Private hash for storing the new monitored files.
        my %new_monitored_files = ();
 
-       # Loop through the temporary hash which contains the main settings
-       # and search for files which should be monitored. Compare if the file
-       # already was part of the Add them to the
-       # private new hash of monitored files which will be returned.
+       # Loop through the temporary hash which contains the main settings.
+       # Search for files which should be monitored and extract the requested
+       # parser. Compare if the file already was a part of the hash which contains
+       # the monitored files and add them to the private new hash of monitored
+       # files which will be returned.
         foreach my $config_option (keys %mainsettings) {
                 # Skip option if it does not look like "Monitor_XYZ".
                 next unless($config_option =~ m/^Monitor_/);
 
+               # Splitt monitor instruction into 2 parts, to grab the
+               # requested parser module.
+               my ($start, $parser) = split (/_/, $config_option);
+
+               # Convert parser name into lower case format.
+               # Internally the parser module name is completely handled
+               # in this way. This also prevents from any problems related
+               # how the parser name has been spelled in the config file.
+               $parser = lc($parser);
+
+               # Check if the configured parser is available and valid.
+               next unless(&Guardian::Parser::IsSupportedParser($parser));
+
                 # Get the configured file for this option.
                 my $file = $mainsettings{$config_option};
 
@@ -75,9 +62,9 @@ sub GenerateMonitoredFiles (\%\%) {
                 # of monitored files.
                 unless(exists($current_monitored_files{$file})) {
                         # Add the file, init and store the fileposition.
-                        $new_monitored_files{$file} = &InitFileposition($file);
-                } else {
-                       # Add the file and grab the fileposition from the existing hash.
+                        $new_monitored_files{$file} = $parser;
+               } else {
+                       # Copy file and parser information to the new hash.
                        $new_monitored_files{$file} = $current_monitored_files{$file};
                }
         }
@@ -86,4 +73,149 @@ sub GenerateMonitoredFiles (\%\%) {
        return %new_monitored_files;
 }
 
+#
+## The FilePositions function.
+#
+## This function is responsible for creating and/or updating the hash which
+## stores the current cursor position of the end of file (EOF) of all
+## monitored files.
+#
+## The function requires the hash of currently monitored files and the old hash
+## of the current file positions in order to work properly.
+#
+sub FilePositions (\%\%) {
+       # Dereference the given hash-refs and store
+       # them into a new temporary hashes.
+       my %monitored_files = %{ $_[0] };
+       my %current_file_positions = %{ $_[1] };
+
+       # Private hash for storing the new monitored files.
+       my %new_file_positions = ();
+
+       # Loop through the hash of monitored files.
+       # Compare if the file allready has been a part of the hash
+       # which contains the file positions and transfer the stored
+       # cursor position into the temporary hash which will be returned.
+       #
+       # Otherwise, call the responsible function to obtain the current
+       # end of file (EOF) and store it.
+       foreach my $file (keys %monitored_files) {
+               # Check if the filename is allready part of the hash
+               # of file positions.
+               if (exists($current_file_positions{$file})) {
+                       # Copy file position into temporary hash.
+                       $new_file_positions{$file} = $current_file_positions{$file};
+               } else {
+                       # Call function to obtain the file position.
+                       my $position = &_initFileposition($file);
+
+                       # Add filename and position to the temporary hash.
+                       $new_file_positions{$file} = $position;
+               }
+       }
+
+       # Return the new_file_positions hash.
+       return %new_file_positions;
+}
+
+#
+## Wrapper function for IP address and network validation.
+#
+## This wrapper function uses the external Net::IP perl module to
+## check if a given input is a valid IPv4/IPv6 address or network.
+#
+sub IsValidAddressOrNetwork ($) {
+       my $address = shift;
+
+       # Check if the address is a valid IPv4/IPv6 address or network.
+       # Return "undef" False if the address is not valid.
+       my $ip = new Net::IP ($address) || return undef;
+
+       # If we got here, the address is valid. Return True.
+       return 1;
+}
+
+#
+## Address/Network to binary format caluculator function.
+#
+## This function is used to convert a given single IP address
+## or network into a binary format.
+#
+## The used Net::IP module is not able to directly detect
+## single addresses or network ranges. Only an element which may be
+## a single address or a whole network can be assigned, for which a
+## lot of different values can be calculated. In case the input has
+## been a single address, the module will calculate the same binary
+## address (intip) and last address for the network range (last_int)
+## because internally it uses a /32 bit prefix for IPv4 and a /128 prefix
+## on IPv6 addresses.
+#
+## So a single address can be detected by just comparing both calculated
+## addresses if they are equal.
+#
+sub IPOrNet2Int($) {
+       my $address = shift;
+
+       # Assign and validate the given address, or directly return
+       # nothing (False) and exit the function.
+       my $ip = new Net::IP ($address) || return;
+
+       # Convert the given address into integer format.
+       my $first .= $ip->intip();
+
+       # Calculate last address for the given network.
+       my $last .= $ip->last_int();
+
+       # Check whether the first address equals the last address.
+       # If this is true, a single IP address has been passed.
+       if ($first eq $last) {
+               # Return the binary converted single address.
+               return $first;
+       }
+
+       # If both addresses are not equal a network has been passed.
+       #
+       # Check if the converted first address is less than the calculated last
+       # address of the network.
+       elsif ($first < $last) {
+               # Return the binary converted first and last address of
+               # the given network.
+               return $first, $last;
+       }
+
+       # If we got here, something strange happend, return nothing (False).
+       else {
+               return;
+       }
+}
+
+#
+## Function for fileposition initialization.
+#
+## This function is used to get the cursor position of the end of file (EOF) of
+## a specified file.
+#
+## In order to prevent from permanently read and keep files opened, or dealing
+## with huge logfiles, at initialization time of the worker processes, the file will
+## be opened once and the cursor position of the end of file (EOF) get stored.
+#
+sub _initFileposition ($) {
+       my $file = $_[0];
+
+       # Open the file.
+       open(FILE, $file) or die "Could not open $file. $!";
+
+       # Just seek to the end of the file (EOF).
+       seek(FILE, 0, 2);
+
+       # Get and store the position.
+       my $position = tell(FILE),
+
+       # Close the file again.
+       close(FILE);
+
+       # Return the position.
+       return $position;
+}
+
 1;