From 3a815d1814c850aa43e302a35e03fdb67ddfb37d Mon Sep 17 00:00:00 2001 From: Vincent Li Date: Thu, 9 Oct 2025 17:15:40 +0000 Subject: [PATCH] fwhosts.cgi: Fix for bug 13876 & bug 13877 sync IPFire fwhosts.cgi commit 2398cc431a3fb2cd4141b6a846f0cd0742f6a97c Author: Michael Tremer Date: Thu Sep 25 17:05:32 2025 +0200 fwhosts.cgi: Escape PROT in the right place Signed-off-by: Michael Tremer commit ad995081302f6b28ea11c74e56306d94a7bee076 Author: Michael Tremer Date: Thu Sep 25 17:02:18 2025 +0200 fwhosts.cgi: Check country code before proceeding Signed-off-by: Michael Tremer commit a2c624b99dbcecb469e6001505731049ef5cbbd3 Author: Adolf Belka Date: Thu Sep 25 13:12:37 2025 +0200 fwhosts.cgi Fix for bug 13876 & bug 13877 Fixes: Bug 13876 savelocationgrp COUNTRY_CODE Stored Cross-Site Scripting Fixes: Bug 13877 saveservice PROT Stored Cross-Site Scripting Signed-off-by: Adolf Belka Reviewed-by: Bernhard Bitsch Signed-off-by: Michael Tremer commit 798556ec29207d5131a7600d5489f1ee92a7b87a Author: Michael Tremer Date: Mon Jun 23 17:16:57 2025 +0000 fwhosts.cgi: Move the tooltip into the usage counter This will clutter the page less as we don't have any good icon sets. Signed-off-by: Michael Tremer Tested-by: Adolf Belka Signed-off-by: Michael Tremer commit 61b277aa9c578a9a69e552f593a8bde421b811bc Author: Michael Tremer Date: Mon Jun 23 17:16:56 2025 +0000 fwhosts.cgi: Don't show anything if a host/group is unused Signed-off-by: Michael Tremer commit ca811a746a79f0e02cfb780cbd4543a057131e3a Author: Michael Tremer Date: Mon Jun 23 17:16:55 2025 +0000 fwhosts.cgi: Remove whitespace issues Signed-off-by: Michael Tremer commit 5511d94ed0d8ea6fd372d52cba515b4d6726abed Author: Peer Dietzmann Date: Mon Jun 23 17:16:54 2025 +0000 fwhosts.cgi: Show in which firewall rule objects are being used Signed-off-by: Michael Tremer Tested-by: Adolf Belka Signed-off-by: Michael Tremer commit 341eb00a821c4254ddd04968beed2e98e5a33aff Author: Michael Tremer Date: Sat May 3 15:10:16 2025 +0200 fwhosts.cgi: Correctly show IP addresses for WireGuard RW peers Signed-off-by: Michael Tremer Signed-off-by: Vincent Li --- config/cfgroot/general-functions.pl | 8 + html/cgi-bin/fwhosts.cgi | 353 ++++++++++++++++++++++++++-- langs/en/cgi-bin/en.pl | 1 + langs/zh/cgi-bin/zh.pl | 1 + 4 files changed, 346 insertions(+), 17 deletions(-) diff --git a/config/cfgroot/general-functions.pl b/config/cfgroot/general-functions.pl index 45fa4be65..51122df3c 100644 --- a/config/cfgroot/general-functions.pl +++ b/config/cfgroot/general-functions.pl @@ -870,6 +870,14 @@ sub validportrange # used to check a port range } } +# Checks for a valid country code +sub validcc($) { + my $cc = shift; + + # Must contain of exactly two uppercase characters, or must be A1, A2, or A3 + return ($cc =~ m/^([A-Z]{2}|A[123])$/); +} + sub IpInSubnet { my $addr = shift; my $network = shift; diff --git a/html/cgi-bin/fwhosts.cgi b/html/cgi-bin/fwhosts.cgi index 60c5a1953..dca425b69 100644 --- a/html/cgi-bin/fwhosts.cgi +++ b/html/cgi-bin/fwhosts.cgi @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2013 Alexander Marx # +# Copyright (C) 2013-2025 IPFire Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -703,6 +703,10 @@ if ($fwhostsettings{'ACTION'} eq 'savelocationgrp') # Check name if (!&validhostname($grp)){$errormessage.=$Lang::tr{'fwhost err name'};} + unless (&General::validcc($fwhostsettings{'COUNTRY_CODE'})) { + $errormessage = $Lang::tr{'fwhost invalid country code'}; + } + # Check for existing group name. if (!&checkgroup($grp) && $fwhostsettings{'update'} ne 'on'){ $errormessage = $Lang::tr{'fwhost err grpexist'}; @@ -714,7 +718,7 @@ if ($fwhostsettings{'ACTION'} eq 'savelocationgrp') } if ($fwhostsettings{'update'} eq 'on'){ - @target=$fwhostsettings{'COUNTRY_CODE'}; + @target = $fwhostsettings{'COUNTRY_CODE'}; $type='Location Group'; #check if host/net exists in grp @@ -1544,21 +1548,20 @@ END @@ -2107,8 +2111,10 @@ END $customhost{$key}[4]=~s/\s+//g; my $hostcount=0; $hostcount=&gethostcount($customhost{$key}[0]); - print"$customhost{$key}[0]".&getcolor($ip)."$customhost{$key}[3]$hostcount x"; - print<$customhost{$key}[0]$color$customhost{$key}[3]$hostcount x
@@ -2183,7 +2189,8 @@ sub viewtablegrp print "
$grpname   "; print " $Lang::tr{'remark'}:  $remark   " if ($remark ne ''); my $netgrpcount=&getnetcount($grpname); - print "$Lang::tr{'used'}: $netgrpcount x"; + my $groupusedin=&getusedin($grpname); + print "$Lang::tr{'used'}: $netgrpcount x"; if($netgrpcount == '0') { print"
"; @@ -2321,8 +2328,8 @@ sub viewtablelocationgrp # Get group count. my $locationgrpcount=&getlocationcount($grpname); - print "$Lang::tr{'used'}: $locationgrpcount x"; - + my $locationusedin=&getlocusedin($grpname); + print "$Lang::tr{'used'}: $locationgrpcount x"; # Only display delete icon, if the group is not used by a firewall rule. if($locationgrpcount == '0') { print"
\n"; @@ -2464,10 +2471,11 @@ END END #Neuer count $srvcount=&getsrvcount($customservice{$key}[0]); + my $serviceusedin=&getsrvusedin($customservice{$key}[0]); if($customservice{$key}[3] eq 'All ICMP-Types'){print $Lang::tr{'fwdfw all icmp'};} elsif($customservice{$key}[3] ne 'BLANK'){print $customservice{$key}[3];} print<$srvcount x + $srvcount x @@ -2539,7 +2547,8 @@ sub viewtableservicegrp if($count >0){print"";$count=1;} print "
$grpname    "; print "$Lang::tr{'remark'}:  $remark " if ($remark ne ''); - print "  $Lang::tr{'used'}: $grpcount x"; + my $srvgrpusedin=&getsrvusedin($customservicegrp{$key}[0]); + print "  $Lang::tr{'used'}: $grpcount x"; if($grpcount == '0') { print""; @@ -2812,6 +2821,106 @@ sub getlocationcount } return $counter; } +sub getlocusedin +{ + my $groupname=shift; + my $titletext=""; + + # Location groups are stored as "group:groupname" in the + # firewall settings files. + my $searchstring = join(':', "group",$groupname); + + #Count services used in firewall - config + my $fwfwtext=""; + # first set title if found + foreach my $key1 (keys %fwfwd) { + if($fwfwd{$key1}[4] eq $searchstring){ + $fwfwtext = "$Lang::tr{'firewall rules'}:"; + } + if($fwfwd{$key1}[6] eq $searchstring){ + $fwfwtext = "$Lang::tr{'firewall rules'}:"; + } + } + # then add rule numbers + my @fwfwrules = (); + foreach my $key1 (keys %fwfwd) { + if($fwfwd{$key1}[4] eq $searchstring){ + push(@fwfwrules, $key1); + } + if($fwfwd{$key1}[6] eq $searchstring){ + push(@fwfwrules, $key1); + } + } + my @fwfwarraysorted = sort { $a <=> $b } @fwfwrules; + foreach my $rule (@fwfwarraysorted) + { + $fwfwtext .= " - $rule"; + } + #Count services used in firewall - input + my $fwintext=""; + foreach my $key2 (keys %fwinp) { + if($fwinp{$key2}[4] eq $searchstring){ + $fwintext = "$Lang::tr{'incoming firewall access'}:"; + } + if($fwinp{$key2}[6] eq $searchstring){ + $fwintext = "$Lang::tr{'incoming firewall access'}:"; + } + } + my @fwinrules = (); + foreach my $key2 (keys %fwinp) { + if($fwinp{$key2}[4] eq $searchstring){ + push(@fwinrules, $key2); + } + if($fwinp{$key2}[6] eq $searchstring){ + push(@fwinrules, $key2); + } + } + my @fwinarraysorted = sort { $a <=> $b } @fwinrules; + foreach my $rule (@fwinarraysorted) + { + $fwintext .= " - $rule"; + } + #Count services used in firewall - outgoing + my $fwouttext=""; + foreach my $key3 (keys %fwout) { + if($fwout{$key3}[4] eq $searchstring){ + $fwouttext = "$Lang::tr{'outgoing firewall access'}:"; + } + if($fwout{$key3}[6] eq $searchstring){ + $fwouttext = "$Lang::tr{'outgoing firewall access'}:"; + } + } + my @fwoutrules = (); + foreach my $key3 (keys %fwout) { + if($fwout{$key3}[4] eq $searchstring){ + push(@fwoutrules, $key3); + } + if($fwout{$key3}[6] eq $searchstring){ + push(@fwoutrules, $key3); + } + } + my @fwoutarraysorted = sort { $a <=> $b } @fwoutrules; + foreach my $rule (@fwoutarraysorted) + { + $fwouttext .= " - $rule"; + } + if ($fwfwtext) { + $titletext .= "$fwfwtext" + } + if ($fwintext) { + if ($titletext) { + $titletext .= " " + } + $titletext .= "$fwintext" + } + if ($fwouttext) { + if ($titletext) { + $titletext .= " " + } + $titletext .= "$fwouttext" + } + return $titletext; +} sub getnetcount { my $searchstring=shift; @@ -2851,6 +2960,122 @@ sub getnetcount } return $srvcounter; } +sub getusedin +{ + my $searchstring=shift; + my $titletext=""; + my $groups=(); + my $rules=(); + + #Count services used in Network/Host group + my $servicegrouptext=""; + foreach my $key (keys %customgrp) { + if($customgrp{$key}[2] eq $searchstring){ + $servicegrouptext = "$Lang::tr{'fwhost cust grp'}:"; + } + } + foreach my $key (keys %customgrp) { + if($customgrp{$key}[2] eq $searchstring){ + $servicegrouptext .= " - $customgrp{$key}[0]"; + } + } + #Count services used in firewall - config + my $fwfwtext=""; + # first set title if found + foreach my $key1 (keys %fwfwd) { + if($fwfwd{$key1}[4] eq $searchstring){ + $fwfwtext = "$Lang::tr{'firewall rules'}:"; + } + if($fwfwd{$key1}[6] eq $searchstring){ + $fwfwtext = "$Lang::tr{'firewall rules'}:"; + } + } + # then add rule numbers + my @fwfwrules = (); + foreach my $key1 (keys %fwfwd) { + if($fwfwd{$key1}[4] eq $searchstring){ + push(@fwfwrules, $key1); + } + if($fwfwd{$key1}[6] eq $searchstring){ + push(@fwfwrules, $key1); + } + } + my @fwfwarraysorted = sort { $a <=> $b } @fwfwrules; + foreach my $rule (@fwfwarraysorted) + { + $fwfwtext .= " - $rule"; + } + #Count services used in firewall - input + my $fwintext=""; + foreach my $key2 (keys %fwinp) { + if($fwinp{$key2}[4] eq $searchstring){ + $fwintext = "$Lang::tr{'incoming firewall access'}:"; + } + if($fwinp{$key2}[6] eq $searchstring){ + $fwintext = "$Lang::tr{'incoming firewall access'}:"; + } + } + my @fwinrules = (); + foreach my $key2 (keys %fwinp) { + if($fwinp{$key2}[4] eq $searchstring){ + push(@fwinrules, $key2); + } + if($fwinp{$key2}[6] eq $searchstring){ + push(@fwinrules, $key2); + } + } + my @fwinarraysorted = sort { $a <=> $b } @fwinrules; + foreach my $rule (@fwinarraysorted) + { + $fwintext .= " - $rule"; + } + #Count services used in firewall - outgoing + my $fwouttext=""; + foreach my $key3 (keys %fwout) { + if($fwout{$key3}[4] eq $searchstring){ + $fwouttext = "$Lang::tr{'outgoing firewall access'}:"; + } + if($fwout{$key3}[6] eq $searchstring){ + $fwouttext = "$Lang::tr{'outgoing firewall access'}:"; + } + } + my @fwoutrules = (); + foreach my $key3 (keys %fwout) { + if($fwout{$key3}[4] eq $searchstring){ + push(@fwoutrules, $key3); + } + if($fwout{$key3}[6] eq $searchstring){ + push(@fwoutrules, $key3); + } + } + my @fwoutarraysorted = sort { $a <=> $b } @fwoutrules; + foreach my $rule (@fwoutarraysorted) + { + $fwouttext .= " - $rule"; + } + if ($servicegrouptext) { + $titletext .= "$servicegrouptext" + } + if ($fwfwtext) { + if ($titletext) { + $titletext .= " " + } + $titletext .= "$fwfwtext" + } + if ($fwintext) { + if ($titletext) { + $titletext .= " " + } + $titletext .= "$fwintext" + } + if ($fwouttext) { + if ($titletext) { + $titletext .= " " + } + $titletext .= "$fwouttext" + } + return $titletext +} sub getsrvcount { my $searchstring=shift; @@ -2881,6 +3106,100 @@ sub getsrvcount } return $srvcounter; } +sub getsrvusedin +{ + my $searchstring=shift; + my $titletext=""; + #Count services used in servicegroups + my $servicegrouptext=""; + foreach my $key (keys %customservicegrp) { + if($customservicegrp{$key}[2] eq $searchstring){ + $servicegrouptext = "$Lang::tr{'outgoing firewall access'}:"; + } + } + foreach my $key (keys %customservicegrp) { + if($customservicegrp{$key}[2] eq $searchstring){ + $servicegrouptext .= " - $customservicegrp{$key}[0]"; + } + } + my $fwfwtext=""; + # first set title if found + foreach my $key1 (keys %fwfwd) { + if($fwfwd{$key1}[15] eq $searchstring){ + $fwfwtext = "$Lang::tr{'firewall rules'}:"; + } + } + # then add rule numbers + my @fwfwrules = (); + foreach my $key1 (keys %fwfwd) { + if($fwfwd{$key1}[15] eq $searchstring){ + push(@fwfwrules, $key1); + } + } + my @fwfwarraysorted = sort { $a <=> $b } @fwfwrules; + foreach my $rule (@fwfwarraysorted) + { + $fwfwtext .= " - $rule"; + } + #Count services used in firewall - input + my $fwintext=""; + foreach my $key2 (keys %fwinp) { + if($fwinp{$key2}[15] eq $searchstring){ + $fwintext = "$Lang::tr{'incoming firewall access'}:"; + } + } + my @fwinrules = (); + foreach my $key2 (keys %fwinp) { + if($fwinp{$key2}[15] eq $searchstring){ + push(@fwinrules, $key2); + } + } + my @fwinarraysorted = sort { $a <=> $b } @fwinrules; + foreach my $rule (@fwinarraysorted) + { + $fwintext .= " - $rule"; + } + #Count services used in firewall - outgoing + my $fwouttext=""; + foreach my $key3 (keys %fwout) { + if($fwout{$key3}[15] eq $searchstring){ + $fwouttext = "$Lang::tr{'outgoing firewall access'}:"; + } + } + my @fwoutrules = (); + foreach my $key3 (keys %fwout) { + if($fwout{$key3}[15] eq $searchstring){ + push(@fwoutrules, $key3); + } + } + my @fwoutarraysorted = sort { $a <=> $b } @fwoutrules; + foreach my $rule (@fwoutarraysorted) + { + $fwouttext .= " - $rule"; + } + if ($servicegrouptext ne '') { + $titletext .= "$servicegrouptext"; + } + if ($fwfwtext ne '') { + if ($titletext) { + $titletext .= " "; + } + $titletext .= "$fwfwtext"; + } + if ($fwintext ne '') { + if ($titletext) { + $titletext .= " "; + } + $titletext .= "$fwintext"; + } + if ($fwouttext) { + if ($titletext ne '') { + $titletext .= " "; + } + $titletext .= "$fwouttext"; + } + return $titletext +} sub deletefromgrp { my $target=shift; diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 815d63c1d..65d0373b2 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -1343,6 +1343,7 @@ 'fwhost hint' => 'Note', 'fwhost hosts' => 'Firewall Hosts', 'fwhost icmptype' => 'ICMP type:', +'fwhost invalid country code' => 'Invalid Country Code', 'fwhost ip_mac' => 'IP/MAC address', 'fwhost ipadr' => 'IP address:', 'fwhost ipsec host' => 'IPsec clients:', diff --git a/langs/zh/cgi-bin/zh.pl b/langs/zh/cgi-bin/zh.pl index 3e15ea2e9..424b7a6de 100644 --- a/langs/zh/cgi-bin/zh.pl +++ b/langs/zh/cgi-bin/zh.pl @@ -1331,6 +1331,7 @@ 'fwhost hint' => '注意', 'fwhost hosts' => '防火墙主机', 'fwhost icmptype' => 'ICMP类型:', +'fwhost invalid country code' => '无效国家地代码', 'fwhost ip_mac' => 'IP/MAC地址', 'fwhost ipadr' => 'IP地址:', 'fwhost ipsec host' => 'IPsec客户端:',