#!/usr/bin/perl
###########################################################################
#
# Program : Log Analyzer for DansGuardian
# Author : Jimmy Myrick (jmyrick@tiger1.tiger.org)
# Version : .1.1
# Released : July 6, 2002
#
# 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 2 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.
#
# Heck, if you like it though and want to send me something, that's
# ok too.
#
# Change history is available here for now:
# http://www.tiger.org/technology/dg
#
###########################################################################
###########################################################################
#
#Cambiar para apuntar al directorio de logs del DansGuardian
# NOTA: El / inicial ES NECESARIO!!
#
###########################################################################
$logdir = '/var/log/dansguardian/';
###########################################################################
#
# Nombre del archivo de logueo. Cambiar segun el prefijo de sus archivos
# Por defecto es access.log y no deberia ser modificado.
#
# Cualquier archivo en $logdir que coincida con el prefijo en $logfile y
# este comprimido con gzip con la extension .gz sera tambien leido
# Los resultados se mostraran en orden cronologico inverso al nombre de
# los archivos.
#
# Ejemplo:
# Si tiene los archivos: access.log access.log.0.gz access.log.1.gz
# se mostraran primero los resultados contenidos en access.log.1.gz
# seguidos por los contenidos en access.log.0.gz y luego los en
# access.log
#
# El programa no ejecuta ningun ordenamiento y los resultados se muestran
# en el orden en que se encuentran en el archivo. Si sus resultados aparecen
# fuera de secuencia controle los nombres/fechas para asegurarse que son
# comprimidos y rotados correctamente. Si usa newsyslog.conf bajo FreeBSD
# esto no sera un problema.
#
###########################################################################
$logfile = 'access.log';
###########################################################################
#
# Si necesita los modulos perl abajo indicados, descarguelos y
# descomprimalos en algun directorio, Lugo haga cd al directorio y ejecute
# los comandos: perl Makefile.pl; make; make test; make install
#
# Si necesita instrucciones adicionales:
# http://www.cpan.org/modules/INSTALL.html
# Puede obtener los archivos en:
# http://www.cpan.org/authors/id/LDS/CGI.pm-2.81.tar.gz
#
###########################################################################
use CGI;
###########################################################################
#
# Esto es necesario para descomprimir los archivos de log en linea.
# Para obtenerlo:
# http://www.cpan.org/authors/id/PMQS/Compress-Zlib-1.16.tar.gz
#
###########################################################################
use Compress::Zlib;
###########################################################################
#
# Esto determinara automagicamente de donde es llamado el programa.
# En caso negativo quite la marca de comentario de la primera linea,
# cambie el contenido al nombre de su servidor y path y comente la
# segunda linea.
# Puede usar los comandos de restriccion del apache para limitar el
# acceso a este archivo, si lo desea.
#
###########################################################################
#$cgipath = 'http://www.internal.net/cgi-bin/dglog-es.pl';
$cgipath = $ENV{SCRIPT_NAME};
###########################################################################
#
# NO DEBERIA SER NECESARIO MODIFICAR NADA DEBAJO DE ESTA LINEA
#
###########################################################################
$q = new CGI;
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon = $mon + 1; # mon starts at 0
$year = $year + 1900; # year needs 1900 added
$pagename = 'Analizador de Registros para DansGuardian';
$a = $q->param('a');
if ($a eq 'i') { # Inquiry into logs
# Estos son los valores que enviara el usuario a travez del navegador
$sIP = "TODO"; # direccion IP
$sUN = "TODO"; # nombre de usuario
$sURL = "TODO"; # URL to show or trace a denied site - this is the URL to trace
$sSD = "TODO"; # Complete start date
$sSDY = "TODO"; # Start date year
$sSDM = "TODO"; # Start date month
$sSDD = "TODO"; # Start date day
$sED = "TODO"; # Complete end date
$sEDY = "TODO"; # End date year
$sEDM = "TODO"; # End date month
$sEDD = "TODO"; # End date day
$sA = "TODO"; # Action
$sSumCnt = "20"; # Number of summary sites to show
$sSumDen = "off"; # Show denied summary? on/off
$sSumAlw = "off"; # Show allowed summary? on/off
$sL = "off"; # Turn URL's into links? on/off
$sZ = "off"; # Examine gziped files? on/off
$sIP = &validateIP($q->param('sIP')) if $q->param('sIP') ne "";
$sUN = $q->param('sUN') if $q->param('sUN') ne "";
$sURL = $q->param('sURL') if $q->param('sURL') ne "";
if ($q->param('sSDY') ne "" &&
$q->param('sSDM') ne "" &&
$q->param('sSDD') ne "" &&
$q->param('sEDY') ne "" &&
$q->param('sEDM') ne "" &&
$q->param('sEDD') ne "") {
$sSDY = $q->param('sSDY');
$sSDM = $q->param('sSDM');
$sSDD = $q->param('sSDD');
$sEDY = $q->param('sEDY');
$sEDM = $q->param('sEDM');
$sEDD = $q->param('sEDD');
$sSD = $sSDY.'.'.$sSDM.'.'.$sSDD;
$sSD = convertDate($sSD);
$sED = $sEDY.'.'.$sEDM.'.'.$sEDD;
$sED = convertDate($sED);
if ($sSD > $sED) {
$msg = "Fecha Final es anterior a Fecha Inicial";
&printMenu;
}
}
$sA = &validateAction($q->param('sA')) if $q->param('sA') ne ""; # Action
$sSumCnt = &validateSummary($q->param('sSumCnt'))
if $q->param('sSumCnt') ne "";
$sSumDen = $q->param('sSumDen') if $q->param('sSumDen') eq 'on';
$sSumAlw = $q->param('sSumAlw') if $q->param('sSumAlw') eq 'on';
$sL = $q->param('sL') if $q->param('sL') eq 'on';
$sZ = $q->param('sZ') if $q->param('sZ') eq 'on';
# Need a few global variables to keep from passing back and forth a bunch
$linesRead, $allowTotal, $blockTotal, $grandTotal = 0;
&searchLog;
}
elsif ($a eq 'h') {
&displayHelp;
}
else {
&printMenu;
}
#############
sub searchLog
#############
{
my $first = 0;
&printHeader;
print "";
print "Informe para :
Fecha Inicial: $sSD | Fecha Final: $sED |
Usuario : $sUN | IP: $sIP |
Accion: $sA | URL: $sURL\n";
print "";
opendir(D, $logdir);
@files = grep {/^$logfile/} readdir(D);
@files = sort {$b cmp $a} @files;
closedir(D);
foreach $file (@files) {
if ($file =~ /\.gz/) {
if ($sZ eq 'on') {
if ($first == 0) {
print "Ignoring gzip logfile(s) in $logdir: ";
$first = 1;
}
print "$file | ";
next;
}
$gz = gzopen($logdir.$file,r);
if (!$gz) {
$msg = "No se puede abrir $logdir$file. Controle Permisos.";
&printMenu;
}
while ($gz->gzreadline($line)) {
&checkLine($line);
}
$gz->gzclose;
}
else {
print "
";
unless (open(F,$logdir.$file)) {
$msg = "No se puede abrir $logdir$file. Controle Permisos.";
&printMenu;
}
while ($line = ) {
&checkLine($line);
}
close(F);
}
}
if ($sSumAlw eq "on" && $allowTotal != 0) {
&showSummarySites($allowTotal,'PERMITIDO',$sSumCnt,%topSites);
}
if ($sSumDen eq "on" && $blockTotal != 0) {
&showSummarySites($blockTotal,'DENEGADO',$sSumCnt,%blockSites);
}
print "
Coincidencias totales: $grandTotal |
Total de Registros: $linesRead
Total Registros $whatToShow (solo los primeros $topNum) : $subTotal
";
print "
";
}
###################
sub validateSummary
###################
{
my ($count) = @_;
if ($count < 0 || $count > 100) {
$count = 20;
}
return($count);
}
##############
sub validateIP
##############
{
my ($checkIP) = @_;
if ($checkIP eq 'TODO') {
return('TODO');
}
elsif ($checkIP =~ /^((2([0-4]\d|5[0-5])|1?\d{1,2})(\.|$)){4}/) {
return ($checkIP);
}
else {
$msg = "Direccion IP invalida.";
&printMenu;
}
}
##################
sub validateAction {
##################
my ($action) = @_;
# Need to make the actions a hash and reference them that way
# Make it easier to add/modify and can validate that way too
# Maybe later.
if ($action eq "none") { return ("TODO"); }
return ($action);
}
###############
sub convertDate {
###############
my ($workDate) = @_;
($year, $mon, $day) = split(/\./,$workDate);
if (length($mon) == 1) { $mon = '0'.$mon; }
if (length($day) == 1) { $day = '0'.$day; }
if (($mon ge "01" && $mon le "12") && ($day ge "01" && $day le "31") &&
($year ge "2000" && $year le "2035")) {
$goodDate = $year.$mon.$day;
return ($goodDate);
} else {
$msg = "Fecha Invalida";
&printMenu;
}
}
###############
sub buildSelect
###############
{
my ($start, $end, $type) = @_;
my $x = 0;
## print "