use strict; use warnings; use Win32; use Win32::OLE; use Win32::Daemon; use Net::FTP; use constant SERVICE_NAME => 'HTMLReqCapture'; use constant SERVICE_DESC => 'HTML Request Capture Service'; use constant false => 0; use constant true => 1; my $HTTPAnalyzer; my $tempvar = 'uninit'; main(); sub main { # Get command line argument - if none passed, use empty string my $opt = shift (@ARGV) || ""; # Check command line argument if ($opt =~ /^(-i|--install)$/i) { install_service(SERVICE_NAME, SERVICE_DESC); } elsif ($opt =~ /^(-r|--remove)$/i) { remove_service(SERVICE_NAME); } elsif ($opt =~ /^(--run)$/i) { # Redirect STDOUT and STDERR to a log file # Derive the name of the file from the name of the program # The log file will be in the scripts directory, with extension .log my ($cwd,$bn,$ext) = ( Win32::GetFullPathName($0) =~ /^(.*\\)(.*)\.(.*)$/ ) [0..2] ; my $log = $cwd . $bn . ".log"; # Redirect STDOUT and STDERR to log file open(STDOUT, ">> $log") or die "Couldn't open $log for appending: $!\n"; open(STDERR, ">&STDOUT"); # Autoflush, no buffering $|=1; # Register the events which the service responds to Win32::Daemon::RegisterCallbacks( { start => \&Callback_Start, running => \&Callback_Running, stop => \&Callback_Stop, pause => \&Callback_Pause, continue => \&Callback_Continue, } ); my %Context = ( last_state => SERVICE_STOPPED, start_time => time(), ); # Start the service passing in a context and indicating to callback # using the "Running" event every 300000 milliseconds (5 minutes). # NOTE: the StartService method with in 'callback mode' will block, in other # words it won't return until the service has stopped, but the callbacks below # will respond to the various events - START, STOP, PAUSE etc... print "Starting service...\n"; Win32::Daemon::StartService( \%Context, 300000 ); # Here the service has stopped close STDERR; close STDOUT; } else { print "No valid options passed - nothing done\n"; } } sub Callback_Running { my( $Event, $Context ) = @_; my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); my $timestamp = sprintf("%02d:%02d:%02d", $hour, $min, $sec); print "Time entering callback_running is $timestamp\n"; $timestamp = sprintf("%02d%02d%02d", $hour, $min, $sec); my $filename = "c:\\agentName_ip_$timestamp.xml"; $HTTPAnalyzer->SaveLog($filename, 0 ); print "$timestamp: log saved, about to clear...\n"; $HTTPAnalyzer->Clear(); ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); $timestamp = sprintf("%02d:%02d:%02d", $hour, $min, $sec); print "The time leaving callback_running is $timestamp\n"; } sub Callback_Start { my( $Event, $Context ) = @_; print "Starting...\n"; # Create HTTPAnalyzer Stand-Alone Object $HTTPAnalyzer = Win32::OLE->new('HttpAnalyzerStd.HTTPAnalyzerStandAlone'); $HTTPAnalyzer->{Visible}=false; print "About to start analyzing\n"; $HTTPAnalyzer->AttachAllSessions(); $HTTPAnalyzer->Start(); $tempvar = 'started'; $Context->{last_state} = SERVICE_RUNNING; Win32::Daemon::State( SERVICE_RUNNING ); } sub Callback_Pause { my( $Event, $Context ) = @_; print "Pausing...\n"; $Context->{last_state} = SERVICE_PAUSED; Win32::Daemon::State( SERVICE_PAUSED ); } sub Callback_Continue { my( $Event, $Context ) = @_; print "Continuing...\n"; $Context->{last_state} = SERVICE_RUNNING; Win32::Daemon::State( SERVICE_RUNNING ); } sub Callback_Stop { my( $Event, $Context ) = @_; print "Stopping...\n"; $HTTPAnalyzer->stop(); $tempvar = 'stop'; $Context->{last_state} = SERVICE_STOPPED; Win32::Daemon::State( SERVICE_STOPPED ); # We need to notify the Daemon that we want to stop callbacks and the service. Win32::Daemon::StopService(); } sub install_service { my ($srv_name, $srv_desc) = @_; my ($path, $parameters); # Get the program's full filename, break it down into constituent parts my $fn = Win32::GetFullPathName($0); my ($cwd,$bn,$ext) = ( $fn =~ /^(.*\\)(.*)\.(.*)$/ ) [0..2] ; # Determine service's path to executable based on file extension if ($ext eq "pl") { # Source perl script - invoke perl interpreter $path = "\"$^X\""; # Parameters include extra @INC directories and perl script # @INC directories must not end in \ otherwise perl hangs my $inc = ($cwd =~ /^(.*?)[\\]?$/) [0]; # The command includes the --run switch needed in main() $parameters = "-I " . "\"$inc\"" . " \"$fn\" --run"; } elsif ($ext eq "exe") { # Compiled perl script - invoke the compiled script $path = "\"$fn\""; $parameters = ""; } else { # Invalid file type? die "Can not install service for $fn, file extension $ext not supported\n"; } my $username = "mydomain\\myusername"; my $pword = "MyPassw0rd"; # Populate the service configuration hash # The hash is required by Win32::Daemon::CreateService my %srv_config = ( name => $srv_name, display => $srv_name, path => $path, description => $srv_desc, parameters => $parameters, service_type => SERVICE_WIN32_OWN_PROCESS, start_type => SERVICE_AUTO_START, user => $username, password => $pword ); # Install the service if( Win32::Daemon::CreateService( \%srv_config ) ) { print "Service installed successfully\n"; } else { print "Failed to install service\n"; } } sub remove_service { my ($srv_name, $hostname) = @_; $hostname ||= Win32::NodeName(); if ( Win32::Daemon::DeleteService ( $srv_name ) ) { print "Service uninstalled successfully\n"; } else { print "Failed to uninstall service\n"; } }