#!/usr/bin/perl

###########################################################################
#
# Modified by Antonio Carranza Lopez (NETWORK SECURITY SYSTEMS) (Spain)
#
# 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
#
#
# Modified by Antonio Carranza Lopez (http://www.nss.es)
# Released : October 30, 2003
#
# He añadido algunas funciones nuevas para el control de usuarios
#
# - El formato es tabular (tabla) de forma que los datos pueden ser 
#   copiados/pegados a una hoja de caulculo.
#
# - Se pueden solicitar resumenes por Usuarios y por IP's
# 
# - Se suman las duraciones de las conexiones y se establece un criterio
#   por el cual se supone el usuario no ha dejado de navegar (tiempo)
#
###########################################################################


###########################################################################
#
# 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};

###########################################################################
#
#    DEFINE EL TIEMPO QUE SE USARA PARA DETERMINAR SI EL USUARIO HA DEJADO
#    DE NAVEGAR ENTRE CONEXION Y CONEXION EN SEGUNDOS. Y EL INCREMENTO DE
#    TIEMPO QUE SE APLICARA A LA NUEVA CONEXION
#
#    SI HAN PASADO MENOS DE $NavValue SEGUNDOS ENTRE DOS PETICIONES SE SUMA
#    COMO TIEMPO DE CONEXION EL TRANSCURRIDO ENTRE LA ULTIMA Y LA ACTUAL
#
#    NavValue defines how much time have to pass between conexions to DG
#    to consider that the user still navigating. And the NewIncTime determines
#    how much time will be added to an user when a new coexion is stablishes
#    up the NavValue
#
###########################################################################

$NavValue = 50;
$NewIncTime = 1;

###########################################################################
#
#    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 (PROCINET)';

$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 = "50";    # Number of summary sites to show
  $sSumDen = "off";    # Show denied summary? on/off
  $sSumAlw = "off";    # Show allowed summary? on/off
  $sSumUsr = "off";   # Show User's summary? on/off
  $sSumIPs = "off";	# Show Ip's summary? on/off
  $sIncTem = "off";    # Show Increments of time in normal view
  $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';
  $sSumUsr = $q->param('sSumUsr') if $q->param('sSumUsr') eq 'on';
  $sSumIPs = $q->param('sSumIPs') if $q->param('sSumIPs') eq 'on';
  $sIncTem = $q->param('sIncTem') if $q->param('sIncTem') 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 "<font face=arial,helvetica,sans-serif size=2>";
  print "Informe para PROCINET:<br>
   Fecha Inicial: <b>$sSD</b> | Fecha Final: <b>$sED</b> |
   Usuario : <b>$sUN</b> | IP: <b>$sIP</b> |
   Accion: <b>$sA</b> | URL: <b>$sURL</b><hr></font>\n";
  print "<font face=arial,helvetica,sans-serif size=1>";

  if ($sSumAlw eq "off" && $sSumDen eq "off" && $sSumUsr eq "off" && $sSumIPs eq "off") {
     print "<table border=0 cellpadding=2 cellspacing=0>";
     print "<tr><td bgcolor=gray><font color = white>Fecha</font></td><td bgcolor=gray><font color = white>Hora</font></td>";
     if ($sIncTem eq "on") {
        print "<td bgcolor=gray><font color = white>Usr</font></td><td bgcolor=gray><font color = white>IP</font></td>";
     }
     print "<td bgcolor=gray><font color = white>Estado</font></td><td bgcolor=gray><font color = white>IP</font></td>";
     print "<td bgcolor=gray><font color = white>Usuario</font></td><td bgcolor=gray><font color = white>Solicitud</font></td><td bgcolor=gray><font color = white>Motivo</font></td></tr>";
  }

  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 "<p>";
      unless (open(F,$logdir.$file)) {
        $msg = "No se puede abrir $logdir$file. Controle Permisos.";
        &printMenu;
      }
      while ($line = <F>) {
        &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);
  }
  if ($sSumUsr eq "on" && $blockTotal != 0) {
    &showSummaryUsers($UsrTotal,'USUARIOS',$sSumCnt,%topUsr,%ttUsr,%LDUsr,%LTUsr);
  }
  if ($sSumIPs eq "on" && $blockTotal != 0) {
    &showSummaryIPs($IPsTotal,'HOST IP',$sSumCnt,%topIPs, %ttIPs,%LDIPs,%LTIPs);
  }

  if ($sSumAlw eq "off" && $sSumDen eq "off" && $sSumUsr eq "off" && $sSumIPs eq "off") {
     print "</table>";
  }


  print "<center><hr noshade size=1 width=50%>
         <font size=2>Coincidencias totales: $grandTotal |
         Total de Registros: $linesRead</font>
         <hr noshade size=1 width=50%></font>";
  print "<center><a href=$cgipath>Volver al Menu</a></center>";
}

