#!/usr/bin/perl

####################################################################################
#                           DEMARC (c) 2000-2001, DEMARC Org.
#   1.
#          REDISTRIBUTION
#
#          Redistributions of source code must retain the above copyright notice,
#          this list of conditions and the following disclaimer.
#   2.
#          FREE FOR NON-COMMERCIAL USE
#
#          You may not sell DEMARC, nor sell any of the functionality it provides.
#          No part of DEMARC may be used as part of any commercial product or
#          service without having first obtained a commercial licence from DEMARC org
#          unless exempt by meeting one of the following conditions.
#
#            a. You are using it for an ISP (Internet Service Provider) that has
#               less than a 1000 user subscriber base.
#
#            b. Your company has less than 25 employees.
#
#            c. You have extenuating circumstances and have received written
#               authorization from DEMARC Org. to use this software free of charge.
#
#          A free evaluation period of 60 days is granted for any commercial entity
#          who does not meet the requirements above but wishes to first try out the product.
#
#   3.
#          TRADEMARKS AND NOTICES
#
#          The software, graphics and documentation which make up DEMARC are
#          Copyright (c) 2000-2001 DEMARC Org. You agree to respect these rights and
#          leave all notices and product references intact.
#
#   4.
#          LIMITATION OF LIABILITY AND DISCLAIMER OF WARRANTY
#
#          THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
#          LAW. DEMARC ORG. PROVIDE THIS PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
#          EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#          WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
#          RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
#          PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR
#          OR CORRECTION.
#
#         Any questions or comments regarding this license or the official evaluation of
#                individual circumstances may be directed to info@demarc.org
####################################################################################




#NOTE 
# :set tabstop=4  (in vi[m])
# to bring this bad boy into focus


BEGIN{
	# CHANGE this to reflect where you have your StaticServices.pm module
	# which SHOULD be the same as where this script resides
	push (@INC,"/usr/local/www/demarc/htdocs/demarc/");
};

use StaticServices; #Make SURE your cgi-bin directory is in your INC array above
use DBI;
use DBD::mysql;
use CGI;
use CGI::Cookie;
use strict;
use Digest::MD5  qw(md5_hex);

# MIME::Base64 needed for decoding basic auth


use vars qw (	$db @substitutions $header_printed $debug_level 
					$current_row_color $program_name $program_version 
					%FORM $cgi $current_page $recent_alert 
					@messages @services $logged_in_as $downed_hosts_array_ref 
					$minimum_monitoring_table %cookies $total_count
					$is_admin 
				);

my $use_Apache_DBI_with_mod_perl = 1;

if ($use_Apache_DBI_with_mod_perl && $ENV{'MOD_PERL'}){
    require Apache::DBI;
    Apache::DBI->import();
}

my $db_user 					= "snort_useer";
my $db_password				= "db_password";
my $db_host						= "127.0.0.1";
my $db_name						= "snort";

my $whois_command				= "/usr/bin/whois";
my $traceroute_command  	= "/usr/sbin/traceroute";
my $nslookup_command  		= "/usr/sbin/nslookup";
my $ping_command  			= "/usr/sbin/ping";
my $monitor_sid				= 1;
my $detect_basic_auth		= 1;  #Auto deMIME basic authentication in payload?
my $default_limit 			= 60;
my $allow_anonymous_access = 0;
my $allow_user_to_change_email = 1;
my $validate_ip				= 1; #1||0 for checking session ID comes from the same IP every time
												 # ONLY change if you are having problems with people
												 # checking from proxies like AOL where IPs appear to change
												 # over the course of a single session
my $session_timeout_minutes= 30; #number of minutes for a user's session to timout after if idle

###############################################################
# Alert Priority levels are set as follows:
#
# 1 - HIGH ALERT 		- action should be taken on this alert
# 2 - WARNING ALERT	- action may need further action
# 3 - -\
# 4 -   \_LOW LEVEL ALERTS - can be categorized as you see fit
# 5 -   /
# 6 - _/
#
my $priority_levels			= "123456";
my $alert_priority_levels	= "12";
my $high_alert_level			= 1;
my $mid_alert_level			= 1;
my $default_priority_level	= "2";
###############################################################

my $allowed_cache_minutes	= "1";
my $allowed_long_cache_minutes	= "5";
my $use_cache					= 1;
my $system_type				= "bsd"; #options: bsd|linux

my $row1_color					= "#000000";
my $row2_color					= "#000000";
my $row3_color					= "#001E4B";
my $row4_color					= "#244A75";
my $row5_color					= "#021439";
my $row6_color					= "#003F92";
my $header_row_color			= "#003366";
my $vert_header_row_color	= "#000000";

my $standard_table_attrs	= " BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH=\"100%\" ";

#my $v_graphics_path	= "http://demarc.org/pub-images";
my $v_graphics_path	= "/pub-images";
my $this_program		= "demarc";
my $v_base_path		= "/dm";
my $base_path			= "/usr/local/www/dm";
my $template_subdir	= "/templates";
my $home_url			= "$v_base_path/$this_program";

################
# Reset vlues for MOD_PERL (such a blessing, and SUCH a curse!)
$recent_alert 			= ();
$current_page 			= ();
@substitutions			= ();
$header_printed		= ();
%FORM						= ();
%cookies					= ();
$cgi						= ();
@messages				= ();
$total_count			= ();
$is_admin				= (); #Comment out for SERIOUS SECURITY BREACH! (ie don't do it!)
$minimum_monitoring_table 	= ();
$downed_hosts_array_ref		= ();

@services				= qw(
									Ping
									HTTP
									SSH
									SMTP
									FTP
									HTTPS
									Telnet
									POP3
									DNS
									IMAP4
									NNTP
									load
									disks
);


my $ctime 				= time();




################################
# No need to change below here

$program_name 		= "DEMARC";
$program_version	= "1.04";

####################
# Get FORM vars
$cgi = new CGI;
%FORM = $cgi->Vars;
####################
# Check for cookies:
%cookies = fetch CGI::Cookie;

###### File Paths (relative to $base_path and $template subdir)
my $main_template				= "$base_path$template_subdir/main.html";
my $search_form				= "$base_path$template_subdir/search_form.html";
my $new_service_form			= "$base_path$template_subdir/new_service_form.html";
my $monitor_ids_form			= "$base_path$template_subdir/monitor_ids_form.html";
my $monitor_md5_form			= "$base_path$template_subdir/monitor_md5_form.html";
my $monitor_service_form	= "$base_path$template_subdir/monitor_service_form.html";
my $age_data_form				= "$base_path$template_subdir/age_data_form.html";
my $general_config_form		= "$base_path$template_subdir/general_config_form.html";
my $configure_md5_form		= "$base_path$template_subdir/configure_md5_form.html";
my $admin_user_config_form	= "$base_path$template_subdir/admin_user_config.html";
my $ul_user_config_form		= "$base_path$template_subdir/ul_user_config.html";
my $ul_email_config_form	= "$base_path$template_subdir/ul_user_config_email.html";


my $footer_string	= "$program_name - Version $program_version";

#####################################
### Check if we are using HTTPS and check for user
if (!$ENV{'SSL_SERVER_CERT'}){
		&push_message("<FONT COLOR=red>You are <B>NOT</B> using HTTPS, all administrative functions have been locked out</FONT>");
}

###################
# Authentication:

if ($FORM{'username'} && $FORM{'password'}){
	$logged_in_as = &login($FORM{'username'},$FORM{'password'});
	if (!$logged_in_as){
			&push_message("<FONT COLOR=red><B>Login Failure.</B></FONT>");
         &print_login_screen;
         &safe_exit;
   }
	# if we're still here then login was a success	
}
elsif (($cookies{'s_key'}) && ($cookies{'s_key'}->value)){
	$logged_in_as = &check_login($cookies{'s_key'}->value);
	if (!$logged_in_as){
		   &print_login_screen;
   		&safe_exit;
	}
	# if we're still here then validation was a success	
}
else{
	&print_login_screen;
	&safe_exit;
}
#=cut

push (@substitutions,"\\[USER\\],-,$logged_in_as");

#####################################
###  Get shared monitoring info:
($downed_hosts_array_ref,$minimum_monitoring_table) = &get_minimum_monitoring_table;
#####################################

#############################################
# Control Section
#############################################

