#!/usr/bin/perl
###############################################################################
#                                                                             #
# IPFire.org - A linux based firewall                                         #
# Copyright (C) 2007-2012  IPFire Team  <info@ipfire.org>                     #
#                                                                             #
# 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 <http://www.gnu.org/licenses/>.       #
#                                                                             #
# Based on Steffen Schoch (sschoch@users.sourceforge.net)                     #
#                                                                             #
###############################################################################

use IPC::Open2;
use IO::Handle;

require '/var/ipfire/general-functions.pl';

my %proxysettings=();
$proxysettings{'ENABLE_FILTER'} = 'off';
$proxysettings{'ENABLE_CLAMAV'} = 'off';
$proxysettings{'ENABLE_UPDXLRATOR'} = 'off';
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);

# define here your redirectors
my @redirectors = ();

if ($proxysettings{'ENABLE_FILTER'} eq 'on') {
	push(@redirectors, "/usr/bin/squidGuard");
}

if ($proxysettings{'ENABLE_CLAMAV'} eq 'on') {
	push(@redirectors, "/usr/bin/squidclamav");
}

if ($proxysettings{'ENABLE_UPDXLRATOR'} eq 'on') {
	push(@redirectors, "/usr/sbin/updxlrator");
}

# Attention: keep in mind that the order of your redirectors is important.
# It doesn't make sense to scan for viruses on pages you restrict access to...
# So place first your tools which restrict access, then the tools which do the
# content filtering!

##### no need to change anything below this line #####

# init
$| = 1;
STDOUT->autoflush(1);

my $debug=0; # enable only for debugging

if (-e "/var/ipfire/proxy/enable_redirector_debug") {
	writetolog("Urlfilter = ".$proxysettings{'ENABLE_FILTER'}." Clamav = ".$proxysettings{'ENABLE_CLAMAV'}." Updxlrator = ".$proxysettings{'ENABLE_UPDXLRATOR'});
	$debug = 1;
}

# Open one instance for each redirector in the list and
# put them into an array with the STDIN and STDOUT file
# descriptors.
my @instances = ();

foreach my $redirector (@redirectors) {
	my $desc_out = new IO::Handle();
	my $desc_in  = new IO::Handle();

	my $pid = open2($desc_out, $desc_in, $redirector);

	if ($debug) {
		&writetolog("Started an instance of $redirector with PID $pid");
	}

	push(@instances, [$redirector, $desc_out, $desc_in]);
}

# wait for data...
my $line;
while ($line = <>) {
	my $return = "ERR\n";

	foreach my $instance (@instances) {
		my $redirector = @$instance[0];
		my $desc_out   = @$instance[1];
		my $desc_in    = @$instance[2];
		my $response;

		# Send request to the redirector.
		$desc_in->print($line);

		# Wait for a response.
		$response = $desc_out->getline;

		# Catch invalid responses from squidGuard.
		if ($redirector eq "/usr/bin/squidGuard" && $response eq "Processing file and database") {
			system("logger -t ipfire 'Emergency - squidGuard not initialised please run squidGuard -C all'");
			next;
		}

		# Writing debug output.
		if ($debug) {
			my $len_response = length($response);

			&writetolog("Queried $redirector for: $line");
			&writetolog("  --> Response ($len_response): $response");
		}

		# If we got a decisive response, we send it back to squid
		# and stop querying any more redirectors.
		if ($response =~ /^(OK|BH)/) {
			if ($debug) {
				&writetolog("  --  Stopped querying redirectors");
			}

			$return = $response;
			last;
		}
	}

	# Send response back to squid.
	if ($debug) {
		&writetolog("Sending back to squid: $return");
	}
	print $return;
}

exit 0;

sub writetolog {
	my $message = shift;
	chomp($message);

	open(FILE, ">>/var/log/squid/redirector_debug") || die "Unable to acces file /var/log/squid/redirector_debug";
	print FILE "$message\n";
	close(FILE);
}