#############
sub checkLine
#############
{
  my ($line) = @_;
  $linesRead++;

  # Print out a '.' every 1000 log file lines read. Keep browser connect alive
  if (($linesRead % 1000) == 0) {
    print " ";
  } 
  ($date,$time,$user,$ip,$url,$toeol) = split(/ /,$line,6);
  # Rule out the easy matches first 
  return if ($sIP ne "TODO" && $sIP ne $ip);
  return if ($sUN ne "TODO" && $sUN ne $user);

  # Don't do a date comparison unless we are told to
  if ($sSD ne "TODO" || $sED ne "TODO") {
    $dgDate = &convertDate($date);
    return if (!($dgDate ge $sSD && $dgDate le $sED));
  }

  $url =~ /(\w+):\/\/([\w\.-]+)\/?(\S*)/;  
  $protocol = $1; # HTTP, FTP
  $baseurl = $2;  # domain part without http:// or ftp://
  return if ($sURL ne "TODO" && $sURL ne $baseurl);
  $toeol =~ /(\*.+\*)? ?(.+)? (\w+) (\d+)$/;
  $action = $1; # *DENIED# or *EXCEPTION* etc., if exists
  $reason = $2; # Reason for #1 if exists
  $method = $3; # method (GET POST)
  $size = $4;   # size
  if ($sA ne "TODO") { 
    return if ($sA eq "denAll" &&
      $action ne "*DENIED*");
    return if ($sA eq "excAll" &&
      $action ne "*EXCEPTION*");
    return if ($sA eq "denSite" && 
      !($reason =~ /^Banned site/));
    return if ($sA eq "denRegURL" && 
      !($reason =~ /^Banned Regular Expression URL/));
    return if ($sA eq "denPhrase" && 
      !($reason =~ /^Banned Phrase/));
    return if ($sA eq "denCombPhrase" && 
      !($reason =~ /^Banned combination phrase/));
    return if ($sA eq "denWeightPhrase" && 
      !($reason =~ /^Weighted phrase limit/));
    return if ($sA eq "denExt" && 
      !($reason =~ /^Banned extension/));
    return if ($sA eq "denMIME" && 
      !($reason =~ /^Banned MIME Type/));
    return if ($sA eq "denICRA" && 
      !($reason =~ /^ICRA/));
    return if ($sA eq "denBlanketIP" && 
      !($reason =~ /^Blanket IP Block/));
    return if ($sA eq "excSite" && 
      !($reason =~ /^Exception site/));
    return if ($sA eq "excPhrase" && 
      !($reason =~ /^Exception phrase/));
    return if ($sA eq "excCombPhrase" && 
      !($reason =~ /^Combination exception phrase/));
  }

  # Need to do a count for grandTotal if allowed OR denied summary selected 
  if ($sSumAlw eq "on" || $sSumDen eq "on" || $sSumUsr eq "on" || $sSumIPs eq "on") {
    if ($action ne '*DENIED*') {
      # Don't waste memory if didn't want this, but need to count for grandTotal
      $topSites{$baseurl}++ if $sSumAlw eq "on";
      $allowTotal++;
    }
    else {
      # Don't waste memory if didn't want this, but need to count for grandTotal
      $blockSites{$baseurl}++ if $sSumDen eq "on";
      $blockTotal++;
    }
      $grandTotal++;
      $topUsr{$user}++ if $sSumUsr eq "on";
      $topIPs{$ip}++ if $sSumIPs eq "on";
      $IPsTotal++ if $sSumIPs eq "on";
      $UsrTotal++ if $sSumUsr eq "on";
      # Add time between conexion to users, IPs
      $ttUsr{$user} = $ttUsr{$user} + &DateDiff($LDUsr{$user},$LTUsr{$user},$date,$time) if $sSumUsr eq "on";
      $ttIPs{$ip} = $ttIPs{$ip} + &DateDiff($LDUsr{$user},$LTUsr{$user},$date,$time) if $sSumIPs eq "on";
  }
  else {
    print "<tr><td>$date</td><td>$time</td>";
    if ($sIncTem eq 'on') {
    print "<td>", &DateDiff($LDUsr{$user},$LTUsr{$user},$date,$time),"</td><td>", &DateDiff($LDUsr{$user},$LTUsr{$user},$date,$time), "</td>";
    }
    if ($action ne "" && $reason ne "") {
      print "<td><font color=red>$action</font></td>";
    } else {
      print "<td align='center'><font color=green>Ok</font></td>";
    }
    print "<td><a href=$cgipath?a=i&sSDY=$sSDY&sSDM=$sSDM&sSDD=$sSDD&sEDY=$sEDY&sEDM=$sEDM&sEDD=$sEDD&sIP=$ip&sZ=$sZ&sL=$sL>$ip</a></td><td align = 'center'>$user</td>";
    if ($sL eq 'on') {
      print "<td><a href=\"$url\" target=_blank>$url</a>&nbsp;$method&nbsp;$size</td>";
    } else {
      print "<td>$url &nbsp; $method &nbsp; $size</td>";
    }
    print "<td><font color=red>$reason &nbsp;</font></td>";
    print "</tr>";
    $grandTotal++;
  }
  # Save last date and Time of users, IPs
  $LDUsr{$user} = $date;
  $LTUsr{$user} = $time;
  $LDIPs{$ip} = $date;
  $LTIPs{$ip} = $time;

}