if ($FORM{'td'} eq "view_payload"){
	($FORM{'sid'}=~/^\d+$/) || &error("No SID passed");
	($FORM{'cid'}=~/^\d+$/) || &error("No CID passed");
	&view_payload($FORM{'sid'},$FORM{'cid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "search"){
	$current_page = "search";
	&print_search;
	&safe_exit;
}
elsif ($FORM{'td'} eq "about"){
	$current_page = "about";
	&print_about;
	&safe_exit;
}
elsif ($FORM{'td'} eq "logout"){
	$current_page = "logout";
	&logout;
	&print_login_screen;
	&safe_exit;
}
elsif ($FORM{'td'} eq "show_events"){
	$current_page = "show_events";
	my $table = &print_events(	
						offset_type		=> $FORM{'offset_type'},
						offset_number	=> $FORM{'offset_number'},
						sid				=> $FORM{'sid'},
						cid				=> $FORM{'cid'},
						tcp				=> $FORM{'tcp'},
						udp				=> $FORM{'udp'},
						icmp				=> $FORM{'icmp'},
						other				=> $FORM{'other'},
						signature		=> $FORM{'signature'},
						signature_is	=> $FORM{'signature_is'},
						start				=> $FORM{'start'},
						limit				=> $FORM{'limit'},
						src_ip			=> $FORM{'src_ip'},
						dst_ip			=> $FORM{'dst_ip'},
						hr_s				=> $FORM{'hr_s'},
						min_s				=> $FORM{'min_s'},
						day_s				=> $FORM{'day_s'},
						mon_s				=> $FORM{'mon_s'},
						yr_s				=> $FORM{'yr_s'},
						hr_f				=> $FORM{'hr_f'},
						min_f				=> $FORM{'min_f'},
						day_f				=> $FORM{'day_f'},
						mon_f				=> $FORM{'mon_f'},
						yr_f				=> $FORM{'yr_f'},
						search_type		=> $FORM{'search_type'},
				);
	push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
	&print_main_with_key($main_template);
	&safe_exit;
}
elsif ($FORM{'td'} eq "delete"){
(&is_admin) || (&error("Only the administrator can delete records."));
   $current_page = "main";
	if (!($FORM{'delete_type'}=~/^limit$|^all$/)){ 
		&error("You must specify whether you would like to delete the entire query or simply the events on the page you were viewing.");
	}
my $delete_array_ref = &print_events(
                  offset_type    => $FORM{'offset_type'},
                  offset_number  => $FORM{'offset_number'},
                  sid            => $FORM{'sid'},
                  cid            => $FORM{'cid'},
                  tcp            => $FORM{'tcp'},
                  udp            => $FORM{'udp'},
                  icmp           => $FORM{'icmp'},
                  other          => $FORM{'other'},
                  signature      => $FORM{'signature'},
                  start          => $FORM{'start'},
                  limit          => $FORM{'limit'},
                  src_ip         => $FORM{'src_ip'},
                  dst_ip         => $FORM{'dst_ip'},
                  hr_s           => $FORM{'hr_s'},
                  min_s          => $FORM{'min_s'},
                  day_s          => $FORM{'day_s'},
                  mon_s          => $FORM{'mon_s'},
                  yr_s           => $FORM{'yr_s'},
                  hr_f           => $FORM{'hr_f'},
                  min_f          => $FORM{'min_f'},
                  day_f          => $FORM{'day_f'},
                  mon_f          => $FORM{'mon_f'},
                  yr_f           => $FORM{'yr_f'},
                  search_type    => $FORM{'search_type'},
						delete_type		=> $FORM{'delete_type'},
            );
	&delete_events($delete_array_ref);
	my $events_deleted = (@$delete_array_ref);
	&push_message("<FONT COLOR=red><B>Delete Successfull.</B></FONT>");
	&print_stats;
		&log_event(	username => "$logged_in_as",
						action 	=> "deleted $events_deleted events",
						target	=> '',
					 );
	&safe_exit;
}
elsif ($FORM{'td'} eq "unique_events_since"){
	($FORM{'offset_type'}=~/^day$|^hour$/) || ($FORM{'offset_type'} = '');
	($FORM{'offset_number'}=~/^\d+$/) || ($FORM{'offset_number'} = '');
	my $table = &unique_events_since($FORM{'offset_type'},$FORM{'offset_number'});
	push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
	&print_main_with_key($main_template);
	&safe_exit;
}
elsif ($FORM{'td'} eq "mini_me"){
	$current_page = "mini_me";
	&print_mini_me;
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_monitoring_page"){
	$current_page = "monitor";
	&print_monitor_page;
	&safe_exit;
}
elsif ($FORM{'td'} eq "delete_monitored_service"){
	(&is_admin) || &error("You must be the administrator to perform this function");
	&delete_monitored_service($FORM{'long_ip'},$FORM{'service'});
   $current_page = "monitor";
   &print_monitor_page;
	my $dotted_ip = &convert_long_ip($FORM{'long_ip'});
	&log_event(	username => "$logged_in_as",
					action 	=> "deleted service monitoring event",
					target	=> "$dotted_ip - $FORM{'service'}",
				 );
   &safe_exit;
}
elsif ($FORM{'td'} eq "arin_whois"){
	($FORM{'ip'}) || &error("No IP address specified for query.");
	&query_arin($FORM{'ip'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "traceroute"){
	($FORM{'ip'}) || &error("No IP address specified for traceroute.");
	&traceroute($FORM{'ip'},$FORM{'timeout'},$FORM{'no_name_resolution'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "ping"){
	($FORM{'ip'}) || &error("No IP address specified for ping.");
	&ping($FORM{'ip'},$FORM{'count'},$FORM{'no_name_resolution'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "nslookup"){
	($FORM{'ip'}) || &error("No IP address specified for nslookup.");
	&nslookup($FORM{'ip'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "config"){
	$current_page = "config";
	(&is_anonymous) && &error("There are no options here for Anonymous users.");
	if (&is_admin){
		&print_config;
	}
	else{
		&print_config_user_level;
	}
	&safe_exit;
}
elsif ($FORM{'td'} eq "md5_config_select"){
	$current_page = "config";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&print_md5_select_menu;
	&safe_exit;
}
elsif ($FORM{'td'} eq "update_md5_rules"){
	$current_page = "config";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&print_md5_config($FORM{'sid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_update_md5_rules"){
	(&is_admin) || &error("You must be the administrator to perform this function");
	&update_md5_rules($FORM{'sid'},$FORM{'md5_rules'});
	&print_md5_config($FORM{'sid'});
	&log_event(	username => "$logged_in_as",
					action 	=> "updated md5 rules",
					target	=> "",
				 );
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_sid_menu"){
	(&is_admin) || &error("You must be the administrator to perform this function");
	$current_page = "config";
	&print_config_sid_menu();
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_sid"){
	(&is_admin) || &error("You must be the administrator to perform this function");
	$current_page = "config";
	&print_config_rules($FORM{'sid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_monitored_service_history_detail"){
	$current_page = "monitor";
	&print_monitor_event_detail($FORM{'eid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_ids_monitor"){
	$current_page = "config";
	&print_monitor_ids_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_host_monitoring_event"){
	$current_page = "config";
	&add_host_monitoring_event;
	&print_monitor_service_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_ids_monitoring_event"){
	$current_page = "config";
	&add_ids_monitoring_event;
	&print_monitor_ids_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "alter_monitor_alert_rule"){
	$current_page = "config";
	&update_monitor_alert_rule;
	&print_monitor_service_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "alter_ids_alert_rule"){
	$current_page = "config";
	&update_ids_alert_rule;
	&print_monitor_ids_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_md5_monitor"){
	$current_page = "config";
	&print_monitor_md5_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_md5_monitoring_event"){
	$current_page = "config";
	&add_md5_monitoring_event;
	&print_monitor_md5_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "alter_md5_alert_rule"){
	$current_page = "config";
	&update_md5_alert_rule;
	&print_monitor_md5_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_service_monitor"){
	$current_page = "config";
	&print_monitor_service_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_rules"){
	(&is_admin) || &error("You must be the administrator to perform this function");
	$current_page = "config";
	&config_rules($FORM{'sid'},$FORM{'rules_type'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_config_rules"){
	(&is_admin) || &error("You must be the administrator to perform this function");
	$current_page = "config";
	&do_config_rules($FORM{'sid'},$FORM{'rules_type'},$FORM{'rules_text'},$FORM{'new_ruleset_name'},$FORM{'action'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_monitoring_event"){
	$current_page = "config";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&print_add_monitoring_event_page;
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_add_monitoring_event"){
	$current_page = "config";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&do_add_monitoring_event;
	&print_add_monitoring_event_page;
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_monitored_host"){
	$current_page = "monitor";
	&view_monitored_host(	long_ip => $FORM{'long_ip'},
									service => $FORM{'service'},
								);
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_md5_page"){
	$current_page = "md5";
	&view_md5_page($FORM{'minimal'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_md5_details_page"){
	$current_page = "md5";
	&view_md5_page('',$FORM{'sid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "confirm_all_md5_changes"){
	$current_page = "md5";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&confirm_all_md5_changes;
	&view_md5_page();
	&safe_exit;
}
elsif ($FORM{'td'} eq "confirm_selective_md5_changes"){
	$current_page = "md5";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&confirm_selective_md5_changes($FORM{'sid'});
	&view_md5_page();
	&safe_exit;
}
elsif ($FORM{'td'} eq "age_data"){
	$current_page = "config";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&print_age_data_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_age_data"){
	$current_page = "config";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&age_data(	services => $FORM{'age_ago_services'},
					ids		=> $FORM{'age_ago_ids'}
				);
	&print_age_data_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "general_config"){
	$current_page = "config";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&print_general_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_log_entries"){
	$current_page = "config";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&print_log($FORM{'tail'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "user_config"){
	$current_page = "config";
	&print_user_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "user_level_config"){
	$current_page = "config";
	&print_user_level_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "ul_change_email"){
	$current_page = "config";
	&ul_change_email($FORM{'new_email'});
	&print_user_level_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "ul_change_password"){
	$current_page = "config";
	&ul_change_password($FORM{'old_pw'},$FORM{'new_pw'},$FORM{'new_pw_confirm'});
	&print_user_level_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_user"){
	$current_page = "config";
	(&is_admin) || &error("You must be the administrator to perform this function");
	&do_add_user($FORM{'new_username'},$FORM{'new_password'},$FORM{'new_email'},$FORM{'ip_restrict'});
	&print_user_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "modify_user"){
	$current_page = "config";
	&do_modify_user($FORM{'current_user'},$FORM{'action'},$FORM{'new_value'});
	&print_user_config_form;
	&safe_exit;
}
else{
	$current_page = "main";
	&print_stats;
	&safe_exit;
}



#############################################
# Functions
#############################################

sub connect_to_db{
if (!$db || !$db->ping){

# function args override defaults, but error out if neither are there.
 $db_user         ||  &error("No database user specified.");
 $db_password     ||  &error("No database password specified.");
 $db_host         ||  &error("No database host specified.");
 $db_name         ||  &error("No database specified.");

 $db = DBI->connect("dbi:mysql:host=$db_host;database=$db_name", $db_user , $db_password) || &error("Connection Problem! ". $DBI::errstr);

}
return $db;
}


####################
sub error{
my ($error_string,$plain_page) = @_;

if ($plain_page){
	&print_header;
	print "<HTML><BODY BGCOLOR=black TEXT=red><CENTER><H2>$error_string</H2></CENTER></BODY></HTML>";
	&safe_exit;
}

push (@substitutions,"\\[MAIN_TABLE\\],-,<CENTER><FONT COLOR=red><B>$error_string</B></FONT></CENTER>");
&print_main_with_key($main_template);
&safe_exit;
}
####################
sub debug{
my ($d_string,$d_level) = @_;

return if ($debug_level && $d_level && ($debug_level > $d_level));

&print_header;
print $d_string . "<BR>";
}
####################
sub print_header{

return if ($header_printed);
$header_printed = 1;
print "Content-type: text/html\n\n";
}
###################
sub safe_exit{

if (!$ENV{'MOD_PERL'} && $db){
    $db->disconnect;
}

exit;
}
###################
sub print_events{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $proto;
my @where_array;
my @special_where_array;
my @proto_array;
my $where;
my $limit;
my $row_count;
my $search_type;
my $return_count;
my $start;

&safe_slash(\$args{'signature'});
&safe_slash(\$args{'signature_is'});
($args{'sid'}=~/^\d+$/) 
	|| ($args{'sid'} = ());
($args{'cid'}=~/^\d+$/) 
	|| ($args{'cid'} = ());
($args{'start_record'}=~/^\d+$/) 
	|| ($args{'start_record'} = ());
($args{'limit'}=~/^\d+$/) 
	|| ($args{'limit'} = ());
($args{'start'}=~/^\d+$/) 
	|| ($args{'start'} = ());
($args{'limit'}=~/^\d+$/) 
	|| ($args{'limit'} = ());

#Time restrictions:
#db-defaults to 0's for bad input, 
#but at least make sure its all numbers:
($args{'hr_s'}=~/^\d+$/) 
	|| ($args{'hr_s'} = "0");
($args{'min_s'}=~/^\d+$/) 
	|| ($args{'min_s'} = "0");
($args{'day_s'}=~/^\d+$/) 
	|| ($args{'day_s'} = "0");
($args{'mon_s'}=~/^\d+$/) 
	|| ($args{'mon_s'} = "0");
($args{'yr_s'}=~/^\d+$/) 
	|| ($args{'yr_s'} = "0");
($args{'hr_f'}=~/^\d+$/) 
	|| ($args{'hr_f'} = "0");
($args{'min_f'}=~/^\d+$/) 
	|| ($args{'min_f'} = "0");
($args{'day_f'}=~/^\d+$/) 
	|| ($args{'day_f'} = "0");
($args{'mon_f'}=~/^\d+$/) 
	|| ($args{'mon_f'} = "0");
($args{'yr_f'}=~/^\d+$/) 
	|| ($args{'yr_f'} = "0");


# IP focusing
($args{'src_ip'}=~/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) 
	|| ($args{'src_ip'} = ());
($args{'dst_ip'}=~/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) 
	|| ($args{'dst_ip'} = ());

# Table stuff:
($args{'cellpadding'}=~/^\d+$/) 
	|| ($args{'cellpadding'} = "0");
($args{'cellspacing'}=~/^\d+$/) 
	|| ($args{'cellspacing'} = "1");
($args{'table_width'}=~/^\d+\%{0,1}$/) 
	|| ($args{'table_width'} = "100%");
($args{'first_color'}) 
	|| ($args{'first_color'} = $row1_color);
($args{'second_color'}) 
	|| ($args{'second_color'} = $row2_color);
($args{'header_row_color'}) 
	|| ($args{'header_row_color'} = $header_row_color);
($args{'border_color'}) 
	|| ($args{'border_color'} = $row1_color);

&safe_slash(\$args{'order_by'});

($args{'offset_type'}=~/^day$|^hour$/) || ($FORM{'offset_type'} = '');
($args{'offset_number'}=~/^\d+$/) || ($FORM{'offset_number'} = '');
	

if ($args{'signature'}){
	push (@where_array,"(sig_name LIKE '%$args{'signature'}%')");
}
if ($args{'signature_is'}){
	push (@where_array,"(sig_name =  '$args{'signature_is'}')");
}
if ($args{'sid'}){
	push (@where_array,"(event.sid = '$args{'sid'}')");
}
if ($args{'cid'}){
	push (@where_array,"(event.cid = '$args{'cid'}')");
}
if (($args{'offset_type'}) && ($args{'offset_number'})){
	push (@special_where_array,"(timestamp >= date_add(now(),interval -$args{'offset_number'} $args{'offset_type'}))");
}

# The right time period:
if ($args{'yr_s'} ||$args{'mon_s'} || $args{'day_s'} || $args{'hr_s'} || $args{'min_s'}){
	push (@where_array,"(timestamp >= '$args{'yr_s'}-$args{'mon_s'}-$args{'day_s'} $args{'hr_s'}:$args{'min_s'}:00')");
}
if ($args{'yr_f'} ||$args{'mon_f'} || $args{'day_f'} || $args{'hr_f'} || $args{'min_f'}){
	push (@where_array,"(timestamp <= '$args{'yr_f'}-$args{'mon_f'}-$args{'day_f'} $args{'hr_f'}:$args{'min_f'}:00')");
}

#Make sure we get the protocol we want
# Deal with protocols in a special (OR) manner

if ($args{'tcp'}){
	push (@proto_array,"(tcp_dport IS NOT NULL)");
}

if ($args{'udp'}){
	push (@proto_array,"(udp_dport IS NOT NULL)");
}
if ($args{'icmp'}){
	push (@proto_array,"(icmp_type IS NOT NULL)");
}
if ($args{'other'}){
	push (@proto_array,"((icmp_type IS NULL) AND (udp_dport IS NULL) AND (tcp_dport IS NULL))");
}
if (@proto_array){
	my $temp_string = "( ";
	foreach (@proto_array){
		$temp_string .= " $_ OR";
	}
	$temp_string =~s/OR$/\) /;#Take off last OR and end with )
	push (@special_where_array,$temp_string);
}



#Only get certain ips src/dst if requested
if ($args{'src_ip'}){
	push (@where_array,"(ip_src = '" . &convert_dotted_ip($args{'src_ip'}) . "')");
}
if ($args{'dst_ip'}){
	push (@where_array,"(ip_dst = '" . &convert_dotted_ip($args{'dst_ip'}) . "')");
}
	
# Limit the results if applicable:
if (!$args{'delete_type'} || $args{'delete_type'} eq "limit"){
	if (($args{'start'}=~/^\d+$/) && ($args{'limit'})){
		$limit = " LIMIT $args{'start'},$args{'limit'} ";
	}
	elsif ($args{'limit'}){
		$limit = " LIMIT $args{'limit'} ";
	}
}

#Figure out if we're doing an OR/AND search

$search_type = ($args{'search_type'} eq "ANY")? "OR" : "AND";

#Put together where clause:
if (@where_array){
#	$where = " WHERE 1=1 ";
	$where = " WHERE ";
	foreach (@where_array){
		#$where .= " AND $_ ";
		$where .= " $_ $search_type";
	}
	# Take off the last boolean connector:
	$where=~s/$search_type$//;
}

# now add the special ones that HAVE to be ANDs

if (@special_where_array){
		$where .= (@where_array)?" AND ( " : " WHERE (";
	foreach (@special_where_array){
		$where .= " $_ AND";
	}
	# take off the last boolean connector, and add closing ):
	$where=~s/AND$/) /;
}

if ($current_page ne "main"){
# Get total returned rows count first:
$sql_query = "SELECT count(*) as COUNT \
					FROM event \
                  LEFT JOIN iphdr   ON  ((event.cid = iphdr.cid) AND (event.sid = iphdr.sid)) \
                  LEFT JOIN tcphdr  ON ((event.cid = tcphdr.cid) AND (event.sid = tcphdr.sid)) \
                  LEFT JOIN udphdr  ON ((event.cid = udphdr.cid) AND (event.sid = udphdr.sid)) \
						LEFT JOIN signature  ON (event.signature = signature.sig_id)  \
                  LEFT JOIN icmphdr ON ((event.cid = icmphdr.cid) AND (event.sid = icmphdr.sid)) $where";
$db_ptr = &run_query($sql_query);
$hash_ref = $db_ptr->fetchrow_hashref;
$return_count = $$hash_ref{'COUNT'};
push (@substitutions,"<TOTAL_ROWS_RETURNED>,-,Total rows returned: $return_count") if ($current_page ne "main");
}

if (!$args{'delete_type'}){
$sql_query = "SELECT \
					event.*,iphdr.ip_src,iphdr.ip_dst,tcphdr.tcp_sport,\
					tcphdr.tcp_dport,udphdr.udp_sport,udphdr.udp_dport,\
					sensor.hostname,sig_name ";
# Add "feelers" for accurate protocol IDing
$sql_query .= ", udphdr.sid AS UDP, icmphdr.sid AS ICMP, tcphdr.sid AS TCP ";
}
else{
	#then we just want to get the sid and cid s:
	$sql_query = " SELECT event.sid,event.cid ";
}
$sql_query .= " FROM event \
						LEFT JOIN iphdr 	ON  ((event.cid = iphdr.cid) AND (event.sid = iphdr.sid)) \
						LEFT JOIN tcphdr 	ON ((event.cid = tcphdr.cid) AND (event.sid = tcphdr.sid)) \
						LEFT JOIN udphdr 	ON ((event.cid = udphdr.cid) AND (event.sid = udphdr.sid)) \
						LEFT JOIN icmphdr ON ((event.cid = icmphdr.cid) AND (event.sid = icmphdr.sid)) \
						LEFT JOIN sensor  ON (event.sid = sensor.sid)  \
						LEFT JOIN signature  ON (event.signature = signature.sig_id)  \
					$where \
				  ORDER BY timestamp DESC $limit";

$db_ptr = &run_query($sql_query);

if ($args{'delete_type'}){
	#then we just have return the list to be deleted:
	my @delete_array;
	while ($hash_ref = $db_ptr->fetchrow_hashref){
		push (@delete_array,"$$hash_ref{'sid'},$$hash_ref{'cid'}");
	}
	return \@delete_array;
}

$table .= "<TABLE width=\"$args{'table_width'}\" border=0 cellspacing=\"$args{'cellspacing'}\" cellpadding=\"2\">";

	if ($current_page eq "show_events"){
  		$table .= "<TR BGCOLOR=#003366><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" COLSPAN=6 align=center><B>Event List</B></TD></TR>\n";
 	} 
 	else
    	{
			#$table .= "<TR BGCOLOR=#003366><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" COLSPAN=6 align=center><B>Last 6 Events</B></TD></TR>\n";
			$table .= "<TR BGCOLOR=#003366><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" COLSPAN=6 align=center><B>$args{'title'}</B></TD></TR>\n";
	}
$table .= "<TR BGCOLOR=#244A75><TD align=center><b>Signature</b></TD><TD align=center><b>Type</b></TD><TD align=center><b>Source</b></TD><TD align=center><b>Destination</b></TD><TD align=center><b>Sensor</b></TD><TD align=center><b>Time/Date</b></TD></TR>\n";

while ($hash_ref = $db_ptr->fetchrow_hashref){
	$row_count++;
	$table .= "<TR bgcolor=\"#001E4B\">";
	$table .= "<TD width=90%>&nbsp;";
	if ($$hash_ref{'sig_name'}=~/portscan.{1,11}from/i){
			$$hash_ref{'sig_name'}=~s/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/<A HREF=\"$home_url?td=arin_whois&ip=$1\">$1<\/A>/g;
			$table .= "$$hash_ref{'sig_name'}";
	}
	else{
			$table .= "<A HREF=\"$home_url?td=view_payload&sid=$$hash_ref{'sid'}&cid=$$hash_ref{'cid'}\">";
			$table .= "$$hash_ref{'sig_name'}";
			$table .= "</A>";
	}
	$table .= "&nbsp;</TD>";

# TCP/UDP/ICMP
   if ($$hash_ref{'TCP'}){
      $proto = "TCP";
   }
   elsif ($$hash_ref{'UDP'}){
      $proto = "UDP";
   }
   elsif ($$hash_ref{'ICMP'}){
      $proto = "ICMP";
   }
   elsif ($$hash_ref{'sig_name'}=~/portscan/i){
      $proto = "Scan";
   }
   else{
      $proto = "???";
   }

	$table .= "<TD>&nbsp;<B>$proto</B>&nbsp;</TD>";
   
# Source IP/port:
   $table .= "<TD nowrap>&nbsp;";

	if ($$hash_ref{'ip_src'}){
		my $src_ip = &convert_long_ip($$hash_ref{'ip_src'});
		$table .= "<A HREF=\"$home_url?td=show_events&src_ip=$src_ip&limit=$default_limit\">$src_ip</A>";
	}
	else{
		$table .= "NA";
	}
	if ($$hash_ref{'tcp_sport'}){
			$table .= ":$$hash_ref{'tcp_sport'}";
	}
	elsif ($$hash_ref{'udp_sport'}){
			$table .= ":$$hash_ref{'udp_sport'}";
	}
	else{
			$table .= ":na";
	}

	$table .= "&nbsp;</TD><TD nowrap>&nbsp;";

# Dest IP/port:
	
   if ($$hash_ref{'ip_dst'}){
      my $dst_ip = &convert_long_ip($$hash_ref{'ip_dst'});
      $table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&dst_ip=$dst_ip\">$dst_ip</A>";
   }
   else{
      $table .= "NA";
   }
   if ($$hash_ref{'tcp_dport'}){
         $table .= ":$$hash_ref{'tcp_dport'}";
   }
   elsif ($$hash_ref{'udp_dport'}){
         $table .= ":$$hash_ref{'udp_dport'}";
   }
   else{
         $table .= ":na";
   }
   $table .= "&nbsp;</TD>";
# Sensor / host
   $table .= "<TD align=center>&nbsp;$$hash_ref{'hostname'}&nbsp;</TD>";
# Time / Date
	#strip seconds off to save space:
	$$hash_ref{'timestamp'}=~s/:\d\d$//;
	#strip year off to save space (not needed!):
	$$hash_ref{'timestamp'}=~s/^\d\d\d\d\-//;
	$$hash_ref{'timestamp'}=~s/(\d\d\-\d\d) (\d\d:\d\d)/$2 $1/;
   $table .= "<TD NOWRAP>&nbsp;$$hash_ref{'timestamp'}&nbsp;</TD>\n";
	$table .= "</TR>\n";
}
$table .= "<TR><TD bgcolor=\"$args{'second_color'}\" align=center valign=bottom colspan=6 height=40><B>No Records Returned</B></TD></TR>\n"
	if (!$row_count);

# Start the form:
$table .= << "EOF";
<TR><TD align=center colspan=6 bgcolor="$row3_color">
<TABLE cellpadding=0 cellspacing=0 border=0 WIDTH=\"100%\">
<TR><TD ALIGN=center>
<TABLE cellpadding=2 cellspacing=0 border=0 BGCOLOR=\"$row2_color\">
EOF

$table .= "<FORM ACTION=\"$home_url\" METHOD=get>";
$table .= "<TR><TD valign=top bgcolor=\"$row3_color\">";
$table .= "<B>Events in the past:</B>"; 
$table .= "<SELECT NAME=offset_number style=\"font-size:8pt;\">";
$table .= "<OPTION SELECTED>$args{'offset_number'}</OPTION>" if ($args{'offset_number'});
$table .= << "EOF";
<OPTION>1</OPTION>
<OPTION>2</OPTION>
<OPTION>3</OPTION>
<OPTION>4</OPTION>
<OPTION>5</OPTION>
<OPTION>6</OPTION>
<OPTION>7</OPTION>
<OPTION>8</OPTION>
<OPTION>9</OPTION>
<OPTION>10</OPTION>
<OPTION>11</OPTION>
<OPTION>12</OPTION>
<OPTION>13</OPTION>
<OPTION>14</OPTION>
<OPTION>15</OPTION>
<OPTION>16</OPTION>
<OPTION>17</OPTION>
<OPTION>18</OPTION>
<OPTION>19</OPTION>
<OPTION>20</OPTION>
<OPTION>21</OPTION>
<OPTION>22</OPTION>
<OPTION>23</OPTION>
<OPTION>24</OPTION>
</SELECT>
<INPUT TYPE=hidden NAME=td VALUE=show_events>
<SELECT NAME=offset_type style="font-size:8pt;">
EOF
if ($args{'offset_type'}=~/hour/){
   $table .= "<OPTION value=hour selected>Hours</OPTION>";
}
elsif ($args{'offset_type'}=~/day/){
   $table .= "<OPTION value=day selected>Days</OPTION>";
}
$table .= << "EOF";
<OPTION value=day>Days</OPTION>
<OPTION value=hour>Hours</OPTION>
</SELECT>
 </TD>
<TD valign=top bgcolor="$row3_color">
<B>#</B><FONT SIZE="3"><B>/</B></FONT><B>Page:</B>
<SELECT NAME=limit style="font-size:8pt;">
EOF
$table .= "<OPTION selected>$args{'limit'}</OPTION>" if ($args{'limit'} && ($args{'limit'} > 10));
$table .= << "EOF";
<OPTION>60</OPTION>
<OPTION>50</OPTION>
<OPTION>40</OPTION>
<OPTION>30</OPTION>
<OPTION>20</OPTION>
<OPTION>10</OPTION>
</SELECT>
 </TD>
EOF
$table .= "<TD valign=top align=center bgcolor=\"$row3_color\">TCP:<INPUT TYPE=checkbox NAME=tcp " ;
$table .=  ($args{'tcp'})? " checked> </TD>":"></TD>";
$table .= "<TD valign=top align=center bgcolor=\"$row3_color\">UDP:<INPUT TYPE=checkbox NAME=udp " ;
$table .=  ($args{'udp'})? " checked> </TD>":"></TD>";
$table .= "<TD valign=top align=center bgcolor=\"$row3_color\">ICMP:<INPUT TYPE=checkbox NAME=icmp " ;
$table .= ($args{'icmp'})? " checked> </TD>":"></TD>";
$table .= "<TD valign=top align=center bgcolor=\"$row3_color\">OTHER:<INPUT TYPE=checkbox NAME=other " ;
$table .= ($args{'other'})? " checked> </TD>":"></TD>";
$table .= "<TD bgcolor=\"$row3_color\"><INPUT TYPE=Submit Value=\"Go\" style=\"font-size:8pt;\">";
$table .= "</TD>";
$table .= "</FORM>";
$table .= "</TR>\n";
$table .= "</TABLE>";
#$table .= "</TABLE></TD></TR>\n"; 

#</TABLE>
$table .= "</TD><TD ALIGN=right>";

if ($current_page eq "main"){
	$table .= "<A HREF=\"$home_url?offset_number=1&td=show_events&offset_type=day&limit=60\"><B>More...</B></A> &nbsp; &nbsp;";
}
else{
	$table .= "&nbsp;";
}

$table .= << "EOF";
</TD></TR>
</TABLE>
</TD></TR>
<TR HEIGHT=2 BGCOLOR="#003366"><TD COLSPAN=6><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>
</TABLE>
EOF


if ($args{'limit'} && ($current_page ne "main")){
	# First get the args to pass:
	my $get_string;
	foreach (keys %args){
		if ($_ eq "signature"){
			$get_string .= "&signature=" . &linkify($args{'signature'});
		}
		elsif ($args{$_} && ($_ !~/^start$|color|table_width|^cell/)){
			$get_string .= "&$_=$args{$_}";
		}
	}

	$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\"><TR>";
	#$table .= "<TD WIDTH=50% ALIGN=left>";
	$table .= "<TD WIDTH=50%>";
	if ($args{'start'}){
		$start = $args{'start'};
		($args{'limit'}) ? ($start-=$args{'limit'}): ($start-=30);
		$start = "0" if ($start<0);  
		$table .= "&nbsp;<A HREF=\"$home_url?td=show_events&start=$start$get_string\">";
		$table .= "<B>&lt; BACK</B></A>"
	}
	$table .= "&nbsp;</TD>";
$table .= "<TD ALIGN=center NOWRAP>Records " ;
$table .= ($args{'start'})? $args{'start'} : "0" ;
$table .= " to " ;
$table .=  (($args{'start'} + $args{'limit'}) <= $return_count) ? ($args{'start'} + $args{'limit'}) : $return_count ;
$table .= " of $return_count</TD>";
	$table .= "<TD WIDTH=50% ALIGN=right>&nbsp;";
	if (($start + $args{'limit'}) < $return_count){
		$start = $args{'start'};
		$start += $args{'limit'};
		$table .= "<A HREF=\"$home_url?td=show_events&start=$start$get_string\">";
		$table .= "<B>NEXT &gt;</B></A>&nbsp;";
	}
	$table .= "</TD>";
	$table .= "</TR>\n</TABLE>\n";
}

if ((&is_admin) && ($current_page ne "main")){
	$table .= &get_delete_table(\%args);
}
return $table;
push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
##############
sub print_stats{
my $table;

$table .= "$minimum_monitoring_table";
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 BGCOLOR=\"#000000\" WIDTH=\"100%\"><TR><TD>";
$table .= &print_events(
						start_record		=> 0,
						limit					=> 6,
						title					=> "Last 6 Events",
						cellspacing			=> 1,
						cellpadding			=> 2,
						tcp					=> 1,
						udp					=> 1,
						icmp					=> 1,
						other					=> 1,
						header_row_color	=> $header_row_color,
			);
$table .= "</TD></TR></TABLE>\n";
$table .= "<BR>";
$table .= &unique_events_since("day",-1,11);

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
##############
sub run_query{
my ($sql_query) = @_;
&connect_to_db();

#my ($t1,$t2);
my $prepared = $db->prepare($sql_query);
if (!$prepared){
        #Then there's an error with the syntax of the query:
        &error("Database Error: Please try again");
#        &error("Syntax Error in SQL Query:<BR><B>$sql_query</B><P>".$db->errstr);
}
my $dbquery = $prepared->execute();
if (my $error_string = $prepared->errstr){
        &error("$error_string : $sql_query");
#        &error("Database Error: Please try again");
}
return $prepared;
}
#######################
sub view_payload{
my ($sid,$cid) = @_;

my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $decoded;
my $decoded_ascii_string;
my $table2;
my $payload_table;
my $reference_link;

$sql_query = "SELECT hostname,data_payload,timestamp,sig_name,ref_id \
	      FROM \
			data,event \
			LEFT JOIN signature ON (event.signature = signature.sig_id) \
			LEFT JOIN sig_reference ON (event.signature = sig_reference.sig_id) \
			LEFT JOIN sensor ON (event.sid = sensor.sid) \
	      WHERE 	\
			data.sid ='$sid' AND \
			data.cid ='$cid' AND \
			data.sid = event.sid AND \
			data.cid = event.cid ";

$db_ptr = &run_query($sql_query);
if ($hash_ref = $db_ptr->fetchrow_hashref){

	if ($$hash_ref{'ref_id'}=~/^\d+$/){
		$reference_link = &get_reference_link($$hash_ref{'ref_id'});
	}
	
	$decoded = &decode_hex($$hash_ref{'data_payload'});
	$decoded_ascii_string = &decode_hex($$hash_ref{'data_payload'},"RETURN_STRING");

	# Sub out TEXTAREA HTML tags for safety while displaying
	$decoded_ascii_string=~s/<(\/{0,1})TEXTAREA>/<$1TA>/g;
	$decoded=~s/<(\/{0,1})TEXTAREA>/<$1TA>/g;

	$payload_table = "<BR>\n<TABLE CELLPADDING=2 CELLSPACING=1 BORDER=0 ALIGN=CENTER>\n";
	$payload_table .= "<TR BGCOLOR=\"#003366\"><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" align=center><B>Event Payload</B></TD></TR>\n";
	$payload_table .= "<TR BGCOLOR=\"#244A75\">";
	$payload_table .= "<TD align=center><B>Payload with Hex</B></TD>";
	$payload_table .= "</TR>\n";
	$payload_table .= "<TR BGCOLOR=\"#001E4B\">";
	$payload_table .= "<TD align=center><FORM ACTION=\"javascript:void(0);\">";
	$payload_table .= "<TEXTAREA rows=8 cols=70>$decoded</TEXTAREA>";
	$payload_table .= "</TD></TR>\n";
	$payload_table .= "<TR BGCOLOR=\"#244A75\"><TD align=center><B>Alt-255 Decoded Payload</B></TD></TR>\n";
	$payload_table .= "<TR BGCOLOR=\"#001E4B\"><TD align=center><FORM ACTION=\"javascript:void(0);\">";
	$payload_table .= "<TEXTAREA rows=6 cols=70 WRAP=virtual>$decoded_ascii_string</TEXTAREA>";
	$payload_table .= "</TD></TR>\n";
	$payload_table .= "<TR HEIGHT=2><TD BGCOLOR=\"#003366\" COLSPAN=5><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n"; 
	$payload_table .= "</TABLE>\n<BR>\n";
if (($detect_basic_auth) && ($decoded_ascii_string=~/Authorization: Basic (\S+)/)){
	my $basic_auth = $1;
	eval{
		require MIME::Base64;
		MIME::Base64->import();
		my $cracked = MIME::Base64::decode($basic_auth);
		&push_message("<FONT COLOR=red>Basic Authentication in payload : $cracked</FONT>");
	};
}

}
else{
	#still have to get the timestamp and signature:
	$sql_query = "SELECT timestamp,signature,sig_name,hostname \
					  FROM event \
         			LEFT JOIN signature ON (event.signature = signature.sig_id) \
						LEFT JOIN sensor ON (event.sid = sensor.sid) \
					  WHERE \
						event.sid = '$sid' AND \
						cid = '$cid'";
	$db_ptr = &run_query($sql_query);
	($hash_ref = $db_ptr->fetchrow_hashref) || &error("No such event exists");
}

#Get general header table:
	$table .= &get_general_header_table($sid,$cid,$$hash_ref{'timestamp'},$$hash_ref{'sig_name'},$reference_link,$$hash_ref{'hostname'});
#Get IP header table:
	$table .= &get_ip_header_table($sid,$cid);
#Get TCP header table:
	$table .= &get_tcp_header_table($sid,$cid);
#Get ICMP header table:
	$table .= &get_icmp_header_table($sid,$cid);
#Get UDP header table:
	$table .= &get_udp_header_table($sid,$cid);
#Insert Payload table created earlier:
	$table .= $payload_table;



push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);



}
#########################
sub decode_hex{
my ($hex_stuff,$return_ascii) = @_;
my @buf1;
my @buf2;
my $ascii;
my $j;
my $hex_ascii_sep       = "   ";
my $sep1                = " ";
my $char_spacer         = " ";


# Decode hex crap and split into hex/ascii arrays
foreach ($hex_stuff =~ /[0-9a-fA-F]{2}/g) {

        push (@buf1,  $_);
        #push (@buf2,  chr(hex($_)));
        push (@buf2,  &validate_char(chr(hex($_))));

}

return join('',@buf2) if $return_ascii;

##############
# Combine two arrays into readable format:

for ($j=0;$j<=(@buf1);$j++){
        if (($j > 2) && ((($j+1) % 16) == 1)){
                #print out asci stuff
                for (1..16){
                        $ascii .= $hex_ascii_sep if ($_==1);
                      #  $ascii .= $sep1 if ($_==9);
                        #$ascii .= &validate_char(shift @buf2);
                        $ascii .= (shift @buf2);
                }
                $ascii .= "\n";
        }
        elsif (($j > 2) && ((($j+1) % 8) == 1)){
                $ascii .= $sep1;
        }
        else{
                $ascii .= $char_spacer if ($j != 0);
        }

        $ascii .= $buf1[$j];
}

if (@buf2){ #check for left over stuff
            #(ie didnt end on 16th hex out needed to dump the ascii)

        my $left_over = ($j % 16);
        for (0..(16-($j % 16))){
                $ascii .= " " x 3;
        }
		# Take off the last space
		$ascii=~s/ $//;
        if ($j<8){
                $ascii .= $sep1;
        }
        $ascii .= $hex_ascii_sep;

        for (my $r=0;$r<(@buf2);$r++){
                #$ascii .= &validate_char($buf2[$r]);
                $ascii .= $buf2[$r];
        }
}
return ($ascii);
}

###################
sub validate_char{
my ($c)         = @_;
my $c2          ;
my $oob_spacer  = ".";

my $char_num = (ord $c);
if (($char_num>=32) && ($char_num <=127)){
        $c2 = $c;
}
else{
        $c2 = $oob_spacer;
}

return $c2;
}
################
sub get_ip_header_table{
my ($sid,$cid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my @table_header_columns_1 = ('IP Src','Src Port','Src Service','IP Dst','Dst Port','Dst Service');
my @table_header_columns_2 = ('Ver','Hlen','TOS','Length','ID', 'Flags','Offset','Chksum','TTL');
my @table_fields_2 = ('ip_ver','ip_hlen','ip_tos','ip_len','ip_id'
			,'ip_flags','ip_off','ip_csum','ip_ttl');
my $services_hash_ref = StaticServices::get_services_hash_ref();
my $proto;
my $sport;
my $dport;

$sql_query = "SELECT  \
      iphdr.sid, iphdr.cid, iphdr.ip_src, iphdr.ip_dst,\
      iphdr.ip_ver, iphdr.ip_hlen, iphdr.ip_tos, \
      iphdr.ip_len, iphdr.ip_id, iphdr.ip_flags, \
      iphdr.ip_off, iphdr.ip_ttl, iphdr.ip_proto, iphdr.ip_csum, \
		tcphdr.tcp_sport, tcphdr.tcp_dport, \
		udphdr.udp_sport, udphdr.udp_dport \
         FROM iphdr \
				LEFT JOIN tcphdr ON ((iphdr.cid = tcphdr.cid) AND (iphdr.sid = tcphdr.sid)) \
         	LEFT JOIN udphdr ON ((iphdr.cid = udphdr.cid) AND (iphdr.sid = udphdr.sid)) \
         WHERE \
      iphdr.sid = '$sid' AND \
      iphdr.cid = '$cid'";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || &error("No such payload exists");

$table = "<BR>\n<TABLE CELLSPACING=1 CELLPADDING=2 BORDER=0 WIDTH=\"100%\">";
#First row - IP and port stuff:
$table .= "<TR bgcolor=\"#003366\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=6><B>Port Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"#244A75\">";
foreach (@table_header_columns_1){
	$table .= "<TD align=center><B>$_</B></TD>";
}
$table .= "</TR>\n";

$table .= "<TR BGCOLOR=\"#001E4B\">";
my $ip_s = &convert_long_ip($$hash_ref{'ip_src'});
$table .= "<TD align=center>";
$table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&src_ip=$ip_s\">$ip_s</A>";
$table .= "<BR><A HREF=\"$home_url?td=arin_whois&ip=$ip_s\">Arin</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=traceroute&ip=$ip_s\">Trace</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=ping&ip=$ip_s\">Ping</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=nslookup&ip=$ip_s\">NSlookup</A>";
$table .= "</TD>";
#$table .= "<TD align=center>$$hash_ref{'tcp_sport'}</TD>";
if ($$hash_ref{'tcp_sport'}){
	$table .= "<TD align=center>$$hash_ref{'tcp_sport'}</TD>";
	$proto = "tcp";
	$sport = $$hash_ref{'tcp_sport'};
}
elsif($$hash_ref{'udp_sport'}){
   $table .= "<TD align=center>$$hash_ref{'udp_sport'}</TD>";
	$proto = "udp";
	$sport = $$hash_ref{'udp_sport'};
}
else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
		$proto = "NA";
		$sport = "NA";
}
$table .= ($$services_hash_ref{$proto."_".$sport}) ? "<TD align=center>$$services_hash_ref{$proto.'_'.$sport}</TD>": "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";

my $ip_d = &convert_long_ip($$hash_ref{'ip_dst'});
$table .= "<TD align=center>";
$table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&dst_ip=$ip_d\">$ip_d</A>";
$table .= "<BR><A HREF=\"$home_url?td=arin_whois&ip=$ip_d\">Arin</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=traceroute&ip=$ip_d\">Trace</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=ping&ip=$ip_d\">Ping</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=nslookup&ip=$ip_d\">NSlookup</A>";
$table .= "</TD>";
if ($$hash_ref{'tcp_dport'}){
	$table .= "<TD align=center>$$hash_ref{'tcp_dport'}</TD>";
	$proto = "tcp";
	$dport = $$hash_ref{'tcp_dport'};
}
elsif($$hash_ref{'udp_sport'}){
   $table .= "<TD align=center>$$hash_ref{'udp_dport'}</TD>";
	$proto = "udp";
	$dport = $$hash_ref{'udp_dport'};
}
else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
		$proto = "NA";
		$dport = "NA";
}
$table .= ($$services_hash_ref{$proto."_".$dport}) ? "<TD align=center>$$services_hash_ref{$proto.'_'.$dport}</TD>": "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"#003366\" COLSPAN=6><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n<BR>\n";

# Second Row (ip):
$table .= "<TABLE CELLSPACING=1 CELLPADDING=2 BORDER=0 WIDTH=100%>";
#IP Information
$table .= "<TR bgcolor=\"#003366\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=9><B>IP Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"#244A75\">";
# Verticle Header row
foreach (@table_header_columns_2){
	$table .= "<TD align=center><B>$_</B></TD>";
}
$table .= "</TR><TR BGCOLOR=\"#001E4B\">\n";
foreach (@table_fields_2){
	#($table .= "<TD>$$hash_ref{$_}</TD>") ?($$hash_ref{$_}):($table .= "<TD>BBB</TD>");
	if ($$hash_ref{$_}){
		$table .= "<TD align=center>$$hash_ref{$_}</TD>";
	}
	else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
	}
}
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"#003366\" COLSPAN=9><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n<BR>\n";

return $table;
}
################
sub get_icmp_header_table{
my ($sid,$cid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my @table_header_columns = ('Type','Code','Checksum','ID','Sequence');
my @table_fields 			 = ('icmp_type','icmp_code','icmp_csum','icmp_id','icmp_seq');

$sql_query = "SELECT  \
				icmp_type,icmp_code,icmp_csum,icmp_id,icmp_seq 
         FROM icmphdr \
         WHERE \
      		sid = '$sid' AND \
      		cid = '$cid'";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return; #Simply return, no errors

$table .= "<TABLE CELLSPACING=1 CELLPADDING=2 BORDER=0 WIDTH=\"100%\">";
#ICMP Information
# Verticle Header row
$table .= "<TR bgcolor=\"#003366\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=5><B>ICMP Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"#244A75\">";
foreach (@table_header_columns){
	$table .= "<TD align=center><B>$_</B></TD>";
}
$table .= "</TR>\n";
$table .= "<TR BGCOLOR=\"#001E4B\">";
foreach (@table_fields){
	if ($$hash_ref{$_}){
		$table .= "<TD align=center>$$hash_ref{$_}</TD>";
	}
	else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
	}
}
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"#003366\" COLSPAN=5><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>";

return $table;
}
################
sub get_udp_header_table{
my ($sid,$cid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my @table_header_columns = ('Src Port','Dst Port','Length','Checksum');
my @table_fields 			 = ('udp_sport','udp_dport','udp_len','udp_csum');

$sql_query = "SELECT  \
				udp_sport,udp_dport,udp_len,udp_csum \
         FROM udphdr \
         WHERE \
      		sid = '$sid' AND \
      		cid = '$cid'";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return; #Simply return, no errors

$table .= "<TABLE CELLPADDING=2 CELLSPACING=1 BORDER=0 WIDTH=100%>";
# Verticle Header row
$table .= "<TR bgcolor=\"#003366\"><TD background=\"$v_graphics_path/bg_title.gif\" colspan=4 align=center><B>UDP Information</B></TD></TR>";
$table .="<TR BGCOLOR=\"#244A75\">";
foreach (@table_header_columns){
	$table .= "<TD align=center width=\"25%\"><B>$_</B></TD>";
}
$table .= "</TR>\n";
$table .= "<TR BGCOLOR=\"#001E4B\">";
foreach (@table_fields){
	if ($$hash_ref{$_}){
		$table .= "<TD align=center>$$hash_ref{$_}</TD>";
	}
	else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
	}
}
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"#003366\" COLSPAN=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>";

return $table;
}
################
sub get_tcp_header_table{
my ($sid,$cid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my @table_header_columns = ('Seq','Ack', 'Urp','Res',   'Win','Flags','Offset','Chksum');
my @table_fields = ('tcp_seq','tcp_ack','tcp_urp','tcp_res','tcp_win','tcp_flags','tcp_off','tcp_csum');

$sql_query = "SELECT  \
            	tcp_seq,tcp_ack,tcp_urp,tcp_res,tcp_win,tcp_flags,tcp_off,tcp_csum \
         	  FROM tcphdr \
         	  WHERE \
            	sid = '$sid' AND \
            	cid = '$cid'";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return; #Simply return, no errors

#Third Row (tcp):
$table .= "<TABLE CELLSPACING=1 CElLPADDING=2 BORDER=0 WIDTH=\"100%\">";
#TCP Information
$table .= "<TR bgcolor=\"#003366\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=8><B>TCP Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"#244A75\">";
# Verticle Header row
foreach (@table_header_columns){
	$table .= "<TD align=center><B>$_</B></TD>";
}
$table .= "</TR>\n<TR BGCOLOR=\"#001E4B\">\n";
foreach (@table_fields){
	if ($$hash_ref{$_}){
		$table .= "<TD align=center>$$hash_ref{$_}</TD>";
	}
	else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
	}
}
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"#003366\" colspan=8><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
$table .= "</TABLE>\n";

return $table;
}
#####################
sub convert_long_ip{
my ($long) = @_;
my $t1;
my $new_ip;

for (my $i=3;$i>=0;$i--){
        $t1 = sprintf ("%d",($long / (256 ** $i)));
        $new_ip .= $t1.".";
        $long = $long - ($t1 * (256 ** $i))
}
$new_ip =~s/\.$//;

return $new_ip;
}
####################
sub convert_dotted_ip{
my ($ip) = @_;

my @IP = split(/\./,$ip);

my $long_ip =(
  		   ($IP[0]*(256**3))
  		 + ($IP[1]*(256**2))
  		 + ($IP[2]*(256**1))
  		 + ($IP[3])
  		  );
return $long_ip;
}
####################
sub get_general_header_table{
my ($sid,$cid,$timestamp,$signature,$reference_link,$hostname) = @_;
my @table_header_columns = ('SID','CID','TimeStamp');
my $table;


$table  = "<TABLE CELLSPACING=1 CELLPADDING=2 BORDER=0 WIDTH=\"100%\">";

# Signature row first:
$table .= "<TR bgcolor=\"#003366\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=4><B>Basic Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"#244A75\">";
$table .= "<TD align=center WIDTH=\"50%\"><B>Signature</B></TD>";
foreach (@table_header_columns){
	$table .= "<TD align=center nowrap><B>$_</B></TD>";
}
$table .= "</TR>\n";
$table .= "<TR BGCOLOR=\"#001E4B\">";
$table .= "<TD align=center>&nbsp;$signature &nbsp;$reference_link</TD>";
$table .= "<TD align=center width=100>&nbsp;$sid&nbsp;-&nbsp($hostname)</TD>";
$table .= "<TD align=center width=100>&nbsp;$cid&nbsp;</TD>";
$table .= "<TD align=center nowrap>&nbsp;$timestamp&nbsp;</TD>";
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"#003366\" COLSPAN=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n";

return $table;
}
###########

##################
sub print_main_with_key{
my ($file_to_print,$to_string) = @_;

my $message;
if (@messages){
	foreach (@messages){
		$message .= "<CENTER>$_</CENTER><BR>";
	}
}
push (@substitutions,"\\[MESSAGE\\],-,$message");

my $menu_bar = &get_menu_bar;
   push (@substitutions,"\\[MENU_BAR\\],-,$menu_bar");

my $extra_head = ($current_page=~/^main$|^monitor$/)? "<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"180;\">" : " ";
   push (@substitutions,"<EXTRA_HEAD>,-,$extra_head");

my $unique = &get_unique_events_count;
   push (@substitutions,"\\[UNIQUE_EVENTS_COUNT\\],-,$unique");
my $total = &get_total_events_count;
   push (@substitutions,"\\[TOTAL_EVENTS_COUNT\\],-,$total");

my $table = &get_proto_stats_table;
   push (@substitutions,"<_STATS_>,-,$table");
return &print_with_key($file_to_print,$to_string);
}
##################
sub print_mini_me{
my $table;

my $stats_table = &get_proto_stats_table;
my $bgcolor;
my $linkcolor;

$bgcolor = "#080E19";
#$linkcolor = "#CCCCFF";
$linkcolor = "#FF9900";

my $body_focus = ($recent_alert) ? " onload=\"window.focus();startBlink();\" " : " startBlink(); ";
$table =<< "EOF";
<HTML>
<HEAD>
<TITLE>Mini View</TITLE>
<style type="text/css">
<!--
td { font-family: Arial, Helvetica, sans-serif; font-size: 8pt; font-weight: normal }
A:link    {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: none; color: $linkcolor }
A:visited {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: none; color: $linkcolor}
A:hover   {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: underline; color: yellow}
form { margin-bottom: 0}
-->
</style>
<META HTTP-EQUIV="REFRESH" CONTENT="180;">
<script LANGUAGE="JavaScript1.1">
<!--//Begin
function close_me(){
 	if (window.big_poppa != null){
		window.big_poppa.location.reload();
		window.big_poppa.focus();
	} else {
		notorious=window.open('$home_url','big_poppa');
		notorious.focus();
	}
		window.close();
}

// End -->
</script>
</HEAD>
<body bgcolor=$bgcolor text=white link=$linkcolor vlink=$linkcolor alink=red marginwidth=0 marginheight=0 topmargin=0 leftmargin=0 rightmargin=0 border=0 $body_focus>
EOF
$table .= "<center>";
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=145><TR><TD>";
$table .= $stats_table;
$table .= "</TD></TR>\n</TABLE>\n";
$table .= "</center>";
$table .= "</BODY></HTML>";
&print_header;
print $table;

}
######################
sub print_with_key{
my ($file_to_print,$to_string,$about_to_print) = @_;
my $sub;
my @arrayed;


if (!$to_string){
    &print_header;
}

my $linkcolor;
#$linkcolor = "#CCCCFF";
$linkcolor = "#FF9900";

push (@substitutions,"\\[LINKCOLOR\\],-,$linkcolor");

   #my $ltime=localtime();
   my $ltime=format_localtime();
   push (@substitutions,"\\[DATESTAMP\\],-,$ltime");
   push (@substitutions,"\\[PROGRAM_NAME\\],-,$program_name");
   push (@substitutions,"\\[PROGRAM_VERSION\\],-,$program_version");
   push (@substitutions,"\\[HOME_URL\\],-,$v_base_path/$this_program");
   push (@substitutions,"\\[G_P\\],-,$v_graphics_path");
   push (@substitutions,"\\[FOOTER\\],-,<A HREF=\"$home_url?td=about\">$footer_string</A>");

if (!$about_to_print){
   open (KEYED, "$file_to_print") || die "Can't Open $file_to_print: $!\n";
	#load the file into one string
	   while (<KEYED>){
	        $about_to_print .= $_;
	   }
	   close KEYED;
}

#do one pass through the file for each variable that needs to be sub-ed
 foreach $sub(@substitutions){
                @arrayed=split(/,-,/,$sub);
                $about_to_print=~s/$arrayed[0]/$arrayed[1]/g;
        }
=head
#DEBUG FOR SCREENSHOTS
$about_to_print=~s/\d{1,3}\.\d{1,3}(\.\d{1,3}\.\d{1,3})/192.168$1/g;
#BAD ASS REGEX FOLLOWS:
$about_to_print=~s/A HREF\s*=\s*\"[\s\S]+?\"/a href=\'javascript:alert(\"Mockup version... links do not work!\");\'/g;
$about_to_print=~s/101freeway/your_domain/ig;
$about_to_print=~s/101freeway/your_domain/ig;
=cut

if (!$to_string){
       print $about_to_print;
}
else{
    return $about_to_print;
}
}
###########################
sub print_about{

my $about_text = << 'EOF';

<table width="80%" border="0" cellspacing="0" cellpadding="6" align="center">
  <tr> 
    <td colspan="2">
      <h1>demarc -</h1>
    </td>
  </tr>
  <tr> 
    <td width="20">&nbsp;</td>
    <td><font size="+1">A demarc (an abbreviation for demarcation point) marks 
      the point where communications facilities owned by one organization interface 
      with that of another organization. In telephone terminology, this is the 
      interface between customer-premises equipment and network service provider 
      equipment. </font></td>
  </tr>
</table>
<p>&nbsp;</p>
<table width="80%" border="0" cellspacing="0" cellpadding="6" align="center">
  <tr align="center"> 
    <td><font face="Arial, Helvetica, sans-serif"><a href="mailto:info@demarc.org">info@demarc.org</a></font></td>
  </tr>
</TABLE>
EOF


push (@substitutions,"\\[MAIN_TABLE\\],-,$about_text");
&print_main_with_key($main_template);
}
###########################
sub get_proto_stats_table{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $db_ptr_2;
my $hash_ref_2;
my $table;
my $total_count;
my $icmp_count;
my $tcp_count;
my $udp_count;
my $other_count;
my $icmp_percent;
my $tcp_percent;
my $udp_percent;
my $other_percent;
my $max_width = 42;
my $title_color = "#003F92";
#my $inner_color = "#000033";
my $inner_color = "#021439";
my $newest_proto = "Other";
my $alert_bg = "#FFFFFF";
my $alert_link;
my $mini_me_target;
my $cached_expire_seconds;

if (($current_page ne "mini_me") && $use_cache){
	($table,$cached_expire_seconds) = &recent_cached_copy('side_menu',$allowed_cache_minutes);
	if ($table){
		$cached_expire_seconds = ($allowed_cache_minutes * 60) - $cached_expire_seconds;
		$table =~s/Quick Stats\s*<\/B>/Quick Stats <\/B><BR>\(cached, exp in $cached_expire_seconds secs\)/;
		$recent_alert = 1 if ($table=~/<RECENT_ALERT>/);
		$recent_alert = 2 if ($table=~/<RECENT_ALERT_WARN>/);
		return $table;
	}
}

$mini_me_target = " TARGET=big_poppa " if ($current_page eq "mini_me");

# Total:
$total_count = &count_total_records;
($total_count) || ($total_count = "0");#Pretty view if 0 records

# TCP:
$sql_query = "SELECT count(*) as count FROM tcphdr";
$db_ptr = &run_query($sql_query);
$tcp_count = ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'count'} : 0;

# UDP:
$sql_query = "SELECT count(*) as count FROM udphdr";
$db_ptr = &run_query($sql_query);
$udp_count = ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'count'} : 0;

# ICMP:
$sql_query = "SELECT count(*) as count FROM icmphdr";
$db_ptr = &run_query($sql_query);
$icmp_count = ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'count'} : 0;

$other_count = $total_count - ($icmp_count + $tcp_count + $udp_count);

$tcp_percent =  ($total_count) 
			? &round(($tcp_count/$total_count)*100)
			: 0 ;
$udp_percent =  ($total_count)
			? &round(($udp_count/$total_count)*100)
			: 0;
$icmp_percent =  ($total_count)
			? &round(($icmp_count/$total_count)*100)
			: 0;
$other_percent =  ($total_count)
			? &round(($other_count/$total_count)*100)
			:0;

#Now make the table:
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=1  WIDTH=\"100%\">\n<TR><TD BGCOLOR=\"#CB9400\">";
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 BGCOLOR=\"#426286\" WIDTH=\"100%\">\n<TR><TD BGCOLOR=\"#426286\">";
$table .= "<TABLE BORDER=0 CELLSPACING=2 CELLPADDING=0 WIDTH=\"100%\" BGCOLOR=\"#426286\">\n";

$table .= "<TR bgcolor=\"$title_color\"><TD COLSPAN=2 ALIGN=center>";
my $ltime = &format_localtime();


$table .= "<B>Quick Stats</B></TD></TR>\n";
$table .= "<TR bgcolor=\"#021439\"><TD colspan=2 align=center>$ltime</TD></TR>\n";

#Get info on last event
# First add needed priority clause:
my $priority_where = " (signature.sig_name RLIKE 'P-[$alert_priority_levels]-.*') ";
if ($alert_priority_levels=~/$default_priority_level/){
	$priority_where = "( $priority_where OR !(signature.sig_name RLIKE 'P-[$priority_levels]-.*')) ";
}



$sql_query = "	SELECT \
						max(timestamp) AS LAST, \
						(TO_DAYS(NOW()) - TO_DAYS(MAX(timestamp))) AS DAYS_SINCE, \
						((TIME_TO_SEC(NOW()) - TIME_TO_SEC(MAX(timestamp)))/60) AS MINUTE_DIFF \
					FROM event,signature \ 
					WHERE signature.sig_id = event.signature AND $priority_where \
					LIMIT 1";


$db_ptr = &run_query($sql_query);
$hash_ref = $db_ptr->fetchrow_hashref;

$sql_query = "	SELECT \
						event.sid,event.cid,sig_name, \ 
						tcp_sport, icmp_type, udp_sport,signature.sig_name \
					FROM \
						event\
							LEFT JOIN tcphdr ON ((event.sid = tcphdr.sid) AND (event.cid = tcphdr.cid)) \
                     LEFT JOIN icmphdr ON ((event.sid = icmphdr.sid) AND (event.cid = icmphdr.cid)) \
                     LEFT JOIN udphdr ON ((event.sid = udphdr.sid) AND (event.cid= udphdr.cid)) \
         				LEFT JOIN signature ON (event.signature = signature.sig_id) \
					WHERE\
						timestamp = '$$hash_ref{'LAST'}' AND $priority_where \
					LIMIT 1"; #LIMIT is just in case there were two at the same timestamp


$db_ptr_2 = &run_query($sql_query);
$hash_ref_2 = $db_ptr_2->fetchrow_hashref;


if ($$hash_ref_2{'tcp_sport'}){
		$newest_proto = "TCP";
}
elsif ($$hash_ref_2{'udp_sport'}){
		$newest_proto = "UDP";
}
elsif ($$hash_ref_2{'icmp_type'}){
		$newest_proto = "ICMP";
}

my $alert_link .= "$home_url?td=view_payload&sid=$$hash_ref_2{'sid'}&cid=$$hash_ref_2{'cid'}"; 

$table .= "<TR><TD COLSPAN=2 ALIGN=center BGCOLOR=$title_color>";
$table .= "<B>Last NIDS Alert:</B></TD></TR>\n";

$table .= "<TR><TD align=center colspan=2 bgcolor=\"RECENT_COLOR\" onMouseOver=\"this.style.cursor='hand';window.status='View Latest Alert';this.style.backgroundColor='red';return true\" onMouseOut=\"this.style.cursor='auto';this.style.backgroundColor='RECENT_COLOR';window.status='';return true\">";

if ($$hash_ref{'DAYS_SINCE'}){
	$table .= "$$hash_ref{'DAYS_SINCE'} days ago";
}
else{
$table .= "<FONT COLOR=\"$alert_bg\">";

	if ($$hash_ref{'MINUTE_DIFF'} > 60){
		my $hours 	= int($$hash_ref{'MINUTE_DIFF'}/60);
		my $minutes	= ($$hash_ref{'MINUTE_DIFF'}%60);
		$table .= "$hours hr $minutes min ago";
	}
	else{
		# for making page color red / yellow
		if ($$hash_ref{'MINUTE_DIFF'} < 10){
			if (($high_alert_level==$default_priority_level) || ($$hash_ref_2{'sig_name'}=~/^P-$high_alert_level-/)){
				$recent_alert = 1;
				$table .= "\n<BLINK><B>$$hash_ref{'MINUTE_DIFF'} minutes ago</B></BLINK><RECENT_ALERT>\n";
			}
			else{
				$recent_alert = 2;
				$table .= "\n<B>$$hash_ref{'MINUTE_DIFF'} minutes ago</B><RECENT_ALERT_WARN>\n";
			}
		}
		else{
			$table .= "$$hash_ref{'MINUTE_DIFF'} minutes ago";
		}
	}
$table .= "</FONT>";
}
if ($recent_alert == 1){
#red
	$table =~s/RECENT_COLOR/#990000/g;
	$alert_link = "class=alert"
		if ($newest_proto ne "Other");
}
elsif ($recent_alert == 2){
#orange   
	$table =~s/RECENT_COLOR/#CC6600/g; # I breaka you fingas
	$alert_link = "class=alert" 
		if ($newest_proto ne "Other");
}
else{
#orange   
#green
   	$table =~s/RECENT_COLOR/#000033/g;
		$alert_link = "";
}
#truncated signature:
$table .= "<BR>";
#$table .= "</TD></TR>\n<TR><TD bgcolor=\"#021439\" colspan=2>";
$table .= "<FONT COLOR=\"$alert_bg\">";
$table .= "$newest_proto\: </FONT>";
$table .= "<A HREF=\"$home_url?td=view_payload&sid=$$hash_ref_2{'sid'}&cid=$$hash_ref_2{'cid'}\" $mini_me_target style=\"color:#FFFF00;\">" 
	if ($newest_proto ne "Other");

$table .= ($$hash_ref_2{'sig_name'}=~/(^.{40})/) ? "$1..." : $$hash_ref_2{'sig_name'};
$table .= "</A>" 
	if ($newest_proto ne "Other");
	
$table .= "</TD>";


$table .= "</TR>\n";

# Monitored host minimum table
$table .= "<TR><TD COLSPAN=2 ALIGN=center BGCOLOR=$title_color>";
$table .= "<B>Monitored Hosts</B></TD></TR>\n";
if ($downed_hosts_array_ref && @$downed_hosts_array_ref){
	my $downed_host_count;
	foreach (@$downed_hosts_array_ref){
		if ($downed_host_count++ > 3){
			$table .= "<TR><TD COLSPAN=2 ALIGN=center BGCOLOR=\"$inner_color\">";
			$table .= "<A HREF=\"$home_url?td=view_monitoring_page\" $mini_me_target><B>More...</B></A>";
			$table .= "</TD></TR>\n";
			last;
		}
		my @host_breakdown = split(/,-,/,$_);
		my $link = "$home_url?td=view_monitored_host&long_ip=$host_breakdown[2]&service=" . &linkify($host_breakdown[3]);
		$table .= "<TR><TD ALIGN=right BGCOLOR=\"$inner_color\">";
		$table .= "$host_breakdown[1] - <A HREF=\"$link\" $mini_me_target>$host_breakdown[3]</A>";
		$table .= "</TD><TD ALIGN=center BGCOLOR=\"$inner_color\">";
#push (@man_down,"$current_group,-,$$hosts_ref[$i],-,$$ips_ref[$i],-,$_,$status");
		$table .= "<A HREF=\"$link\" $mini_me_target>$host_breakdown[4]</A>";
		$table .= "</TD></TR>\n";
	}
}
else{
	$table .= "<TR><TD ALIGN=left BGCOLOR=$inner_color>";
	$table .= "All monitored hosts</TD>";
	$table .= "<TD ALIGN=center BGCOLOR=$inner_color><A HREF=\"$home_url?td=view_monitoring_page\" $mini_me_target>";
	$table .= &color_code("GREEN");
	$table .= "</A></TD></TR>\n";
}

# MD5 minimum display

my @md5_min = &get_minimum_md5_alert_status;
$table .= "<TR><TD COLSPAN=2 ALIGN=center BGCOLOR=$title_color>";
$table .= "<B>Monitored Files</B></TD></TR>\n";
if (@md5_min){
	my $c2;
	foreach (@md5_min){
		if ($c2++ >= 4){
			$table .= "<TR><TD ALIGN=center COLSPAN=2 BGCOLOR=$inner_color><A HREF=\"$home_url?td=view_md5_page&minimal=1\" $mini_me_target>";
			$table .= "more...</A></TD></TR>";
			last;
		}
		my @split_a = split(/\;/,$_);
		$table .= "<TR><TD BGCOLOR=$inner_color>&nbsp;<A HREF=\"$home_url?td=view_md5_page&minimal=1\" $mini_me_target>";
		$table .= "$split_a[0]</a></TD>";
		$table .= "<TD ALIGN=center BGCOLOR=$inner_color><A HREF=\"$home_url?td=view_md5_page&minimal=1\" $mini_me_target>";
		$table .= "$split_a[1]</A></TD></TR>";
	}
}
else{
         $table .= "<TR><TD ALIGN=left BGCOLOR=$inner_color>All monitored files</TD>";
			$table .= "<TD ALIGN=center BGCOLOR=$inner_color><A HREF=\"$home_url?td=view_md5_page\" $mini_me_target>";
			$table .= &color_code("GREEN");
         $table .= "</A></TD></TR>";
}
		

#$table .= "<TR><TD COLSPAN=2 ALIGN=center>" . &get_hourly_stats(target => $mini_me_target) . "</TD></TR>\n";
$table .= &get_hourly_stats(target => $mini_me_target);


$table .= &get_sensor_stats(target => $mini_me_target);


# Title it:
$table .= "<TR><TD COLSPAN=2 ALIGN=center bgcolor=\"$title_color\"><B>Protocol Breakdown</B></TD></TR>\n";
# TCP first
$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
$table .= "TCP  ";
$table .= "<A HREF=\"$home_url?td=show_events&tcp=tcp&limit=$default_limit\" $mini_me_target>";
$table .= "($tcp_percent%)</A></TD>";
$table .= "<TD bgcolor=\"$inner_color\">";
$table .= "<A HREF=\"$home_url?td=show_events&tcp=tcp&limit=$default_limit\" $mini_me_target>";
$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"" . &round(($tcp_percent/100)*$max_width) . "\"><IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 height=20 width=4></A></TD></TR>\n";

# UDP
$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
$table .= "UDP  ";
$table .= "<A HREF=\"$home_url?td=show_events&udp=udp&limit=$default_limit\" $mini_me_target>";
$table .= "($udp_percent%)</A></TD>";
$table .= "<TD bgcolor=\"$inner_color\">";
$table .= "<A HREF=\"$home_url?td=show_events&udp=udp&limit=$default_limit\" $mini_me_target>";
$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" height=20 border=0 width=\"" . &round(($udp_percent/100)*$max_width) . "\"><IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 height=20 width=4></A></TD></TR>\n";

# ICMP
$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
$table .= "ICMP  ";
$table .= "<A HREF=\"$home_url?td=show_events&icmp=icmp&limit=$default_limit\" $mini_me_target>";
$table .= "($icmp_percent%)</A></TD>";
$table .= "<TD bgcolor=\"$inner_color\">";
$table .= "<A HREF=\"$home_url?td=show_events&icmp=icmp&limit=$default_limit\" $mini_me_target>";
$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" height=20 border=0 width=\"" . &round(($icmp_percent/100)*$max_width) . "\"><IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 height=20 width=4></A></TD></TR>\n";

# OTHER (portscans)
$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
$table .= "SCANS  ";
$table .= "<A HREF=\"$home_url?td=show_events&other=other&limit=$default_limit\" $mini_me_target>";
$table .= "($other_percent%)</A></TD>";
$table .= "<TD bgcolor=\"$inner_color\">";
$table .= "<A HREF=\"$home_url?td=show_events&other=other&limit=$default_limit\" $mini_me_target>";
$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"" . &round(($other_percent/100)*$max_width) . "\"><IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 height=20 width=4></A></TD></TR>\n";


### Top offenders src_ip:
$sql_query = "	SELECT \
						count(*) AS COUNT,event.sid,ip_src,ip_dst \
					FROM \
						event \
							LEFT JOIN iphdr ON ((event.sid = iphdr.sid) AND \
							(event.cid = iphdr.cid)) \
					WHERE \
						(ip_src IS NOT NULL) AND \
						(ip_dst IS NOT NULL) \
					GROUP BY ip_src \
					ORDER BY COUNT DESC \
					LIMIT 6";
$db_ptr 		= &run_query($sql_query);
$table .= "<TR bgcolor=\"$title_color\"><TD colspan=2 ALIGN=center>";
$table .= "<B>Top 6 Src IPs</B>";
$table .= "</TD></TR>\n";
my $src_ip_count = 0;
while ($hash_ref   = $db_ptr->fetchrow_hashref){
	$src_ip_count++;
	$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
	my $src_ip = &convert_long_ip($$hash_ref{'ip_src'});
	$table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&src_ip=$src_ip\" $mini_me_target>";
	$table .= "$src_ip</A></TD><TD align=center bgcolor=\"$inner_color\">($$hash_ref{'COUNT'})</TD></TR>\n";
}
$table .= "<TR><TD bgcolor=\"$inner_color\" align=center colspan=2>No Results</TD></TR>\n" if (!$src_ip_count);

### Top offenders dst_ip:
$sql_query = "	SELECT \
						count(*) AS COUNT,event.sid,ip_src,ip_dst \
					FROM \
						event \
							LEFT JOIN iphdr ON ((event.sid = iphdr.sid) AND \
							(event.cid = iphdr.cid)) \
					WHERE \
						(ip_src IS NOT NULL) AND \
						(ip_dst IS NOT NULL) \
					GROUP BY ip_dst \
					ORDER BY COUNT DESC \
					LIMIT 6";
$db_ptr 		= &run_query($sql_query);
$table .= "<TR bgcolor=\"$title_color\"><TD colspan=2 ALIGN=center>";
$table .= "<B>Top 6 Dst IPs</B>";
$table .= "</TD></TR>\n";
my $src_ip_count = 0;
while ($hash_ref   = $db_ptr->fetchrow_hashref){
	$src_ip_count++;
	$table .= "<TR bgcolor=\"$inner_color\"><TD>&nbsp;";
	my $dst_ip = &convert_long_ip($$hash_ref{'ip_dst'});
	$table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&dst_ip=$dst_ip\" $mini_me_target>";
	$table .= "$dst_ip</A></TD><TD align=center>($$hash_ref{'COUNT'})</TD></TR>\n";
}
$table .= "<TR><TD bgcolor=\"$inner_color\" align=center colspan=2>No Results</TD></TR>\n" if (!$src_ip_count);
$table .= "<TR bgcolor=\"$title_color\"><TD COLSPAN=2 ALIGN=center><A HREF=\"$home_url\" target=\"big_poppa\" onClick=\"close_me();return false;\"  style=\"color:yellow\"><B>Main Screen</B></A></TD></TR>\n" if ($mini_me_target);

if ($current_page ne "mini_me"){
$table .= "<TR><TD bgcolor=\"$title_color\" align=center colspan=2>";
$table .= << "EOF";
<A HREF="$home_url?td=mini_me" target="MiniMe" onClick="load_mini_me();return false;" style="color:yellow;"><B>Mini View</B></A>
</TD></TR>
EOF
}


$table .= "</TABLE>\n";
$table .= "</TD></TR>\n</TABLE>\n";
$table .= "</TD></TR>\n</TABLE>\n";

if (($current_page ne "mini_me") && $use_cache){
	#update the cached version of the side menu if we're cacheing
	&update_cache('side_menu',$table);
}
return $table;
}
#######################
sub round {
    my($number,$lt_rule) = @_;
	my $num = int($number + .5);
	return $num if ($num > 1);
	if ($lt_rule){
		return "<1";
	}
	return "0";
}
#######################
sub unique_events_since{
my ($offset_type,$offset_number,$limit_rows) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $count;
my $inner_color = "#000000";

($offset_number=~/^\d+$/) || ($offset_number=1); #default offset if none passed
($offset_type=~/^day$|^hour$/) || ($offset_type="day"); #default type to day

$sql_query = "	SELECT \
						count(*) as COUNT,max(timestamp) as max,\ 
						min(timestamp) as min,event.sid,hostname,sig_name as signature \
					FROM event\
 						LEFT JOIN sensor \
							ON (sensor.sid = event.sid)  \
						LEFT JOIN signature \
							ON (event.signature = signature.sig_id) \
					WHERE \
						timestamp >= date_add(now(),interval -$offset_number $offset_type) \
					GROUP BY signature,sid \
					ORDER BY COUNT DESC";


$db_ptr = &run_query($sql_query);
#($hash_ref = $db_ptr->fetchrow_hashref) || return "No records returned for that time period";

$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">\n";
$table .= "<TR bgcolor=\"#003366\"><TD background=\"$v_graphics_path/bg_title.gif\" colspan=5 align=center>";
$table .= "<B>Unique Events in the past $offset_number $offset_type</B>";
$table .= "</TD></TR>\n";
$table .= "<TR bgcolor=\"#244A75\"><TD align=center><B>Freq</B></TD>";
$table .= "<TD align=center><B>Signature</B></TD>";
$table .= "<TD align=center><B>Sensor</B></TD>";
$table .= "<TD align=center><B>First Event</B></TD>";
$table .= "<TD align=center><B>Last Event</B></TD>";
$table .= "</TR>\n";

while ($hash_ref = $db_ptr->fetchrow_hashref){
	$count++;
	if ($limit_rows && ($count >= $limit_rows)){
	#	$table .= "<TR bgcolor=\"#001E4B\"><TD align=center COLSPAN=5>";
	#	$table .= "<A HREF=\"$home_url?td=unique_events_since&offset_type=day&offset_number=1\">";
	#	$table .= "<B>More...</B>";
	#	$table .= "</A>";
	#	$table .= "</TD></TR>\n";
		last;
	}
#=cut
	$table .= "<TR bgcolor=\"#001E4B\"><TD align=center>$$hash_ref{'COUNT'}</TD>";
	$table .= "<TD>&nbsp;";
	$table .= "<A HREF=\"$home_url?td=show_events&sid=$$hash_ref{'sid'}&limit=30&offset_type=$offset_type&offset_number=$offset_number&signature=" . &linkify($$hash_ref{'signature'}) . "\">";
	$table .= "$$hash_ref{'signature'}";
	$table .= "</A>";
	$table .= "</TD>";
	$table .= "<TD align=center>$$hash_ref{'hostname'}</TD>";
	$$hash_ref{'min'}=~s/:\d\d$//;
	$$hash_ref{'min'}=~s/^\d{4}\-//;
	$$hash_ref{'min'}=~s/(\d\d\-\d\d) (\d\d:\d\d)/$2 $1/;
	$table .= "<TD align=center>$$hash_ref{'min'}</TD>";
	$$hash_ref{'max'}=~s/:\d\d$//;
	$$hash_ref{'max'}=~s/^\d{4}\-//;
	$$hash_ref{'max'}=~s/(\d\d\-\d\d) (\d\d:\d\d)/$2 $1/;
	$table .= "<TD align=center>$$hash_ref{'max'}</TD>";
	#$table .= "<TD align=center>$$hash_ref{''}</TD>";
	$table .= "</TR>\n";
}

if (!$count){
	$table .= "<TR><TD align=center colspan=5>";
	$table .= "<B>No records returned for that time period</B></TR>\n";
}
$table .= "<FORM ACTION=\"$home_url\" METHOD=POST>\n";
$table .= "<TR bgcolor=\"#001E4B\"><TD align=center colspan=5>";
$table .= "<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=\"100%\">";
$table .= "<TR bgcolor=\"#001E4B\"><TD align=center><B>";
$table .= "Unique Events/sensor in the past";
$table .= ($offset_number>1)? "s" : "";
$table .= "</B>";
$table .= << "EOF";
<INPUT TYPE=hidden NAME=td VALUE=unique_events_since>
<SELECT NAME=offset_number style="font-size:8pt;">
<OPTION SELECTED>$offset_number</OPTION>
<OPTION>1</OPTION>
<OPTION>2</OPTION>
<OPTION>3</OPTION>
<OPTION>4</OPTION>
<OPTION>5</OPTION>
<OPTION>6</OPTION>
<OPTION>7</OPTION>
<OPTION>8</OPTION>
<OPTION>9</OPTION>
<OPTION>10</OPTION>
<OPTION>11</OPTION>
<OPTION>12</OPTION>
<OPTION>13</OPTION>
<OPTION>14</OPTION>
<OPTION>15</OPTION>
<OPTION>16</OPTION>
<OPTION>17</OPTION>
<OPTION>18</OPTION>
<OPTION>19</OPTION>
<OPTION>20</OPTION>
<OPTION>21</OPTION>
<OPTION>22</OPTION>
<OPTION>23</OPTION>
<OPTION>24</OPTION>
</SELECT>
<SELECT NAME=offset_type  style="font-size:8pt;">
EOF
if ($offset_type=~/hour/){
   $table .= "<OPTION value=hour selected>Hours</OPTION>";
}
else{
   $table .= "<OPTION value=day selected>Days</OPTION>";
}
$table .= << "EOF";
<OPTION value=day>Days</OPTION>
<OPTION value=hour>Hours</OPTION>
</SELECT>
<INPUT TYPE=Submit Name=Submit Value=Go style="font-size:8pt;">
EOF
$table .= "</TD>";
$table .= "<TD ALIGN=right>";
	if ($current_page eq "main"){
      $table .= "<A HREF=\"$home_url?td=unique_events_since&offset_type=day&offset_number=1\">";
      $table .= "<B>More...</B></A> &nbsp; &nbsp;";
	}
	else{
		$table .= "&nbsp;";
	}
$table .= "</TD></TR>\n";
$table .= "</FORM>";
$table .= "</TABLE>\n";
$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"#003366\" COLSPAN=5><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
$table .= "</TABLE>\n";


return $table;
}
#######################
sub linkify{
my ($st) = @_;
	$st=~s/\s/%20/g;
return $st;
}
######################
sub query_arin{
my ($host) = @_;
my $result;
my $p;


	# show what we looked up
	$result .= "<CENTER><B>whois $host</B></CENTER><P>";

	#No exploit here thank you very much
	$host=~tr/a-zA-Z0-9\.\-\_//dc;

if ($system_type=~/^linux$/i){
	$result .= `$whois_command $host\@whois.arin.net`;
}
else{
	#default to BSD style
	$result .= `$whois_command -a $host`;
}

	# Add links for further queries
	$result=~s/\((.{4,}?)\)/<A HREF=\"$home_url\?td=arin_whois&ip=$1\">\($1\)<\/A>/g;
	# add mailto: tags
	$result=~s/\s(\S+?\@\S+?\.\w{2,4})\s/<A HREF="mailto:$1">$1<\/A>/g;
	$result=~s/\n/<BR>\n/g;
push (@substitutions,"\\[MAIN_TABLE\\],-,$result");
&print_main_with_key($main_template);
	
}
##############
sub get_hourly_stats{
# Get stats for the last 6 hours
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my %hours_hash;
my %yesterday_hours_hash;
my $current_hour;
my @last_6_hours;
my $yesterday;
my $max_height=30;
my $max_value;
my $row1;
my $row2;
my $table;
my $title_color = "#003F92";
my $inner_color = "#021439";

$sql_query = "	SELECT \
						count(*) AS COUNT,\
						EXTRACT(HOUR FROM timestamp) AS HOURS, \
						EXTRACT(HOUR FROM NOW()) AS NOW \
					FROM \
						event \
					WHERE \
						TO_DAYS(timestamp) = TO_DAYS(NOW()) \
					GROUP BY  \
						HOURS";

$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	$hours_hash{$$hash_ref{'HOURS'}} = $$hash_ref{'COUNT'};
	$current_hour = $$hash_ref{'NOW'} if (!$current_hour);
}
if ($current_hour <= 6){
$sql_query = " SELECT \
                  count(*) AS COUNT,\
                  EXTRACT(HOUR FROM timestamp) AS HOURS \
               FROM \
                  event \
               WHERE \
                  TO_DAYS(timestamp) = TO_DAYS(DATE_ADD(NOW(), INTERVAL -1 DAY)) \
               GROUP BY  \
                  HOURS";	
$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
   $yesterday_hours_hash{$$hash_ref{'HOURS'}} = $$hash_ref{'COUNT'};
}
}

for (1..6){
	push (@last_6_hours,"$current_hour");
	$current_hour--;
	$current_hour = 23 if ($current_hour < 0);
}


# Do a run through just to get the max value:
for (my $i=0;$i<(@last_6_hours);$i++){
   if ((!$yesterday) && ($i>0) && ($last_6_hours[$i] > $last_6_hours[($i - 1)])){
      $yesterday = 1;
   }
   if (!$yesterday){
		$max_value = $hours_hash{$last_6_hours[$i]} if ($hours_hash{$last_6_hours[$i]} > $max_value);
   }
   else{
		$max_value = $yesterday_hours_hash{$last_6_hours[$i]} if ($yesterday_hours_hash{$last_6_hours[$i]} > $max_value);
   }

}


$yesterday = ();#Reset for the "real deal"


for (my $i=0;$i<(@last_6_hours);$i++){
	if ((!$yesterday) && ($i>0) && ($last_6_hours[$i] > $last_6_hours[($i - 1)])){
		$yesterday = 1;
	}
# Get date info from DB call to avoid problems at start of mon/day/yr:
$sql_query = "	SELECT \
						EXTRACT(MONTH FROM DATE_ADD(NOW(), INTERVAL -$i HOUR)) AS MONTH, \
						EXTRACT(DAY FROM DATE_ADD(NOW(), INTERVAL -$i HOUR)) AS DAY, \
						EXTRACT(YEAR FROM DATE_ADD(NOW(), INTERVAL -$i HOUR)) AS YEAR, \
						EXTRACT(MONTH FROM DATE_ADD(NOW(), INTERVAL (-$i+1) HOUR)) AS MONTH_F, \
						EXTRACT(DAY FROM DATE_ADD(NOW(), INTERVAL (-$i+1) HOUR)) AS DAY_F, \
						EXTRACT(YEAR FROM DATE_ADD(NOW(), INTERVAL (-$i+1) HOUR)) AS YEAR_F \

";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || &error("Error retrieving date information");
my $year 	= $$hash_ref{'YEAR'};
my $month	= $$hash_ref{'MONTH'};
my $day		= $$hash_ref{'DAY'};
my $hour		= $last_6_hours[$i];
my $year_f 	= $$hash_ref{'YEAR_F'};
my $month_f	= $$hash_ref{'MONTH_F'};
my $day_f	= $$hash_ref{'DAY_F'};
my $hour_f	= ($last_6_hours[$i]+1);
$hour_f = 0 if ($hour_f == 24);


	if (!$yesterday){
		my $row1_temp;
		my $temp_link = "<A HREF=\"$home_url?td=show_events&limit=30&yr_s=$year&mon_s=$month&day_s=$day&hr_s=$hour&yr_f=$year_f&mon_f=$month_f&day_f=$day_f&hr_f=$hour_f\" $args{'target'} >";
		$row1_temp .= "<TD valign=bottom align=left bgcolor=\"$inner_color\" WIDTH=40 NOWRAP>";

		$row1_temp .= $temp_link;
		$row1_temp .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"";
		$row1_temp .= (($max_value) && ($hours_hash{$last_6_hours[$i]})) ? 
				&round( ($hours_hash{$last_6_hours[$i]}/$max_value) * $max_height) : "1";
		$row1_temp .= "\">";
		$row1_temp .= "<IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 width=4 height=20>";
#		$hours_hash{$last_6_hours[$i]}=~s/(^\d+)(\d)\d\d$/$1\.$2k/;
		$row1_temp .= "</A></TD>";

		my $hour = $last_6_hours[$i];
		#$hour = ($hour > 12) ? ($hour-12) . " PM" : "$hour AM";
		if ($hour==0){
				$hour = "12 AM";
		}
		elsif($hour < 12){
				if ($hour < 10){
					$hour = "&nbsp;$hour AM";
				}
				else{
					$hour = "$hour AM";
				}
		}
		elsif($hour == 12){
				$hour = "12 PM";
		}
		else{
				if ($hour < 22){
					$hour = "&nbsp;".($hour-12)." PM";
				}
				else{
					$hour = ($hour-12) . " PM";
				}
		}

		$row1 .= "<TR><TD bgcolor=\"$inner_color\">$hour ". $temp_link ;
		$row1 .= ($hours_hash{$last_6_hours[$i]})? "($hours_hash{$last_6_hours[$i]})" : "(0)";
		$row1 .= "</A></TD>$row1_temp</TR>\n";
		
	}
	else{
		my $row1_temp;
		my $temp_link = "<A HREF=\"$home_url?td=show_events&limit=30&yr_s=$year&mon_s=$month&day_s=$day&hr_s=$hour&yr_f=$year_f&mon_f=$month_f&day_f=$day_f&hr_f=$hour_f\" $args{'target'} >";
		$row1_temp .= "<TD align=left valign=bottom bgcolor=\"$inner_color\" WIDTH=40 NOWRAP>";
		$row1_temp .= $temp_link;
		$row1_temp .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"";
		$row1_temp .= (($max_value) && ($yesterday_hours_hash{$last_6_hours[$i]})) ? 
				&round( ($yesterday_hours_hash{$last_6_hours[$i]}/$max_value) * $max_height) : "1";
      $row1_temp .= "\">";
		$row1_temp .= "<IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 width=4 height=20>";
#		$yesterday_hours_hash{$last_6_hours[$i]}=~s/(^\d+)(\d)\d\d$/$1\.$2k/;
      $row1_temp .= "</A></TD>";

		my $hour = $last_6_hours[$i];
		if ($hour==0){
				$hour = "12 AM";
		}
		elsif($hour < 12){
				if ($hour < 10){
					$hour = "&nbsp;$hour AM";
				}
				else{
					$hour = "$hour AM";
				}
		}
		elsif($hour == 12){
				$hour = "12 PM";
		}
		else{
				if ($hour < 22){
					$hour = "&nbsp;".($hour-12)." PM";
				}
				else{
					$hour = ($hour-12) . " PM";
				}
		}
		$row1 .= "<TR><TD  bgcolor=\"$inner_color\" ALIGN=left>$hour ". $temp_link ;
      $row1 .= ($yesterday_hours_hash{$last_6_hours[$i]})? "($yesterday_hours_hash{$last_6_hours[$i]})" : "(0)";
		$row1 .= "</A></TD>$row1_temp</TR>\n";
	}

}
$table .= "<TR><TD colspan=2 align=center bgcolor=\"$title_color\"><B>Alerts (Last 6 Hrs)</B></TD></TR>";
$table .= $row1;
return $table;
}
##############
sub get_sensor_stats{
# Get stats for alert %/sensor
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $max_height=30;
my $max_value;
my $table;
my %host_values;

$sql_query = "	SELECT hostname,COUNT(*) AS COUNT,event.sid \
					FROM event \
					LEFT JOIN sensor ON event.sid = sensor.sid \
					GROUP BY event.sid \
					ORDER BY COUNT";

$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
   $host_values{$$hash_ref{'sid'} ." - ". $$hash_ref{'hostname'}} = $$hash_ref{'COUNT'};
}


# Do a run through just to get the max value:
foreach (keys %host_values){
	$max_value = $host_values{$_} if ($host_values{$_} > $max_value);
}

# Now create the table (rows) for mini-view

foreach (sort(keys %host_values)){
	$table .= "<TR><TD align=left bgcolor=\"$row5_color\" WIDTH=40 NOWRAP>&nbsp;";
	$_=~/^(\d+)\s+\-\s+(.*)$/;
	my $sid 	= $1;
	my $host	= $2;
	$table .= "$host";
	$table .= "&nbsp;<A HREF=\"$home_url?td=show_events&limit=60&sid=$sid\" $args{'target'} >(";
	$table .= (($max_value) && ($host_values{$_}))
            ? &round( (($host_values{$_}/$max_value) * $max_height),"lt1") 
            : "0";
	$table .= "%)</A>";
	$table .= "</TD>";
	$table .= "<TD align=left valign=bottom bgcolor=\"$row5_color\">";
	$table .= "<A HREF=\"$home_url?td=show_events&limit=60&sid=$sid\" $args{'target'} >";
	$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"";
	$table .= (($max_value) && ($host_values{$_}))
				? &round( ($host_values{$_}/$max_value) * $max_height)
				: 1;
	$table .= "\">";
	$table .= "<IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 width=4 height=20>";
	$table .= "</A></TD></TR>";

}
$table = "<TR><TD colspan=2 align=center bgcolor=\"$row6_color\"><B>% Alerts/Sensor</B></TD></TR>" . $table;
return $table;
}
################
sub print_search{

	my $table = &get_search_form;
	my $sid_list = &get_sids_dropdown("sid");
	$table=~s/\[SID_LIST\]/$sid_list/;
	my $signatures_list = &get_signatures_dropdown("signature_is");
	$table=~s/\[SIGNATURE_LIST\]/$signatures_list/;

	push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
	&print_main_with_key($main_template);

}
#################
sub get_total_events_count{
my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = "SELECT count(*) AS COUNT FROM event";
$db_ptr = &run_query($sql_query);
return ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'COUNT'} : "0";
}
#################
sub get_unique_events_count{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $unique_count;
my $cached_expire_seconds;

if ($use_cache){
	($unique_count,$cached_expire_seconds) = &recent_cached_copy('unique_events',$allowed_long_cache_minutes);
}
if (!$use_cache || !$unique_count){
	$sql_query = "SELECT count(distinct signature) AS COUNT FROM event";
	$db_ptr = &run_query($sql_query);
	($hash_ref = $db_ptr->fetchrow_hashref) || return;
	$unique_count = $$hash_ref{'COUNT'};
}
&update_cache('unique_events',$unique_count) if ($use_cache);
return $unique_count;
}
#################
sub get_delete_table{
my ($args_ref) = @_;
my $table;

(&is_admin) || return;

$table .= "<FORM METHOD=POST ACTION=\"$home_url\">";
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\">\n<TR><TD ALIGN=center>";
$table .= "<INPUT TYPE=hidden NAME=td VALUE=delete>";
foreach (keys %$args_ref){
	$table .= "<INPUT TYPE=hidden NAME=\"$_\" VALUE=\"$$args_ref{$_}\">\n";
}
$table .= << "EOF";
<SELECT NAME=delete_type>
<OPTION VALUE=0>-Select Action-</OPTION>
<OPTION VALUE=limit>Delete only this page from this query</OPTION>
<OPTION VALUE=all>Delete all the results from this query</OPTION>
</SELECT>
<INPUT TYPE=Submit VALUE=Go style="font-size:8pt">
<p>
EOF

$table .= "</TD></TR>\n</TABLE>\n</FORM>\n";

return $table;
}
##################
sub delete_events{
my ($delete_array_ref) = @_;
my $sql_query;
my $db_ptr;

my @tables_array = ('data','event','icmphdr','tcphdr','udphdr','iphdr','opt');
foreach (@$delete_array_ref){
	my @temp_array = split(/,/,$_);
	foreach (@tables_array){
		$sql_query = "DELETE FROM $_ WHERE sid='$temp_array[0]' AND cid='$temp_array[1]'";
		$db_ptr = &run_query($sql_query);
	}
}

return 1;
}
###############
sub push_message{
my ($message) = @_;
	push (@messages,$message);
}
###########################
sub print_config{

my $table;

$table .= << "EOF";
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center>
<TR bgcolor="#003366">
<TD ALIGN=center COLSPAN=2 background="$v_graphics_path/bg_title.gif"><B>Configuration Menu</B></TD>
</TR>
<TR bgcolor="#001E4B">
<TD><br>&nbsp;<A HREF="$home_url?td=user_config"><b>Configure Users</b></A>&nbsp;<br><br></TD>
<TD>Configuration of DEMARC users/admins.</TD>
</TR>
<TR bgcolor="#001E4B">
<TD><br>&nbsp;<A HREF="$home_url?td=config_sid_menu"><b>Configure Sensor's Snort Rules</b></A>&nbsp;<br><br></TD>
<TD WIDTH=300>Allows you to remotely configure snort conf/rules <BR>(assuming DEMARC client is running on sensor).</TD>
</TR>
<TR bgcolor="#001E4B">
<TD><br>&nbsp;<A HREF="$home_url?td=add_monitoring_event"><b>Add Host/Service Monitoring Event</b></A>&nbsp;<br><br></TD>
<TD>Add services/hosts for DEMARC to monitor.</TD>
</TR>
<TR bgcolor="#001E4B">
<TD><br>&nbsp;<A HREF="$home_url?td=md5_config_select"><b>Configure File Integrity Check</b></A>&nbsp;<br><br></TD>
<TD>Configure File Integrity Checks on a per sensor basis<BR>(assuming DEMARC client is running on sensor).</TD>
</TR>
<TR bgcolor="#001E4B">
<TD><br>&nbsp;<A HREF="$home_url?td=config_service_monitor"><b>Configure Host/Service Alerts</b></A>&nbsp;<br><br></TD>
<TD>Define alert rules for changes in monitored host/service status.
</TD>
</TR>
<TR bgcolor="#001E4B">
<TD><br>&nbsp;<A HREF="$home_url?td=config_ids_monitor"><b>Configure IDS Alerts</b></A>&nbsp;<br><br></TD>
<TD>Define alert rules for IDS alerts from Snort.</TD>
</TR>
<TR bgcolor="#001E4B">
<TD><br>&nbsp;<A HREF="$home_url?td=config_md5_monitor"><b>Configure File Integrity Check Alerts</b></A>&nbsp;<br><br></TD>
<TD>Define alert rules for File Integrity Check discrepancies.
</TD>
</TR>
<TR bgcolor="#001E4B">
<TD><br>&nbsp<A HREF="$home_url?td=age_data"><b>Expire Old Data</b></A>&nbsp;<br><br></TD>
<TD>Delete old IDS/Monitoring data to speed up database access.</TD>
</TR>
<TR bgcolor="#001E4B">
<TD><br>&nbsp<A HREF="$home_url?td=view_log_entries&tail=1000"><b>View Last 1000 Log Entries</b></A>&nbsp;<br><br></TD>
<TD>View last 1000 log entries from the master log.</TD>
</TR>
<TR HEIGHT=2 BGCOLOR="#003366"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>
</TABLE>
EOF

=head
<TR bgcolor="#001E4B">
<TD><br>&nbsp;<A HREF="$home_url?td=general_config"><b>General Configuration Options</b></A>&nbsp;<p></TD>
<TD>View/modify general configuration options for the system.</TD>
</TR>
=cut

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###########################
sub print_config_user_level{

my $table;

$table .= << "EOF";
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=center>
<TR><TD BGCOLOR="$row2_color">
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=11>
<TR><TD BGCOLOR="$row3_color" ALIGN=center COLSPAN=2 background="$v_graphics_path/bg_title.gif">
	<B>Configuration Menu</B>
</TD></TR>
<TR><TD BGCOLOR="$row3_color">
	<A HREF="$home_url?td=user_level_config">Update User Settings</A>
</TD><TD BGCOLOR="$row3_color">
Configuration of DEMARC user profile.
</TD>
</TR>
<TR><TD BGCOLOR="$row3_color">
	<A HREF="$home_url?td=config_service_monitor">Configure Host/Service Alerts</A>
</TD><TD BGCOLOR="$row3_color">
Define alert rules for changes in monitored host/service status.
</TD>
</TR>
<TR><TD BGCOLOR="$row3_color">
	<A HREF="$home_url?td=config_ids_monitor">Configure IDS Alerts</A>
</TD><TD BGCOLOR="$row3_color">
Define alert rules for IDS alerts from Snort.
</TD>
</TR>
<TR><TD BGCOLOR="$row3_color">
	<A HREF="$home_url?td=config_md5_monitor">Configure File Integrity Check Alerts</A>
</TD><TD BGCOLOR="$row3_color">
Define alert rules for File Integrity Check discrepancies.
</TD>
</TR>
</TABLE>
</TD></TR></TABLE>
EOF




push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
#########################
sub print_config_sid_menu{
my $table;

#	$table .= &get_sid_select_table;
	$table .= "<CENTER>Please click on the sensor you would like to configure</CENTER>";
	$table .= &get_sid_info_table;
push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###########################
sub print_config_rules{
my ($sid) = @_;
($sid=~/^\d+$/) || &error("Invalid SID:$sid");

my $table;

$table .= &get_sid_select_table($sid);
$table .= "<BR>";
$table .= &get_sid_info_table($sid);

$table .= &get_rules_select_table($sid);

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###########################
sub config_rules{
my ($sid,$rules_name) = @_;
($sid=~/^\d+$/) || &error("Invalid SID:$sid");
&safe_slash(\$rules_name);

my $table;

$table .= &get_sid_select_table($sid);
$table .= &get_rules_select_table($sid,$rules_name);
$table .= &print_edit_rules($sid,$rules_name);

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###########################
sub do_config_rules{
my ($sid,$rules_type,$rules_text,$new_ruleset_name,$action) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

($sid=~/^\d+$/) || &error("Invalid SID : $sid");
&safe_slash(\$rules_type);
&safe_slash(\$rules_text);
&safe_slash(\$new_ruleset_name) if ($new_ruleset_name);

if($action=~/^change_priority_to/){
	if ($rules_type eq "snort.conf"){
		&error("You may not change priorities in snort.conf.");
	}
	$action=~/^change_priority_to_(\d+$)/ || &error("Invalid Priority to change to: $action");
	my $new_priority = $1;
	#first take off all old priorities
	$rules_text=~s/msg:\s*\"P\-\d\-/msg: \"/g;
	#Now add new priorities:
	$rules_text=~s/msg:\s*\"/msg: \"P\-$new_priority\-/g;
	# then allow it to flow through the rules and it will write
	# the update at the end:
	&push_message("<FONT COLOR=red>Priorities updated to P-$new_priority</FONT>");
}
elsif($action=~/^remove_priorities/){
	if ($rules_type eq "snort.conf"){
		&error("You may not change priorities in snort.conf.");
	}
	#take off all old priorities
   $rules_text=~s/msg:\s*\"P\-\d\-/msg: \"/g;
   # then allow it to flow through the rules and it will write
   # the update at the end:
	&push_message("<FONT COLOR=red>All priorities have been removed</FONT>");
}
elsif($action=~/^copy_snort_conf_to_new_sid/){
	my $last_sid = &get_last_sid();
	$last_sid++;
	#First check to see if we already have one for this sensor:
   $sql_query = "SELECT snort_conf FROM dm_conf WHERE sid='$sid'";
   $db_ptr = &run_query($sql_query);
   if ($hash_ref=$db_ptr->fetchrow_hashref){
		&safe_slash(\$$hash_ref{'snort_conf'});
      #then we can copy it to the new sid:
      $sql_query = "INSERT INTO dm_conf VALUES ('$last_sid',NOW(),'','$$hash_ref{'snort_conf'}')";
   }
   else{
		&error("There is no snort.conf file for sensor $sid.");
   }
   $db_ptr = &run_query($sql_query);
   &touch_rules_update_time($last_sid);
}
elsif($action=~/^delete_all_rules/){
	$sql_query = "DELETE FROM dm_rules WHERE sid='$sid'";
	$db_ptr = &run_query($sql_query);
	&touch_rules_update_time($sid);
	&push_message("<FONT COLOR=red>All rules have been removed for this sensor.</FONT>");
	&config_rules($sid);
	&safe_exit;
}
elsif ($rules_type eq "new"){
	&error("You must specify a name for the new ruleset.") if (!$new_ruleset_name);
	&error("You may not enter a blank new ruleset.") if (!$rules_text);
	$sql_query = "SELECT rules_type FROM dm_rules WHERE rules_type = '$rules_type' AND sid='$sid'";
	$db_ptr = &run_query($sql_query);
	&error("Ruleset with same name already exists for this sensor.") if ($hash_ref=$db_ptr->fetchrow_hashref);
	# OK, its unique, so lets insert it
	$sql_query = "INSERT INTO dm_rules VALUES('$sid','$new_ruleset_name','$rules_text')";
	$db_ptr = &run_query($sql_query);
	&touch_rules_update_time($sid);
}
elsif($action=~/^copy_to/){
	if ($rules_type eq "snort.conf"){
		&error("You may not copy snort.conf over to another sensor because manual editing of the file is most likely required.");
	}
	$action=~/^copy_to_(\d+$)/ || &error("Invalid SID to copy to: $action");
	my $copy_to_sid = $1;
	#make sure sensor exists:
	$sql_query = "SELECT sid FROM sensor WHERE sid = '$copy_to_sid'";
	$db_ptr = &run_query($sql_query);
	if (!($hash_ref=$db_ptr->fetchrow_hashref)){
		# check if its a new sensor that isn't online yet
		$sql_query = "SELECT sid FROM dm_conf WHERE sid = '$copy_to_sid'";
		$db_ptr = &run_query($sql_query);
	}
	&error("Sensor $copy_to_sid doesn't exist.") if (!($hash_ref=$db_ptr->fetchrow_hashref));
	#make sure that sensor doesn't already have a ruleset by that name:
   $sql_query = "SELECT rules_type FROM dm_rules WHERE rules_type = '$rules_type' AND sid='$copy_to_sid'";
   $db_ptr = &run_query($sql_query);
   &error("Ruleset with that name already exists for that sensor.") if ($hash_ref=$db_ptr->fetchrow_hashref);
	#ok, we should be safe, lets insert it
	$sql_query = "INSERT INTO dm_rules VALUES('$copy_to_sid','$rules_type','$rules_text')";
	$db_ptr = &run_query($sql_query);
	&touch_rules_update_time($copy_to_sid);
}
elsif($action=~/^copy_all_to/){
	my $db_ptr_2;
	my $hash_ref_2;
	if ($rules_type eq "snort.conf"){
		&error("You may not copy snort.conf over to another sensor because manual editing of the file is most likely required.");
	}
	$action=~/^copy_all_to_(\d+$)/ || &error("Invalid SID to copy to: $action");
	my $copy_to_sid = $1;
	#make sure sensor exists:
	$sql_query = "SELECT sid FROM sensor WHERE sid = '$copy_to_sid'";
	$db_ptr = &run_query($sql_query);
	if (!($hash_ref=$db_ptr->fetchrow_hashref)){
		# check if its a new sensor that isn't online yet
		$sql_query = "SELECT sid FROM dm_conf WHERE sid = '$copy_to_sid'";
		$db_ptr = &run_query($sql_query);
	}
	&error("Sensor $copy_to_sid doesn't exist.") if (!($hash_ref=$db_ptr->fetchrow_hashref));

	# get list of all the rulesets to copy:
	$sql_query = "SELECT rules_type,snort_rules FROM dm_rules WHERE sid = '$sid'";
	$db_ptr = &run_query($sql_query);
	while ($hash_ref=$db_ptr->fetchrow_hashref){
		#make sure that sensor doesn't already have a ruleset by that name:
   	$sql_query = "SELECT rules_type FROM dm_rules WHERE rules_type = '$$hash_ref{'rules_type'}' AND sid='$copy_to_sid'";
   	$db_ptr_2 = &run_query($sql_query);
   	next if ($hash_ref_2=$db_ptr_2->fetchrow_hashref);
		# lets slash it:
		&safe_slash(\$$hash_ref{'rules_type'});
		&safe_slash(\$$hash_ref{'snort_rules'});
		#ok, we should be safe, lets insert it
		$sql_query = "INSERT INTO dm_rules VALUES('$copy_to_sid','$$hash_ref{'rules_type'}','$$hash_ref{'snort_rules'}')";
		$db_ptr_2 = &run_query($sql_query);
	}
	&touch_rules_update_time($copy_to_sid);
}
elsif($rules_type eq "snort.conf"){
	#First check to see if we already have one for this sensor:
	$sql_query = "SELECT snort_conf FROM dm_conf WHERE sid='$sid'";
   $db_ptr = &run_query($sql_query);
	if ($hash_ref=$db_ptr->fetchrow_hashref){
		#then we're just updating:
		$sql_query = "UPDATE dm_conf SET snort_conf = '$rules_text', last_updated = NOW() WHERE sid='$sid'";
	}
	else{
		# then its a new record for this sid
		$sql_query = "INSERT INTO dm_conf VALUES ('$sid',NOW(),'','$rules_text')";
	}
	$db_ptr = &run_query($sql_query);
	&touch_rules_update_time($sid);
}
else{
	$sql_query = "SELECT rules_type FROM dm_rules WHERE rules_type = '$rules_type' AND sid='$sid'";
   $db_ptr = &run_query($sql_query);
   &error("Ruleset with that name doesn't exist for this sensor.") if (!($hash_ref=$db_ptr->fetchrow_hashref));
	# check if we're supposed to delete this ruleset:
	if ($action eq "delete"){
		$sql_query = "DELETE FROM dm_rules WHERE sid = '$sid' AND rules_type = '$rules_type'";
   	$db_ptr = &run_query($sql_query);
		&touch_rules_update_time($sid);
		&push_message("<FONT COLOR=red><CENTER>Ruleset Deleted.</CENTER></FONT>");
		&config_rules($sid);
		return;
	}
	$sql_query = "UPDATE dm_rules SET snort_rules = '$rules_text' WHERE sid='$sid' AND rules_type = '$rules_type'";
   $db_ptr = &run_query($sql_query);
	&touch_rules_update_time($sid);
}

&push_message("<FONT COLOR=red><CENTER>Rules Updated.</CENTER></FONT>");
&config_rules($sid,$rules_type);
}
###########################
sub print_config_sid{
my ($sid,$configtype) = @_;
my $table;

&error("Invalid SID : $sid") if ($sid!~/^\d+$/);
&error("Invalid configure type: $configtype") if ($configtype!~/^snort\.conf$|^rules$/);
$table .= &get_sid_select_table($sid);
$table .= "<FORM ACTION=\"$home_url\" METHOD=post><INPUT TYPE=hidden NAME=td VALUE=\"do_config_sid\">";
$table .= "<INPUT TYPE=hidden NAME=sid VALUE=\"$sid\">";
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2>";
if ($configtype eq "snort.conf"){
	$table .= "<TR><TD ALIGN=center><B>snort.conf file for SID # $sid</B></TD></TR>\n";
	$table .= "<TR><TD><TEXTAREA NAME=\"snort.conf\" rows=20 cols=70>";
	$table .= &get_snort_conf($sid);
	$table .= "</TEXTAREA>";

}
elsif ($configtype eq "rules"){
	$table .= "<TR><TD ALIGN=center><B>IDS rules file for SID # $sid</B></TD></TR>\n";
	$table .= "<TR><TD><TEXTAREA NAME=\"rules\" rows=20 cols=70>";
	$table .= &get_snort_rules($sid);
	$table .= "</TEXTAREA>";

}
$table .= "</TD></TR>\n";
$table .= "<TR><TD ALIGN=center>";
$table .= "<INPUT TYPE=Submit VALUE=Update>";
$table .= "</TD></TR>\n</TABLE>\n";
push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
############################
sub get_sid_select_table{
my ($sid,$td) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $hostname;
my $where_rules;

$td = "config_sid" if (!$td);

$table  = "<FORM ACTION=\"$home_url\" METHOD=post>";
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center>";
$table .= "<TD><B>Sensor to configure:</B></TD>";
$table .= "<TD><INPUT TYPE=hidden NAME=td VALUE=\"$td\"><SELECT NAME=sid>";

$sql_query = "SELECT sid,hostname FROM sensor";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	$where_rules .= " sid != '$$hash_ref{'sid'}' AND";
	if ($sid && ($sid == $$hash_ref{'sid'})){
		$table .= "<OPTION VALUE=$$hash_ref{'sid'} SELECTED>$$hash_ref{'sid'} - $$hash_ref{'hostname'}</OPTION>";
		$hostname = $$hash_ref{'hostname'};
	}
	else{
		$table .= "<OPTION VALUE=$$hash_ref{'sid'}>$$hash_ref{'sid'} - $$hash_ref{'hostname'}</OPTION>";
	}
#	$table .= "$$hash_ref{'sid'}<BR>";
}
$where_rules =~s/AND$//;
$sql_query = " SELECT sid FROM dm_conf WHERE $where_rules";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   $table .= "<OPTION VALUE=$$hash_ref{'sid'}>$$hash_ref{'sid'} - [NOT_CHECKED_IN_YET]</OPTION>";
}




$table .= "</SELECT>";
# Add last updated data if there's a sid:
$table .= "</TD>";
$table .= "<TD><INPUT TYPE=Submit VALUE=Change style=\"font-size:8pt\"></TD>";

$table .= "</TR>\n";

=head
if ($sid=~/^\d+$/){
	$sql_query = "	SELECT \
						last_updated,last_implemented,\
(UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_implemented)) AS DIFF \
						FROM dm_conf \
						WHERE sid = '$sid'";
	$db_ptr = &run_query($sql_query);
	if ($hash_ref=$db_ptr->fetchrow_hashref){
		my $ago;
		if ($$hash_ref{'DIFF'}<60){
			$ago = "$$hash_ref{'DIFF'} seconds ago";
		}
		elsif ($$hash_ref{'DIFF'}<(60*60)){
         $ago = sprintf ("%.2f minutes ago", ($$hash_ref{'DIFF'}/60));
      }
		elsif ($$hash_ref{'DIFF'}<(60*60*24)){
         $ago = sprintf ("%.2f hours ago", (($$hash_ref{'DIFF'}/60)/60));
      }
		else{
         $ago = sprintf ("%.2f days ago",( (($$hash_ref{'DIFF'}/60)/60)/24));
		}

		$table .= "<TR><TD COLSPAN=4>";
		$table .= "Host $hostname (SID $sid) was last updated with current conf/rulesets $ago<BR>";
		$table .= "Rules for this host were last modified $$hash_ref{'last_updated'}";
		$table .= "</TD></TR>\n";
	}
}
=cut

$table .= "</TABLE></FORM>";
return $table;
}
############################
sub get_rules_select_table{
my ($sid,$rule_type) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

$table = &get_sid_select_table($sid);
my @rules_types = &get_rules_types($sid);

$table  = "<FORM ACTION=\"$home_url\" METHOD=post>";
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center>";
$table .= "<TR>";
$table .= "<TD><B>Ruleset to configure:</B></TD>";
$table .= "<TD>";
$table .= "<INPUT TYPE=hidden NAME=td VALUE=\"config_rules\">";
$table .= "<INPUT TYPE=hidden NAME=sid VALUE=\"$sid\">";
$table .= "<SELECT NAME=rules_type>";
$table .= "<OPTION selected>snort.conf</OPTION>\n";
foreach (@rules_types){
	if ($rule_type && ($rule_type eq "$_")){
		$table .= "<OPTION selected>$_</OPTION>\n";
	}
	else{
		$table .= "<OPTION>$_</OPTION>\n";
	}
}
if ($rule_type && ($rule_type eq "new")){
	$table .= "<OPTION value=new selected>Create NEW ruleset</OPTION>\n" 
}
else{
	$table .= "<OPTION value=new>Create NEW ruleset</OPTION>\n" 
}


$table .= "</SELECT>";
$table .= "</TD>";
$table .= "<TD><INPUT TYPE=Submit VALUE=Go style=\"font-size:8pt\"></TD>";

$table .= "</TR>\n</TABLE>\n</FORM>\n";

return $table;
}
#########################
sub get_rules_types{
my ($sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @rules_types;

$sql_query = "SELECT rules_type FROM dm_rules WHERE sid = '$sid' ORDER BY UPPER(rules_type)";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@rules_types,$$hash_ref{'rules_type'});
}

return @rules_types;
}
##########################
sub get_snort_conf{
my ($sid) = @_;
($sid=~/^\d+$/) || return;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $value;

$sql_query = "SELECT * FROM dm_conf WHERE sid='$sid'";
$db_ptr = &run_query($sql_query);
return ($hash_ref=$db_ptr->fetchrow_hashref)? return $$hash_ref{'snort_conf'} : return;
}
##########################
sub get_snort_rules{
my ($sid,$rules_name) = @_;
($sid=~/^\d+$/) || return;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $value;
&safe_slash(\$rules_name);

$sql_query = "SELECT * FROM dm_rules WHERE sid='$sid' AND rules_type = '$rules_name'";
$db_ptr = &run_query($sql_query);
return ($hash_ref=$db_ptr->fetchrow_hashref)? return $$hash_ref{'snort_rules'} : return;
}
##########################
sub update_config{
my ($sid,$text,$field) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $create_new_record;
&safe_slash(\$text);

($sid=~/^\d+$/) || &error("No SID passed");
($field=~/^snort\.conf$|^rules$/) || &error("Invalid field to update: $field");

# first check to see if this sid already has a record:
$sql_query = "SELECT sid FROM dm_rules WHERE sid='$sid'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || ($create_new_record = 1);

if ($create_new_record){
	$sql_query = "INSERT INTO dm_rules VALUES ('$sid',NOW(),'',";
	if ($field eq "snort.conf"){
		$field = "snort_conf";
		$sql_query .= "'$text','')";
	}
	else{
		$sql_query .= "'','$text')";
	}
}
else{
	# just update the old record:
	$field = "snort_conf" if ($field eq "snort.conf"); #change to work with db fieldname
	$field = "snort_rules" if ($field eq "rules"); #change to work with db fieldname
	$sql_query = "UPDATE dm_rules SET $field = '$text' WHERE sid = '$sid'";
}
$db_ptr = &run_query($sql_query);
&touch_rules_update_time($sid);

return 1;
}
#################
sub safe_slash{
my ($string_ref) = @_;

$$string_ref=~s/(['\\])/\\$1/g;

}
#################
sub get_md5{
my ($sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $digest;
my $snort_rules_data;

$sql_query = "SELECT * FROM dm_rules WHERE sid = '$sid'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;

$snort_rules_data = $$hash_ref{'snort_conf'} . "\n" . $$hash_ref{'snort_rules'};

$digest = md5_hex($snort_rules_data);

return $digest;
}
###################
sub print_edit_rules{
my ($sid,$rules_name) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $text;
my $table;
my $new_stuff;
&safe_slash(\$rules_name);

if ($rules_name eq "new"){
	$new_stuff = "<TR><TD>Ruleset Name (required) : <INPUT TYPE=text size=20 NAME=new_ruleset_name></TD></TR>\n";
}


if ($rules_name eq "snort.conf"){
	$sql_query = "SELECT snort_conf FROM dm_conf WHERE sid = '$sid'";
	$db_ptr = &run_query($sql_query);
	$text = ($hash_ref=$db_ptr->fetchrow_hashref)? $$hash_ref{'snort_conf'} : "";
}
else{
	$sql_query = "SELECT snort_rules FROM dm_rules WHERE rules_type = '$rules_name' AND sid = '$sid'";
	$db_ptr = &run_query($sql_query);
	$text = ($hash_ref=$db_ptr->fetchrow_hashref)? $$hash_ref{'snort_rules'} : "";
}
$table .= << "EOF";
<FORM ACTION="$home_url" METHOD=post>
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center>
$new_stuff
<TR><TD>
<INPUT TYPE=hidden NAME=td VALUE=do_config_rules>
<INPUT TYPE=hidden NAME=sid VALUE="$sid">
<INPUT TYPE=hidden NAME=rules_type VALUE="$rules_name">
</TD></TR>
<TR bgcolor="#003366"><TD background="$v_graphics_path/bg_title.gif" align=center><B>Editing: $rules_name</B></TD></TR>
<TR bgcolor="#001E4B"><TD nowrap align=center>
&nbsp;<TEXTAREA rows=20 cols=70 NAME=rules_text wrap=off>$text</TEXTAREA>&nbsp;<br><br>
<SELECT NAME=action>
<OPTION value=update selected>Update</OPTION>
<OPTION value=delete>Delete</OPTION>
EOF
if ($rules_name!~/^snort\.conf$|^new$/){
my @sids = &get_sids();
   foreach (@sids){
         my @temp_array = split(/,/,$_);
         $table .= "<OPTION value=\"copy_to_$temp_array[0]\">Copy ruleset to SID $temp_array[0] - $temp_array[1]</OPTION>\n";
   }
   foreach (@sids){
         my @temp_array = split(/,/,$_);
         $table .= "<OPTION value=\"copy_all_to_$temp_array[0]\">Copy ALL rulesets for current sensor to SID $temp_array[0] - $temp_array[1]</OPTION>\n";
   }
### Options for changing priority:
my @p_array = split(//,$priority_levels);
   foreach (@p_array){
      $table .= "<OPTION value=\"change_priority_to_$_\">Change ALL priorities in ruleset to P-$_</OPTION>\n";
   }
   $table .= "<OPTION value=\"remove_priorities\">Remove ALL priorities in ruleset</OPTION>\n";
   $table .= "<OPTION value=\"delete_all_rules\">Remove ALL RULES for this sensor.</OPTION>\n";

}

#Option for copying snort.conf to new SID
my $last_sid = &get_last_sid;
if ($last_sid){
   $last_sid++;
   $table .= "<OPTION value=\"copy_snort_conf_to_new_sid\">Copy snort.conf to NEW SID ($last_sid) about to come online.</OPTION>";
}


$table .= << "EOF";
</SELECT>
<INPUT TYPE=submit VALUE=Go style=\"font-size:8pt\"><br><br>
</TD></TR>
<TR HEIGHT=2 BGCOLOR="#003366"><TD><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>
</TABLE>
</FORM>
EOF



return $table;
}
##################
sub get_sids{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @sids;
my $where_rules;

$sql_query = "SELECT sid,hostname FROM sensor";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@sids,"$$hash_ref{'sid'},$$hash_ref{'hostname'}");
	$where_rules .= " sid != '$$hash_ref{'sid'}' AND";
}

$where_rules =~s/AND$//;
$sql_query = "	SELECT sid FROM dm_conf WHERE $where_rules";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@sids,"$$hash_ref{'sid'},[NOT_CHECKED_IN_YET]");
}

return @sids;
}
###############
sub touch_rules_update_time{
my ($sid) = @_;
my $sql_query;
my $db_ptr;

($sid=~/^\d+$/) || &error("SID not passed to update rules time function.");
$sql_query = "UPDATE dm_conf SET last_updated=NOW() WHERE sid='$sid'";
$db_ptr = &run_query($sql_query);
}
##################
sub get_sid_info_table{
my ($sid) = @_;
# $sid is if we only want to see one sensor's info
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $where;

if ($sid=~/^\d$/){
	$where = " WHERE sensor.sid = '$sid' ";
}

$sql_query = "	SELECT \
						sensor.sid,hostname,interface,\
						last_updated,last_implemented, \
(UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_implemented)) AS DIFF, \
(UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_updated)) AS DIFF2, \
(UNIX_TIMESTAMP(last_updated)-UNIX_TIMESTAMP(last_implemented)) AS LAPSE \
					FROM \
						sensor \
							LEFT JOIN dm_conf ON sensor.sid = dm_conf.sid $where \
					ORDER BY sid";

$table =<< "EOF";
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 width=\"100%\">
<TR BGCOLOR=#003366><TD BACKGROUND="$v_graphics_path/bg_title.gif" align=center colspan=6><B>Sensor Details</B></TD></TR>
<TR bgcolor=\"#244A75\">
<TD ALIGN=center><b>SID</b></TD>
<TD ALIGN=center><b>Hostname</b></TD>
<TD ALIGN=center><b>Interface</b></TD>
<TD ALIGN=center><b>Ruleset Last Updated</b></TD>
<TD ALIGN=center><b>Ruleset Last Implemented</b></TD>
<TD ALIGN=center><b>In-Sync</b></TD>
</TR>
EOF

	$db_ptr = &run_query($sql_query);
	while ($hash_ref=$db_ptr->fetchrow_hashref){
		my $never = 0;
		$table .= "<TR bgcolor=\"#001E4B\">";
		$table .= "<TD align=center>&nbsp;$$hash_ref{'sid'}</TD>";
		$table .= "<TD align=center>&nbsp;";
			$table .= "<A HREF=\"$home_url?td=config_sid&sid=$$hash_ref{'sid'}\">" if (!$where);
		$table .= $$hash_ref{'hostname'};
			$table .= "</A>" if (!$where);
		$table .= "</TD>";
		$table .= "<TD align=center>&nbsp;$$hash_ref{'interface'}</TD>";
		$table .= "<TD align=center>&nbsp;$$hash_ref{'last_updated'}</TD>";
		if ($$hash_ref{'last_implemented'}=~/[1-9]/){
					$table .=  "<TD align=center>&nbsp;$$hash_ref{'last_implemented'} ("  . &time_ago($$hash_ref{'DIFF'}) . ")";
		}
		else{
					$table .=  "<TD align=center>Never<BR><FONT COLOR=red>Rules have never been implemented on host.  <BR>Client possibly not running?</FONT>";
					$never = 1;
		}
		#$table .= (!$never && ($$hash_ref{'LAPSE'} > (60*10)))
		$table .= (!$never && ($$hash_ref{'LAPSE'}) && ($$hash_ref{'DIFF2'} > (60*10)))
					? "<BR><FONT COLOR=red>Rules on host have been stale for over 10 minutes. <BR>Client possibly not running?</FONT></TD>"
					: "</TD>";
		$table .= "<TD align=center>";
		$table .= ($$hash_ref{'last_implemented'} ne $$hash_ref{'last_updated'}) ? "<FONT COLOR=red>NO</FONT>" : "YES";
		$table .= "</TD>";

		$table .= "</TR>\n";
	}
$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=6><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n";
return $table;
}
##############
sub time_ago{
my ($seconds) = @_;
my $ago;
($seconds) || return "0 seconds ago";

      if ($seconds<60){
         $ago = "$seconds seconds ago";
      }
      elsif ($seconds<(60*60)){
         $ago = sprintf ("%.2f minutes ago", ($seconds/60));
      }
      elsif ($seconds<(60*60*24)){
         $ago = sprintf ("%.2f hours ago", (($seconds/60)/60));
      }
      else{
         $ago = sprintf ("%.2f days ago",( (($seconds/60)/60)/24));
      }

return $ago;
}
############
sub recent_cached_copy{
my ($key,$cache_limit) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

&safe_slash(\$key);

# Check to see if there's a cached version of the
# side menu that we can deliver to save a whole 
# bunch o' queries


$sql_query = "	SELECT \
						dm_content, \
						UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_updated) AS cache_age
					FROM \
						dm_cache \
					WHERE \
						sid 		= '$monitor_sid' AND \
						dm_key 	= '$key' AND \
						((UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_updated)) < ($cache_limit * 60))";

$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;
return ($$hash_ref{'dm_content'},$$hash_ref{'cache_age'});


}
##############
sub update_cache{
my ($key,$cache) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

&safe_slash(\$key);
&safe_slash(\$cache);


#check to see if there's already a cached version in there:
$sql_query = "	SELECT \
						last_updated \
					FROM dm_cache \
					WHERE \
						sid = '$monitor_sid' AND \
						dm_key = '$key'";
$db_ptr = &run_query($sql_query);

if ($hash_ref=$db_ptr->fetchrow_hashref){
	# then we're just updating:
	$sql_query = "	UPDATE dm_cache \
						SET \
							last_updated = NOW(), \
							dm_content = '$cache' \
						WHERE \
							sid = '$monitor_sid' AND \
							dm_key = '$key'";
}
else{
	# we have to add a new row:
	$sql_query = "	INSERT INTO dm_cache \
						VALUES ( \
							'$monitor_sid', \
							'$key', \
							'$cache', \
							NOW()  \
						)";
}
$db_ptr = &run_query($sql_query);
}
######################
sub traceroute{
my ($host,$timeout_seconds,$no_name_resolution) = @_;

$host						=~tr/a-zA-Z0-9\.\-\_//dc;
($host) 				|| return;
$|                   = 1;
($timeout_seconds 	=~/^\d+$/) || ($timeout_seconds= 10);
my $flags 				= ($no_name_resolution)? " -n " : " ";
my $data					= "<CENTER><B>Traceroute to $host</B></CENTER>\n<P>";


eval {
   local $SIG{ALRM} = sub { die"timed_out\n"};
   alarm $timeout_seconds;

open (IN,"$traceroute_command $flags $host |") || &error("Can't do it: $!");

   while (<IN>){
		$_	=~s/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/<A HREF=\"$home_url\?td=arin_whois&ip=$1\">$1<\/A>/;
      $data .=  "$_ <BR>";
   }
   close IN;
};
if ($@){
   $data .= "<BR><B>TIMED OUT!</B>\n";
}

$timeout_seconds+=10;
my $trace_link = ($no_name_resolution)
	? "<A HREF=\"$home_url\?td=traceroute&ip=$host\">Rerun traceroute with name resolution</A>" 
	:"<A HREF=\"$home_url\?td=traceroute&no_name_resolution=1&ip=$host\">Rerun traceroute with no name resolution</A>";

$data .= << "EOF";
<P ALIGN=left>
$trace_link
<BR>
<A HREF=\"$home_url\?td=traceroute&timeout=$timeout_seconds&ip=$host\">Rerun traceroute with longer timeout</A>
<P>
EOF

push (@substitutions,"\\[MAIN_TABLE\\],-,$data");
&print_main_with_key($main_template);
}
######################
sub nslookup{
my ($host) = @_;

my $timeout_seconds;
$host						=~tr/a-zA-Z0-9\.\-\_//dc;
($host) 				|| return;
$|                   = 1;
($timeout_seconds 	=~/^\d+$/) || ($timeout_seconds= 10);
my $data					= "<CENTER><B>NSlookup for $host</B></CENTER>\n<P>";


eval {
   local $SIG{ALRM} = sub { die"timed_out\n"};
   alarm $timeout_seconds;

open (IN,"$nslookup_command $host |") || &error("Can't do it: $!");

   while (<IN>){
#		$_	=~s/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/<A HREF=\"$home_url\?td=arin_whois&ip=$1\">$1<\/A>/;
      $data .=  "$_ <BR>";
   }
   close IN;
};
if ($@){
   $data .= "<BR><B>TIMED OUT!</B>\n";
}

push (@substitutions,"\\[MAIN_TABLE\\],-,$data");
&print_main_with_key($main_template);
}
######################
sub ping{
my ($host,$count) = @_;

$host						=~tr/a-zA-Z0-9\.\-\_//dc;
($host) 				|| return;
$|                   = 1;
($count =~/^\d+$/) || ($count= 4);
my $data					= "<CENTER><B>Pinging $host</B></CENTER>\n<P>";
my $timeout_seconds	= 2*$count;


eval {
   local $SIG{ALRM} = sub { die"timed_out\n"};
   alarm $timeout_seconds;

open (IN,"$ping_command -c $count $host |") || &error("Can't do it: $!");

   while (<IN>){
#		$_	=~s/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/<A HREF=\"$home_url\?td=arin_whois&ip=$1\">$1<\/A>/;
      $data .=  "$_ <BR>";
   }
   close IN;
};
if ($@){
   $data .= "<BR><B>TIMED OUT!</B>\n";
}

$count+=4;

$data .= << "EOF";
<P ALIGN=left>
<BR>
<A HREF=\"$home_url\?td=ping&count=$count&ip=$host\">Rerun with longer ping count.</A>
<P>
EOF

push (@substitutions,"\\[MAIN_TABLE\\],-,$data");
&print_main_with_key($main_template);
}
############################
sub get_monitor_menu_table{
my $table;

$table = "<A HREF=\"$home_url?td=add_monitoring_event\">Add Monitoring Event</A>";

return $table;
}
##########################
sub print_add_monitoring_event_page{
my $table;
my $html = &get_new_service_page;

my $services_dropdown = &get_services_dropdown;
push (@substitutions,"\\[SERVICE_LIST\\],-,$services_dropdown");
my $group_list = &get_groups_dropdown;
push (@substitutions,"\\[GROUP_LIST\\],-,$group_list");
my $sid_list = &get_sids_dropdown;
push (@substitutions,"\\[SID_LIST\\],-,$sid_list");
my $host_list = &get_hosts_dropdown;
push (@substitutions,"\\[IP_LIST\\],-,$host_list");


$table = &print_with_key('',"TO_STRING",$html);
#@substitutions = ();

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
############################
sub get_services_dropdown{
my $dropdown;

#simply formats global @services var

$dropdown = "<SELECT NAME=service>\n";

$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>- Select -</OPTION>\n";

foreach (@services){
	$dropdown .= "<OPTION>$_</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
############################
sub get_groups_dropdown{
my $dropdown;
my $sql_query;
my $db_ptr;
my $hash_ref;

$dropdown = "<SELECT NAME=grouping>\n";
$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>- Select -</OPTION>\n";

$sql_query = "SELECT DISTINCT grouping FROM dm_monitor_current ORDER BY UPPER(grouping)";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   $dropdown .= "<OPTION>$$hash_ref{'grouping'}</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
############################
sub get_sids_dropdown{
my ($select_name,$label_option) = @_;

($select_name) || ($select_name = "client_sid");
($label_option) || ($label_option = "- Select -");

my $dropdown;
my $sql_query;
my $db_ptr;
my $hash_ref;

$dropdown = "<SELECT NAME=$select_name>\n";
$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>$label_option</OPTION>\n";

$sql_query = "SELECT sid,hostname FROM sensor ORDER BY sid";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   $dropdown .= "<OPTION VALUE=\"$$hash_ref{'sid'}\">$$hash_ref{'sid'} - $$hash_ref{'hostname'}</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
############################
sub get_hosts_dropdown{
my $dropdown;
my $sql_query;
my $db_ptr;
my $hash_ref;

$dropdown = "<SELECT NAME=ip>\n";
$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>- Select -</OPTION>\n";

$sql_query = "SELECT DISTINCT ip_addr,host_name FROM dm_monitor_current ORDER BY UPPER(host_name)";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	my $dotted_ip = &convert_long_ip($$hash_ref{'ip_addr'});
   $dropdown .= "<OPTION VALUE=\"$$hash_ref{'ip_addr'}\">$$hash_ref{'host_name'} - $dotted_ip</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
##########################
sub do_add_monitoring_event{
# vars are taken from global FORM vars
my $sql_query;
my $db_ptr;
my $hash_ref;
my $ip;
my $long_ip;
my $host_name;
my $grouping;
my $service;
my $port;
my $client_sid;

$client_sid = $FORM{'client_sid'} if  ($FORM{'client_sid'}=~/^\d+$/);
# Check for Service
if (!$FORM{'service'} || ($FORM{'service'} eq "NOT_SELECTED")){
	&error("No service selected to monitor!");
}
$service = $FORM{'service'};

(!$FORM{'port'} || ($FORM{'port'}=~/^\d+$/)) || &error("Port number must consist only of digits");

$client_sid = ($FORM{'client_sid'}=~/^\d+$/)? $FORM{'client_sid'} : "";# Don't error out if there's bunk input, just set to ''


# Check for new host to monitor
if ($FORM{'ip_manual'}){
	if ($FORM{'ip_manual'}!~/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/){
		&error("IP address must be in dotted quad format.<BR>ie: 192.168.0.1");
	}
# Make sure we do not already have this host:
$long_ip 	= &convert_dotted_ip($FORM{'ip_manual'});
my $temp_string;
($temp_string,$host_name,$grouping) = &get_monitored_host_info($long_ip);
if ($temp_string){
	&error("Host with that IP address already exists as hostname: $host_name in the group: $grouping");
}

	if(!$FORM{'host_name'}){
		&error("cYou must either select a preexisting host to monitor or supply the IP address AND hostname for a new host to monitor");
	}
	if ($FORM{'group_manual'}){
		$grouping = $FORM{'group_manual'};
	}
	elsif ($FORM{'grouping'}){
		$grouping = $FORM{'grouping'};
	}
	else{
		&error("You must either type in a new group name for this host or select a preexisting group from the dropdoiwn list");
	}
	
$ip 			= $FORM{'ip_manual'};
$host_name 	= $FORM{'host_name'}; 

}
else{
# Check to make sure host exists:
($FORM{'ip'} eq "NOT_SELECTED") 
		&&  &error("You must either select a preexisting host to monitor or supply the IP address AND hostname for a new host to monitor");

($long_ip,$host_name,$grouping) = &get_monitored_host_info($FORM{'ip'});
(!$long_ip) && &error("chosen host does not exist!");
$ip = &convert_long_ip($long_ip);

}

#ok, now lets just try and save them from putting the same entry in twice:
$sql_query = "	SELECT sid FROM dm_monitor_current \
					WHERE \
						sid 		= '$monitor_sid' AND \
						ip_addr	= '$long_ip' AND \
						service 	= '$service' AND \
						port		= '$port'";
$db_ptr = &run_query($sql_query);
 ($hash_ref=$db_ptr->fetchrow_hashref)
	&& &error("There is already a monitoring event set with the same IP address, service, and port");


&safe_slash(\$service);
&safe_slash(\$host_name);
&safe_slash(\$grouping);
$sql_query = "INSERT INTO dm_monitor_current VALUES( \
					'$monitor_sid','$service','$long_ip', \
					'$host_name','$grouping', NOW() , \
					'','','','$client_sid','$port',NOW(), \
					'','',''
				)";
&connect_to_db;
($db->do($sql_query)) || &error("DB error occured while adding new service, please try again.");
&push_message("<FONT COLOR=red><CENTER>New Monitor Event Added.</CENTER></FONT>");

my $dotted_ip = &convert_long_ip($long_ip);
&log_event(	username => "$logged_in_as",
				action 	=> "added host monitoring event",
				target	=> "$dotted_ip - $service",
			 );


}
####################
sub get_monitored_host_info{
my ($long_ip) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = "	SELECT \
						DISTINCT ip_addr,host_name,grouping \
					FROM \
						dm_monitor_current \
					WHERE \
						ip_addr 	= '$long_ip' AND \
						sid		= '$monitor_sid'";

$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;
return ($$hash_ref{'ip_addr'},$$hash_ref{'host_name'},$$hash_ref{'grouping'});

}
###############
sub print_monitor_page{
my $table;

$table = &get_full_monitoring_table;

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###############
sub get_full_monitoring_table{
my @groupings;
my @services;
my $table;

@groupings = &get_groupings;
foreach (@groupings){
my $cols = 1;

$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\" BGCOLOR=\"$row1_color\">\n<TR><TD>\n";
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">\n";
	my $group = $_;
	&safe_slash(\$group);
	@services = &get_services_for_grouping($group);
	$cols = (@services) + 1;
	$table .= "<TR BGCOLOR=\"#003366\"><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" align=center colspan=\"$cols\"><B>$_</B></TD></TR>\n";
	$table .= "<TR bgcolor=\"#244A75\"><TD ALIGN=left><IMG SRC=\"$v_graphics_path/spacer.gif\" width=60 height=2><B>Host</B></TD>";
	foreach (@services){
		$table .= "<TD ALIGN=center width=50><B>$_</B></TD>";
	}
	$table .= "</TR>\n";
	my ($hosts_ref,$ips_ref) = &get_hosts_in_group($group);
	for (my $i=0;$i<(@$hosts_ref);$i++){
		my $dotted_ip = &convert_long_ip($$ips_ref[$i]);
		$table .= "<TR bgcolor=\"#001E4B\"><TD ALIGN=left>&nbsp;$$hosts_ref[$i] $dotted_ip</TD>";
		foreach (@services){
			my $status = &get_status_color_for(	ip			=> $$ips_ref[$i],
															service	=> $_);
															
			my $link = ($status=~/src/)? "<A HREF=\"$home_url?td=view_monitored_host&long_ip=$$ips_ref[$i]&service=$_\">$status</A>" : $status;
			$table .= "<TD ALIGN=center>$link</TD>";
		}
		$table .= "</TR>\n";
	}
$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=\"$cols\"><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
$table .= "</TABLE>\n";
$table .= "</TD></TR>\n</TABLE>\n<BR>\n";
}

return $table;
}
###############
sub get_minimum_monitoring_table{
my ($mini_me_target) = @_;
my @groupings;
my @services;
my $table;
my $bad_mojo;
my $bad_host_mojo;
my $bad_group_mojo;
my $final_table;
my @man_down; # for mini-me
my $cols = 1;

@groupings = &get_groupings;

#HEADER table
$final_table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH=\"100%\">";
$final_table .= "<TR BGCOLOR=\"$header_row_color\"><TD ALIGN=center BACKGROUND=\"$v_graphics_path/bg_title.gif\">";
$final_table .= "<B>Host Monitoring Alerts</B>";
$final_table .= "</TD></TR>\n";
$final_table .= "</TABLE>\n";
#$final_table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\">";
#$final_table .= "<TR><TD ALIGN=center BGCOLOR=\"#000000\">\n";

foreach (@groupings){
$table 		= (); #clear the temp table
$bad_group_mojo	= ();

my $current_group = $_;
	my $group = $_;
	&safe_slash(\$group);
	@services = &get_services_for_grouping($group);
	$cols = (@services) + 1;

	$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">";
	$table .= "<TR BGCOLOR=\"#244A75\"><TD ALIGN=left>&nbsp;<B>($current_group) - Host</B></TD>";
	foreach (@services){
		$table .= "<TD ALIGN=center width=\"50\"><B>$_</B></TD>";
	}
	$table .= "</TR>\n";
	my ($hosts_ref,$ips_ref) = &get_hosts_in_group($group);
	for (my $i=0;$i<(@$hosts_ref);$i++){
		my $table_2;
		$bad_host_mojo = ();
		my $dotted_ip = &convert_long_ip($$ips_ref[$i]);
		$table_2 .= "<TR BGCOLOR=\"#001E4B\"><TD ALIGN=left>&nbsp;$$hosts_ref[$i] $dotted_ip</TD>";
		foreach (@services){
			
			my $status = &get_status_color_for(	ip			=> $$ips_ref[$i],
															service	=> $_);
															
			my $link = ($status=~/SRC/i)? "<A HREF=\"$home_url?td=view_monitored_host&long_ip=$$ips_ref[$i]&service=$_\">$status</A>" : $status;
			$table_2 .= "<TD ALIGN=center>$link</TD>";
			if (($status=~/SRC/i) && ($status!~/green/i)){
				$bad_host_mojo = 1; 
				push (@man_down,"$current_group,-,$$hosts_ref[$i],-,$$ips_ref[$i],-,$_,-,$status");
			}
		}
		$table_2 .= "</TR>\n";
		if ($bad_host_mojo){
			$table .= $table_2; 
			$bad_mojo 			= 1;
			$bad_group_mojo	= 1;
		}
	}
$table .= "</TD></TR></TABLE>";

$final_table .= $table if ($bad_group_mojo);
}
if (!$bad_mojo){
	#$final_table .= "<tr bgcolor=\"$row3_color\"><td align=center><B>All Monitored Hosts/Services&nbsp;" . &color_code("GREEN"). "</B></td></tr>";
	$final_table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">";
	$final_table .= "<TR BGCOLOR=\"#244A75\"><TD ALIGN=center>";
	$final_table .= "<B>All Monitored Hosts/Services&nbsp;" . &color_code("GREEN"). "</B>";
	$final_table .= "</TD></TR></TABLE>";
}


$final_table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">\n";
$final_table .= "<tr bgcolor=\"$row3_color\"><td align=right><A HREF=\"$home_url?td=view_monitoring_page\"><B>More...&nbsp;&nbsp;</B></A></tr>";
$final_table .= "</TABLE>\n";

$final_table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH=\"100%\">\n";
$final_table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$final_table .= "</TABLE><BR>";

return (\@man_down,$final_table);
}
###############
sub get_groupings{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @groupings;

$sql_query = " SELECT \
                  DISTINCT grouping \
               FROM \
                  dm_monitor_current \
               WHERE \
                  sid = '$monitor_sid' \
               ORDER BY UPPER(grouping)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@groupings,$$hash_ref{'grouping'});
}

return @groupings;
}
###############
sub get_hosts_in_group{
my ($group) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @hosts;
my @ips;

$sql_query = " SELECT \
                  DISTINCT ip_addr,host_name \
               FROM \
                  dm_monitor_current \
               WHERE \
                  sid 		= '$monitor_sid' AND \
						grouping	= '$group' \
               ORDER BY UPPER(host_name)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   push (@hosts,$$hash_ref{'host_name'});
   push (@ips,$$hash_ref{'ip_addr'});
}

return (\@hosts,\@ips);
}

###############
sub get_services_for_grouping{
my ($grouping) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @services;

$sql_query = " SELECT \
                  DISTINCT service \
               FROM \
                  dm_monitor_current \
               WHERE \
                  sid = '$monitor_sid' AND \
						grouping = '$grouping' \
					ORDER BY UPPER(service)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@services,$$hash_ref{'service'});
}

return @services;
}
#################
sub get_status_color_for{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

($args{'ip'}=~/^\d+$/) || return;
($args{'service'}) || return;

$sql_query = "	SELECT \
						current_status, \
						(UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_checked)) AS DIFF \
					FROM \
						dm_monitor_current \
					WHERE \
						ip_addr = '$args{'ip'}' AND \
						service = '$args{'service'}'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return "<B>-</B>";

# check if it is still a valid reading (less than 11 mins old)
if ($$hash_ref{'DIFF'} >= (11 * 60)){
	return &color_code("BLUE");
}
else{
	return &color_code($$hash_ref{'current_status'});
}
}
#####################
sub color_code{
my ($current_status) = @_;
my $green_image = "<img src=\"$v_graphics_path/green.gif\" alt=green width=16 height=16 border=0>";
my $yellow_image = "<img src=\"$v_graphics_path/yellow.gif\"alt=yellow  width=16 height=16 border=0>";
my $red_image = "<img src=\"$v_graphics_path/red.gif\" alt=red width=16 height=16 border=0>";
my $blue_image = "<img src=\"$v_graphics_path/blue.gif\" alt=blue width=16 height=16 border=0>";

if ($current_status =~/GREEN/){
	return $green_image;
}
elsif ($current_status =~/YELLOW/){
	return $yellow_image;
}
elsif ($current_status =~/RED/){
	return $red_image;
}
else{
	return $blue_image;
}

}
########################
sub view_monitored_host{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

($args{'long_ip'}=~/^\d+$/) || &error("No IP address passed");
$args{'service'}=~tr/a-zA-Z0-9\.\-\_//dc;
($args{'service'}) || &error("No service passed");

$sql_query = " SELECT * \
               FROM \
                  dm_monitor_current \
               WHERE \
                  ip_addr = '$args{'long_ip'}' AND \
                  service = '$args{'service'}'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || &error("No status was found for that host/service");


$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2  WIDTH=\"80%\" align=center>\n";
$table .=   "<TR BGCOLOR=\"#003366\">";
$table .=   "<TD background=\"$v_graphics_path/bg_title.gif\" colspan=3 align=center><b>Event Information</b></TD>";
$table .=   "</TR>\n";
$table .=   "<TR BGCOLOR=\"#244A75\">\n";
$table .=	"<TD align=center><b>Service</b></TD><TD align=center><b>Host</b></TD><TD align=center><b>Status</b></TD>";
$table .=	"</TR>\n";
$table .=	"<TR bgcolor=\"#001E4B\">";
$table .= 	"<TD align=center>";
$table .= 		"<B>$$hash_ref{'service'}</B>";
$table .=   "</TD>";
$table .= 	"<TD align=center>";
$table .= 	"<B>$$hash_ref{'host_name'} - " . &convert_long_ip($$hash_ref{'ip_addr'}) . "</B></TD>";
$table .= 	"<TD align=center><b>$$hash_ref{'current_status'}</b></TD>";
$table .= 	"</TR>\n";
$table .=   "<TR bgcolor=\"#001E4B\">";
$table .=   "<TD colspan=3 align=center>";
if (&is_admin){
   $table .= "<A HREF=\"$home_url?td=delete_monitored_service&long_ip=$args{'long_ip'}&service=$args{'service'}\"><B>Click to Delete Monitoring of $$hash_ref{'service'} on this Host</B></A>";
}
$table .=   "</TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=3><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE><br>\n";


$$hash_ref{'current_detail'}=~s/\n/\n<BR>/g;
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 width=\"80%\" align=center>\n";
$table .=   "<TR BGCOLOR=\"#003366\">";
$table .=   "<TD background=\"$v_graphics_path/bg_title.gif\" colspan=2 align=center><b>Current Event Detail</b></TD>";
$table .= 	"</TR>\n";
$table .=   "<TR BGCOLOR=\"#244A75\">";
$table .=   "<TD valign=top align=center>";
$table .=   &color_code($$hash_ref{'current_status'});
$table .= 	"</TD>";
#$table .=	"<TD>&nbsp;<B>[TIMESTAMP]</B></TD>";
$table .=	"<TD>&nbsp;<B>Since: $$hash_ref{'last_changed'}</B></TD>";
$table .=	"</TR>\n";
$table .= 	"<TR BGCOLOR=\"#001E4B\">";
$table .=   "<TD>&nbsp;</TD>";
$table .=	"<TD>";
$table .= 	"$$hash_ref{'current_detail'}";
$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE><br>\n";


$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2  WIDTH=\"80%\" align=center>\n";
$table .=   "<TR BGCOLOR=\"#003366\">";
$table .=   "<TD background=\"$v_graphics_path/bg_title.gif\" colspan=2 align=center><b>Last 24 Hours</b></TD>";
$table .=   "</TR>\n";
$table .=   "<TR BGCOLOR=\"#001E4B\">";
$table .=   "<TD>";
# Get the history graph:
$table .= &get_history_graph($args{'long_ip'},$args{'service'});

$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE><br>\n";
$table .= &get_previous_events(  ip       => $args{'long_ip'},
                                 service  => $args{'service'},
                                 limit    => 40,
                              );

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
############################
sub get_history_graph{
my ($long_ip,$service) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $now;
my $max_minutes = 11; #after this we figure the client is dead and reflect that in the graph
my @durations;
my @time_refs;
my @time_status;
my $day_seconds = 60 * 60 * 24;
my $now_hour;
my $start_time;
my $last_status;
my $spacer_gif		= "<IMG SRC=\"$v_graphics_path/spacer.gif\" width=2 height=20>";
my $dead_client = 0;
my $current_status = "BLUE"; #in case we get no return;

# check if it's been updated lately
# to determine what our endpoint should be:
$sql_query = " SELECT \
						current_status, \
                  UNIX_TIMESTAMP(NOW()) AS NOW, \
                  UNIX_TIMESTAMP(last_checked) AS LAST, \
                  EXTRACT(HOUR FROM NOW()) AS NOW_HOUR, \
                  UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_checked) AS DIFF \
               FROM \
                  dm_monitor_current \
                WHERE \
                  (ip_addr = '$long_ip') AND \
                  (service = '$service')";


$db_ptr = &run_query($sql_query);
$hash_ref=$db_ptr->fetchrow_hashref;
$current_status = $$hash_ref{'current_status'} if ($$hash_ref{'current_status'});
if ($$hash_ref{'DIFF'} > ($max_minutes*60)){
	$now = $$hash_ref{'NOW'};
	$dead_client = 1;
}
else{
	$now = $$hash_ref{'LAST'};
}
$now_hour = $$hash_ref{'NOW_HOUR'};

# make time scale:
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\">\n<TR>\n";
$table .= "<TD WIDTH=\"2%\">&nbsp;</TD>";
my $temp_reverse;
for (1..24){
	$temp_reverse = "<TD ALIGN=left WIDTH=\"4%\">$now_hour</TD>" . $temp_reverse;
	&subtract_hour(\$now_hour);
}
$table .= $temp_reverse;
$table .= "<TD WIDTH=\"2%\">&nbsp;</TD>";
$table .= "</TR>\n<TR><TD>&nbsp;</TD><TD colspan=24 NOWRAP>";
$table .= "<TABLE BORDER=0 WIDTH=\"100%\" CELLSPACING=1 CELLPADDING=0><TR HEIGHT=20>\n";


$sql_query = "	SELECT \ 
						UNIX_TIMESTAMP(event_timestamp) AS TIME, \
						UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME($now), INTERVAL -1 DAY)) AS START, \
						status \
					FROM \
						dm_monitor_events \
					WHERE \
						(event_timestamp >= DATE_ADD(FROM_UNIXTIME($now), INTERVAL -1 DAY)) AND \
						(ip_addr = '$long_ip') AND \
						(service = '$service') \
					ORDER BY time DESC";

$db_ptr = &run_query($sql_query);
my $time;
my $recent_events;

while ($hash_ref=$db_ptr->fetchrow_hashref){
	$recent_events = 1 if (!$recent_events);#shows that there was at least one result
	if (!$start_time){ #then this is our first run through :
		if ($dead_client){
			push (@durations,($now - $$hash_ref{'TIME'}));
			push (@time_refs,$now);
			push (@time_status,"BLUE");
		}
		$start_time = $$hash_ref{'START'};
	}
	my $duration = ($time_refs[((@time_status) - 1)]) 
			? ($time_refs[((@time_status) - 1)] - $$hash_ref{'TIME'})
			: ($now - $$hash_ref{'TIME'});
	push (@durations,$duration);
	push (@time_refs,$$hash_ref{'TIME'});
	push (@time_status,$$hash_ref{'status'});
	$time = $$hash_ref{'TIME'};
}


if ($recent_events){

	# Check for the leftover value:
	if ($time != $start_time){
		my $duration = ($time_refs[((@time_status) - 1)])
	         ? ($time_refs[((@time_status) - 1)] - $start_time)
	         : ($now - $start_time);
	#check for old value:
	$sql_query = "	SELECT status FROM dm_monitor_events \
						WHERE \
							(event_timestamp <= DATE_ADD(FROM_UNIXTIME($now), INTERVAL -1 DAY)) AND \
	                  (ip_addr = '$long_ip') AND \
	                  (service = '$service') AND \
							(sid = '$monitor_sid') \
						ORDER BY event_timestamp DESC \
						LIMIT 1";
	my $db_ptr_2 = &run_query($sql_query);
	my $hash_ref_2;
	my $old_status = ($hash_ref_2=$db_ptr_2->fetchrow_hashref)
		? $$hash_ref_2{'status'}
		: 'BLUE';

	   push (@durations,$duration);
	   push (@time_refs,$start_time);
	   push (@time_status,$old_status);# = no report
	}
}
else{
# then there were no recent results, so we'll assume that the current status is 
# what it's been for the past 24 hrs:
	push (@durations,($now - $start_time));
	$sql_query = " SELECT \
                  UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME($now), INTERVAL -1 DAY)) AS START";
	$db_ptr = &run_query($sql_query);
	($hash_ref=$db_ptr->fetchrow_hashref) || &error("DB error while trying to get date information.");
	push (@time_refs,$$hash_ref{'START'});
   push (@time_status,$current_status);# = current status we got in the beginning
}

for (my $i=((@durations)-1);$i>=0;$i--){
	my $percent = &round(($durations[$i] / $day_seconds) * 100);
#	$percent -= 1 if ($percent > 1);
	$percent = ($percent > 0) 
		? "$percent%"
		: "1%";
		#: "4";
#&debug(&convert_long_ip($long_ip) . " has $percent of the day at $time_status[$i]");
	$table .= "<TD WIDTH=\"$percent\" BGCOLOR=\"";
	if ($time_status[$i] =~/green/i){
		$table .= "green";
		$last_status = "green";
	}
	elsif ($time_status[$i] =~/red/i){
		$table .= "red";
		$last_status = "red";
	}
	elsif ($time_status[$i] =~/yellow/i){
		$table .= "yellow";
		$last_status = "yellow";
	}
	else{
		$table .= "blue";
		$last_status = "blue";
	}
	$table .= "\">$spacer_gif</TD>";
}

$table .= "<TD>&nbsp;</TD></TR>\n</TABLE>\n";
$table .="</TD></TR></TABLE>\n";
return $table;


}
##################
sub get_previous_events{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $results;

($args{'ip'}=~/^\d+$/) 	|| return;# non-critical, don't error out
($args{'service'}) 		|| return;# non-critical, don't error out
($args{'limit'}=~/^\d+$/)|| ($args{'limit'} = 40);
&safe_slash(\$args{'service'});

$sql_query = "	SELECT \
						eid, status, event_timestamp, detail \
					FROM \
						dm_monitor_events \
					WHERE \
                  (ip_addr = '$args{'ip'}') AND \
                  (service = '$args{'service'}') AND \
                  (sid = '$monitor_sid') \
               ORDER BY event_timestamp DESC \
               LIMIT $args{'limit'}";

$db_ptr = &run_query($sql_query);
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 width=\"80%\" align=center>\n";

# Header row:
$table .= "<TR BGCOLOR=\"$header_row_color\"><TD COLSPAN=2 BACKGROUND=\"$v_graphics_path/bg_title.gif\" ALIGN=center>";
$table .= "<B>Last $args{'limit'} Events</B>";
$table .= "</TD></TR>\n";


while ($hash_ref=$db_ptr->fetchrow_hashref){
	$table .= "<TR BGCOLOR=\"#244A75\">";
	$table .= "<TD ALIGN=center>";
	$table .= "<A HREF=\"$home_url?td=view_monitored_service_history_detail&eid=$$hash_ref{'eid'}\">";
	$table .= &color_code($$hash_ref{'status'});
	$table .= "</A>";
	$table .= "</TD>";
	#$table .= "<TD>&nbsp;<b>[TIMESTAMP]</b></TD>";
	$table .= "<TD>&nbsp;<b>$$hash_ref{'event_timestamp'}</b></TD>";
	$$hash_ref{'detail'}=~s/(^[\s\S]*?\n[\s\S]*?\n[\s\S]*?)\n[\s\S]*$/$1\.\.\./; #truncate detail to 3 lines
	$$hash_ref{'detail'}=~s/^[\s\S]*?\n//; #take out first line (timedate stamp)
	$$hash_ref{'detail'}=~s/\n/<BR>\n/g;
	$table .= "</TR>";
	$table .= "<TR BGCOLOR=\"#001E4B\">";
	$table .= "<TD>&nbsp;</TD>";
	$table .= "<TD>$$hash_ref{'detail'}</TD>";
	$table .= "</TR>\n";
	$results = 1;
}
$table .= "<TR><TD ALIGN=center><B>No Events in history yet</B></TD></TR>\n" if (!$results);
$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n";

return $table;
}
##################
sub subtract_hour{
my ($hour_ref) = @_;

$$hour_ref-- ;
$$hour_ref = 23 if ($$hour_ref < 0);

}
###################
sub is_admin{

return 1 if ($is_admin);
#return 1 if ($logged_in_as=~/^admin$/i);

return 0;
}
###################
sub delete_monitored_service{
my ($long_ip,$service) = @_;

($long_ip=~/^\d+$/) 	|| &error("Invalid IP passed.");
$service					=~tr/a-zA-Z0-9\.\-\_//dc;
($service) 				|| &error("No service passed");

my $sql_query;

$sql_query = "	DELETE FROM \
						dm_monitor_current \
					WHERE \
						sid 		= '$monitor_sid' AND \
						ip_addr 	= '$long_ip' AND \
						service	= '$service' ";
&connect_to_db;
($db->do($sql_query)) || &error("DB error occured while deleting service, please try again.");

&push_message("<FONT COLOR=red><CENTER>Monitored service $service for " . &convert_long_ip($long_ip) . " deleted.</CENTER></FONT>");
}
#######################
sub set_cookie{
my ($session_uid) = @_;
    my $cookie = new CGI::Cookie(-name => 's_key', -value => $session_uid, -path => '/');
    print "Set-Cookie: ",$cookie->as_string, "\n";

}
#######################
sub print_login_screen{
my $html = &get_login_page;
my $message;
if (@messages){
	foreach (@messages){
		$message .= "<CENTER>$_</CENTER><BR>";
	}
}
push (@substitutions,"\\[MESSAGE\\],-,$message");

&print_with_key('','',$html);

}
######################
sub get_login_page{

my $html;
$html = << 'EOF';
<html>
<head>
<title>DEMARC</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
td { font-family: Arial, Helvetica, sans-serif; font-size: 8pt; font-weight: normal }
A:link    {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: none; color: #FF9900 }
A:visited {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: none; color: #FF9900 }
A:hover   {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: underline; color: yellow}
A:link.nav {  font-family: Verdana, Arial, Helvetica, sans-serif; color: #000000}
A:visited.nav {  font-family: Verdana, Arial, Helvetica, sans-serif; color: #000000}
A:hover.nav {  font-family: Verdana, Arial, Helvetica, sans-serif; color: red;}
form { margin-bottom: 0}
-->
</style>
<script language="JavaScript1.1">
<!-- //Begin
function turnOn(imgName) {document[imgName].src=eval(imgName+"1.src");return false;}
function turnOff(imgName) {document[imgName].src=eval(imgName+"0.src");return false;}

function load_mini_me(){
window_handle=window.open('/dm/demarc?td=mini_me', 'MiniMe', 'top=0,left=0,scrollbars,resizable,width=166,height=500');
window_handle.focus();
return false;
}



// End -->
</script>
</head>

<body bgcolor="#000000" background="/images/background.gif" marginwidth=0 marginheight=0 topmargin=0 leftmargin=0 rightmargin=0 border=0 text=white>
<table border=0 cellpadding=0 cellspacing=0 width="100%">
<tr height=1 bgcolor=#CB9400><td><spacer type=block height=1></td></tr>
<tr height=20><td height=20 background="/images/bg_top.jpg" valign=top nowrap><center><img src="/images/demarc.jpg" width="215" height="38" alt="::demarc::" border="0"></center></td></tr>
<tr height=1 bgcolor=#B22404><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#000000><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#71797F><td><spacer type=block height=1></td></tr>

<tr bgcolor=#5A6267 height=20><td valign=top nowrap><center><spacer type=block height=20></center></td></tr>

<tr height=1 bgcolor=#333333><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#000000><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#CB9400><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#B22404><td><spacer type=block height=1></td></tr>
<tr height=2 bgcolor=#000000><td><spacer type=block height=2></td></tr>
</table>
<center>
<form method="post" action="[HOME_URL]">

        <table border="0" cellspacing="0" cellpadding="1">
          <tr><TD colspan=2 align=center>[MESSAGE]</TD></TR> 
          <tr> 
EOF
if ($allow_anonymous_access){
	$html .= << 'EOF';
            <td colspan="2" align="center"><b>Please login or click &quot;anonymous&quot; 
              button to login as an anonymous user.</b></td>
EOF
}
else{
	$html .= << 'EOF';
            <td colspan="2" align="center"><b>Please login</b></td>  
EOF
}
$html .= << 'EOF';
          </tr>
<tr><td>&nbsp;</td></tr>
	</table>
<table border="0" cellspacing="1" cellpadding="1" bgcolor="#CB9400" align="center">          
   <tr>
    <td>
        <table width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="#5A6267">
	<tr height=15><td rowspan=8 width=60>&nbsp;</td><td colspan=2><spacer type=block height=15></td><td rowspan=8 width=90>&nbsp;</td></tr>   
	<tr> 
            <td><b>Username</b></td>
            <td> 
              <input type="text" name="username" size="15" maxlength="16" autocomplete="off">
            </td>
          </tr>
          <tr> 
            <td><b>Password</b></td>
            <td> 
              <input type="password" name="password" size="15" maxlength="16" autocomplete="off">
  		<input type=hidden name=td value="login">
            </td>
          </tr>
	<tr height=5><td colspan=2><spacer type=block height=5></td></tr>
          <tr><td>&nbsp;</td> 
            <td align=center> 
              <input type="image" src="/images/bt_login0.gif" name="[login]" value="Login" alt="[login]" border=0>
            </td>
          </tr>
EOF
if ($allow_anonymous_access){
	$html .= << 'EOF';
          <tr><td>&nbsp;</td>
            <td align=center><a href="[HOME_URL]?td=login&username=anonymous&password=anonymous">anonymous</a></td>
          </tr>
EOF
}
$html .= << 'EOF';
	<tr height=15><td colspan=3><spacer type=block height=15></td></tr>
        </table>
    </td>
  </tr>
</table>
</form>
</center>
<SCRIPT LANGUAGE="JavaScript"><!--//
document.forms[0].elements[0].focus();
//--></SCRIPT>
</body>
</html>

EOF

return $html;
}
################
sub check_login{
my ($session_id) = @_;

($session_id) || return;
&expire_sessions;
my $sql_query;
my $db_ptr;
my $hash_ref;

if ($session_id eq "ANONYMOUS"){
	if ($allow_anonymous_access){
		return "Anonymous";
	}
	else{
		&error("Anonymous access is not allowed. BTW how did you get that session key unless you're trying to be a bad bad boy?","PLAIN");
	}
}

$sql_query = "	SELECT \
						admin,username,UNIX_TIMESTAMP(current_login_timedate) AS LOGINTIME \
					FROM \
						dm_sessions \
					WHERE current_session_id = '$session_id' ";

if ($validate_ip){
	# make sure their session key hasn't been jacked
	$sql_query .= " AND current_ip = '" . &convert_dotted_ip($ENV{'REMOTE_ADDR'}) . "' ";
}
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;

# extend users session if we're near the end and they're still using the session:
if (($$hash_ref{'LOGIN_TIME'} + ($session_timeout_minutes*60))  < (time() + (5*60))){
	#ie : user has less than 5 minutes left before s/he is expired
	$sql_query = "	UPDATE dm_sessions \
						SET current_login_timedate = NOW() \
						WHERE username = '$$hash_ref{'username'}'"; 
	&connect_to_db;
	($db->do($sql_query)) || &error("DB error occured while updating user's timeout. Please try again.","PLAIN");
}
# store admin value if they're an admin
$is_admin = 1 if ($$hash_ref{'admin'});
return $$hash_ref{'username'};

}
##################
sub expire_sessions{
my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = " UPDATE dm_sessions \
               SET current_session_id = '' \
               WHERE \
						DATE_ADD(current_login_timedate, INTERVAL $session_timeout_minutes MINUTE) < NOW()";
&connect_to_db;
($db->do($sql_query));
}
###################
sub login{
my ($username,$password) = @_;

&safe_slash(\$username);
&safe_slash(\$password);

my $sql_query;
my $db_ptr;
my $hash_ref;
my $crypted_pw = crypt($password,$password);
my $long_ip 	= &convert_dotted_ip($ENV{'REMOTE_ADDR'});
my $new_session_id;

if ($username eq "anonymous"){
	if ($allow_anonymous_access){
		&set_cookie("ANONYMOUS");
		&log_event(	username => "Anonymous",
						action 	=> "login",
						target	=> '',
					 );

		return "Anonymous";	
	}
	else{
		&error("Anonymous access is not allowed.","PLAIN");
	}
}

$sql_query = "	SELECT \
						ip_restrict,admin,username,current_ip,current_login_timedate \
					FROM \
						dm_sessions \
					WHERE \
						username = '$username' AND \
						password = '$crypted_pw'";

#&debug($sql_query);
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;

if (!(&check_if_immune($ENV{'REMOTE_ADDR'},$$hash_ref{'ip_restrict'}))){
		&log_event(	username => "$username",
						action 	=> "attempted login from restricted ip",
						target	=> '',
					 );
		&error("You are not allowed to log in to this service from $ENV{'REMOTE_ADDR'}","BLANK");
}


if ($$hash_ref{'current_ip'} && $$hash_ref{'current_login_timedate'}){
	&push_message("<FONT COLOR=red style=\"font-family:arial; font-size:8pt;\"><CENTER>Last login from ". &convert_long_ip($$hash_ref{'current_ip'}) . " on $$hash_ref{'current_login_timedate'}.</CENTER></FONT>");
}

#Register the new login:
$new_session_id = time() . &rand_string(6);

$sql_query = " UPDATE dm_sessions \
               SET \
						current_session_id 	  = '$new_session_id', \
						current_ip				  = '$long_ip' , \
						current_login_timedate = NOW() \
					WHERE \
						username = '$username' AND \
                  password = '$crypted_pw'";
&connect_to_db;
($db->do($sql_query)) || &error("DB Error while registering login.");	

&log_event(	username => "$username",
				action 	=> "login",
				target	=> '',
);

# store admin value if they're an admin
$is_admin = 1 if ($$hash_ref{'admin'});

&set_cookie($new_session_id);

return $username;
}
####################################
sub rand_string{
my ($suggested_length,$exact_length) = @_;
my $randstring;
my $i;

    for($i=0,$randstring="";$i<$suggested_length;$i++){
        if(int(rand(2))){
            $randstring.=chr(65+(int(rand(26))));
        }
        else{
            $randstring.=chr(97+(int(rand(26))));
        }
		if (!$exact_length){
        if(int(rand(2))){
            $randstring.=int(rand(10));
        }
		}
    }
    return $randstring;
}
####################################
sub logout{
	&set_cookie("REVOKED");
	&log_event(	username => "$logged_in_as",
					action 	=> "logout",
					target	=> '',
	);
}
####################################
sub print_monitor_ids_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my @signatures;
my $sig_list;
my $table;
my $email_tag;
my $users_email;
my $non_admin_where;
my $ip_list;
my $group_list;
my $service_list;

$html = &get_monitor_ids_form;

@signatures = &get_signatures_array;

#$sig_list = "<SELECT NAME=signature>\n";
#$sig_list .= "<OPTION VALUE=0> - Select - </OPTION>";
foreach (@signatures){
	my $shorter_sig = $_;
	$shorter_sig=~s/(^.{50}).*$/$1\.\.\./;
	$sig_list .= "<OPTION VALUE=\'$_\'>$shorter_sig</OPTION>\n";
}
$sig_list .= "</SELECT>";
push (@substitutions,"\\[SIGNATURE_LIST\\],-,<SELECT NAME=signature>\n<OPTION VALUE=0> - Select - </OPTION>$sig_list");

$users_email = &get_users_email;

if (&is_admin){
	$email_tag = "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$users_email\">";
}
else{
	$email_tag = "<B>$users_email</B>";
}
push (@substitutions,"\\[EMAIL_ADDRESS\\],-,$email_tag");
$table = &print_with_key('','TO_STRING',$html);

######
# List of current alert rules:

if (!(&is_admin)){
	$non_admin_where = " AND (email_address = '$users_email') ";
}

	$sql_query = "	SELECT * \
						FROM	dm_ids_alert_rules \
						WHERE (sid = '$monitor_sid') $non_admin_where \
						ORDER BY \
							email_address";
$db_ptr = &run_query($sql_query);

	
while ($hash_ref=$db_ptr->fetchrow_hashref){
	$table .= "<FORM ACTION=\"$home_url\" METHOD=POST>";
   $table .= "<INPUT TYPE=hidden NAME=td VALUE=\"alter_ids_alert_rule\">";
   $table .= "<INPUT TYPE=hidden NAME=alert_uid VALUE=\"$$hash_ref{'alert_uid'}\">";
	$table .= "<TABLE BORDER=0 WIDTH=\"80%\" CELLSPACING=1 CELLPADDING=2 align=center>\n";
   $table .= "<TR bgcolor=\"#003366\"><TD colspan=4 align=center background=\"$v_graphics_path/bg_title.gif\"><B>Modify IDS Monitor Alert Rule $$hash_ref{'alert_uid'}</B></TD></TR>\n";
   $table .= "<TR bgcolor=\"#244A75\">";
	$table .= "<TD align=center width=\"25%\"><b>Email Recipient</b></TD><TD align=center width=\"25%\"><b>Alert Level</b></TD>";
   $table .= "<TD align=center width=\"25%\"><b>Notify From</b></TD><TD align=center width=\"25%\"><b>Notify Until</b></TD>";
	$table .= "</TR>";
	$table .= "<TR bgcolor=\"#001E4B\">";
   $table .= "<TD align=center>";
   $table .= (&is_admin || ($users_email eq $$hash_ref{'email_address'}))
            ? "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$$hash_ref{'email_address'}\">"
            : $$hash_ref{'email_address'};
   $table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= "<SELECT NAME=priority_level>";
my @p_array;
	$p_array[1] = "RED / P-1-";
	$p_array[2] = "YELLOW / P-2-";
	$p_array[3] = "P-3-";
	$p_array[4] = "P-4-";
	$p_array[5] = "P-5-";
	$p_array[6] = "P-6-";
	$table .= ($$hash_ref{'priority_level'})
				? "<OPTION VALUE=\"$$hash_ref{'priority_level'}\" selected>$p_array[$$hash_ref{'priority_level'}]</OPTION><OPTION VALUE=0>-Select-</OPTION>"
				: "<OPTION value=0 selected>-Select-</OPTION>";
	$table .= << "EOF";
                <option value="1">RED / P-1-</option>
                <option value="2">YELLOW / P-2-</option>
                <option value="3">P-3-</option>
                <option value="4">P-4-</option>
                <option value="5">P-5-</option>
                <option value="6">P-6-</option>
              </select>
EOF
	$table .= "</TD>";
   $table .= "<TD align=center>";
   $table .= "<SELECT NAME=only_alert_from_hour>";
   my $hr_alert_hour = $$hash_ref{'only_alert_from_hour'};
   if ($hr_alert_hour == 0){
      $hr_alert_hour = "12 AM";
   }
   elsif ($hr_alert_hour < 12){
      $hr_alert_hour = "$hr_alert_hour AM";
   }
   elsif ($hr_alert_hour == 12){
      $hr_alert_hour = "12 PM";
   }
   else{
      $hr_alert_hour -= 12;
      $hr_alert_hour = "$hr_alert_hour PM";
   }

   $table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_from_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF
   $table .= "</TD><TD align=center>";
   $table .= "<SELECT NAME=only_alert_to_hour>";
   $hr_alert_hour = $$hash_ref{'only_alert_to_hour'};
   if ($hr_alert_hour == 0){
      $hr_alert_hour = "12 AM";
   }
   elsif ($hr_alert_hour < 12){
      $hr_alert_hour = "$hr_alert_hour AM";
   }
   else{
      $hr_alert_hour -= 12;
      $hr_alert_hour = "$hr_alert_hour PM";
   }

   $table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_to_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF
	$table .= "</TD>";
	$table .= "</TR>\n";
   $table .= "<TR bgcolor=\"#244A75\">";
   $table .= "<TD align=center colspan=2><b>Existing Signature</b></TD><TD align=center colspan=2><b>Signature Contains</b></TD>";
   $table .= "</TR>";
   $table .= "<TR bgcolor=\"#001E4B\">";
	$table .= "<TD align=center colspan=2>";
	$table .= "<SELECT NAME=signature>";
	$table .= ($$hash_ref{'signature_is'})
				? "<OPTION selected>$$hash_ref{'signature_is'}</OPTION><OPTION value=0>-Select-</OPTION>"
				: "<OPTION selected value=0>-Select-</OPTION>";
	$table .= $sig_list;
	$table .= "</TD>";
	$table .= "<TD align=center colspan=2><INPUT TYPE=text SIZE=30 maxlength=60 NAME=signature_contains VALUE=\"$$hash_ref{'signature_contains'}\"></TD>";
	$table .= "</TR>\n";

## Third Row
	$table .= "<TR bgcolor=\"#001E4B\">";
	$table .= "<TD COLSPAN=4 ALIGN=center>";
	$table .= << "EOF";
<SELECT NAME=action>
<OPTION selected>Update</OPTION>
<OPTION>Delete</OPTION>
</SELECT>
EOF
	$table .= "<INPUT TYPE=Submit VALUE=Update style=\"font-size:8pt\"></TD>";
	$table .= "</TR>\n";
	$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
	$table .= "</TABLE>\n";
	$table .= "</FORM><br>\n";
}




push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
####################################
sub print_monitor_md5_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my $table;
my $email_tag;
my $users_email;
my $non_admin_where;


$users_email = &get_users_email;

if (&is_admin){
	$email_tag = "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$users_email\">";
}
else{
	$email_tag = "<B>$users_email</B>";
}
push (@substitutions,"\\[EMAIL_ADDRESS\\],-,$email_tag");

my $sid_list = &get_sids_dropdown("monitored_sid","ANY");
push (@substitutions,"\\[SID_LIST\\],-,$sid_list");

$table = &print_with_key($monitor_md5_form,'TO_STRING');

######
# List of current alert rules:

if (!(&is_admin)){
	$non_admin_where = " AND (email_address = '$users_email') ";
}

	$sql_query = "	SELECT *, \
						((TIME_TO_SEC(suspend_until) - TIME_TO_SEC(NOW()))/60) AS MINUTE_DIFF \
						FROM	dm_md5_alert_rules \
						WHERE (sid = '$monitor_sid') $non_admin_where \
						ORDER BY \
							UPPER(email_address)";
$db_ptr = &run_query($sql_query);

	
$sid_list=~s/^[\s\S]*?\/option\s*>//i;

while ($hash_ref=$db_ptr->fetchrow_hashref){
	$table .= "<FORM ACTION=\"$home_url\" METHOD=POST>";
   $table .= "<INPUT TYPE=hidden NAME=td VALUE=\"alter_md5_alert_rule\">";
   $table .= "<INPUT TYPE=hidden NAME=alert_uid VALUE=\"$$hash_ref{'alert_uid'}\">";
	$table .= "<TABLE BORDER=0 WIDTH=\"80%\" CELLSPACING=1 CELLPADDING=2 align=center>\n";
	$table .= "<TR BGCOLOR=\"#003366\"><TD align=center background=\"$v_graphics_path/bg_title.gif\" colspan=4><B>Current MD5 File Integrity Alert Rule $$hash_ref{'alert_uid'}</B></TD></TR>\n";
#ROW 1 
  	$table .= "<TR bgcolor=\"#244A75\">";
	$table .= "<TD colspan=2 align=center width=\"50%\"><b>Email Recipient</b></TD><TD align=center width=\"50%\" colspan=2><b>Sensor</b></TD>";
	$table .= "</TR>\n";

	$table .= "<TR bgcolor=\"#001E4B\">";
   $table .= "<TD align=center colspan=2 >";
   $table .= (&is_admin || ($users_email eq $$hash_ref{'email_address'}))
            ? "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$$hash_ref{'email_address'}\">"
            : $$hash_ref{'email_address'};
   $table .= "</TD>";
	$table .= "<TD align=center colspan=2>";
	$table .= "<SELECT NAME=monitored_sid>\n";
	$table .= ($$hash_ref{'monitored_sid'})
				? "<OPTION selected>$$hash_ref{'monitored_sid'}</OPTION><OPTION VALUE=0>ANY</OPTION>"
				: "<OPTION selected VALUE=0>ANY</OPTION>";
	$table .= $sid_list;
	$table .= "</TD>";
	$table .= "</TR>";

   $table .= "<TR bgcolor=\"#244A75\">";
   $table .= "<TD align=center><b>Alert Level</b></TD><TD align=center><b>Email Detail Level</b></TD><TD align=center><b>Notify From</b></TD><TD align=center><b>Notify Until</b></TD>";
   $table .= "</TR>\n";
	$table .= "<TR bgcolor=\"#001E4B\">";
   $table .= "<TD ALIGN=center>";
   $table .= "<SELECT NAME=alert_level>\n";
      if ($$hash_ref{'alert_level'} == 1){
         $table .= "<OPTION VALUE=0>ANY</OPTION>";
         $table .= "<OPTION VALUE=1 selected>RED</OPTION>";
         $table .= "<OPTION VALUE=2>YELLOW</OPTION>";
      }
      elsif ($$hash_ref{'alert_level'} == 2){
         $table .= "<OPTION VALUE=0>ANY</OPTION>";
         $table .= "<OPTION VALUE=1>RED</OPTION>";
         $table .= "<OPTION VALUE=2 selected>YELLOW</OPTION>";
      }
      else{
         $table .= "<OPTION VALUE=0 selected>ANY</OPTION>";
         $table .= "<OPTION VALUE=1>RED</OPTION>";
         $table .= "<OPTION VALUE=2>YELLOW</OPTION>";
      }
   $table .= "</SELECT>";

   $table .= "</TD>";
   $table .= "<TD ALIGN=center>";
   $table .= "<SELECT NAME=detail_level>\n";
      if ($$hash_ref{'detail_level'} == 1){
         $table .= "<OPTION VALUE=1 selected>High</OPTION>";
      }
      else{
         $table .= "<OPTION VALUE=0 selected>Low</OPTION>";
      }
   $table .= << "EOF";
<OPTION VALUE=0>Low</OPTION>
<OPTION VALUE=1>High</OPTION>
EOF

   $table .= "</SELECT>";
	$table .= "</TD>";

   $table .= "<TD ALIGN=center>";
   $table .= "<SELECT NAME=only_alert_from_hour>";
   my $hr_alert_hour = $$hash_ref{'only_alert_from_hour'};
   if ($hr_alert_hour == 0){
      $hr_alert_hour = "12 AM";
   }
   elsif ($hr_alert_hour < 12){
      $hr_alert_hour = "$hr_alert_hour AM";
   }
   elsif ($hr_alert_hour == 12){
      $hr_alert_hour = "12 PM";
   }
   else{
      $hr_alert_hour -= 12;
      $hr_alert_hour = "$hr_alert_hour PM";
   }

   $table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_from_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF

   $table .= "</TD><TD align=center>";
   $table .= "<SELECT NAME=only_alert_to_hour>";
   $hr_alert_hour = $$hash_ref{'only_alert_to_hour'};
   if ($hr_alert_hour == 0){
      $hr_alert_hour = "12 AM";
   }
   elsif ($hr_alert_hour < 12){
      $hr_alert_hour = "$hr_alert_hour AM";
   }
   else{
      $hr_alert_hour -= 12;
      $hr_alert_hour = "$hr_alert_hour PM";
   }

   $table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_to_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF


   $table .= "</TD></TR>\n";

   $table .= "<TR bgcolor=\"#244A75\">";
   $table .= "<TD align=center colspan=4><b>Suspend Alerts (Hours)</b></TD>";
   $table .= "</TR>\n";
	$table .= "<TR bgcolor=\"#001E4B\">";
   $table .= "<TD ALIGN=center colspan=4>";
   $table .= << "EOF";
<SELECT NAME=suspend_alerts>
<OPTION VALUE=0 selected>NA</OPTION>
<OPTION VALUE=99>RESET</OPTION>
<OPTION VALUE=1> 1 </OPTION>
<OPTION VALUE=2> 2 </OPTION>
<OPTION VALUE=3> 3 </OPTION>
<OPTION VALUE=4> 4 </OPTION>
<OPTION VALUE=5> 5 </OPTION>
<OPTION VALUE=6> 6 </OPTION>
</SELECT>
</TD>
EOF
	$table .= "</TR>";


   $table .= "<TR bgcolor=\"#001E4B\">";
   $table .= "<TD COLSPAN=4 ALIGN=center>";	
	if ($$hash_ref{'MINUTE_DIFF'} > 0){
		$table .= "<B>Alerts suspended for $$hash_ref{'MINUTE_DIFF'} more minutes.</B><BR>";
	}

	$table .= << "EOF";
<SELECT NAME=action>
<OPTION selected>Update</OPTION>
<OPTION>Delete</OPTION>
</SELECT>
EOF
	$table .= "<INPUT TYPE=Submit VALUE=Update style=\"font-size:8pt\"></TD>";
	$table .= "</TR>\n";
	$table .= "<TR BGCOLOR=\"#003366\" HEIGHT=2><TD colspan=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
	$table .= "</TABLE>\n";
	$table .= "</FORM><BR>\n";
}




push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
####################################
sub print_monitor_service_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my @services;
my $service_list;
my $table;
my $email_tag;
my $users_email;
my $non_admin_where;
my @ip_addresses;
my $ip_list;
my @groups;
my $group_list;

$html = &get_monitor_service_form;

$service_list = &get_services_dropdown;

$service_list=~s/^[\s\S]+?<\/OPTION>//i; #take it out for the update form later
push (@substitutions,"\\[SERVICE_LIST\\],-,<SELECT NAME=service><OPTION VALUE=any selected>ANY</OPTION>$service_list");

@ip_addresses = &get_ip_address_array;
foreach (@ip_addresses){
	$ip_list .= "<OPTION VALUE=\"$_\">" . &convert_long_ip($_) . "</OPTION>";
}
$ip_list .= "</SELECT>";
push (@substitutions,"\\[IP_LIST\\],-,<SELECT NAME=ip_addr><OPTION selected>ANY</OPTION>$ip_list");

@groups = &get_group_array;
foreach (@groups){
	$group_list .= "<OPTION>$_</OPTION>";
}
$group_list .= "</SELECT>";
push (@substitutions,"\\[GROUP_LIST\\],-,<SELECT NAME=grouping><OPTION selected>ANY</OPTION>$group_list");


$users_email = &get_users_email;

if (&is_admin){
	$email_tag = "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$users_email\">";
}
else{
	$email_tag = "<B>$users_email</B>";
}
push (@substitutions,"\\[EMAIL_ADDRESS\\],-,$email_tag");
$table = &print_with_key('','TO_STRING',$html);

###
# Now for the existing alerts:
if (!(&is_admin)){
	$non_admin_where = " AND (email_address = '$users_email') ";
}

	$sql_query = "	SELECT * \
						FROM	dm_monitor_alert_rules \
						WHERE (sid = '$monitor_sid') $non_admin_where \
						ORDER BY \
							grouping,ip_addr";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   $table .= "<TABLE BORDER=0 WIDTH=\"85%\" CELLSPACING=1 CELLPADDING=2 align=center>\n";
   $table .= "<TR bgcolor=\"#003366\"><TD colspan=4 align=center background=\"$v_graphics_path/bg_title.gif\"><B>Host/Service Monitor Alert Rule $$hash_ref{'alert_uid'}</B></TD></TR>\n";
	$table .= "<FORM ACTION=\"$home_url\" METHOD=POST>";
	$table .= "<TR bgcolor=\"#244A75\">\n";
	$table .= "<TD ALIGN=center width=\"25%\"><b>Email Recipient</b></TD>";
	$table .= "<TD ALIGN=center width=\"25%\"><b>IP Address</b></TD>";
	$table .= "<TD ALIGN=center width=\"25%\"><b>Group</b></TD>";
	$table .= "<TD ALIGN=center width=\"25%\"><b>Maximum Alert Frequency</b></TD>";
$table .= "</TR>\n";
	$table .= "<TR bgcolor=\"#001E4B\">\n";
   $table .= "<TD align=center>";
   if (&is_admin){
         $table .= "<INPUT TYPE=text SIZE=22 NAME=email_address VALUE=\"$$hash_ref{'email_address'}\">";
   }
   else{
         $table .= "<B>$$hash_ref{'email_address'}</B>";
   }
   $table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= "<INPUT TYPE=hidden NAME=td VALUE=\"alter_monitor_alert_rule\">";
	$table .= "<INPUT TYPE=hidden NAME=alert_uid VALUE=\"$$hash_ref{'alert_uid'}\">";
	$table .= "<SELECT NAME=ip_addr>";
	$table .= ($$hash_ref{'ip_addr'})
				? "<OPTION VALUE=\"$$hash_ref{'ip_addr'}\" selected>" . &convert_long_ip($$hash_ref{'ip_addr'}) . "</OPTION><OPTION VALUE=any>ANY</OPTION>"
				: "<OPTION value=any selected>ANY</OPTION>";
	$table .= $ip_list;
	$table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= "<SELECT NAME=grouping>";
	$table .= ($$hash_ref{'grouping'})
				? "<OPTION selected>$$hash_ref{'grouping'}</OPTION><OPTION value=any>ANY</OPTION>"
				: "<OPTION selected>ANY</OPTION>";
	$table .= $group_list;
	$table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= "<SELECT NAME=limit_alerts>";
	$table .= ($$hash_ref{'limit_alerts'})
				? "<OPTION VALUE=\"$$hash_ref{'limit_alerts'}\" selected>$$hash_ref{'limit_alerts'} Mins</OPTION><OPTION VALUE=0>No Rate Limit</OPTION>"
				: "<OPTION selected>No Rate Limit</OPTION>";
	$table .= << "EOF";
<OPTION VALUE=10>10 Mins</OPTION>
<OPTION VALUE=15>15 Mins</OPTION>
<OPTION VALUE=30>30 Mins</OPTION>
<OPTION VALUE=45>45 Mins</OPTION>
<OPTION VALUE=60>60 Mins</OPTION>
</SELECT>
EOF
	$table .= "</TD>";
	$table .= "</TR>\n";
## Second Row
	$table .= "<TR bgcolor=\"#244A75\">\n";
	$table .= "<TD align=center nowrap><b>Notify of REDs until Resolved</b></TD><TD align=center nowrap><b>Notify of YELLOWs until Resolved</b></TD><TD align=center><b>Notify From</b></TD><TD align=center><b>Notify Until</b></TD>";
	$table .= "</TR>\n";
   $table .= "<TR bgcolor=\"#001E4B\">\n";
	$table .= "<TD align=center>";
	$table .= "<SELECT NAME=continual_reds>";
	$table .= ($$hash_ref{'continual_reds'})
				? "<OPTION VALUE=1 selected>Yes</OPTION>"
				: "<OPTION VALUE=0 selected>No</OPTION>";
	$table .= << "EOF";
<OPTION VALUE=1>Yes</OPTION>
<OPTION VALUE=0>No</OPTION>
</SELECT>
EOF
	$table .= "</TD>";
   $table .= "<TD align=center>";
	$table .= "<SELECT NAME=continual_yellows>";
	$table .= ($$hash_ref{'continual_yellows'})
				? "<OPTION VALUE=1 selected>Yes</OPTION>"
				: "<OPTION VALUE=0 selected>No</OPTION>";
	$table .= << "EOF";
<OPTION VALUE=1>Yes</OPTION>
<OPTION VALUE=0>No</OPTION>
</SELECT>
EOF
   $table .= "</TD>";
   $table .= "<TD align=center>";
	$table .= "<SELECT NAME=only_alert_from_hour>";
	my $hr_alert_hour = $$hash_ref{'only_alert_from_hour'};
	if ($hr_alert_hour == 0){
		$hr_alert_hour = "12 AM";
	}
	elsif ($hr_alert_hour < 12){
		$hr_alert_hour = "$hr_alert_hour AM";
	}
	elsif ($hr_alert_hour == 12){
		$hr_alert_hour = "12 PM";
	}
	else{
		$hr_alert_hour -= 12;
		$hr_alert_hour = "$hr_alert_hour PM";
	}

	$table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_from_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF
   $table .= "</TD>";
   $table .= "<TD align=center>";
	$table .= "<SELECT NAME=only_alert_to_hour>";
	$hr_alert_hour = $$hash_ref{'only_alert_to_hour'};
	if ($hr_alert_hour == 0){
		$hr_alert_hour = "12 AM";
	}
	elsif ($hr_alert_hour < 12){
		$hr_alert_hour = "$hr_alert_hour AM";
	}
	else{
		$hr_alert_hour -= 12;
		$hr_alert_hour = "$hr_alert_hour PM";
	}

	$table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_to_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF


	$table .= "</TD></TR>\n";
## Third Row
   $table .= "<TR bgcolor=\"#244A75\">\n";
	$table .= "<TD ALIGN=center><b>Alert Level</b></TD><TD ALIGN=center><b>Email Detail Level</b></TD><TD ALIGN=center colspan=2><b>Service</b></TD>";
   $table .= "</TR>\n";
   $table .= "<TR bgcolor=\"#001E4B\">\n";
   $table .= "<TD align=center>";
	$table .= "<SELECT NAME=alert_level>\n";
   $table .= ($$hash_ref{'status_level'})
            ? "<OPTION selected>$$hash_ref{'status_level'}</OPTION><OPTION VALUE=\"any\">ANY</OPTION>"
            : "<OPTION VALUE=\"any\" selected>ANY</OPTION>";
	$table .= << "EOF";
<OPTION VALUE="red">RED</OPTION>
<OPTION VALUE="yellow">YELLOW</OPTION>
<OPTION VALUE="blue">BLUE</OPTION>
</SELECT>
EOF

	$table .= "</TD>";
   $table .= "<TD align=center>";
   $table .= "<SELECT NAME=detail_level>\n";
   if ($$hash_ref{'detail_level'} == 1){
		$table .= "<OPTION VALUE=1 selected>High</OPTION>";
	}
	else{
		$table .= "<OPTION VALUE=0 selected>Low</OPTION>";
	}
   $table .= << "EOF";
<OPTION VALUE="0">Low</OPTION>
<OPTION VALUE="1">High</OPTION>
</SELECT>
</TD>
EOF

	$table .= "<TD COLSPAN=2 ALIGN=center>";
	$table .= "<SELECT NAME=service>\n";
	$table .= ($$hash_ref{'service'})
				? "<OPTION selected>$$hash_ref{'service'}</OPTION><OPTION VALUE=\"NOT_SELECTED\" >ANY</OPTION>"
				: "<OPTION VALUE=\"NOT_SELECTED\" selected>ANY</OPTION>";
	$table .= $service_list;
	$table .= "</TD></TR>\n";
###
# Update Button Row
	$table .= "<TR bgcolor=\"#001E4B\"><TD COLSPAN=4 ALIGN=center>";
	$table .= << "EOF";
<SELECT NAME=action>
<OPTION selected>Update</OPTION>
<OPTION>Delete</OPTION>
</SELECT>
EOF
	$table .= "<INPUT TYPE=Submit VALUE=Update style=\"font-size:8pt\"></TD>";
	$table .= "</TR>\n";
   $table .= "<TR HEIGHT=2 bgcolor=\"#003366\"><TD colspan=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
	$table .= "</TABLE>\n";
	$table .= "</FORM><br>";
}
	
	


push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
#####################################
sub get_signatures_array{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @signatures;

$sql_query = "	SELECT \
						DISTINCT signature,sig_name \
					FROM event \
					LEFT JOIN signature ON event.signature = signature.sig_id
					ORDER BY UPPER(sig_name)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@signatures,$$hash_ref{'sig_name'});
}


return @signatures;
}
#####################################
sub get_services_array{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @services;

$sql_query = "	SELECT \
						DISTINCT service \
					FROM dm_monitor_current \
					ORDER BY UPPER(service)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@services,$$hash_ref{'signature'});
}


return @services;
}
#####################################
sub get_ip_address_array{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @ips;

$sql_query = "	SELECT \
						DISTINCT ip_addr \
					FROM dm_monitor_current \
					ORDER BY UPPER(ip_addr)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@ips,$$hash_ref{'ip_addr'});
}


return @ips;
}
#####################################
sub get_group_array{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @groups;

$sql_query = "	SELECT \
						DISTINCT grouping \
					FROM dm_monitor_current \
					ORDER BY UPPER(grouping)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@groups,$$hash_ref{'grouping'});
}


return @groups;
}
######################################
sub get_monitor_ids_form{
my $html;

open (IN,$monitor_ids_form) || &error("Can't open IDS form");
while (<IN>){
	$html .= $_;
}
close IN;

return $html;
}
###############
sub get_search_form{
my $html;

open (IN,$search_form) || &error("Can't open Search form");
while (<IN>){
	$html .= $_;
}
close IN;

return $html;
}
######################################
sub get_monitor_service_form{
my $html;

open (IN,$monitor_service_form) || &error("Can't open Service form");
while (<IN>){
	$html .= $_;
}
close IN;

return $html;
}
##############
sub get_new_service_page{
my $html;

open (IN,$new_service_form) || &error("Can't open New Service form");
while (<IN>){
	$html .= $_;
}
close IN;

return $html;

}
##############
sub get_generic_page{
my ($file) = @_;
if (!(-r $file)){
	print STDERR "Can't read template file: $file : $!\n";#For the web logs!
	&error("Can't read template file");
}
my $html;

open (IN,$file) || &error("Can't open form template");
while (<IN>){
   $html .= $_;
}
close IN;

return $html;

}
######################################
sub get_users_email{
my $sql_query;
my $db_ptr;
my $hash_ref;
&safe_slash(\$logged_in_as);

$sql_query = "	SELECT \
						email_address \
					FROM dm_sessions \
					WHERE \
						username = '$logged_in_as'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;

return $$hash_ref{'email_address'};
}
######################################
sub add_host_monitoring_event{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $users_email;

#check the input:
($FORM{'alert_level'}=~/^red$|^yellow$|^blue$/)
	|| ($FORM{'alert_level'}='');
($FORM{'service'}) || ($FORM{'service'} = "");
$FORM{'service'} = '' if ($FORM{'service'} eq "NOT_SELECTED");
($FORM{'continual_reds'}=~/^1$/)
	|| ($FORM{'continual_reds'}="0");
($FORM{'continual_yellows'}=~/^1$/)
	|| ($FORM{'continual_yellows'}="0");
($FORM{'limit_alerts'}=~/^\d+$/)
	|| ($FORM{'limit_alerts'}="0");
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
(($FORM{'only_alert_from_hour'}>=0) && ($FORM{'only_alert_from_hour'}<24))
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
(($FORM{'only_alert_to_hour'}>=0) && ($FORM{'only_alert_to_hour'}<24))
	|| ($FORM{'only_alert_to_hour'}="23");
($FORM{'ip_addr'}=~/^\d+$/)
	|| ($FORM{'ip_addr'}='');
$FORM{'grouping'} = '' if ($FORM{'grouping'}=~/^any$/i);
($FORM{'detail_level'}=~/^\d+$/)
	|| ($FORM{'detail_level'}='0');

&safe_slash(\$FORM{'service'});
&safe_slash(\$FORM{'grouping'});

if (&is_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};


}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
}
&safe_slash(\$users_email);

$sql_query = "	INSERT INTO \
						dm_monitor_alert_rules \
					VALUES( \
						'$monitor_sid', '$FORM{'grouping'}', \
						'$FORM{'ip_addr'}', '$FORM{'service'}', \
						'$FORM{'limit_alerts'}','$users_email', \
						'$FORM{'continual_reds'}','$FORM{'continual_yellows'}', \
						'$FORM{'only_alert_from_hour'}','$FORM{'only_alert_to_hour'}', \
						'','$FORM{'alert_level'}','$FORM{'detail_level'}')";
&connect_to_db;
($db->do($sql_query)) || &error("DB Error while inserting monitoring alert.");	
&push_message("<FONT COLOR=red><CENTER>Monitoring Event Added</CENTER></FONT>");

&log_event(	username => "$logged_in_as",
				action 	=> "added host monitoring alert rule",
				target	=> "$users_email",
			 );
					


}
######################################
sub add_ids_monitoring_event{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $users_email;

#check the input:
($FORM{'signature'}) || ($FORM{'signature'} = ''); #takes out the "0" if no selection
($FORM{'priority_level'}=~/^\d$/)
	|| ($FORM{'priority_level'}='');
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
(($FORM{'only_alert_from_hour'}>=0) && ($FORM{'only_alert_from_hour'}<24))
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
(($FORM{'only_alert_to_hour'}>=0) && ($FORM{'only_alert_to_hour'}<24))
	|| ($FORM{'only_alert_to_hour'}="23");


&safe_slash(\$FORM{'signature'});
&safe_slash(\$FORM{'signature_contains'});

if (&is_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};


}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
}
&safe_slash(\$users_email);
$sql_query = "	INSERT INTO \
						dm_ids_alert_rules \
					VALUES( \
						'$monitor_sid', '',
						'$FORM{'signature'}', '$FORM{'signature_contains'}', \
						'$FORM{'priority_level'}','$users_email', \
						'$FORM{'only_alert_from_hour'}','$FORM{'only_alert_to_hour'}','' \
					) ";
&connect_to_db;
($db->do($sql_query)) || &error("DB Error while inserting monitoring alert.");	
&push_message("<FONT COLOR=red><CENTER>IDS Monitoring Event Added</CENTER></FONT>");

&log_event(	username => "$logged_in_as",
				action 	=> "added IDS monitoring alert rule",
				target	=> "$users_email",
			 );
					


}
######################################
sub add_md5_monitoring_event{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $users_email;

#check the input:
($FORM{'alert_level'}=~/^[12]$/)
	|| ($FORM{'alert_level'}='');
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
(($FORM{'only_alert_from_hour'}>=0) && ($FORM{'only_alert_from_hour'}<24))
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
(($FORM{'only_alert_to_hour'}>=0) && ($FORM{'only_alert_to_hour'}<24))
	|| ($FORM{'only_alert_to_hour'}="23");
($FORM{'monitored_sid'}=~/^\d+$/)
	|| ($FORM{'monitored_sid'}="");
($FORM{'detail_level'}=~/^\d+$/)
	|| ($FORM{'detail_level'}="0");


&safe_slash(\$FORM{'signature'});
&safe_slash(\$FORM{'signature_contains'});

if (&is_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};


}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
}
&safe_slash(\$users_email);

$sql_query = "	INSERT INTO \
						dm_md5_alert_rules \
					VALUES( \
						'$monitor_sid', '$FORM{'monitored_sid'}',
						'','$FORM{'alert_level'}','$users_email', \
						'$FORM{'only_alert_from_hour'}','$FORM{'only_alert_to_hour'}','','$FORM{'detail_level'}' \
					) ";
&connect_to_db;
($db->do($sql_query)) || &error("DB Error while inserting monitoring alert.");	
&push_message("<FONT COLOR=red><CENTER>File Integrity Monitoring Event Added</CENTER></FONT>");

&log_event(	username => "$logged_in_as",
				action 	=> "added MD5 monitoring alert rule",
				target	=> "$users_email",
			 );
					


}
###################################################
sub update_md5_alert_rule{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $where;
my $users_email;

($FORM{'alert_level'}=~/^[12]$/)
	|| ($FORM{'priority_level'}='');
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
($FORM{'monitored_sid'}=~/^\d+$/)
	|| ($FORM{'monitored_sid'}='');
($FORM{'detail_level'}=~/^\d+$/)
	|| ($FORM{'detail_level'}='0');
($FORM{'alert_uid'}=~/^\d+$/) || &error("Alert UID not found/ in wrong format: $FORM{'alert_uid'}");


if (&is_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};
	&safe_slash(\$FORM{'email_address'});
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_md5_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_md5_alert_rules \
							SET \
								email_address			= '$FORM{'email_address'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								monitored_sid			= '$FORM{'monitored_sid'}', \
								detail_level			= '$FORM{'detail_level'}', \
								alert_level				= '$FORM{'alert_level'}' ";
	}

	$where 		= " WHERE \
							alert_uid	= '$FORM{'alert_uid'}' ";
	$sql_query .= $where;
}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
	&safe_slash(\$users_email);
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_md5_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_md5_alert_rules \
							SET \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								monitored_sid			= '$FORM{'monitored_sid'}', \
								detail_level			= '$FORM{'detail_level'}', \
								alert_level				= '$FORM{'alert_level'}' ";
	}

	$where		= "	WHERE \
								email_address = '$users_email' AND \
								alert_uid	= '$FORM{'alert_uid'}' ";
	$sql_query .= $where;
}
&connect_to_db;
($db->do($sql_query)) || &error("No matching alert found to update.");	
if ($FORM{'action'} eq "Delete"){
	&push_message("<FONT COLOR=red><CENTER>File Integrity Alert $FORM{'alert_uid'} Deleted</CENTER></FONT>");
}
else{
	&push_message("<FONT COLOR=red><CENTER>File Integrity Alert $FORM{'alert_uid'} Modified</CENTER></FONT>");
}

###############
# Check if they wanted to suspend alerts:
if ($FORM{'suspend_alerts'}){
	if ($FORM{'suspend_alerts'} == 99){
		#then we're supposed to reset it
		$sql_query = "	UPDATE dm_md5_alert_rules \
							SET suspend_until = NOW() $where";
		($db->do($sql_query)) || &error("No matching alert found to reset suspend time.");
	}
	else{
		$sql_query = "	UPDATE dm_md5_alert_rules \
							SET suspend_until = DATE_ADD(NOW(), INTERVAL $FORM{'suspend_alerts'} HOUR) $where";
		($db->do($sql_query)) || &error("No matching alert found to update suspend time.");
	}
}

&log_event(	username => "$logged_in_as",
				action 	=> "updated MD5 monitoring alert rule",
				target	=> "$users_email",
			 );

}
###################################################
sub update_ids_alert_rule{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $users_email;

($FORM{'priority_level'}=~/^[1-6]$/)
	|| ($FORM{'priority_level'}='');
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
($FORM{'alert_uid'}=~/^\d+$/) || &error("Alert UID not found/ in wrong format: $FORM{'alert_uid'}");

&safe_slash(\$FORM{'signature'});
&safe_slash(\$FORM{'signature_contains'});

if (&is_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_ids_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_ids_alert_rules \
							SET \
								signature_is			= '$FORM{'signature'}', \
								signature_contains	= '$FORM{'signature_contains'}', \
								email_address			= '$FORM{'email_address'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								priority_level			= '$FORM{'priority_level'}' ";
	}

	$sql_query .= " WHERE \
							alert_uid	= '$FORM{'alert_uid'}' ";
}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_ids_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_ids_alert_rules \
							SET \
								signature_is			= '$FORM{'signature'}', \
								signature_contains	= '$FORM{'signature_contains'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								priority_level			= '$FORM{'priority_level'}' ";
	}

	$sql_query .= "	WHERE \
								email_address = '$users_email' AND \
								alert_uid	= '$FORM{'alert_uid'}' ";
}
&connect_to_db;
($db->do($sql_query)) || &error("No matching alert found to update.");	
if ($FORM{'action'} eq "Delete"){
	&push_message("<FONT COLOR=red><CENTER>IDS Alert $FORM{'alert_uid'} Deleted</CENTER></FONT>");
}
else{
	&push_message("<FONT COLOR=red><CENTER>IDS Alert $FORM{'alert_uid'} Modified</CENTER></FONT>");
}


&log_event(	username => "$logged_in_as",
				action 	=> "updated IDS monitoring alert rule",
				target	=> "$users_email",
			 );


}
###################################################
sub update_monitor_alert_rule{
my $sql_query;
my $db_ptr;

($FORM{'alert_level'}=~/^red$|^yellow$|^blue$/)
	|| ($FORM{'alert_level'}='');
($FORM{'service'}) || ($FORM{'service'} = "");
$FORM{'service'} = '' if ($FORM{'service'} eq "NOT_SELECTED");
($FORM{'continual_reds'}=~/^1$/)
	|| ($FORM{'continual_reds'}="0");
($FORM{'continual_yellows'}=~/^1$/)
	|| ($FORM{'continual_yellows'}="0");
($FORM{'limit_alerts'}=~/^\d+$/)
	|| ($FORM{'limit_alerts'}="0");
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
($FORM{'ip_addr'}=~/^\d+$/)
	|| ($FORM{'ip_addr'}='');
($FORM{'detail_level'}=~/^\d+$/)
	|| ($FORM{'detail_level'}='0');
$FORM{'grouping'} = '' if ($FORM{'grouping'}=~/^any$/i);
($FORM{'alert_uid'}=~/^\d+$/) || &error("Alert UID not found/ in wrong format: $FORM{'alert_uid'}");

my $users_email;
&safe_slash(\$FORM{'service'});
&safe_slash(\$FORM{'grouping'});

if (&is_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};
	&safe_slash(\$FORM{'email_address'});
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_monitor_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_monitor_alert_rules \
							SET \
								grouping 				= '$FORM{'grouping'}', \
								ip_addr					= '$FORM{'ip_addr'}', \
								service					= '$FORM{'service'}', \
								limit_alerts			= '$FORM{'limit_alerts'}', \
								email_address			= '$FORM{'email_address'}', \
								continual_reds			= '$FORM{'continual_reds'}', \  
								continual_yellows		= '$FORM{'continual_yellows'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								detail_level			= '$FORM{'detail_level'}', \
								status_level			= '$FORM{'alert_level'}' ";
	}

	$sql_query .= " WHERE \
							alert_uid	= '$FORM{'alert_uid'}' ";
}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_monitor_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_monitor_alert_rules \
							SET \
								grouping 				= '$FORM{'grouping'}', \
								ip_addr					= '$FORM{'ip_addr'}', \
								service					= '$FORM{'service'}', \
								limit_alerts			= '$FORM{'limit_alerts'}', \
								continual_reds			= '$FORM{'continual_reds'}', \  
								continual_yellows		= '$FORM{'continual_yellows'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								detail_level			= '$FORM{'detail_level'}', \
								status_level			= '$FORM{'alert_level'}' ";
	}

	$sql_query .= "	WHERE \
								email_address = '$users_email' AND \
								alert_uid	= '$FORM{'alert_uid'}' ";
}
&connect_to_db;
($db->do($sql_query)) || &error("No matching alert found to update.");	
if ($FORM{'action'} eq "Delete"){
	&push_message("<FONT COLOR=red><CENTER>Monitoring Alert $FORM{'alert_uid'} Deleted</CENTER></FONT>");
}
else{
	&push_message("<FONT COLOR=red><CENTER>Monitoring Alert $FORM{'alert_uid'} Modified</CENTER></FONT>");
}

