From 4313aa18e9e3b3f6717946b88c8a67f79dea40be Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 8 Feb 2015 13:37:06 +0100 Subject: [PATCH] fwhosts.cgi: Add support for GeoIP groups. --- html/cgi-bin/fwhosts.cgi | 531 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 530 insertions(+), 1 deletion(-) diff --git a/html/cgi-bin/fwhosts.cgi b/html/cgi-bin/fwhosts.cgi index c3642f0f0e..395dca83c6 100644 --- a/html/cgi-bin/fwhosts.cgi +++ b/html/cgi-bin/fwhosts.cgi @@ -27,6 +27,8 @@ use Sort::Naturally; use CGI::Carp 'fatalsToBrowser'; no warnings 'uninitialized'; require '/var/ipfire/general-functions.pl'; +require "/var/ipfire/geoip-functions.pl"; +require "/usr/lib/firewall/firewall-lib.pl"; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; @@ -36,6 +38,7 @@ my %customhost=(); my %customgrp=(); my %customservice=(); my %customservicegrp=(); +my %customgeoipgrp=(); my %ccdnet=(); my %ccdhost=(); my %ipsecconf=(); @@ -62,6 +65,7 @@ my $configccdhost = "${General::swroot}/ovpn/ovpnconfig"; my $configipsec = "${General::swroot}/vpn/config"; my $configsrv = "${General::swroot}/fwhosts/customservices"; my $configsrvgrp = "${General::swroot}/fwhosts/customservicegrp"; +my $configgeoipgrp = "${General::swroot}/fwhosts/customgeoipgrp"; my $fwconfigfwd = "${General::swroot}/firewall/config"; my $fwconfiginp = "${General::swroot}/firewall/input"; my $fwconfigout = "${General::swroot}/firewall/outgoing"; @@ -73,6 +77,7 @@ unless (-e $confighost) { system("touch $confighost"); } unless (-e $configgrp) { system("touch $configgrp"); } unless (-e $configsrv) { system("touch $configsrv"); } unless (-e $configsrvgrp) { system("touch $configsrvgrp"); } +unless (-e $configgeoipgrp) { system("touch $configgeoipgrp"); } &General::readhash("${General::swroot}/main/settings", \%mainsettings); &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); @@ -671,6 +676,84 @@ if ($fwhostsettings{'ACTION'} eq 'savegrp') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'savegeoipgrp') +{ + my $grp=$fwhostsettings{'grp_name'}; + my $rem=$fwhostsettings{'remark'}; + my $count; + my $type; + my @target; + my @newgrp; + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + + # Check for existing group name. + if (!&checkgroup($grp) && $fwhostsettings{'update'} ne 'on'){ + $errormessage = $Lang::tr{'fwhost err grpexist'}; + } + + # Check remark. + if ($rem ne '' && !&validremark($rem) && $fwhostsettings{'update'} ne 'on'){ + $errormessage = $Lang::tr{'fwhost err remark'}; + } + + if ($fwhostsettings{'update'} eq 'on'){ + @target=$fwhostsettings{'COUNTRY_CODE'}; + $type='GeoIP Group'; + + #check if host/net exists in grp + my $test="$grp,$fwhostsettings{'oldremark'},@target"; + foreach my $key (keys %customgeoipgrp) { + my $test1="$customgeoipgrp{$key}[0],$customgeoipgrp{$key}[1],$customgeoipgrp{$key}[2]"; + if ($test1 eq $test){ + $errormessage=$Lang::tr{'fwhost err isingrp'}; + $fwhostsettings{'update'} = 'on'; + } + } + } + + if (!$errormessage){ + #on first save, we have an empty @target, so fill it with nothing + my $targetvalues=@target; + if ($targetvalues == '0'){ + @target="none"; + } + #on update, we have to delete the dummy entry + foreach my $key (keys %customgeoipgrp){ + if ($customgeoipgrp{$key}[0] eq $grp && $customgeoipgrp{$key}[2] eq "none"){ + delete $customgeoipgrp{$key}; + last; + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + #create array with new lines + foreach my $line (@target){ + push (@newgrp,"$grp,$rem,$line"); + } + #append new entries + my $key = &General::findhasharraykey (\%customgeoipgrp); + foreach my $line (@newgrp){ + foreach my $i (0 .. 3) { $customgeoipgrp{$key}[$i] = "";} + my ($a,$b,$c,$d) = split (",",$line); + $customgeoipgrp{$key}[0] = $a; + $customgeoipgrp{$key}[1] = $b; + $customgeoipgrp{$key}[2] = $c; + $customgeoipgrp{$key}[3] = $type; + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + #update counter in Host/Net + $fwhostsettings{'update'}='on'; + } + #check if ruleupdate is needed + my $geoipgrpcount=0; + $geoipgrpcount=&getgeoipcount($grp); + if($geoipgrpcount > 0 ) + { + &General::firewall_config_changed(); + } + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq 'saveservice') { my $ICMP; @@ -798,6 +881,12 @@ if ($fwhostsettings{'ACTION'} eq 'editgrp') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'editgeoipgrp') +{ + $fwhostsettings{'update'}='on'; + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq 'editservice') { $fwhostsettings{'updatesrv'}='on'; @@ -830,6 +919,12 @@ if ($fwhostsettings{'ACTION'} eq 'resetgrp') $fwhostsettings{'remark'} =""; &showmenu; } +if ($fwhostsettings{'ACTION'} eq 'resetgeoipgrp') +{ + $fwhostsettings{'grp_name'} =""; + $fwhostsettings{'remark'} =""; + &showmenu; +} # delete if ($fwhostsettings{'ACTION'} eq 'delnet') { @@ -887,6 +982,37 @@ if ($fwhostsettings{'ACTION'} eq 'deletegrphost') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'deletegeoipgrpentry') +{ + my $grpremark; + my $grpname; + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + foreach my $key (keys %customgeoipgrp){ + if($customgeoipgrp{$key}[0].",".$customgeoipgrp{$key}[1].",".$customgeoipgrp{$key}[2].",".$customgeoipgrp{$key}[3] eq $fwhostsettings{'delentry'}){ + $grpname=$customgeoipgrp{$key}[0]; + $grpremark=$customgeoipgrp{$key}[1]; + #check if we delete the last entry, then generate dummy + if ($fwhostsettings{'last'} eq 'on'){ + $customgeoipgrp{$key}[1] = ''; + $customgeoipgrp{$key}[2] = 'none'; + $customgeoipgrp{$key}[3] = ''; + $fwhostsettings{'last'}=''; + last; + }else{ + delete $customgeoipgrp{$key}; + } + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + &General::firewall_config_changed(); + if ($fwhostsettings{'update'} eq 'on'){ + $fwhostsettings{'remark'}= $grpremark; + $fwhostsettings{'grp_name'}=$grpname; + } + &addgeoipgrp; + &viewtablegeoipgrp; +} + if ($fwhostsettings{'ACTION'} eq 'delgrp') { &General::readhasharray("$configgrp", \%customgrp); @@ -903,6 +1029,22 @@ if ($fwhostsettings{'ACTION'} eq 'delgrp') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'delgeoipgrp') +{ + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + &decrease($fwhostsettings{'grp_name'}); + foreach my $key (sort keys %customgeoipgrp) + { + if($customgeoipgrp{$key}[0] eq $fwhostsettings{'grp_name'}) + { + delete $customgeoipgrp{$key}; + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + $fwhostsettings{'grp_name'}=''; + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq 'delservice') { &General::readhasharray("$configsrv", \%customservice); @@ -977,6 +1119,11 @@ if ($fwhostsettings{'ACTION'} eq $Lang::tr{'fwhost newgrp'}) &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq $Lang::tr{'fwhost newgeoipgrp'}) +{ + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq $Lang::tr{'fwhost newservice'}) { &addservice; @@ -1011,6 +1158,31 @@ if ($fwhostsettings{'ACTION'} eq 'changegrpremark') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'changegeoipgrpremark') +{ + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + if ($fwhostsettings{'oldrem'} ne $fwhostsettings{'newrem'} && (&validremark($fwhostsettings{'newrem'}) || $fwhostsettings{'newrem'} eq '')){ + foreach my $key (sort keys %customgeoipgrp) + { + if($customgeoipgrp{$key}[0] eq $fwhostsettings{'grp'} && $customgeoipgrp{$key}[1] eq $fwhostsettings{'oldrem'}) + { + $customgeoipgrp{$key}[1]=''; + $customgeoipgrp{$key}[1]=$fwhostsettings{'newrem'}; + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp); + $fwhostsettings{'update'}='on'; + $fwhostsettings{'remark'}=$fwhostsettings{'newrem'}; + }else{ + $errormessage=$Lang::tr{'fwhost err remark'}; + $fwhostsettings{'remark'}=$fwhostsettings{'oldrem'}; + $fwhostsettings{'grp_name'}=$fwhostsettings{'grp'}; + $fwhostsettings{'update'} = 'on'; + } + $fwhostsettings{'grp_name'}=$fwhostsettings{'grp'}; + &addgeoipgrp; + &viewtablegeoipgrp; +} if ($fwhostsettings{'ACTION'} eq 'changesrvgrpremark') { &General::readhasharray("$configsrvgrp", \%customservicegrp ); @@ -1085,6 +1257,29 @@ if ($fwhostsettings{'ACTION'} eq 'changegrpname') &addgrp; &viewtablegrp; } +if ($fwhostsettings{'ACTION'} eq 'changegeoipgrpname') +{ + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp ); + if ($fwhostsettings{'oldgrpname'} ne $fwhostsettings{'grp'}){ + #Check new groupname + if (!&validhostname($fwhostsettings{'grp'})){ + $errormessage.=$Lang::tr{'fwhost err name'}."
"; + } + if (!$errormessage){ + # Rename group. + foreach my $key (keys %customgeoipgrp) { + if($customgeoipgrp{$key}[0] eq $fwhostsettings{'oldgrpname'}){ + $customgeoipgrp{$key}[0]=$fwhostsettings{'grp'}; + } + } + &General::writehasharray("$configgeoipgrp", \%customgeoipgrp ); + #change name in FW Rules + &changenameinfw($fwhostsettings{'oldgrpname'},$fwhostsettings{'grp'},6); + } + } + &addgeoipgrp; + &viewtablegeoipgrp; +} ### VIEW ### if($fwhostsettings{'ACTION'} eq '') { @@ -1096,7 +1291,7 @@ sub showmenu { print "$Lang::tr{'fwhost welcome'}"; print<
- +
END @@ -1381,6 +1576,113 @@ END print"
"; &Header::closebox(); } +sub addgeoipgrp +{ + &hint; + &error; + &showmenu; + &Header::openbox('100%', 'left', $Lang::tr{'fwhost addgeoipgrp'}); + + my %checked=(); + my $show=''; + $checked{'check1'}{'off'} = ''; + $checked{'check1'}{'on'} = ''; + $checked{'grp2'}{$fwhostsettings{'grp2'}} = 'CHECKED'; + $fwhostsettings{'oldremark'}=$fwhostsettings{'remark'}; + $fwhostsettings{'oldgrpname'}=$fwhostsettings{'grp_name'}; + my $grp=$fwhostsettings{'grp_name'}; + my $rem=$fwhostsettings{'remark'}; + if ($fwhostsettings{'update'} eq ''){ + print< + + $Lang::tr{'fwhost addgrpname'} +
+ + + $Lang::tr{'remark'}: + + + +
+ + +END + } else { + print< + + $Lang::tr{'fwhost addgrpname'} + + + + + + + + +
+ $Lang::tr{'remark'}: + + + + + + + + + +
+ +

+END + } + if ($fwhostsettings{'update'} eq 'on') { + my @geoip_locations = &fwlib::get_geoip_locations(); + + print< + + + + + + + +
+
+

+END + } + print < + + + + + + + +
+ + + + +
+ +END + &Header::closebox(); +} sub addservice { &error; @@ -1838,6 +2140,195 @@ sub viewtablegrp &Header::closebox(); } +} +sub viewtablegeoipgrp +{ + # If our filesize is "zero" there is nothing to read-in. + if (-z "$configgeoipgrp") { + return; + } + + &Header::openbox('100%', 'left', $Lang::tr{'fwhost cust geoipgrp'}); + &General::readhasharray("$configgeoipgrp", \%customgeoipgrp); + &General::readhasharray("$fwconfigfwd", \%fwfwd); + &General::readhasharray("$fwconfiginp", \%fwinp); + &General::readhasharray("$fwconfigout", \%fwout); + my @grp=(); + my $helper=''; + my $count=1; + my $country_code; + my $grpname; + my $remark; + my $number; + my $delflag; + my @counter; + my %hash; + + # If there are no groups we are finished here. + if (!keys %customgeoipgrp) { + print "
$Lang::tr{'fwhost err emptytable'}"; + return; + } + + # Put all groups in a hash. + foreach my $key (sort { ncmp($customgeoipgrp{$a}[0],$customgeoipgrp{$b}[0]) } + sort { ncmp($customgeoipgrp{$a}[2],$customgeoipgrp{$b}[2]) } keys %customgeoipgrp) { + push (@counter,$customgeoipgrp{$key}[0]); + } + + # Increase current used key. + foreach my $key1 (@counter) { + $hash{$key1}++ ; + } + + # Sort hash. + foreach my $key (sort { ncmp($customgeoipgrp{$a}[0],$customgeoipgrp{$b}[0]) } + sort { ncmp($customgeoipgrp{$a}[2],$customgeoipgrp{$b}[2]) } keys %customgeoipgrp) { + $count++; + if ($helper ne $customgeoipgrp{$key}[0]) { + $delflag='0'; + + foreach my $key1 (sort { ncmp($customgeoipgrp{$a}[0],$customgeoipgrp{$b}[0]) } + sort { ncmp($customgeoipgrp{$a}[2],$customgeoipgrp{$b}[2]) } keys %customgeoipgrp) { + + if ($customgeoipgrp{$key}[0] eq $customgeoipgrp{$key1}[0]) + { + $delflag++; + } + if($delflag > 1){ + last; + } + } + + $number=1; + + # Groupname. + $grpname=$customgeoipgrp{$key}[0]; + + # Group remark. + $remark="$customgeoipgrp{$key}[1]"; + + # Country code. + $country_code="$customgeoipgrp{$key}[2]"; + + if ($count gt 1){ + print""; + $count=1; + } + + # Display groups header. + print "
$grpname   \n"; + print "$Lang::tr{'remark'}:  $remark  \n" if ($remark ne ''); + + # Get group count. + my $geoipgrpcount=&getgeoipcount($grpname); + print "$Lang::tr{'used'}: $geoipgrpcount x"; + + # Only display delete icon, if the group is not used by a firewall rule. + if($geoipgrpcount == '0') { + print"
\n"; + print"\n"; + print"\n"; + print"\n"; + print"
"; + } + + # Icon for group editing. +print < + + + + + + + +END + # Display headlines if the group contains any entries. + if ($country_code ne "none") { +print < + + + + + + + + +END + } + } + + # Check if our group contains any entries. + if ($country_code eq "none") { + print "\n"; + } else { + # Check if we are currently editing a group and assign column backgound colors. + my $col=''; + if ( ($fwhostsettings{'ACTION'} eq 'editgeoipgrp' || $fwhostsettings{'update'} ne '') + && $fwhostsettings{'grp_name'} eq $customgeoipgrp{$key}[0]) { + $col="bgcolor='${Header::colouryellow}'"; + } elsif ($count %2 == 0){ + $col="bgcolor='$color{'color20'}'"; + } else { + $col="bgcolor='$color{'color22'}'"; + } + + # Get country flag. + my $icon = &GeoIP::get_flag_icon($customgeoipgrp{$key}[2]); + + # Print column with flag icon. + my $col_content; + if ($icon) { + $col_content = "$customgeoipgrp{$key}[2]"; + } else { + $col_content = "N/A"; + } + + print "\n"; + + # Print column with country code. + print "\n"; + + # Print column with full country name. + my $country_name = &GeoIP::get_full_country_name($customgeoipgrp{$key}[2]); + print "\n"; + + # Generate from for removing entries from a group. + print "\n"; + print "\n"; + } + + $helper=$customgeoipgrp{$key}[0]; + $number++; + } + + print"
+ $Lang::tr{'flag'} + + $Lang::tr{'countrycode'} + + $Lang::tr{'country'} +
$Lang::tr{'fwhost err emptytable'}
$col_content$customgeoipgrp{$key}[2]$country_name
\n"; + + if ($delflag > 0){ + print"\n"; + + # Check if this group only has a single entry. + foreach my $key2 (keys %hash) { + if ($hash{$key2}<2 && $key2 eq $customgeoipgrp{$key}[0]){ + print "" ; + } + } + } + + print "\n"; + print "\n"; + print "\n"; + print "
\n"; + print "
\n"; + &Header::closebox(); } sub viewtableservice { @@ -2196,6 +2687,44 @@ sub gethostcount } return $srvcounter; } +sub getgeoipcount +{ + my $groupname=shift; + my $counter=0; + + # GeoIP groups are stored as "group:groupname" in the + # firewall settings files. + my $searchstring = join(':', "group",$groupname); + + # Count services used in firewall - forward + foreach my $key1 (keys %fwfwd) { + if($fwfwd{$key1}[4] eq $searchstring){ + $counter++; + } + if($fwfwd{$key1}[6] eq $searchstring){ + $counter++; + } + } + #Count services used in firewall - input + foreach my $key2 (keys %fwinp) { + if($fwinp{$key2}[4] eq $searchstring){ + $counter++; + } + if($fwinp{$key2}[6] eq $searchstring){ + $counter++; + } + } + #Count services used in firewall - outgoing + foreach my $key3 (keys %fwout) { + if($fwout{$key3}[4] eq $searchstring){ + $counter++; + } + if($fwout{$key3}[6] eq $searchstring){ + $counter++; + } + } + return $counter; +} sub getnetcount { my $searchstring=shift; -- 2.39.2