####################
sub showSummarySites {
####################
  my ($subTotal, $whatToShow, $topNum, %sites) = @_;
  my $count = 1;

  print "<table border=0 cellpadding=2 cellspacing=2 align=center>
         <tr><th colspan=6>
         <b><center>
         <hr noshade width=50% size=1>
         Primeros $topNum $whatToShow </b></td></tr>
         <hr noshade width=50% size=1>
         <tr><td align=center>Posicion</td>
             <td align=center>URL</td>
             <td align=center>Cantidad</td>
             <td align=right>Porcentaje sobre <br>$whatToShow</td>
             <td align=right>Porcentaje sobre el <br>Total</td>
             <td align=center>Investigar</td></tr>";

  foreach $key (sort {$sites{$b} <=> $sites{$a}} keys %sites) {
    if ($count <= $topNum) {
      print "<tr>
         <td align=right>$count.&nbsp;&nbsp;</td>";
      print "<td align=right>";
      if ($sL eq 'on') {
        print "<a href=http://$key target=_blank>$key</a>";
      } else {
        print "$key";
      }
      print "</td><td align=right>$sites{$key}</td><td align=right>";
      printf("&nbsp;&nbsp;&nbsp;%2.2f\%",($sites{$key}/$subTotal)*100);
      print "</td><td align=right>";
      printf("&nbsp;&nbsp;&nbsp;%2.2f\%",($sites{$key}/$grandTotal)*100);
      print "</td>";
      print "<td align=center>
             <a href=$cgipath?a=i&sSDY=$sSDY&sSDM=$sSDM&sSDD=$sSDD&sEDY=$sEDY&sEDM=$sEDM&sEDD=$sEDD&sUN=$sUN&sIP=$sIP&sURL=$key&sZ=$sZ&&sA=";
      if ($whatToShow eq "DENIED") { print "denTODOS"; } else { print ""; }
      print ">Ver</a></td></tr>";
      $count++;
    }
    break;
  }
  print "<tr><td colspan=6 align=center>
         <hr noshade size=1 width=85% align=center>
         Total Registros $whatToShow  (solo los primeros $topNum) : $subTotal
         <hr noshade size=1 width=85% align=center>
         </td></tr>";
  print "</table>
         <hr noshade width=100% size=1>";
}