&log_event(	username => "$logged_in_as",
				action 	=> "updated host monitoring alert rule",
				target	=> "$users_email",
			 );



}
########################
sub get_menu_bar{
my $html;

$html .= "<tr bgcolor=#5A6267><td valign=top nowrap><center>";
$html .= "<img src=\"$v_graphics_path/tn_endcapl.gif\" width=\"4\" height=\"20\" alt=\"\" border=\"0\">";

if ($current_page eq "main"){
	$html .= "<A HREF=\"$home_url\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_main2.gif\" width=\"83\" height=\"20\" alt=\"[*main screen*]\" border=\"0\" name=tn_main></a>";
}
else{
	$html .= "<A HREF=\"$home_url\" TARGET=\"_top\" onMouseOver=\"turnOn('tn_main');\" onMouseOut=\"turnOff('tn_main');\"><img src=\"$v_graphics_path/tn_main0.gif\" width=\"83\" height=\"20\" alt=\"[main screen]\" border=\"0\" name=tn_main></a>";
}

if ($current_page eq "show_events"){
	$html .= "<A HREF=\"$home_url?td=show_events&offset_type=day&offset_number=1&limit=60\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_events2.gif\" width=\"83\" height=\"20\" alt=\"[*view events*]\" border=\"0\" name=tn_events></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=show_events&offset_type=day&offset_number=1&limit=60\" TARGET=\"_top\" onMouseOver=\"turnOn('tn_events');\" onMouseOut=\"turnOff('tn_events');\"><img src=\"$v_graphics_path/tn_events0.gif\" width=\"83\" height=\"20\" alt=\"[view events]\" border=\"0\" name=tn_events></a>";
}


if ($current_page eq "monitor"){
	$html .= "<A HREF=\"$home_url?td=view_monitoring_page\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_monitor2.gif\" width=\"83\" height=\"20\" alt=\"[*monitor*]\" border=\"0\" name=tn_monitor></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=view_monitoring_page\" TARGET=\"_top\" onMouseOver=\"turnOn('tn_monitor');\" onMouseOut=\"turnOff('tn_monitor');\"><img src=\"$v_graphics_path/tn_monitor0.gif\" width=\"83\" height=\"20\" alt=\"[monitor]\" border=\"0\" name=tn_monitor></a>";
}

if ($current_page eq "md5"){
	$html .= "<A HREF=\"$home_url?td=view_md5_page&minimal=1\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_md52.gif\" width=\"83\" height=\"20\" alt=\"[*md5*]\" border=\"0\" name=tn_md5></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=view_md5_page&minimal=1\" TARGET=\"_top\" onMouseOver=\"turnOn('tn_md5');\" onMouseOut=\"turnOff('tn_md5');\"><img src=\"$v_graphics_path/tn_md50.gif\" width=\"83\" height=\"20\" alt=\"[md5]\" border=\"0\" name=tn_md5></a>";
}


if ($current_page eq "search"){
	$html .= "<A HREF=\"$home_url?td=search\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_search2.gif\" width=\"83\" height=\"20\" alt=\"[*search*]\" border=\"0\" name=tn_search></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=search\" TARGET=\"_top\" onMouseOver=\"turnOn('tn_search');\" onMouseOut=\"turnOff('tn_search');\"><img src=\"$v_graphics_path/tn_search0.gif\" width=\"83\" height=\"20\" alt=\"[search]\" border=\"0\" name=tn_search></a>";
}


if ($current_page eq "config"){
	$html .= "<A HREF=\"$home_url?td=config\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_configure2.gif\" width=\"83\" height=\"20\" alt=\"[*configure*]\"border=\"0\" name=tn_configure></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=config\" TARGET=\"_top\" onMouseOver=\"turnOn('tn_configure');\" onMouseOut=\"turnOff('tn_configure');\"><img src=\"$v_graphics_path/tn_configure0.gif\" width=\"83\" height=\"20\" alt=\"[configure]\"border=\"0\" name=tn_configure></a>";
}

=head
if ($current_page eq "about"){
	$html .= "<A HREF=\"$home_url?td=about\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_about2.gif\" width=\"83\" height=\"20\" alt=\"[*about*]\" border=\"0\" name=tn_about></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=about\" TARGET=\"_top\" onMouseOver=\"turnOn('tn_about');\" onMouseOut=\"turnOff('tn_about');\"><img src=\"$v_graphics_path/tn_about0.gif\" width=\"83\" height=\"20\" alt=\"[about]\" border=\"0\" name=tn_about></a>";
}

$html .= "<A HREF=\"$home_url?td=logout\" TARGET=\"_top\" onMouseOver=\"turnOn('tn_logout');\" onMouseOut=\"turnOff('tn_logout');\"><img src=\"$v_graphics_path/tn_logout0.gif\" width=\"83\" height=\"20\" alt=\"[logout]\" border=\"0\" name=tn_logout></a>";

=cut

$html .= "<img src=\"$v_graphics_path/tn_endcapr.gif\" width=\"4\" height=\"20\" alt=\"\" border=\"0\"></center></td></tr>";

return $html;
}
######################
sub print_age_data_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $html = &print_with_key($age_data_form,"TO_STRING");
my $local_count;
my $table1;
my $table2;

