From patchwork Mon Apr 27 14:31:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim FitzGeorge X-Patchwork-Id: 3006 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 499nKr21qzz3xQy for ; Mon, 27 Apr 2020 14:32:16 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKp12Wkz3B5; Mon, 27 Apr 2020 14:32:14 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 499nKp04zWz2yxh; Mon, 27 Apr 2020 14:32:14 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 499nKl5Jxzz2xnp for ; Mon, 27 Apr 2020 14:32:11 +0000 (UTC) Received: from smtp.hosts.co.uk (smtp.hosts.co.uk [85.233.160.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKk1sNLz32M for ; Mon, 27 Apr 2020 14:32:10 +0000 (UTC) Received: from [95.149.142.196] (helo=aragorn.hosts.co.uk.tfitzgeorge.me.uk) by smtp.hosts.co.uk with esmtpa (Exim) (envelope-from ) id 1jT4no-0003Z9-9Y; Mon, 27 Apr 2020 15:32:10 +0100 From: Tim FitzGeorge To: development@lists.ipfire.org Subject: [PATCH v2 2/8] ipblacklist: WUI Settings page Date: Mon, 27 Apr 2020 15:31:17 +0100 Message-Id: <20200427143123.6378-3-ipfr@tfitzgeorge.me.uk> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> References: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1587997930; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:in-reply-to:in-reply-to:references:references; bh=SvuIDqAMYikC5T3E6p2/sw5JzJitivid2BgzjiNzuzc=; b=lQOuFEjqVnwdCLPWP5Nj2+FGpK/P++hV+S6TO03aV5W1eBAdaXm4NjTBMjwgrofm9HGHjj bxPvoMs3dFo8AJX6ZUxNq2SP4fTDxd/0ttXPK9jkQZdgdvl7rtI2Na3G8+gkBOVQSqTRew CuBVyQdcnlWOi+YGDC+cPHg94ti2tww/PDCXRIJleKPWrYo8VrKif4tp+1+QCyNciKD7RB FZ0TExFAEUb90s0GjqySRuLQ93dGIp8AMLXEQv6wfB8BFhpcZ5VBo0+smQtWxqoN+4IlDi 6c9MFsOtmI8yr6+T5iaDyag+wQ7alkYR5KnJT9n4WYz+ePoibC2DfTm/dULUXg== ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1587997930; a=rsa-sha256; cv=none; b=FMOtnukAh5i1+Mv5ni+IvrybGBTryrOI+dtQhBHquBmaZh7ooaV0xQT57yhKjfTiuYpPpC 8NBRSRfrtVrYKqH1uN3UM7kR2Xjn4SNPKahXfb0SUJ4Y0kd1Q3FXs5npNdp9wIzNZXGAoB 8wbZntPsWSC/G1dmTSJ5NF2pNTEzLLSEI11x4X74VDAJ9cVh9wB0KHyHYDjPHdS3ImmqC6 R1hS8Ze9KaijX5eHWWKy2UPDGqRrb4Y3FvAlbnxj4FLMVVujIaoEwF3f+KvBnbZiNT/g4U a8a1hPRwD3Ee3mWrZRD4cNUa2KJWglNojP/XPtt1/KjhjRhBqjCtBbA8yG4Xbw== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk X-Rspamd-Queue-Id: 499nKk1sNLz32M X-Spamd-Result: default: False [1.68 / 11.00]; RCVD_TLS_LAST(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[95.149.142.196:received]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; HTML_META_REFRESH_URL(5.00)[]; R_SPF_ALLOW(-0.20)[+ip4:85.233.160.0/27]; MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[tfitzgeorge.me.uk]; ARC_NA(0.00)[]; RWL_MAILSPIKE_GOOD(0.00)[85.233.160.19:from]; ARC_SIGNED(0.00)[i=1]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[]; RCPT_COUNT_TWO(0.00)[2]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-0.93)[-0.928]; IP_REPUTATION_SPAM(0.01)[asn: 8622(0.00), country: GB(0.01), ip: 85.233.160.19(0.00)]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:8622, ipnet:85.233.160.0/19, country:GB]; RCVD_COUNT_TWO(0.00)[2]; BAYES_HAM(-2.99)[99.97%]; RCVD_IN_DNSWL_LOW(-0.10)[85.233.160.19:from] X-Rspamd-Server: mail01.haj.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Signed-off-by: Tim FitzGeorge --- html/cgi-bin/ipblacklist.cgi | 463 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 463 insertions(+) create mode 100644 html/cgi-bin/ipblacklist.cgi diff --git a/html/cgi-bin/ipblacklist.cgi b/html/cgi-bin/ipblacklist.cgi new file mode 100644 index 000000000..28b42edf2 --- /dev/null +++ b/html/cgi-bin/ipblacklist.cgi @@ -0,0 +1,463 @@ +#!/usr/bin/perl + +############################################################################### +# # +# IPFire.org - A linux based firewall # +# # +# 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 # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# Copyright (C) 2018 - 2020 The IPFire Team # +# # +############################################################################### + +use strict; +use CGI qw/:standard/; +# enable the following only for debugging purposes +#use warnings; +#use CGI::Carp 'fatalsToBrowser'; +use Sort::Naturally; +use Socket; + +require '/var/ipfire/general-functions.pl'; +require "${General::swroot}/lang.pl"; +require "${General::swroot}/header.pl"; + +############################################################################### +# Configuration variables +############################################################################### + +my $settings = "${General::swroot}/ipblacklist/settings"; +my $sources = "${General::swroot}/ipblacklist/sources"; +my $getipstat = '/usr/local/bin/getipstat'; +my $getipsetstat = '/usr/local/bin/getipsetstat'; +my $control = '/usr/local/bin/ipblacklistctrl'; +my $lockfile = '/var/run/ipblacklist.pid'; +my %cgiparams = ('ACTION' => ''); + +############################################################################### +# Variables +############################################################################### + +my $errormessage = ''; +my $updating = 0; +my %mainsettings; +my %color; +my %sources; +my %stats; + +# Default settings - normally overwritten by settings file + +my %settings = ( 'DEBUG' => 0, + 'LOGGING' => 'on', + 'ENABLE' => 'off' ); + +# Read all parameters + +Header::getcgihash( \%cgiparams); +General::readhash( "${General::swroot}/main/settings", \%mainsettings ); +General::readhash( "/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color ); +General::readhash( $settings, \%settings ) if (-r $settings); +eval qx|/bin/cat $sources| if (-r $sources); + +# Show Headers + +Header::showhttpheaders(); + +# Process actions + +if ($cgiparams{'ACTION'} eq "$Lang::tr{'save'}") +{ + # Save Button + + my %new_settings = ( 'ENABLE' => 'off', + 'LOGGING' => 'off', + 'DEBUG' => 0 ); + + foreach my $item ('LOGGING', 'ENABLE', keys %sources) + { + $new_settings{$item} = (exists $cgiparams{$item}) ? 'on' : 'off'; + + $updating = 1 if (not exists $settings{$item} or $new_settings{$item} ne $settings{$item}); + } + + # Check for redundant blacklists being enabled + + foreach my $list (keys %sources) + { + if (exists $new_settings{$list} and + $new_settings{$list} eq 'on' and + exists $sources{$list}{'disable'}) + { + my @disable; + + if ('ARRAY' eq ref $sources{$list}{'disable'}) + { + @disable = @{ $sources{$list}{'disable'} }; + } + else + { + @disable = ( $sources{$list}{'disable'} ); + } + + foreach my $disable (@disable) + { + if ($new_settings{$disable} eq 'on') + { + $new_settings{$disable} = 'off'; + + $updating = 1; + $errormessage .= "$Lang::tr{'ipblacklist disable pre'} $disable " . + "$Lang::tr{'ipblacklist disable mid'} $list $Lang::tr{'ipblacklist disable post'}
\n"; + } + } + } + } + + if ($settings{'LOGGING'} ne $new_settings{'LOGGING'}) + { + if ($new_settings{'LOGGING'} eq 'on') + { + system( "$control log-on" ); + } + else + { + system( "$control log-off" ); + } + } + + if ($settings{'ENABLE'} ne $new_settings{'ENABLE'}) + { + if ($new_settings{'ENABLE'} eq 'on') + { + system( "$control enable" ); + } + else + { + system( "$control disable" ); + } + + $updating = 1; + } + + %settings = %new_settings; + + if ($errormessage) + { + $updating = 0; + } + else + { + General::writehash($settings, \%new_settings); + + if ($updating) + { + system( "$control update &" ); + show_running(); + exit 0; + } + } +} + +if (is_running()) +{ + show_running(); + exit 0; +} + +# Show site + +Header::openpage($Lang::tr{'ipblacklist'}, 1, ''); +Header::openbigbox('100%', 'left'); + +error() if ($errormessage); + +configsite(); + +# End of page + +Header::closebigbox(); +Header::closepage(); + +exit 0; + + +#------------------------------------------------------------------------------ +# sub configsite() +# +# Displays configuration +#------------------------------------------------------------------------------ + +sub configsite +{ + # Find preselections + + my $enable = 'checked'; + Header::openbox('100%', 'left', $Lang::tr{'settings'}); + + #### JAVA SCRIPT #### + + print< + \$(document).ready(function() + { + // Show/Hide elements when ENABLE checkbox is checked. + if (\$("#ENABLE").attr("checked")) + { + \$(".sources").show(); + } + else + { + \$(".sources").hide(); + } + + // Toggle Source list elements when "ENABLE" checkbox is clicked + \$("#ENABLE").change(function() + { + \$(".sources").toggle(); + }); + }); + +END + + ##### JAVA SCRIPT END #### + + # Enable checkbox + + $enable = ($settings{'ENABLE'} eq 'on') ? ' checked' : ''; + + print< + + + + + +
$Lang::tr{'ipblacklist use ipblacklists'}

+ +END + + # The following are only displayed if the blacklists are enabled + + $enable = ($settings{'LOGGING'} eq 'on') ? ' checked' : ''; + + print < + + + + + +
$Lang::tr{'ipblacklist log'}
+

+

$Lang::tr{'ipblacklist blacklist settings'}

+ + + + + + + +END + + # Iterate through the list of sources + + my $lines = 0; + + foreach my $list (sort keys %sources) + { + my $name = escapeHTML( $sources{$list}{'name'} ); + my $category = $Lang::tr{"ipblacklist category $sources{$list}{'category'}"}; + $enable = ''; + my $col = ($lines++ % 2) ? "bgcolor='$color{'color20'}'" : "bgcolor='$color{'color22'}'"; + + $enable = ' checked' if (exists $settings{$list} and $settings{$list} eq 'on'); + + print < + + + + \n +END + } + + # The save button at the bottom of the table + + print < + +
$Lang::tr{'ipblacklist id'}$Lang::tr{'ipblacklist name'}$Lang::tr{'ipblacklist category'}$Lang::tr{'ipblacklist enable'}
+END + + if ($sources{$list}{info}) + { + print "$list\n"; + } + else + { + print "$list\n"; + } + + print < + $name$category
+ + + +
+END + + Header::closebox(); +} + + +#------------------------------------------------------------------------------ +# sub get_ipset_stats() +# +# Gets the number of entries in each IPSet. +#------------------------------------------------------------------------------ + +sub get_ipset_stats +{ + my $name; + + system( $getipsetstat ); + + if (-r '/var/tmp/ipsets.txt') + { + open STATS, '<', '/var/tmp/ipsets.txt' or die "Can't open IP Sets stats file: $!"; + + foreach my $line () + { + if ($line =~ m/Name: (\w+)/) + { + $name = $1; + next; + } + + if ($line =~ m/Number of entries: (\d+)/) + { + $stats{$name}{'size'} = $1; + } + } + + close STATS; + + unlink( '/var/tmp/ipsets.txt' ); + } +} + + +#------------------------------------------------------------------------------ +# sub is_running() +# +# Checks to see if the main script is running +#------------------------------------------------------------------------------ + +sub is_running +{ + return 0 unless (-r $lockfile); + + open LOCKFILE, '<', $lockfile or die "Can't open lockfile"; + my $pid = ; + close LOCKFILE; + + chomp $pid; + + return (-e "/proc/$pid"); +} + + +#------------------------------------------------------------------------------ +# sub show_running +# +# Displayed when update is running. +# Shows a 'working' message plus some information about the IPSets. +#------------------------------------------------------------------------------ + +sub show_running +{ + # Open site + + Header::openpage( $Lang::tr{'ipblacklist'}, 1, '' ); + Header::openbigbox( '100%', 'center' ); + error(); + Header::openbox( 'Working', 'center', "$Lang::tr{'ipblacklist working'}" ); + + print < + + + $Lang::tr{  + + + +
+ + +END + + get_ipset_stats(); + + foreach my $name (sort keys %stats) + { + print "\n" if (exists $stats{$name}{'size'}); + } + + print < +END + + Header::closebox(); + + Header::closebigbox(); + Header::closepage(); +} + + +#------------------------------------------------------------------------------ +# sub error() +# +# Shows error messages +#------------------------------------------------------------------------------ + +sub error +{ + Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage\n"; + print " \n"; + Header::closebox(); +} + + +#------------------------------------------------------------------------------ +# sub format_time( seconds ) +# +# Converts time in seconds to HH:MM:SS +#------------------------------------------------------------------------------ + +sub format_time($) { + my $time = shift; + + my $seconds = $time % 60; + my $minutes = $time / 60; + + my $hours = 0; + if ($minutes >= 60) { + $hours = $minutes / 60; + $minutes %= 60; + } + + return sprintf("%3d:%02d:%02d", $hours, $minutes, $seconds); +}
$Lang::tr{'ipblacklist id'}$Lang::tr{'ipblacklist entries'}
$name$stats{$name}{'size'}