####################
sub showSummaryUsers {
####################
  my ($subTotal, $whatToShow, $topNum, %sites) = @_;
  my $count = 1;

  print "<table border=0 cellpadding=2 cellspacing=2 align=center>
         <tr><th colspan=6>
         <b><center>
         <hr noshade width=50% size=1>
         Primeros $topNum $whatToShow </b></td></tr>
         <hr noshade width=50% size=1>
         <tr><td align=center>Posicion</td>
             <td align=center>Usuario</td>
             <td align=center>Cantidad</td>
             <td align=right>Porcentaje<br></td>
             <td align=right>Horas</td>
             <td align=center>Investigar</td></tr>";

  foreach $key (sort {$sites{$b} <=> $sites{$a}} keys %sites) {
    if ($count <= $topNum) {
      print "<tr>
         <td align=right>$count.&nbsp;&nbsp;</td>";
      print "<td align=right>";
      print "$key";
      print "</td><td align=right>$topUsr{$key}</td><td align=right>";
      printf("&nbsp;&nbsp;&nbsp;%2.2f\%",($topUsr{$key}/$subTotal)*100);
      print "</td><td align=right>";
      print &SecondsToTime($ttUsr{$key});
      print "</td>";
      print "<td align=center>
             <a href=$cgipath?a=i&sSDY=$sSDY&sSDM=$sSDM&sSDD=$sSDD&sEDY=$sEDY&sEDM=$sEDM&sEDD=$sEDD&sUN=$key&sIP=$sIP&sURL=$sURL&sZ=$sZ&sA=";
      if ($whatToShow eq "DENIED") { print "denTODOS"; } else { print ""; }
      print ">Ver</a></td></tr>";
      $count++;
    }
    break;
  }
  print "<tr><td colspan=6 align=center>
         <hr noshade size=1 width=85% align=center>
         Total Registros $whatToShow  (solo los primeros $topNum) : $subTotal
         <hr noshade size=1 width=85% align=center>
         </td></tr>";
  print "</table>
         <hr noshade width=100% size=1>";
}

####################
sub showSummaryIPs {
####################
  my ($subTotal, $whatToShow, $topNum, %sites) = @_;
  my $count = 1;

  print "<table border=0 cellpadding=2 cellspacing=2 align=center>
         <tr><th colspan=6>
         <b><center>
         <hr noshade width=50% size=1>
         Primeros $topNum $whatToShow </b></td></tr>
         <hr noshade width=50% size=1>
         <tr><td align=center>Posicion</td>
             <td align=center>Host IP</td>
             <td align=center>Cantidad</td>
             <td align=right>Porcentaje<br></td>
             <td align=right>Horas</td>
             <td align=center>Investigar</td></tr>";

  foreach $key (sort {$sites{$b} <=> $sites{$a}} keys %sites) {
    if ($count <= $topNum) {
      print "<tr>
         <td align=right>$count.&nbsp;&nbsp;</td>";
      print "<td align=right>";
      print "$key";
      print "</td><td align=right>$topIPs{$key}</td><td align=right>";
      printf("&nbsp;&nbsp;&nbsp;%2.2f\%",($topIPs{$key}/$subTotal)*100);
      print "</td><td align=right>";
      print &SecondsToTime($ttIPs{$key});
      print "</td>";
      print "<td align=center>
             <a href=$cgipath?a=i&sSDY=$sSDY&sSDM=$sSDM&sSDD=$sSDD&sEDY=$sEDY&sEDM=$sEDM&sEDD=$sEDD&sUN=$sUN&sIP=$key&sURL=$sUrl&sZ=$sZ&sA=";
      if ($whatToShow eq "DENIED") { print "denTODOS"; } else { print ""; }
      print ">Ver</a></td></tr>";
      $count++;
    }
    break;
  }
  print "<tr><td colspan=6 align=center>
         <hr noshade size=1 width=85% align=center>
         Total Registros $whatToShow  (solo los primeros $topNum) : $subTotal
         <hr noshade size=1 width=85% align=center>
         </td></tr>";
  print "</table>
         <hr noshade width=100% size=1>";
}