$local_count = &count_total_records;


$sql_query = "	SELECT \
						(TO_DAYS(NOW()) - TO_DAYS(timestamp)) as AGO,
						count(*) as COUNT, \
						EXTRACT(YEAR FROM timestamp) as YEAR , \
						EXTRACT(MONTH FROM timestamp) as MONTH , \
						EXTRACT(DAY FROM timestamp) as DAY \
					FROM event \
					GROUP BY \
						YEAR,MONTH,DAY \
					ORDER BY \
						YEAR, MONTH, DAY ";

$db_ptr = &run_query($sql_query);
$table1 .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 ALIGN=center WIDTH=\"80%\">\n";
$table1 .= "<TR BGCOLOR=\"#003366\"><TD ALIGN=center COLSPAN=4 background=\"$v_graphics_path/bg_title.gif\"><B>Breakdown of potential savings by day of IDS data</B></TD></TR>\n";
	$table1 .= "<TR bgcolor=\"#244A75\">";
	$table1 .= "<TD ALIGN=center><B>Days Ago</B></TD>";
	$table1 .= "<TD ALIGN=center><B>Date</B></TD>";
	$table1 .= "<TD ALIGN=center><B>Records</B></TD>";
	$table1 .= "<TD ALIGN=center><B>Cumulitive Savings If Aged Here</B></TD>";
