#!/usr/bin/perl -w
#
# $Id: SnortRules,v 1.3 2002/06/22 18:33:31 cvs Exp $
#
# SnortRules: Check (and update) Snort IDS rules
#
# Miguel Armas <kuko@optyma.net>
#

#--------------------------------------------[ Initialization Section ]----

use strict;
use Getopt::Std;
use pifia;

#--------------------------------------------[ Configuration Section ]----- 
my $priority = "Warning";
my $alarm = "SnortRules";

# Snort Rules directory
my $rulesdir = '<#$snortrulesdir#>';
my $cfgfile = '/etc/snort/oinkmaster.conf';

# Snort rules URL
my $url = '<#$rulesurl#>';

#--------------------------------------------[ Code Section ]----

# proactive flag indicates if we should take proactive measures, that is, 
# install/upgrade packages or just notify. Default is 0 but the global 
# variable proactive takes precedence
my $proactive='<#$proactive#>';

# Set a safe PATH
$ENV{'PATH'} = "/bin:/sbin:/usr/bin:/usr/sbin:/root/bin";

# Option declaration
use vars qw($opt_v $opt_n $opt_p $opt_q);
getopts('vnpq');

# Verbosity level. If not verbose, we shouldn't write any output unless 
# there is a problem. If quiet is set, we won't write ANY output (even if 
# there where errors). verbose has precedence
my $quiet = 1 if ($opt_q);
my $verbose = 1 if ($opt_v);
$quiet = 0 if ($verbose);

# proactive flag handling (parameters has precedence over global variable)
$proactive=1 if ($opt_p);
$proactive=0 if ($opt_n);

# Flag to show that the situation was corrected (in the output)
my $corrected=($proactive ? "CORRECTED" : "");

if ($verbose) {
   print "\n\n";
   print "########################\n";
   print " Running OinkMaster \n";
   print "########################\n";
}

my $cmd;
my $reload=0;
# Set URL if defined
$url="-u $url " if ($url);
if ($proactive) {
   $cmd="su nobody -c 'cd /tmp; oinkmaster.pl -C $cfgfile $url -p -o $rulesdir'";
}
else {
   $cmd="su nobody -c 'cd /tmp; oinkmaster.pl -C $cfgfile $url -p -c -o $rulesdir'";
}

my @out=`$cmd 2>&1`;
if ($?) {
   print "ERROR: oinkmaster exited with errors \n";
   print @out if ($verbose);
   exit 1;
}

print @out if ($verbose);

my @files = grep(/-> File /,@out);
my $rulefiles="";
foreach (@files) {
    $_ =~ /File (.*):/;
    $rulefiles .= "$1 ";
}
@files = grep(/Added files /,@out);
foreach (@files) {
    $_ =~ /Added files .*\/(.*)$/;
    $rulefiles .= "$1 ";
}

if ($rulefiles) {
   print "CHANGES: $rulefiles $corrected\n";
   # If we have changes, and in proactive mode, we must reload snort
   $reload = 1 if ($proactive);
}
else {
   print "NO CHANGES\n" if ($verbose);
}

# Restart snort if needed
if ($reload) {
   if ($verbose) {
      print "Reloading Snort \n";
      $cmd="/etc/init.d/snortd restart";
   }
   else {
      $cmd="/etc/init.d/snortd restart >/dev/null 2>&1";
   }
   system("$cmd");
}