###################
sub validateSummary 
###################
{
  my ($count) = @_;
  if ($count < 0 || $count > 500) {
    $count = 500;
  }
  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 DateDiff {
###############
  my ($LastDate, $LastTime, $NewDate, $NewTime, $Seconds) =@_;
  if ($LastDate eq $NewDate) {
	($LHour, $LMinute, $LSecond) = split(/:/,$LastTime);
	($NHour, $NMinute, $NSecond) = split(/:/,$NewTime);
	$LSeconds = ($LHour * 3600) + ($LMinute * 60) + ($LSecond);
	$NSeconds = ($NHour * 3600) + ($NMinute * 60) + ($NSecond);
	$Seconds = ($NSeconds-$LSeconds);
	if ($Seconds > $NavValue) {
		$Seconds = $NewIncTime;
	}
  }
  else {
  	$Seconds = $NewIncTime;
  }
  return($Seconds);
}

###############
sub SecondsToTime {
###############
  my ($Seconds) =@_;

  $Horas = int($Seconds / 3600);
  $Minutos = int(($Seconds % 3600) / 60);
  $Segundos = int(($Seconds % 3600) % 60);
  if (length($Horas) == 1) { $Horas = '0'.$Horas; }
  if (length($Minutos) == 1) { $Minutos = '0'.$Minutos; }
  if (length($Segundos) == 1) { $Segundos = '0'.$Segundos; }
  $TimeFormat = $Horas . ":" . $Minutos . ":" . $Segundos;
  return($TimeFormat);
}


###############
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 "<option value=\"\">--$type--";
  print "<option value=\"\">-TODAS-";
  for ($x = $start; $x <= $end; $x++) {
    if ($type eq 'Year' && $x == $year) {
      print "<option value=$x selected>$x";
    }
    elsif ($type eq 'Month' && $x == $mon) {
      print "<option value=$x selected>$x";
    }
    elsif ($type eq 'Day' && $x == $mday) {
      print "<option value=$x selected>$x";
    }
    else {
      print "<option value=$x>$x";
    }
  }
}