$table1 .= "</TR>\n";

my $rev_table;
while ($hash_ref=$db_ptr->fetchrow_hashref){
	my $temp_table;
	$temp_table .= "<TR bgcolor=\"#001E4B\">";
	$temp_table .= "<TD align=center>$$hash_ref{'AGO'}</TD>";
	$temp_table .= "<TD align=center>$$hash_ref{'MONTH'}/$$hash_ref{'DAY'}/$$hash_ref{'YEAR'}</TD>";
	$temp_table .= "<TD ALIGN=center>$$hash_ref{'COUNT'}</TD>";
	$local_count -= $$hash_ref{'COUNT'};
	$temp_table .= "<TD ALIGN=center>". ($total_count - $local_count) . "</TD>";
	$temp_table .= "</TR>\n";
	$rev_table = $temp_table . $rev_table;
}
$table1 .= $rev_table;
$table1 .= "<TR bgcolor=\"#003366\" height=2><TD colspan=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table1 .= "</TABLE>";

### Host/Service data:
$sql_query = "SELECT COUNT(*) as COUNT FROM dm_monitor_events";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref);
my $service_row_count = $$hash_ref{'COUNT'};
my $local_service_row_count = $service_row_count;
	
$sql_query = "	SELECT \ 
						(TO_DAYS(NOW()) - TO_DAYS(event_timestamp)) as AGO, \
						count(*) as COUNT, EXTRACT(YEAR FROM event_timestamp) as YEAR , \
						EXTRACT(MONTH FROM event_timestamp) as MONTH , \
						EXTRACT(DAY FROM event_timestamp) as DAY \
					FROM \
						dm_monitor_events \
					GROUP BY \
						YEAR,MONTH,DAY \
					ORDER BY \
						YEAR, MONTH, DAY";
