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.
#
# when the block for this address can be released.
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.
+my %ignorehash = ();
+
# This object will contain the reference to the logger object after calling Init.
my $logger;
my $module_name = "Guardian::" . $self->{FirewallEngine};
eval "use $module_name; 1" or die "Could not load a module for firewall engine: $self->{FirewallEngine}!";
+ # Check if an IgnoreFile has been configured.
+ if (exists($self->{IgnoreFile})) {
+ # Call function to handle the ignore mechanism.
+ &GenerateIgnoreList($self->{IgnoreFile});
+ }
+
# Return the class object.
return $self;
}
return;
}
- # Check if the given address is valid.
- unless(&Guardian::Base::IsValidAddressOrNetwork($address)) {
- # Log error message.
+ # Convert and validate the given address.
+ my $bin_address = &Guardian::Base::IPOrNet2Int($address);
+
+ # Abort if the given address could not be converted because it is not valid.
+ unless ($bin_address) {
$logger->Log("err", "Invalid IP address: $address");
return;
}
+ # Check if address should be ignored.
+ if(&_IsOnIgnoreList($bin_address)) {
+ # Log message.
+ $logger->Log("info", "Ignoring event for $address, because it is part of the ignore list.");
+ return;
+ }
+
# Call required handler.
my $error = $commands{$command}->($self, $address, $module, $message);
return undef;
}
+#
+## GenerateIgnoreList function.
+#
+## This function is responsible for generating/updating the
+## IgnoreHash which contains all ignored IP addresses and
+## networks.
+#
+sub GenerateIgnoreList($) {
+ my $file = shift;
+
+ # Check if the given IgnoreFile could be opened.
+ unless(-e $file) {
+ $logger->Log("err", "The configured IgnoreFile \($file\) could not be opened. Skipped!");
+ return;
+ }
+
+ # Open the given IgnoreFile.
+ open (IGNORE, $file);
+
+ # Read-in the file line by line.
+ while (<IGNORE>) {
+ # Skip comments.
+ next if (/\#/);
+
+ # Skip blank lines.
+ next if (/^\s*$/);
+
+ # 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($_);
+
+ # 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);
+}
+
+#
+## Private function to check if an address is part of the Ignore Hash.
+#
+## This function requires
+#
+sub _IsOnIgnoreList ($) {
+ my $bin_address = shift;
+
+ # Loop through the ignore hash and grab the stored values.
+ foreach my $key ( keys %ignorehash ) {
+ # Dereference values array.
+ my @values = @{$ignorehash{$key}};
+
+ # Obtain amount of items for the current value array.
+ my $items = scalar @values;
+
+ # Whether the amount equals one, the given binary address just
+ # needs to be compared against a single address.
+ if ($items eq "1") {
+ my ($ignored_address) = @values;
+
+ # Simple check if the stored and the given binary address
+ # are the same.
+ if ($bin_address eq $ignored_address) {
+ # The given address is part of the ignore list.
+ $logger->Log("debug", "Address $key found on the ignore list.");
+
+ # Return "1" (True).
+ return 1;
+ }
+ }
+
+ # If the amount equals two, for passed binary address needs to
+ # be checked if it is part of the ignored network range.
+ elsif ($items eq "2") {
+ my ($first_address, $last_address) = @values;
+
+ # Check if the passed binary address is bigger than
+ # the first address and smaler than the last address
+ # (between) the stored network range.
+ if (($bin_address >= $first_address) && ($bin_address <= $last_address)) {
+ # The address is part of an ignored network.
+ $logger->Log("debug", "Address is found inside the ignored network $key.");
+
+ # Return "1" (True).
+ return 1;
+ }
+
+ # If the amount is not eighter one or two, the current entry of the ignorehash seems
+ # to be corrupted. Skip and log it.
+ } else {
+ # Write log message about this corruped item in the ignore hash.
+ $logger->Log("err", "Invalid item in the Ignore Hash: $key - @values");
+
+ # Skip this element of the ignore hash.
+ next;
+ }
+ }
+
+ # If we got here, the given address is not part of the ignore hash.
+ # Return nothing (False).
+ return;
+}
+
1;