#############
sub printMenu
#############
{
  &printHeader;
  print "
    <table align=center bgcolor=ffffff border=1 cellpadding=3 cellspacing=1>\n";
  if ($msg ne "") {
    print "<tr><td colspan=3 bgcolor=c80000 align=center>
           <font face=arial,helvetica,sans-serif size=3><b>$msg</b>
           </font></tr>\n";
  }
  
  # Menu items header row
  print "
  <tr bgcolor=f0f0f0>
  <th width=40%>
    Parametro
  </th>
  <th width=40%>
    Valor
  </th>
  <th width=20%>
    Descripcion
  </th></tr>\n";

  # Menu item for entering date ranges
  print "
  <tr><td align=left>
    Ingrese rango de fechas:
    <form action=$cgipath><input type=hidden name=a value=i>
    <br>
  </td>
  <td align=left>
    Fecha Inicial<br>
    <select name=sSDY>";
  &buildSelect(2002,2010,"Year");
  print "</select><select name=sSDM>";
  &buildSelect(01,12,"Month");
  print "</select><select name=sSDD>";
  &buildSelect(01,31,"Day");
  print "</select><br>
    Fecha Final<br>
    <select name=sEDY>";
  &buildSelect(2002,2010,"Year");
  print "</select><select name=sEDM>";
  &buildSelect(01,12,"Month");
  print "</select><select name=sEDD>";
  &buildSelect(01,31,"Day");
  print "</select>
  </td>
  <td align=center>
    Debe especificarse Inicial y Final.
  </td></tr>\n";

  # Menu item for IP viewing
  print "
  <tr><td align=left>
    Ingrese direccion IP
  </td>
  <td align=left>
    <input name=sIP maxlength=15 size=20>
  </td>
  <td align=center>
    ej: 10.0.0.1<br>
  </td></tr>\n";

  # Menu item for username viewing
  print "
  <tr><td align=left>
    Ingrese Usuario
  </td>
  <td align=left>
    <input name=sUN maxlength=15 size=20>
  </td>
  <td align=center>
    (requiere proxy auth)<br>
  </td></tr>\n";
  
  # Menu item for URL viewing
  print "
  <tr><td align=left>
    Ingrese URL (solo el dominio)
  </td>
  <td align=left>
    <input name=sURL maxlength=30 size=20>
  </td>
  <td align=center>
    Ingrese solo la parte www.domain.com de la URL<br>
  </td></tr>\n";
  
  # Menu item for ACTION
  print "
  <tr><td align=left>
    Ver actividad por ACCION
  </td>
  <td align=left>
    <select name=sA>
    <option value=none>Ver TODOS
    <option value=none>---------------
    <option value=denAll>Ver TODOS Denegado
    <option value=none>---------------
    <option value=excAll>Ver TODOS Excepcion
    <option value=none>---------------
    <option value=denSite>Bloqueo por sitio
    <option value=denPhrase>Bloqueo por Frase
    <option value=denRegURL>Bloqueo por Expresion Regular en URL
    <option value=denCombPhrase>Bloqueo por Combinacion de Frases
    <option value=denWeightPhrase>Bloqueo por Limite Ponderado de Frases
    <option value=denExt>Bloqueo por Extension 
    <option value=denMIME>Bloqueo por tipo MIME
    <option value=denICRA>Bloqueo por Limite ICRA
    <option value=denBlanketIP>Bloqueo por solo IP
    <option value=none>---------------
    <option value=excSite>Sitio Exceptuado
    <option value=excPhrase>Frase Exceptuada
    <option value=excCombPhrase>Exceptuado por Combinacion de Frases
    </select>
   
  </td>
  <td align=center>
    Solo una por informe.
  </td></tr>\n";
  
  # Menu item for selecting summary statistics
  print "
  <tr><td colspan=2 align=left>
    Mostrar informacion resumida para los primeros  
    <input maxlength=3 size=5 name=sSumCnt value=50> 
    <input type=checkbox name=sSumDen>DENEGADO 
    <input type=checkbox name=sSumAlw>PERMITIDO
    <input type=checkbox name=sSumUsr>USUARIOS
    <input type=checkbox name=sSumIPs>HOST IP
  </td>
  <td align=center>
    Resumira los primeros sitios y/o usuarios para el criterio especificado.
  </td></tr>\n";
  print "
  <tr><td colspan=2 align=left>
  Mostrar los incrementos de tiempo en el detalle de conexiones?
  <input type=checkbox name=sIncTem>Si/No</td><td>Se mostraran 2 campos indicando los segundos añadidos por esa conexion al usuario y a la IP</td></tr>\n";
  print "
  <tr><td colspan=3 align=center>
   <table width=100% border=0 cellpadding=0 cellspacing=0 align=center>
    <tr><td>
     <input type=checkbox name=sL>Marque para convertir URLs en links.<br>
     <input type=checkbox name=sZ>Marque para <b>excluir</b> archivos log comprimidos.<br>
     <a href=$cgipath?a=h>Ver Instrucciones de Uso</a><br>
    </td>
    <td align=center valign=middle>
     Oprima el boton de  \"INFORME\" para comenzar<p>
     <input type=submit value=\"INFORME\">&nbsp;&nbsp;&nbsp;
     <input type=reset value=\"Resetear valores\"><br>
    </td></tr>
   </table>
  </td></tr>\n";

  print " </form> </td> </tr> </table> ";
  &printFooter;
  exit;
}

###############
sub printHeader
###############
{
 print $q->header;
 print <<"(EOT)";
 <HTML><HEAD>
 <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
 <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
 <META HTTP-EQUIV="Expires" CONTENT="-1">
 <TITLE>$pagename</TITLE>
 <STYLE>
 <!--
    TABLE       {margin-top: 0; padding-top: 0}
    TD  	{font-family: Serif; font-size: 10pt }
    TH  	{font-family: Serif; font-size: 12pt }
 -->
 </STYLE>
 </HEAD>
 <body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#0000ff"
 alink="#0000ff">
 <center>
 <table width="600" border="0" cellspacing="0" cellpadding="0">
 <tr><th width=600 align=center>
 <font size="4" color="#000000" face="arial">
 <hr noshade size=1 width=90%>
 $pagename 
 <hr noshade size=1 width=90%>
 </th></tr>
 </table>
 </center>

(EOT)
}