$db_ptr = &run_query($sql_query);
$table2 .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 ALIGN=center width=\"80%\">\n";
$table2 .= "<TR bgcolor=\"#003366\"><TD ALIGN=center background=\"$v_graphics_path/bg_title.gif\" COLSPAN=4><B>Breakdown of potential savings by day of Host data</B></TD></TR>\n";
   $table2 .= "<TR bgcolor=\"#244A75\">";
   $table2 .= "<TD ALIGN=center><B>Days Ago</B></TD>";
   $table2 .= "<TD ALIGN=center><B>Date</B></TD>";
   $table2 .= "<TD ALIGN=center><B>Records</B></TD>";
   $table2 .= "<TD ALIGN=center><B>Cumulitive Savings If Aged Here</B></TD>";
$table2 .= "</TR>\n";

my $rev_table;
while ($hash_ref=$db_ptr->fetchrow_hashref){
   my $temp_table;
   $temp_table .= "<TR bgcolor=\"#001E4B\">";
   $temp_table .= "<TD align=center>$$hash_ref{'AGO'}</TD>";
   $temp_table .= "<TD align=center>$$hash_ref{'MONTH'}/$$hash_ref{'DAY'}/$$hash_ref{'YEAR'}</TD>";
   $temp_table .= "<TD align=center>$$hash_ref{'COUNT'}</TD>";
   $local_service_row_count -= $$hash_ref{'COUNT'};
   $temp_table .= "<TD align=center>". ($service_row_count - $local_service_row_count) . "</TD>";
   $temp_table .= "</TR>\n";
   $rev_table = $temp_table . $rev_table;
}
$table2 .= $rev_table;
$table2 .= "<TR bgcolor=\"#003366\" height=2><TD colspan=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table2 .= "</TABLE>\n";

