diff --git a/AN/Tools.pm b/AN/Tools.pm index 09b4b781..424ce82b 100755 --- a/AN/Tools.pm +++ b/AN/Tools.pm @@ -656,7 +656,7 @@ sub _set_paths backups => "/usr/sbin/striker/backups", 'cgi-bin' => "/var/www/cgi-bin", firewalld_services => "/usr/lib/firewalld/services", - firewalld_zones => "/etc/firewalld/zones/", + firewalld_zones => "/etc/firewalld/zones", html => "/var/www/html", skins => "/var/www/html/skins", tools => "/usr/sbin/striker", diff --git a/AN/Tools/System.pm b/AN/Tools/System.pm index 7ee53946..d1a15725 100755 --- a/AN/Tools/System.pm +++ b/AN/Tools/System.pm @@ -406,10 +406,10 @@ sub manage_firewall my $task = defined $parameter->{task} ? $parameter->{task} : "check"; my $port_number = defined $parameter->{port_number} ? $parameter->{port_number} : ""; my $protocol = defined $parameter->{protocol} ? $parameter->{protocol} : "tcp"; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { task => $task, port_number => $port_number, - protocol => $protocol, + protocol => $protocol, }}); # Make sure we have a port or service. @@ -418,6 +418,11 @@ sub manage_firewall # ... return("!!error!!"); } + if (($protocol ne "tcp") && ($protocol ne "udp")) + { + # Bad protocol + return("!!error!!"); + } # Before we do anything, what zone is active? my $active_zone = ""; @@ -439,379 +444,171 @@ sub manage_firewall last; } } + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { active_zone => $active_zone }}); - # Read in all services and store information about them. - #$an->System->_load_firewalld_zones; - - # What is the default zone? Read the config file, if possible, as it is several times faster than - # invoking 'firewall-cmd'. - my $default_zone = ""; - my $firewalld_conf = $an->Storage->read_file({file => $an->data->{path}{configs}{'firewalld.conf'}}); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { firewalld_conf => $firewalld_conf }}); - if ($firewalld_conf =~ /^DefaultZone=(.*)$/m) + # If I still don't know what the active zone is, we're done. + if (not $active_zone) { - $default_zone = $1; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { default_zone => $default_zone }}); + return("!!error!!"); } - # If we didn't get the default zone from the file, try with the 'firewall-cmd' command. - if (not $default_zone) + + # See if the requested port is open. + my $open = 0; + + # If we have an active zone, see if the requested port is open. + my $zone_file = $an->data->{path}{directories}{firewalld_zones}."/".$active_zone.".xml"; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { zone_file => $zone_file }}); + if (not -e $zone_file) { - my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --get-default-zone"; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - - my $output = $an->System->call({shell_call => $shell_call}); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); - foreach my $line (split/\n/, $output) - { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); - if ($line !~ /\s/) - { - $default_zone = $line; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { default_zone => $default_zone }}); - } - last; - } + #... + return("!!error!!"); } - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - active_zone => $active_zone, - default_zone => $default_zone, - }}); - # If we have an active zone, see if the requested port is open. - my $open_tcp_ports = []; - my $open_udp_ports = []; - my $open_services = []; - if ($active_zone) + # Read the XML to see what services are opened already and translate those into port numbers and + # protocols. + my $open_services = []; + my $xml = XML::Simple->new(); + my $body = ""; + eval { $body = $xml->XMLin($zone_file, KeyAttr => { language => 'name', key => 'name' }, ForceArray => [ 'service' ]) }; + if ($@) + { + chomp $@; + my $error = "[ Error ] - The was a problem reading: [$zone_file]. The error was:\n"; + $error .= "===========================================================\n"; + $error .= $@."\n"; + $error .= "===========================================================\n"; + $an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", raw => $error}); + } + else { - ### TODO: Read /etc/firewalld/zones/${active_zone}.xml with XMLin and for each - ### '', read in '$an->data->{path}{directories}{firewalld_services}/foo.xml'. - if (1) + # Parse the already-opened services + foreach my $hash_ref (@{$body->{service}}) { - my $zone_file = $an->data->{path}{directories}{firewalld_zones}."/".$active_zone.".xml"; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { zone_file => $zone_file }}); - - if (not -e $zone_file) - { - die $THIS_FILE." ".__LINE__."; zone config not found: [$zone_file]\n"; - } - my $xml = XML::Simple->new(); - my $body = ""; - eval { $body = $xml->XMLin($zone_file, KeyAttr => { language => 'name', key => 'name' }, ForceArray => [ 'service' ]) }; - if ($@) - { - chomp $@; - my $error = "[ Error ] - The was a problem reading: [$zone_file]. The error was:\n"; - $error .= "===========================================================\n"; - $error .= $@."\n"; - $error .= "===========================================================\n"; - $an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", raw => $error}); - } - else + # Load the details of this service. + my $service = $hash_ref->{name}; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service => $service }}); + $an->System->_load_specific_firewalld_zone({service => $hash_ref->{name}}); + push @{$open_services}, $service; + } + + # Now loop through the open services, protocols and ports looking for the one passed in by + # the caller. If found, the port is already open. + foreach my $service (sort {$a cmp $b} @{$open_services}) + { + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service => $service }}); + foreach my $this_protocol ("tcp", "udp") { - #print Dumper $body; - print "Zone: [$active_zone] open services;\n"; - foreach my $hash_ref (@{$body->{service}}) + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { this_protocol => $this_protocol }}); + foreach my $this_port (sort {$a cmp $b} @{$an->data->{firewalld}{zones}{by_name}{$service}{tcp}}) { - my $service = $hash_ref->{name}; - print "- $service\n"; - $an->System->_load_specific_firewalld_zone({service => $hash_ref->{name}}); - } - - foreach my $service (sort {$a cmp $b} keys %{$an->data->{firewalld}{zones}{by_name}}) - { - print "- $service\n"; - my $tcp_ports = ""; - foreach my $port (sort {$a cmp $b} @{$an->data->{firewalld}{zones}{by_name}{$service}{tcp}}) - { - #print "- tcp: [$port]\n"; - $tcp_ports .= $port.", "; - } - $tcp_ports =~ s/, $//; - if ($tcp_ports) + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { this_port => $this_port }}); + if (($port_number eq $this_port) && ($this_protocol eq $protocol)) { - print " - TCP Ports: [$tcp_ports]\n"; - } - - my $udp_ports = ""; - foreach my $port (sort {$a cmp $b} @{$an->data->{firewalld}{zones}{by_name}{$service}{udp}}) - { - $udp_ports .= $port.", "; - } - $udp_ports =~ s/, $//; - if ($udp_ports) - { - print " - UDP Ports: [$udp_ports]\n"; + # Opened already (as the recorded service). + $open = $service; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'open' => $open }}); + last if $open; } + last if $open; } + last if $open; } + last if $open; } - if (0) + } + + # We're done if we were just checking. However, if we've been asked to open a currently closed port, + # or vice versa, make the change before returning. + my $changed = 0; + if (($task eq "open") && (not $open)) + { + # Map the port to a service, if possible. + my $service = $an->System->_match_port_to_service({port => $port_number}); + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { service => $service }}); + + # Open the port + if ($service) { - my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --zone=".$active_zone." --list-all"; + my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --permanent --add-service ".$service; $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); my $output = $an->System->call({shell_call => $shell_call}); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); - foreach my $line (split/\n/, $output) + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); + if ($output eq "success") { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); - if ($line =~ /services: (.*)$/) - { - my $services = $an->Words->clean_spaces({ string => $1 }); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { services => $services }}); - foreach my $service (split/\s/, $services) - { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service => $service }}); - push @{$open_services}, $service; - } - } - if ($line =~ /ports: (.*)$/) - { - my $open_ports = $an->Words->clean_spaces({ string => $1 }); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { open_ports => $open_ports }}); - foreach my $port (split/\s/, $open_ports) - { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { port => $port }}); - if ($port =~ /^(\d+)\/tcp/) - { - my $tcp_port = $1; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { tcp_port => $tcp_port }}); - push @{$open_tcp_ports}, $tcp_port; - } - elsif ($port =~ /^(\d+)\/udp/) - { - my $udp_port = $1; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { udp_port => $udp_port }}); - push @{$open_udp_ports}, $udp_port; - } - else - { - # Bad port. - return("!!error!!"); - } - } - } + $open = 1; + $changed = 1; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'open' => $open, changed => $changed }}); } - - # Convert services to ports. - foreach my $service (sort @{$open_services}) + else { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service => $service }}); - - my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --info-service ".$service; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - - my $output = $an->System->call({shell_call => $shell_call}); - my $this_port = ""; - my $this_protocol = ""; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); - foreach my $line (split/\n/, $output) - { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); - if ($line =~ /ports: (\d+)\/(.*)$/) - { - $this_port = $1; - $this_protocol = $2; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - this_port => $this_port, - this_protocol => $this_protocol, - }}); - if ($this_protocol eq "tcp") - { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { this_port => $this_port }}); - push @{$open_tcp_ports}, $this_port; - } - elsif ($this_protocol eq "udp") - { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { this_port => $this_port }}); - push @{$open_udp_ports}, $this_port; - } - else - { - # What? - return("!!error!!"); - } - } - } - if ((not $this_port) or (not $this_protocol)) - { - # What? - return("!!error!!"); - } + # Something went wrong... + return("!!error!!"); } } - } - - # Debugging - foreach my $open_tcp_port (sort {$a cmp $b} @{$open_tcp_ports}) - { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { open_tcp_port => $open_tcp_port }}); - } - foreach my $open_udp_port (sort {$a cmp $b} @{$open_udp_ports}) - { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { open_udp_port => $open_udp_port }}); - } - - # See if the requested port is open. - my $open = 0; - if ($protocol eq "tcp") - { - foreach my $port (sort {$a cmp $b} @{$open_tcp_ports}) + else { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { port => $port }}); - if ($port eq $port_number) + my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --permanent --add-port ".$port_number."/".$protocol; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); + + my $output = $an->System->call({shell_call => $shell_call}); + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); + if ($output eq "success") { - $open = 1; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'open' => $open }}); - last; + $open = 1; + $changed = 1; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'open' => $open, changed => $changed }}); } - } - } - elsif ($protocol eq "udp") - { - foreach my $port (sort {$a cmp $b} @{$open_udp_ports}) - { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { port => $port }}); - if ($port eq $port_number) + else { - $open = 1; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'open' => $open }}); - last; + # Something went wrong... + return("!!error!!"); } } } - else - { - # Bad port type - return("!!error!!"); - } - - # If we're opening or closing, work on the active and default zones (or just the one when they're the - # same zone) - my $zones = $default_zone; - if (($default_zone) && ($active_zone)) - { - if ($default_zone ne $active_zone) - { - $zones = $active_zone.",".$default_zone; - } - } - elsif ($default_zone) - { - $zones = $default_zone; - } - elsif ($active_zone) - { - $zones = $active_zone; - } - else - { - # No zones found... - return("!!error!!"); - } - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { zones => $zones }}); - - # We're done if we were just checking. - my $changed = 0; - if (($task eq "open") && (not $open)) + elsif (($task eq "close") && ($open)) { # Map the port to a service, if possible. my $service = $an->System->_match_port_to_service({port => $port_number}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { service => $service }}); - # Open the port - foreach my $zone (split/,/, $zones) + # Close the port + if ($service) { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { zone => $zone }}); + my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --permanent --remove-service ".$service; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - if ($service) + my $output = $an->System->call({shell_call => $shell_call}); + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); + if ($output eq "success") { - my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --permanent --add-service ".$service; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - - my $output = $an->System->call({shell_call => $shell_call}); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); - if ($output eq "success") - { - $open = 1; - $changed = 1; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'open' => $open, changed => $changed }}); - } - else - { - # Something went wrong... - return("!!error!!"); - } + $open = 0; + $changed = 1; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'open' => $open, changed => $changed }}); } else { - my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --permanent --add-port ".$port_number."/".$protocol; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - - my $output = $an->System->call({shell_call => $shell_call}); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); - if ($output eq "success") - { - $open = 1; - $changed = 1; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'open' => $open, changed => $changed }}); - } - else - { - # Something went wrong... - return("!!error!!"); - } + # Something went wrong... + return("!!error!!"); } } - } - elsif (($task eq "close") && ($open)) - { - # Map the port to a service, if possible. - my $service = $an->System->_match_port_to_service({port => $port_number}); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { service => $service }}); - - # Close the port - foreach my $zone (split/,/, $zones) + else { - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { zone => $zone }}); + my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --permanent --remove-port ".$port_number."/".$protocol; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - if ($service) + my $output = $an->System->call({shell_call => $shell_call}); + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); + if ($output eq "success") { - my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --permanent --remove-service ".$service; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - - my $output = $an->System->call({shell_call => $shell_call}); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); - if ($output eq "success") - { - $open = 0; - $changed = 1; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'open' => $open, changed => $changed }}); - } - else - { - # Something went wrong... - return("!!error!!"); - } + $open = 0; + $changed = 1; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'open' => $open, changed => $changed }}); } else { - my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --permanent --remove-port ".$port_number."/".$protocol; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); - - my $output = $an->System->call({shell_call => $shell_call}); - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); - if ($output eq "success") - { - $open = 0; - $changed = 1; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'open' => $open, changed => $changed }}); - } - else - { - # Something went wrong... - return("!!error!!"); - } + # Something went wrong... + return("!!error!!"); } } } @@ -1612,6 +1409,10 @@ sub _load_firewalld_zones # Missing directory... return("!!error!!"); } + + $an->data->{sys}{firewalld}{services_loaded} = 0 if not defined $an->data->{sys}{firewalld}{services_loaded}; + return(0) if $an->data->{sys}{firewalld}{services_loaded}; + local(*DIRECTORY); opendir(DIRECTORY, $directory); while(my $file = readdir(DIRECTORY)) @@ -1628,49 +1429,8 @@ sub _load_firewalld_zones } closedir DIRECTORY; - ### DEBUG stuff... - if (0) - { - foreach my $service (sort {$a cmp $b} keys %{$an->data->{firewalld}{zones}{by_name}}) - { - print "Service name: [$service (".$an->data->{firewalld}{zones}{by_name}{$service}{name}.")]\n"; - - my $tcp_ports = ""; - foreach my $port (sort {$a cmp $b} @{$an->data->{firewalld}{zones}{by_name}{$service}{tcp}}) - { - #print "- tcp: [$port]\n"; - $tcp_ports .= $port.", "; - } - $tcp_ports =~ s/, $//; - if ($tcp_ports) - { - print "- TCP Ports: [$tcp_ports]\n"; - } - - my $udp_ports = ""; - foreach my $port (sort {$a cmp $b} @{$an->data->{firewalld}{zones}{by_name}{$service}{udp}}) - { - $udp_ports .= $port.", "; - } - $udp_ports =~ s/, $//; - if ($udp_ports) - { - print "- UDP Ports: [$udp_ports]\n"; - } - } - } - - if (0) - { - foreach my $protocol ("tcp", "udp") - { - foreach my $port (sort {$a <=> $b} keys %{$an->data->{firewalld}{zones}{by_port}{$protocol}}) - { - my $service = $an->data->{firewalld}{zones}{by_port}{$protocol}{$port}; - print "$port / $protocol -> [$service] (".$an->data->{firewalld}{zones}{by_name}{$service}{name}.")\n"; - } - } - } + # Set this so we don't waste time calling this again. + $an->data->{sys}{firewalld}{services_loaded} = 1; return(0); } @@ -1718,6 +1478,10 @@ sub _load_specific_firewalld_zone $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service => $service }}); } + # We want the service name to be the file name without the '.xml' suffix. + my $service_name = ($service =~ /^(.*?)\.xml$/)[0]; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service_name => $service_name }}); + my $full_path = $an->data->{path}{directories}{firewalld_services}."/".$service; $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { full_path => $full_path }}); if (not -e $full_path) @@ -1733,26 +1497,26 @@ sub _load_specific_firewalld_zone { chomp $@; my $error = "[ Error ] - The was a problem reading: [$full_path]. The error was:\n"; - $error .= "===========================================================\n"; - $error .= $@."\n"; - $error .= "===========================================================\n"; + $error .= "===========================================================\n"; + $error .= $@."\n"; + $error .= "===========================================================\n"; $an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", raw => $error}); } else { - #print Dumper $body; my $name = $body->{short}; - $an->data->{firewalld}{zones}{by_name}{$service}{name} = $name; - if ((not defined $an->data->{firewalld}{zones}{by_name}{$service}{tcp}) or (ref($an->data->{firewalld}{zones}{by_name}{$service}{tcp}) ne "ARRAY")) + $an->data->{firewalld}{zones}{by_name}{$service_name}{name} = $name; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "firewalld::zones::by_name::${service_name}::name" => $an->data->{firewalld}{zones}{by_name}{$service_name}{name} }}); + + if ((not defined $an->data->{firewalld}{zones}{by_name}{$service_name}{tcp}) or (ref($an->data->{firewalld}{zones}{by_name}{$service_name}{tcp}) ne "ARRAY")) { - $an->data->{firewalld}{zones}{by_name}{$service}{tcp} = []; + $an->data->{firewalld}{zones}{by_name}{$service_name}{tcp} = []; } - if ((not defined $an->data->{firewalld}{zones}{by_name}{$service}{udp}) or (ref($an->data->{firewalld}{zones}{by_name}{$service}{udp}) ne "ARRAY")) + if ((not defined $an->data->{firewalld}{zones}{by_name}{$service_name}{udp}) or (ref($an->data->{firewalld}{zones}{by_name}{$service_name}{udp}) ne "ARRAY")) { - $an->data->{firewalld}{zones}{by_name}{$service}{udp} = []; + $an->data->{firewalld}{zones}{by_name}{$service_name}{udp} = []; } - #print "Name: [$name], file: [$file]\n"; foreach my $hash_ref (@{$body->{port}}) { my $this_port = $hash_ref->{port}; @@ -1772,20 +1536,17 @@ sub _load_specific_firewalld_zone start => $start, end => $end, }}); - #print "- Range - $this_port ($start -> $end)...\n"; foreach my $port ($start..$end) { - #print "- $port / $this_protocol\n"; - $an->data->{firewalld}{zones}{by_port}{$this_protocol}{$port} = $service; - push @{$an->data->{firewalld}{zones}{by_name}{$service}{$this_protocol}}, $port; + $an->data->{firewalld}{zones}{by_port}{$this_protocol}{$port} = $service_name; + push @{$an->data->{firewalld}{zones}{by_name}{$service_name}{$this_protocol}}, $port; } } else { # Nope - #print "- $this_port / $this_protocol\n"; - $an->data->{firewalld}{zones}{by_port}{$this_protocol}{$this_port} = $service; - push @{$an->data->{firewalld}{zones}{by_name}{$service}{$this_protocol}}, $this_port; + $an->data->{firewalld}{zones}{by_port}{$this_protocol}{$this_port} = $service_name; + push @{$an->data->{firewalld}{zones}{by_name}{$service_name}{$this_protocol}}, $this_port; } } } @@ -1818,72 +1579,32 @@ sub _match_port_to_service my $port = defined $parameter->{port} ? $parameter->{port} : ""; my $protocol = defined $parameter->{protocol} ? $parameter->{protocol} : "tcp"; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { port => $port, protocol => $protocol, }}); + # Do we already know about this service? my $service_name = ""; - my $services = []; - - # Read in the firewall - my $directory = $an->data->{path}{directories}{firewalld_services}; - $an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0018", variables => { directory => $directory }}); - if (not -d $directory) + if ((exists $an->data->{firewalld}{zones}{by_port}{$protocol}{$port}) && ($an->data->{firewalld}{zones}{by_port}{$protocol}{$port})) { - # Missing directory... - return("!!error!!"); + # Yay! + $service_name = $an->data->{firewalld}{zones}{by_port}{$protocol}{$port}; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service_name => $service_name }}); } - local(*DIRECTORY); - opendir(DIRECTORY, $directory); - while(my $file = readdir(DIRECTORY)) + else { - next if $file !~ /\.xml$/; - my $full_path = $directory."/".$file; - my $service = ($file =~ /^(.*?)\.xml$/)[0]; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - full_path => $full_path, - service => $service, - }}); - - my $xml = XML::Simple->new(); - my $body = ""; - eval { $body = $xml->XMLin($full_path, KeyAttr => { language => 'name', key => 'name' }, ForceArray => [ 'port' ]) }; - if ($@) + # Load all zones and look + $an->System->_load_firewalld_zones; + if ((exists $an->data->{firewalld}{zones}{by_port}{$protocol}{$port}) && ($an->data->{firewalld}{zones}{by_port}{$protocol}{$port})) { - chomp $@; - my $error = "[ Error ] - The was a problem reading: [$file]. The error was:\n"; - $error .= "===========================================================\n"; - $error .= $@."\n"; - $error .= "===========================================================\n"; - $an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", raw => $error}); + # Got it now. + $service_name = $an->data->{firewalld}{zones}{by_port}{$protocol}{$port}; + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service_name => $service_name }}); } - else - { - #print Dumper $body; - my $name = $body->{short}; - foreach my $hash_ref (@{$body->{port}}) - { - my $this_port = $hash_ref->{port}; - my $this_protocol = $hash_ref->{protocol}; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - this_port => $this_port, - this_protocol => $this_protocol, - }}); - if (($this_port eq $port) && ($this_protocol eq $protocol)) - { - # Found it! - $service_name = $service; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service_name => $service_name }}); - last; - } - } - } - last if $service_name; } - closedir DIRECTORY; - $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { service_name => $service_name }}); + $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service_name => $service_name }}); return($service_name); }