###############
sub printFooter
###############
{
  print <<"(EOT)";
  </BODY>
  </HTML>
(EOT)
}

###############
sub displayHelp
###############
{
  &printHeader;
  print<<"(EOF)";
  <table width=75% border=1 cellpadding=2 cellspacing=0 align=center>
  <tr><th bgcolor=f0f0f0><font face=arial,helvetica,sans-serif size=4>
   Instrucciones
  </th></tr>
  <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
  <b>General</b>
  <ul>
  Este programa examinara los archivos de registro creados por el programa
  de clasificacion DansGuardian (http://www.dansguardian.org).<p>
  Pueden especificarse diferentes criterios de busqueda y son acumulativos
  (se suman). Por ejemplo, especificando un rango de fechas y una
  direccion IP mostrara solamente los registros que reunan AMBOS criterios.
  Si desea ver todos los registros no especifique ningun criterio.
  <p>
  Por el momento los resultados no se ordenan. Esto es para asegurar una
  busqueda muy rapida, usar poca memoria, y "alimentar" el navegador 
  periodicamente para evitar un timeout. Esto significa que sus archivos
  de registro deben crearse en orden cronologico por nombre. Esto se hara
  mas importante cuando se agregue la capacidad de examinar multiples
  archivos. Esta facilidad no esta implementada actualmente.
  </ul>
  </td></tr>
  <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
  <b>Fechas</b>
  <ul>
  Seleccione el rango de fechas a considerar. Si se usan fechas, <b>ambas</b> 
  inicial y final deben especificarse. Si no se hace asi el informe no tomara
  en cuenta las fechas. Las fechas consideradas seran igual o mayor que la 
  fecha inicial e igual o menor que la fecha final.
  </ul>
  </td></tr>
  <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
  <b>Direccion IP</b>
  <ul>
  Ingrese una direccion a seleccionar.  Ejemplo:  10.0.0.1
  </ul>
  </td></tr>
  <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
  <b>Usuario</b>
  <ul>
  Ingrese un nombre de usuario. La facilidad proxy auth debe estar habilitada
  en DansGuardian. Si no se muestran los nombres de usuario al generar 
  informes con cualquier criterio, es practicamente seguro que no esta 
  habilitada. Refierase a la instrucciones del programa DansGuardian para 
  ver como hacer eso.
  </ul>
  </td></tr>
  <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
  <b>Accion</b>
  <ul>
  Ingrese una accion a informar.
  Use el menu descolgable para seleccionar la accion a informar. Las ACCIONES
  son casos especiales registrados por DansGuardian. Para informar TODAS las 
  coincidencias para DENEGADO o EXCEPCION, seleccione Ver TODOS Denegado o 
  VER TODOS Excepcion. Solo una ACCION puede informarse al mismo tiempo y 
  puede restringirse. Por ejemplo si se selecciona Bloqueo por Sitio solo   
  las acciones que fueron DENEGADAS debido a que el sitio se encontraba en
  la lista de bloqueo seran informadas.
  </ul>
  </td></tr>
  <tr><td align=left><font face=arial,helvetica,sans-serif size=2>
  <b>Informe Resumido</b>
  <ul>
  Seleccionando esta accion se mostrara un informe resumido para
  la cantidad de sitios ingresada. Se puede seleccionar de 1 a 100 sitios 
  <p>
  Una vez que la pantalla de resumen aparece, se puede "investigar" porque
  un sitio fue bloqueado o permitido y que usuario o maquina visitaba
  ese sitio. Pulse en "ver" bajo la columna "investigar" y se generara
  un nuevo informe con los resultados.
  <p>
  Atencion: si selecciona para ver solo por DENEGADO y marca para ver 
  un resumen por PERMITIDO no habra ningun resultado. Esto es correcto.
  Si no ve el resultado esperado controle los criterios seleccionados.
  <p>
  Convertir  URL's en links
  <ul>Marcando esta casilla las URLs en los informes se convertiran en links.
  </ul>
  </ul>
  </td></tr>
(EOF)
  print "<tr><td align=center><font face=arial,helvetica,sans=serif size=2>
  <a href=$cgipath>Volver a  $pagename</a></tr></td> 
  </table>\n";
}