#################
# Put the two Age DB Data tables together:
$table = << "EOF";
$table1
<br>
$table2
EOF

$html .= $table;

push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
#######################
sub age_data{
my (%args) = @_;
($args{'services'}=~/^\d+$/) || ($args{'services'} = '');
($args{'ids'}=~/^\d+$/) || ($args{'ids'} = '');
my $sql_query;
my $db_ptr;
my $hash_ref;
my $delete_count;

#Make sure we have at least one argument:
($args{'ids'} || $args{'services'}) 
	|| &error("You must select at least one area to age.");

&connect_to_db;# Make sure we're connected bc we're doing a straight  "->do" later

if ($args{'ids'}){
	my $nogo;
	$sql_query = "	SELECT sid,cid \	
						FROM event \
						WHERE \
							timestamp < DATE_ADD(NOW(), INTERVAL -$args{'ids'} DAY)";
	$db_ptr = &run_query($sql_query);
	my @del_array;
	while ($hash_ref = $db_ptr->fetchrow_hashref){
		push (@del_array,"$$hash_ref{'sid'},$$hash_ref{'cid'}");
	}
	if (!(@del_array)){
		&push_message("<FONT COLOR=red><CENTER>No IDS records found to delete.</CENTER></FONT>");
		$nogo = 1;
	}
	else{
		$delete_count = @del_array;
	}

  if (!$nogo){
	my @tables_array = ('data','event','icmphdr','tcphdr','udphdr','iphdr','opt');
	foreach (@del_array){
   	my @temp_array = split(/,/,$_);
   	foreach (@tables_array){
   	   $sql_query = "DELETE FROM $_ WHERE sid='$temp_array[0]' AND cid='$temp_array[1]'";
			$db->do($sql_query);
   	}
	}
	&push_message("<FONT COLOR=red><CENTER>$delete_count IDS records deleted.</CENTER></FONT>");
  }
}
if ($args{'services'}){
	$sql_query = "	DELETE FROM \
							dm_monitor_events \
						WHERE \
							event_timestamp < DATE_ADD(NOW(), INTERVAL -$args{'services'} DAY)";
	my $delete_count = $db->do($sql_query);
   &push_message("<FONT COLOR=red><CENTER>$delete_count Host event records deleted.</CENTER></FONT>");
}

&log_event(	username => "$logged_in_as",
				action 	=> "aged DB data",
				target	=> "IDS: $args{'ids'} , SERVICES: $args{'services'}",
			 );


}
#######################
sub count_total_records{
my $sql_query;
my $db_ptr;
my $hash_ref;

return $total_count if ($total_count);

# Total:
$sql_query = "SELECT count(*) as count FROM event";
$db_ptr = &run_query($sql_query);
$total_count = ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'count'} : 0;

return $total_count;
}
######################
sub get_signatures_dropdown{
my ($select_name) = @_;
my $sig_list;
my @signatures;

@signatures = &get_signatures_array;

$sig_list = "<SELECT NAME=\"$select_name\">\n";
$sig_list .= "<OPTION VALUE=0> - Select - </OPTION>";
foreach (@signatures){
	my $shorter_sig = $_;
	$shorter_sig=~s/(^.{50}).*$/$1\.\.\./;
	$sig_list .= "<OPTION VALUE=\'$_\'>$shorter_sig</OPTION>\n";
}
$sig_list .= "</SELECT>";

 
return $sig_list;
}	
#############################
sub print_general_config_form{
my $html;

$html = &print_with_key($general_config_form,'TO_STRING');

push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
###############################
sub print_md5_select_menu{
my $html;

$html .= "<TABLE BORDER=0 ALIGN=center CELLSPACING=1 CELLPADDING=2>";
$html .= "<TR bgcolor=\"#003366\"><TD background=\"$v_graphics_path/bg_title.gif\" ALIGN=center><B>Configure File Integrity Check</B></TD></TR>";
$html .= "<TR bgcolor=\"#001E4B\"><TD ALIGN=center>";
$html .= &get_sid_select_table('',"update_md5_rules");
$html .= "</TD></TR>";
$html .= "<TR BGCOLOR=\"#003366\" HEIGHT=2><TD><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$html .= "</TABLE>";

push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
###############################
sub print_md5_config{
my ($sid) = @_;
($sid=~/^\d+$/) || &error("Invalid SID: $sid");
my $html;
my $hostname;
my @current_rules_array;
my $current_rules_scalar;

($hostname = &get_hostname_from_sid($sid)) 
		|| &error("SID not found in DB: $sid");
push (@substitutions,"\\[SID\\],-,$sid");
push (@substitutions,"\\[HOSTNAME\\],-,$hostname");

@current_rules_array = &get_current_md5_rules($sid);
foreach (@current_rules_array){
	$current_rules_scalar .= "$_\n";
}
push (@substitutions,"\\[MD5_RULES\\],-,$current_rules_scalar");



$html = &print_with_key($configure_md5_form,'TO_STRING');


push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
##################################
sub get_hostname_from_sid{
my ($sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
($sid=~/^\d+$/) || return;


$sql_query = "SELECT hostname FROM sensor WHERE sid = '$sid'";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return;

return $$hash_ref{'hostname'};
}
##################################
sub get_current_md5_rules{
my ($sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @array;
($sid=~/^\d+$/) || return;


$sql_query = "	SELECT \
						priority,path,recursive,description \
					FROM dm_md5_rules \
					WHERE sid = '$sid' \
					ORDER BY UPPER(priority),UPPER(path)";

$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	push (@array,"$$hash_ref{'priority'};$$hash_ref{'path'};$$hash_ref{'recursive'};$$hash_ref{'description'}");
}

return @array;
}
#################################
sub update_md5_rules{
my ($sid,$md5_rules) = @_;
($sid=~/^\d+$/) || &error("Invalid SID: $sid");
my @rule_array;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $session_uid;
my @rules_to_delete;
&connect_to_db;

@rule_array = split(/\n/,$md5_rules);



$session_uid = &rand_string(4,1);
foreach (@rule_array){
	my @rule = split(/;/,$_);
# take out spaces from beg./end of path
$rule[1]=~s/^\s+|\s+$//g;
# take out trailing slash - not needed
$rule[1]=~s/\/$//g; # g is for: /root//////
	next if (!$rule[1]); #skip bad records
	# make sure alert level is in correct format
	$rule[0]=  ($rule[0]=~/^yellow$/i)
			? "YELLOW"
			: "RED"; 
	#default to 0 for recursive option if not 1
	($rule[2]==1) || ($rule[2]=0);
	#safety first:
	&safe_slash(\$rule[3]);
	&safe_slash(\$rule[1]);

#Check to see if this is an old entry
	$sql_query = "	SELECT path FROM dm_md5_rules \
						WHERE sid = '$sid' AND path = '$rule[1]'";
	$db_ptr = &run_query($sql_query);
	if ($hash_ref = $db_ptr->fetchrow_hashref){
		$sql_query = "	UPDATE dm_md5_rules \
							SET \
								session_uid = '$session_uid', \
								description = '$rule[3]', \
								priority		= '$rule[0]', \
								recursive	= '$rule[2]' \
							WHERE \
								sid 	= '$sid' AND \
								path	= '$rule[1]'";
		$db->do($sql_query);
	}
	else{
		#Then its a new record
		$sql_query = "	INSERT INTO dm_md5_rules \
							VALUES( \
								'$sid', '', \
								'$rule[0]','$rule[1]', \
								'$rule[2]','$rule[3]', \
								NOW(),'$session_uid','1')";
		$db->do($sql_query);
	}
}
# now delete all old entries:
$sql_query = "	SELECT rule_uid \
					FROM dm_md5_rules \
					WHERE \
						sid			= '$sid' AND \
						session_uid != '$session_uid'";
$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	push (@rules_to_delete,$$hash_ref{'rule_uid'});
}
#delete the data attributed to the outdated rules:
foreach (@rules_to_delete){
	$sql_query = "	DELETE FROM dm_md5_data \
						WHERE rule_uid = '$_'";
	$db->do($sql_query);
}
# now delete the rules
$sql_query = "DELETE FROM dm_md5_rules WHERE  \
						sid			= '$sid' AND \
						session_uid != '$session_uid'";
$db->do($sql_query);


&log_event(	username => "$logged_in_as",
				action 	=> "updated md5 rules",
				target	=> "SID: $sid",
			 );

}
##################################
sub view_md5_page{
my ($minimal,$sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
($sid=~/^\d+$/) || ($sid = '');

if (!$sid){
	if (!$minimal){
		$table .= "<CENTER><A HREF=\"$home_url?td=view_md5_page&minimal=1\"><b>Click to Show Minimal View</b></A></CENTER>";
	}
	else{
		$table .= "<CENTER><A HREF=\"$home_url?td=view_md5_page\"><b>Click to Show Detailed View For All Hosts</b></A></CENTER><P>";
	}
}
else{
	$minimal = '';
}

if (!$sid){
	$sql_query = "	SELECT \
							DISTINCT sensor.sid,hostname  \
						FROM \
							dm_md5_rules \
						LEFT JOIN sensor \
						ON dm_md5_rules.sid = sensor.sid";
	$db_ptr = &run_query($sql_query);
}
else{
 $sql_query = " SELECT \
                     sensor.sid,hostname  \
                  FROM \
                     dm_md5_rules \
                  LEFT JOIN sensor \
                  ON dm_md5_rules.sid = sensor.sid \
						WHERE dm_md5_rules.sid = '$sid' \
						LIMIT 1";
   $db_ptr = &run_query($sql_query);
}
while ($hash_ref = $db_ptr->fetchrow_hashref){
	my ($temp_result,$last_checked) = &md5_find_changes($$hash_ref{'sid'},$minimal);
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 ALIGN=center width=80%>";
	$table .= "<TR bgcolor=\"#003366\"><TD COLSPAN=2 background=\"$v_graphics_path/bg_title.gif\">";

	if (!$temp_result){
		$table .= "&nbsp;<B>$$hash_ref{'sid'} - $$hash_ref{'hostname'}</B></TD></TR>";
		if ($last_checked){
			$table .= "<TR bgcolor=\"#244A75\"><TD COLSPAN=2>";
			$table .= "&nbsp;<B>Last checked on:</B> $last_checked";
			$table .= "</TD></TR>";
		}
		else{
			$table .= "<TR><TD COLSPAN=2 ALIGN=left BGCOLOR=\"#244A75\">";
			$table .= "&nbsp;<B>It appears that this host's files have never been checked.<BR>Please make sure that the client is running and is set to perform local File Integrity Checks</B>";
			$table .= "</TD></TR>";
		}
		$table .= "<TR bgcolor=\"$row3_color\"><TD WIDTH=\"10%\" align=center>";
		$table .= &color_code("GREEN");
		$table .= "</TD><TD WIDTH=\"90%\">";
		$table .= " No alerts.";
   	$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n<br>\n";
	}
	else{
		$table .= "&nbsp;<B>$$hash_ref{'sid'} - $$hash_ref{'hostname'}</B>";

		if (!$sid){
			#Give them the chance to view details for this sensor
			$table .= " &nbsp; &nbsp; <A HREF=\"$home_url?td=view_md5_details_page&sid=$$hash_ref{'sid'}\">";
			$table .= "<B>View Details for this Sensor</B>";
			$table .= "</A>";
		}

		if (&is_admin){
			
			#Give them the chance to selectively update md5s:
			$table .= " &nbsp; &nbsp; <A HREF=\"$home_url?td=confirm_selective_md5_changes&sid=$$hash_ref{'sid'}\">";
			$table .= "<B>Confirm changes for this host only</B>";
			$table .= "</A>";
		}
		$table .= "</TD></TR>";
			$table .= "<TR bgcolor=\"#244A75\"><TD COLSPAN=2>";
			$table .= "&nbsp;<B>Last checked on:</B> $last_checked";
			$table .= "</TD></TR>";
		$table .= "<TR bgcolor=\"$row3_color\"><TD COLSPAN=2>";
      $table .= $temp_result;
   	$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n<br>\n"; 
	}
}
if (&is_admin){
	$table .= "<P><CENTER><A HREF=\"$home_url?td=confirm_all_md5_changes\"><B>Confirm/Update All File Integrity Changes For All Monitored Hosts</B></A></CENTER></p><br>";
}



push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
##################################
sub print_user_config_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my $user_list;
my $user_table;

if ($logged_in_as=~/^anonymous$/i){
	&error("Anonymous users have no options here.");
}
elsif (&is_admin){
	#print admin user config menu
	($user_list,$user_table) = &get_user_list("current_user");
	push (@substitutions,"\\[USER_TABLE\\],-,$user_table");
	push (@substitutions,"\\[USER_LIST\\],-,$user_list");
	$html .= &print_with_key($admin_user_config_form,"TO_STRING");

}
else{
	#print user level user config menu
	my $users_email = &get_users_email;
	push (@substitutions,"\\[USERS_EMAIL\\],-,$users_email");
   $html .= &print_with_key($ul_user_config_form,"TO_STRING");
	if ($allow_user_to_change_email){
   	$html .= &print_with_key($ul_email_config_form,"TO_STRING");
	}
}


push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
##################################
sub print_user_level_config_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my $user_list;
my $user_table;

if ($logged_in_as=~/^anonymous$/i){
	&error("Anonymous users have no options here.");
}
else{
	#print user level user config menu
	my $users_email = &get_users_email;
	push (@substitutions,"\\[USERS_EMAIL\\],-,$users_email");
   $html .= &print_with_key($ul_user_config_form,"TO_STRING");
	if ($allow_user_to_change_email){
   	$html .= &print_with_key($ul_email_config_form,"TO_STRING");
	}
}


push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
################################
sub get_user_list{
my ($select_name) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my $table;

($select_name) || ($select_name = "username");

$sql_query = "	SELECT \
							admin,username,email_address, \
							ip_restrict,current_login_timedate,current_ip \
					FROM dm_sessions \
					ORDER BY UPPER(username)";
$db_ptr = &run_query($sql_query);

$html .= "<SELECT NAME=\"$select_name\">\n";
$html .= "<OPTION VALUE=\"NOT_SELECTED\"> - Select -</OPTION>\n";

# User Table Header
$table .= "<TR bgcolor=\"$row4_color\">";
$table .= "<TD ALIGN=center><B>Username</B></TD>";
$table .= "<TD ALIGN=center><B>Email</B></TD>";
$table .= "<TD ALIGN=center><B>Admin</B></TD>";
$table .= "<TD ALIGN=center><B>IP Restriction</B></TD>";
$table .= "<TD ALIGN=center><B>Last Login</B></TD>";
$table .= "</TR>";

while ($hash_ref = $db_ptr->fetchrow_hashref){
	#user table:
	$table .= "<TR bgcolor=\"$row3_color\">";
	$table .= "<TD>&nbsp;$$hash_ref{'username'}</TD>";
	$table .= "<TD>&nbsp;$$hash_ref{'email_address'}</TD>";
	$table .= "<TD align=center>";
	$table .= ($$hash_ref{'admin'})
			? "YES"
			: "NO";
	$table .= "</TD>";
	# wrap every other rule
	$$hash_ref{'ip_restrict'}=~s/([0-9\.\-]*?;[0-9\.\-]*)?;/$1:/g;
	$$hash_ref{'ip_restrict'}=~s/:/;<BR>/g;

	$table .= "<TD>&nbsp;$$hash_ref{'ip_restrict'}</TD>";
	$table .= "<TD align=left>$$hash_ref{'current_login_timedate'} from ";
	$table .= &convert_long_ip($$hash_ref{'current_ip'});
	$table .= "</TD>";
	$table .= "</TR>";
	#select list
	$html .= "<OPTION VALUE=\"$$hash_ref{'username'}\">$$hash_ref{'username'}";
	$html .= "</OPTION>\n";
}
$html .= "</SELECT>";


return ($html,$table);
}
################################
sub do_add_user{
my ($username,$password,$email_address,$ip_restrict) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

($username=~/^[a-zA-Z0-9 ]{3,30}$/)
	|| &error("Usernames may only include alphanumeric characters and be between 3 and 30 characters");

($password=~/.{4,}/) 
	|| &error("Password must be at least 4 characters.");
#make sure it's not all spaces:
&check_ip_restrict_value($ip_restrict);
if ($password=~/\s{2}/){
	&error("You may not have more then one whitespace character in a row.");
}
if ($username eq $password){
	&error("Come on now, you really want your username and password to be the same? <BR> Not on my watch!");
}

if ($email_address=~/.{61}/){
	&error("Email address may only be up to 60 characters.");
}

&safe_slash(\$password);
&safe_slash(\$email_address);

if (&user_exists($username)){
	&error("User with username \"$username\" already exists.");
}

if ($username=~/^anonymous$/i){
	&error("You can't add another user named $username");
}

$password = crypt($password,$password);
# OK, lets add 'em
$sql_query = "	INSERT INTO dm_sessions \
					VALUES ( \
						'$username','$password', \
						'','','','$email_address', \
						'','$ip_restrict','','')";
&connect_to_db;
($db->do($sql_query)) || &error("Error adding user.");	

&push_message("<FONT COLOR=red><CENTER>User \"$username\" Added.</CENTER></FONT>");

&log_event(	username => "$logged_in_as",
				action 	=> "added user",
				target	=> "$username",
			 );

return 1;
}
###################################
sub do_modify_user{
my ($username,$action,$value) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

if ($logged_in_as=~/^anonymous$/i){
	&error("Anonymous users have no options here.");
}

($action=~/^change_password$|^make_admin$|^remove_admin$|change_email$|^change_ip_restrict$|^delete$/)
	|| &error("Invalid action: $action");

&log_event(	username => "$logged_in_as",
				action 	=> "modified user ($action)",
				target	=> "$username",
			 );

if (!(&is_admin())){
	$username = $logged_in_as;
	&error("You are not allowed to delete your own account.") 
		if ($action=~/^delete$/);
	&error("You are not allowed to do that.") 
		if ($action=~/admin/);
	&error("You are not allowed to do that.") 
		if ($action=~/ip_restrict/);
}
if ($username=~/NOT_SELECTED/){
	&error("You must select a user to modify from the dropdown menu.");
}
(&user_exists($username)) 
   || &error("User \"$username\" doesn't exist.");

if ($action=~/^change_password$/){
		($value=~/.{4,}/) 
			|| &error("Password must be at least 4 characters.");
		#make sure it's not all spaces:
		if ($value=~/\s{2}/){
			&error("You may not have more then one whitespace character in a row.");
		}
	# lets do it:
	$value = crypt($value,$value);
	$sql_query = "	UPDATE dm_sessions \
						SET password = '$value' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing password.");
	&push_message("<FONT COLOR=red><CENTER>Password Changed.</CENTER></FONT>");
	return 1;
}
if ($action=~/^make_admin$/){
	$sql_query = "	UPDATE dm_sessions \
						SET admin = '1' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User escalated to <B>admin</B> status.</CENTER></FONT>");
	return 1;
}
if ($action=~/^change_ip_restrict$/){
	&check_ip_restrict_value($value);
	$sql_query = "	UPDATE dm_sessions \
						SET ip_restrict = '$value' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing IP restrict value.");
	&push_message("<FONT COLOR=red><CENTER>IP restrictions changed.</CENTER></FONT>");
	return 1;
}
if ($action=~/^remove_admin$/){
	$sql_query = "	UPDATE dm_sessions \
						SET admin = '0' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User's <B>admin</B> status revoked.</CENTER></FONT>");
	return 1;
}
if ($action=~/^change_email$/){
		if ($value=~/.{61}/){
			&error("Email address may only be up to 60 characters.");
		}
	$sql_query = " UPDATE dm_sessions \
                  SET email_address = '$value' \
						WHERE username = '$username'";
   &connect_to_db;
   ($db->do($sql_query)) || &error("Error changing email address.");
   &push_message("<FONT COLOR=red><CENTER>Email Address Changed to \"$value\".</CENTER></FONT>");
   return 1;
}
if ($action=~/^delete$/){
	if ($username =~/^admin$/i){
		&error("You are not allowed to delete the Admin account");
	}
	$sql_query = "	DELETE FROM dm_sessions \
						WHERE username = '$username'";
   &connect_to_db;
   ($db->do($sql_query)) || &error("Error deleting user \"$username\".");
   &push_message("<FONT COLOR=red><CENTER>User \"$username\" deleted.</CENTER></FONT>");
   return 1;

}

}
###################################
sub user_exists{
my ($username) = @_;

my $sql_query;
my $db_ptr;
my $hash_ref;
&safe_slash(\$username);

$sql_query = "	SELECT username \
					FROM dm_sessions \
					WHERE username = '$username'";
$db_ptr = &run_query($sql_query);

if ($hash_ref = $db_ptr->fetchrow_hashref){
	return 1;
}
else{
	return;
}

}
#####################################
sub is_anonymous{
if ($logged_in_as=~/^anonymous$/i){
	return 1;
}
	
return;
}



####################################################
sub md5_find_changes{
my ($SID,$minimal_detail) = @_;
($SID=~/^\d+$/) || &error("Invalid SID passed: $SID");

my $sql_query;
my $db_ptr;
my $hash_ref;
my $final_message;
my $count;
my $last_checked;


$sql_query = "	SELECT \
						dm_md5_data.md5_uid, 
						dm_md5_data.rule_uid, 
						dm_md5_data.path, 
						dm_md5_data.k_inode, 
						dm_md5_data.k_perms, 
						dm_md5_data.k_uid, 
						dm_md5_data.k_gid, 
						dm_md5_data.k_size, 
						dm_md5_data.k_mtime, 
						dm_md5_data.k_ctime, 
						dm_md5_data.k_md5sum, 
						dm_md5_data.c_inode, 
						dm_md5_data.c_perms, 
						dm_md5_data.c_uid, 
						dm_md5_data.c_gid, 
						dm_md5_data.c_size, 
						dm_md5_data.c_mtime, 
						dm_md5_data.c_ctime, 
						dm_md5_data.c_md5sum, 
						dm_md5_data.last_confirmed, 
						dm_md5_data.last_checked , 
						dm_md5_data.last_changed, 
						dm_md5_data.out_of_sync, 
						dm_md5_data.added_flag, 
						dm_md5_data.modified_flag, 
						dm_md5_data.deleted_flag, 
						dm_md5_data.session_uid,
						dm_md5_rules.sid,
						dm_md5_rules.priority,
						dm_md5_rules.description
					FROM \
						dm_md5_data \
					LEFT JOIN dm_md5_rules \
						ON dm_md5_data.rule_uid = dm_md5_rules.rule_uid \
					WHERE \
						dm_md5_rules.sid			= '$SID' AND \
						out_of_sync = 1 \
					ORDER BY \
						priority,rule_uid";

$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	if (!$count){
		$last_checked = $$hash_ref{'last_checked'};
	}
	$count++;
	my $added_message;
	my $deleted_message;
	my $modified_message;
	my $modified_title;

	if ($$hash_ref{'added_flag'}){
			$added_message = "<TR BGCOLOR=\"$row3_color\"><TD COLSPAN=3><B>ADDED FILE:</B> $$hash_ref{'path'}</TD></TR>\n";
	}
	if ($$hash_ref{'deleted_flag'}){
			$deleted_message = "<TR BGCOLOR=\"$row3_color\"><TD COLSPAN=3><B>DELETED FILE:</B> $$hash_ref{'path'}</TD></TR>\n";
	}
	if ($$hash_ref{'modified_flag'}){
			$modified_title = "<TR><TD COLSPAN=3 ALIGN=left BGCOLOR=\"$row3_color\"><B>MODIFIED FILE:</B> $$hash_ref{'path'}</TD></TR>\n";
            if ($$hash_ref{'k_inode'} != $$hash_ref{'c_inode'}){
					$modified_message .= "<TR BGCOLOR=\"$row3_color\"><TD><B>INODE:</B></TD>";
					$modified_message .= "<TD> $$hash_ref{'k_inode'}</TD>";
					$modified_message .= "<TD>$$hash_ref{'c_inode'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_perms'} ne $$hash_ref{'c_perms'}){
					$modified_message .= "<TR BGCOLOR=\"$row3_color\"><TD><B>PERMISSIONS:</B></TD>";
					$modified_message .= "<TD>$$hash_ref{'k_perms'}";
					$modified_message .= "<TD>$$hash_ref{'c_perms'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_uid'} ne $$hash_ref{'c_uid'}){
					$modified_message .= "<TR BGCOLOR=\"$row3_color\"><TD><B>UID:</B></TD>";
					$modified_message .= "<TD>$$hash_ref{'k_uid'}</TD>";
					$modified_message .= "<TD>$$hash_ref{'c_uid'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_gid'} ne $$hash_ref{'c_gid'}){
					$modified_message .= "<TR BGCOLOR=\"$row3_color\"><TD><B>GID:</B></TD>";
					$modified_message .= "<TD>$$hash_ref{'k_gid'}</TD>";
					$modified_message .= "<TD>$$hash_ref{'c_gid'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_size'} != $$hash_ref{'c_size'}){
					$modified_message .= "<TR BGCOLOR=\"$row3_color\"><TD><B>SIZE:</B></TD>";
					$modified_message .= "<TD>$$hash_ref{'k_size'}</TD>";
					$modified_message .= "<TD>$$hash_ref{'c_size'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_mtime'} != $$hash_ref{'c_mtime'}){
					$$hash_ref{'k_mtime'} = localtime($$hash_ref{'k_mtime'});
					$$hash_ref{'c_mtime'} = localtime($$hash_ref{'c_mtime'});
					$modified_message .= "<TR BGCOLOR=\"$row3_color\"><TD><B>MTIME:</B></TD>";
					$modified_message .= "<TD>$$hash_ref{'k_mtime'}</TD>";
					$modified_message .= "<TD>$$hash_ref{'c_mtime'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_ctime'} != $$hash_ref{'c_ctime'}){
					$$hash_ref{'k_ctime'} = localtime($$hash_ref{'k_ctime'});
					$$hash_ref{'c_ctime'} = localtime($$hash_ref{'c_ctime'});
					$modified_message .= "<TR BGCOLOR=\"$row3_color\"><TD><B>CTIME:</B></TD>";
					$modified_message .= "<TD>$$hash_ref{'k_ctime'}</TD>";
					$modified_message .= "<TD>$$hash_ref{'c_ctime'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_md5sum'} ne $$hash_ref{'c_md5sum'}){
					$modified_message .= "<TR BGCOLOR=\"$row3_color\"><TD><B>MD5_SUM:</B></TD>";
					$modified_message .= "<TD> $$hash_ref{'k_md5sum'}</TD>";
					$modified_message .= "<TD> $$hash_ref{'c_md5sum'}</TD></TR>\n";

				}
	}
	# Put it all together:
	$final_message .= "<TABLE BORDER=0 WIDTH=\"100%\" CELLSPACING=0 CELLPADDING=1>";
	$final_message .= "<TR><TD BGCOLOR=\"#000000\" align=center valign=top>";
   $final_message .= "<TABLE BORDER=0 WIDTH=\"100%\" CELLSPACING=1 CELLPADDING=2 BGCOLOR=\"#000000\">";
	$final_message .= "<TR><TD BGCOLOR=\"$row4_color\" ALIGN=center WIDTH=\"10%\">";
	$final_message .= &color_code($$hash_ref{'priority'});
	$final_message .= "</TD><TD BGCOLOR=\"$row4_color\" width=\"45%\">";
	$final_message .= "<B>$$hash_ref{'path'}</B></TD>";
	$final_message .= "<TD BGCOLOR=\"$row4_color\" width=\"45%\">";
	$final_message .= "<B>$$hash_ref{'description'}</B></TD></TR>";
	$final_message .= $added_message;
	$final_message .= $deleted_message;
	$final_message .= $modified_title;
	if ($modified_message && !$minimal_detail){
		$final_message .= "<TR><TD BGCOLOR=\"$row3_color\">&nbsp;</TD>";
		$final_message .= "<TD BGCOLOR=\"$row3_color\" ALIGN=center><B>Known</B></TD>";
		$final_message .= "<TD BGCOLOR=\"$row3_color\" ALIGN=center><B>Observed</B></TD></TR>";
	}
	$final_message .= $modified_message if (!$minimal_detail);
	$final_message .= "</TABLE>\n</TD></TR>\n</TABLE>\n";
}
if (!$last_checked){
	$sql_query = " SELECT max(last_checked)  AS LC\
						FROM dm_md5_data \
						WHERE sid = '$SID'";
	$db_ptr = &run_query($sql_query);
	$hash_ref = $db_ptr->fetchrow_hashref;
	$last_checked = $$hash_ref{'LC'};
}

return ($final_message,$last_checked);
}
####################
sub confirm_all_md5_changes{
my $sql_query;
my $db_ptr;
my $hash_ref;

#Delete all sub-rules where the file has been deleted:
$sql_query = "	DELETE \
						from dm_md5_data \
					WHERE \	
						deleted_flag = '1'	";
   &connect_to_db;
   $db->do($sql_query);

$sql_query = "	UPDATE \
						dm_md5_data \
					SET \
						k_inode = c_inode, \
						k_perms = c_perms, \
						k_uid = c_uid, \
						k_gid = c_gid, \
						k_size = c_size, \
						k_mtime= c_mtime, \
						k_ctime = c_ctime, \
						k_md5sum = c_md5sum, \	
						last_confirmed = NOW(), \
						added_flag = '', \
						modified_flag = '', \
						deleted_flag = '', \
						out_of_sync = '' \
				";
   ($db->do($sql_query)) || &error("Error updating MD5/File Integrity information.");
   &push_message("<FONT COLOR=red><CENTER>All current file attributes confirmed/updated.</CENTER></FONT>");
	&log_event(	username => "$logged_in_as",
					action 	=> "confirmed all md5 changes",
					target	=> "",
				 );

}
####################
sub confirm_selective_md5_changes{
my ($c_sid) = @_;
($c_sid=~/^\d+$/) || &error("Invalid Sendor ID passed: $c_sid.");
my $sql_query;
my $db_ptr;
my $hash_ref;

#Delete all sub-rules where the file has been deleted:
$sql_query = "	DELETE \
						from dm_md5_data \
					WHERE \	
						sid				= '$c_sid' AND \
						deleted_flag 	= '1'	";
   &connect_to_db;
   $db->do($sql_query);

$sql_query = "	UPDATE \
						dm_md5_data \
					SET \
						k_inode = c_inode, \
						k_perms = c_perms, \
						k_uid = c_uid, \
						k_gid = c_gid, \
						k_size = c_size, \
						k_mtime= c_mtime, \
						k_ctime = c_ctime, \
						k_md5sum = c_md5sum, \	
						last_confirmed = NOW(), \
						added_flag = '', \
						modified_flag = '', \
						deleted_flag = '', \
						out_of_sync = '' \
					WHERE \
						sid = '$c_sid'
				";
   ($db->do($sql_query)) || &error("Error updating MD5/File Integrity information for SID $c_sid.");
   &push_message("<FONT COLOR=red><CENTER>All current file attributes confirmed/updated for SID $c_sid.</CENTER></FONT>");

	&log_event(	username => "$logged_in_as",
					action 	=> "confirmed selective md5 changes",
					target	=> "SID: $c_sid",
				 );

}
######################
sub get_minimum_md5_alert_status{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @bad_md5s;

$sql_query = "	SELECT \
						count(*) AS COUNT,
						dm_md5_data.added_flag, \
						dm_md5_data.modified_flag, \ 
						dm_md5_data.deleted_flag, \
						dm_md5_rules.sid, \
						dm_md5_rules.priority, \
						sensor.hostname \
					FROM \
						dm_md5_data \
					LEFT JOIN dm_md5_rules \
						ON dm_md5_data.rule_uid = dm_md5_rules.rule_uid \
					LEFT JOIN sensor \
						ON dm_md5_rules.sid = sensor.sid \
					WHERE \
						out_of_sync = 1 \
					GROUP BY \
						sid,UPPER(priority) \
					ORDER BY \
						dm_md5_rules.sid,priority";


$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	push (@bad_md5s,"$$hash_ref{'hostname'} ($$hash_ref{'COUNT'});" . &color_code($$hash_ref{'priority'}));
}


return @bad_md5s
}
############################
sub get_reference_link{
my ($ref_id) = @_;
($ref_id=~/^\d+$/) || return;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $link;

$sql_query = "	SELECT \
						reference.ref_system_id, \
						ref_tag,ref_system_name \
					FROM reference \
					LEFT JOIN reference_system \
						ON (reference_system.ref_system_id = reference.ref_system_id) \
					WHERE \
						reference.ref_id = '$ref_id'";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return;

if ($$hash_ref{'ref_system_name'}=~/^arachnids$/i){
	$link = "http://www.whitehats.com/info/IDS$$hash_ref{'ref_tag'}";
}
elsif ($$hash_ref{'ref_system_name'}=~/^cve$/i){
	$link = "http://cve.mitre.org/cgi-bin/cvename.cgi?name=$$hash_ref{'ref_tag'}";
}


if ($link){
	$link = "<A HREF=\"$link\" TARGET=\"IDS_WINDOW\">More Info</A>";
}
return $link;
}
###########################
sub format_localtime{

my $ltime = localtime();
##Format AM/PM
$ltime;
if ($ltime=~/^(\S+\s+\S+\s+\S+\s+)(\d{1,2}):(\d{1,2}:\d{1,2}\s+)(\S+)$/){
	my $hour;
	my $date_string 	= $1;
	my $time_string	= $3;
	my $year_string	= $4;
	my $ampm;
	if ($2 == 0){
	#12 AM
	$hour = 12;
	$ampm = "AM";
	}
	elsif ($2 > 11){
	#PM
	$hour = $2-12;
	$ampm = "PM";
	}
	else{
	#AM
	$hour = $2;
	$ampm = "AM";
	}
	$ltime = "$hour:$time_string $ampm, $date_string $year_string";
}
return $ltime;
}
##################################
sub check_ip_restrict_value{
my ($value) = @_;
($value) || return 1;
my $error;
my $error_string;

my @rules = split(/;/,$value);
foreach (@rules){
	($_ =~/^([0-9\-]{1,})\.([0-9\-]{1,})\.([0-9\-]{1,})\.([0-9\-]{1,})$/) ||
	($error = 1);
}

if ($error){
$error_string = << "EOF";
At least one of the restrictions is in an invalid format.<BR>
They must be in the format:<BR>
<B>192.168.0.1;192.168.1-2.0-255;192.168-169.0-255.10-20</B><BR>
<P>
All restrictions must be separated by a semi-colon.
EOF
&error($error_string);
}

return 1;
}
#######################
sub check_if_immune{
my ($ip_to_check,$ip_restrictions) = @_;
my $ip_found;
my $check;
my @address_array = split(/\./,$ip_to_check);
($ip_restrictions) || return 1;
my @immune_array = split(/;/,$ip_restrictions);

      foreach $check(@immune_array){
         #check for properly formatted condition
         next unless  ($check =~/^([0-9]{1,3}\-{0,1}[0-9]{0,3})\.([0-9]{1,3}\-{0,1}[0-9]{0,3})\.([0-9]{1,3}\-{0,1}[0-9]{0,3})\.([0-9]{1,3}\-{0,1}[0-9]{0,3})$/);
         my $ip_1_from = $1;
         my $ip_1_to;
         my $ip_2_from = $2;
         my $ip_2_to;
         my $ip_3_from = $3;
         my $ip_3_to;
         my $ip_4_from = $4;
         my $ip_4_to;
         if ($ip_1_from =~/\-/){ #then it contains a range
            my @temp_ip = split (/-/,$ip_1_from);
            $ip_1_from = $temp_ip[0];
            $ip_1_to = $temp_ip[1];
         }
         else{$ip_1_to = $ip_1_from;}

         if ($ip_2_from =~/\-/){ #then it contains a range
            my @temp_ip = split (/-/,$ip_2_from);
            $ip_2_from = $temp_ip[0];
            $ip_2_to = $temp_ip[1];
         }
         else{$ip_2_to = $ip_2_from;}

         if ($ip_3_from =~/\-/){ #then it contains a range
            my @temp_ip = split (/-/,$ip_3_from);
            $ip_3_from = $temp_ip[0];
            $ip_3_to = $temp_ip[1];
         }
         else{$ip_3_to = $ip_3_from;}

         if ($ip_4_from =~/-/){ #then it contains a range
            my @temp_ip = split (/-/,$ip_4_from);
            $ip_4_from = $temp_ip[0];
            $ip_4_to = $temp_ip[1];
         }
         else{$ip_4_to = $ip_4_from;}

      #now all the conditions are in parsed, lets check if the ip matches:

        if(
            ($address_array[0] >= $ip_1_from) &&
            ($address_array[0] <= $ip_1_to) &&
            ($address_array[1] >= $ip_2_from) &&
            ($address_array[1] <= $ip_2_to) &&
            ($address_array[2] >= $ip_3_from) &&
            ($address_array[2] <= $ip_3_to) &&
            ($address_array[3] >= $ip_4_from) &&
            ($address_array[3] <= $ip_4_to)
         ){
            $ip_found = 1;
            last;
         }
      }
if ($ip_found){
   #then the IP address is immune, so we'll return 1;
   return 1;
}
else{
   # not found in the immune list, so return null
   return;
}
}
#####################################
sub ul_change_email{
my ($new_email) = @_;
my $sql_query;

($allow_user_to_change_email) || &error("You are not allowed to change your email address.<BR>Please consult the system administrator.");

($new_email=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
	|| &error("Email address does not seem to be valid: $new_email");
$new_email=~tr/\@a-zA-Z0-9\.\-\_//dc;

$sql_query = " UPDATE dm_sessions \
               SET email_address = '$new_email' \
					WHERE username = '$logged_in_as'";
&connect_to_db;
($db->do($sql_query)) || &error("Error changing email address.");

&push_message("<FONT COLOR=red><CENTER>Email Address Changed to \"$new_email\".</CENTER></FONT>");

&log_event( username => "$logged_in_as",
            action   => "changed email address",
            target   => "$new_email",
          );
}
#####################################
sub ul_change_password{
my ($old_password,$new_password,$new_password_confirm) = @_;
my $sql_query;
my $old_c;
my $new_c;
my $db_ptr;
my $hash_ref;

($old_password) || &error("You must fill in your current password.");

if ($new_password ne $new_password_confirm){
	&error("Passwords don't match.. please try again.");
}
if ($logged_in_as eq $new_password){
	&error("Come on now, you really want your username and password to be the same? <BR> Not on my watch!");
}
($new_password=~/.{4,}/) 
	|| &error("Password must be at least 4 characters.");
#make sure it's not all spaces:
if ($new_password=~/\s{2}/){
	&error("You may not have more then one whitespace character in a row.");
}


# lets do it:
$old_c = crypt($old_password,$old_password);
$new_c = crypt($new_password,$new_password);

#check to see if old password matches:
$sql_query = "	SELECT username FROM dm_sessions \
					WHERE \
						username = '$logged_in_as' AND \
                  password = '$old_c'";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || &error("Error changing password.<BR>Current password does not match.");

$sql_query = "	UPDATE dm_sessions \
					SET password = '$new_c' \
					WHERE \
						username = '$logged_in_as' AND \
						password = '$old_c'";
&connect_to_db;
($db->do($sql_query)) || &error("Error changing password.");
&push_message("<FONT COLOR=red><CENTER>Password Changed.</CENTER></FONT>");

&log_event( username => "$logged_in_as",
            action   => "changed password",
            target   => "",
          );

}
############################
sub get_last_sid{
my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = "	SELECT max(sid) AS MAXSID FROM sensor";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return;

return $$hash_ref{'MAXSID'};
}
######################
sub print_monitor_event_detail{
my ($eid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

($eid=~/^\d+$/) || &error("No/Invalid event id specified: $eid");

$sql_query = "	SELECT \
 						service, \
						ip_addr, \
						status, \
						detail, \
						event_timestamp \
					FROM \
						dm_monitor_events \
					WHERE \
						eid = '$eid'";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || &error("So such event exists.");

$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 width=\"80%\" align=center>\n";
$table .=   "<TR BGCOLOR=\"#003366\">";
$table .=   "<TD background=\"$v_graphics_path/bg_title.gif\" colspan=2 align=center><b>Event Detail</b></TD>";
$table .= 	"</TR>\n";
$table .=   "<TR BGCOLOR=\"#244A75\">";
$table .=   "<TD valign=top align=center>";
$table .=   &color_code($$hash_ref{'status'});
$table .= 	"</TD>";
#$table .=	"<TD>&nbsp;<B>[TIMESTAMP]</B></TD>";
$table .=	"<TD>&nbsp;<B>$$hash_ref{'event_timestamp'}</B></TD>";
$table .=	"</TR>\n";
$table .= 	"<TR BGCOLOR=\"#001E4B\">";
$table .=   "<TD>&nbsp;</TD>";
$table .=	"<TD>";
$$hash_ref{'detail'}=~s/\n/\n<BR>/g;
$table .= 	"$$hash_ref{'detail'}";
$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE><br>\n";

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
	
}
######################
sub log_event{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

&safe_slash(\$args{'username'});
&safe_slash(\$args{'action'});
&safe_slash(\$args{'target'});

($args{'username'}) || 
	($args{'username'} = "UNKNOWN");

my $long_ip = &convert_dotted_ip($ENV{'REMOTE_ADDR'});

$sql_query = "	INSERT INTO \
						dm_log \
					VALUES ( \
						'','$args{'username'}', \
						'$args{'action'}', '$args{'target'}', \
						NOW(),'$long_ip' \
					)";

&connect_to_db;
($db->do($sql_query)) || &error("Error logging event.");

}
######################
sub print_log{
my ($last_amount) = @_;
($last_amount=~/^\d+$/) || ($last_amount=1000);
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table_row;
my $table_rows;


$sql_query = "	SELECT * FROM dm_log \
					ORDER BY timestamp DESC \
					LIMIT $last_amount ";

$db_ptr = &run_query($sql_query);
	$table_rows .= "<TR bgcolor=\"#003366\"><TD background=\"$v_graphics_path/bg_title.gif\" colspan=5 align=center>";
	$table_rows .= "<B>Log Entrees</B></TD></TR>\n";
	$table_rows .= "<TR bgcolor=\"#244A75\"><TD align=center><B>Username</B></TD><TD align=center><B>Action</B></TD><TD align=center><B>Target</B></TD><TD align=center><B>Date/Time</B></TD><TD align=center><B>Login IP</B></TD></TR>\n";
while ($hash_ref = $db_ptr->fetchrow_hashref){
	$table_row = "<TR bgcolor=\"#001E4B\"><TD align=center>$$hash_ref{'username'}</TD>";
	$table_row .= "<TD>&nbsp;$$hash_ref{'action'}</TD>";
	$table_row .= "<TD>&nbsp;$$hash_ref{'target'}</TD>";
	$table_row .= "<TD align=center>$$hash_ref{'timestamp'}</TD>";
	$table_row .= "<TD align=center>" . &convert_long_ip($$hash_ref{'ip_address'}) . "</TD>";
	$table_row .= "</TR>\n";

	#prepending vs appending?...
	#$table_rows = $table_row . $table_rows;
	$table_rows .= $table_row;
}

$table_rows = "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center width=\"80%\">$table_rows";
$table_rows .= "<TR HEIGHT=2 BGCOLOR=\"#003366\"><TD COLSPAN=5><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
$table_rows .= "</TABLE>\n<BR>\n";
push (@substitutions,"\\[MAIN_TABLE\\],-,$table_rows");
&print_main_with_key($main_template);

}




