#!/usr/bin/perl
# Copyright Andrew Gavin 2009-2012
#
# This file is part of OpenDLP.
#
# OpenDLP is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenDLP is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with OpenDLP. If not, see .
use CGI qw/:standard/;
use DBI;
use POSIX ":sys_wait_h";
use Proc::Queue;
use File::Path qw (remove_tree);
my $version = get_version();
my $db_admin_file = "../etc/db_admin";
my $is_valid = 1;
my $scantype = "";
my %profile_info = ();
open( DB, $db_admin_file );
my $db_line = ;
close( DB );
chomp $db_line;
my ($db_username, $db_password) = split( ":", $db_line );
header();
my $query = CGI->new;
my $action = $query->param('action');
if( $action !~ /^(pause|resume|uninstall)$/i )
{
$is_valid = 0;
print "Invalid action: Must be \"pause\", \"resume\", or \"uninstall\".
\n";
}
my $scanname = $query->param('scanname');
if( $scanname ne "" && $scanname !~ /^[a-z0-9\ \,\.\-\_]+$/i )
{
$is_valid = 0;
print "Invalid scan name
\n";
}
my $system = $query->param('system');
if( $system ne "" && $system !~ /^[A-Z0-9]{32}$/ )
{
$is_valid = 0;
print "Invalid system tracker
\n";
}
if( $is_valid )
{
# get scan type
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT scantype FROM systems WHERE scan=?";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname );
my $results = $sth->fetchrow_arrayref();
$scantype = $$results[0];
if( $scantype eq "win_agent" )
{
if( $action eq "pause" )
{
print "Pause Agents
\n";
# if no arguments are given
if( $system eq "" && $scanname eq "" )
{
print "No action will be taken: You must at least specify a scan name.
\n";
}
elsif( $scanname ne "" && $system eq "" )
{
print "Attempting to pause agents... \n";
get_profile();
# get all systems in "running" state
my @systems = ();
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT ip FROM systems WHERE scan=? AND control=\"running\"";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
push @systems, $$results[0];
}
my $length_of_systems = @systems;
if( $length_of_systems == 0 )
{
print "No agents are running, so nothing will be paused.
\n";
}
else
{
Proc::Queue::size( $profile_info{concurrent} );
foreach my $ip( @systems )
{
$length_of_systems--;
my $f = fork;
if( defined ($f) and $f == 0 )
{
print "Trying to pause agent on $ip ($length_of_systems systems remain in queue) \n";
my $escape_user = "";
my $length_user = length( $profile_info{username} );
my $x = 0;
for( $x = 0; $x < $length_user; $x++ )
{
$escape_user .= "\\" . substr( $profile_info{username}, $x, 1 );
}
my $escape_pass = "";
my $length_pass = length( $profile_info{password} );
my $x = 0;
for( $x = 0; $x < $length_pass; $x++ )
{
$escape_pass .= "\\" . substr( $profile_info{password}, $x, 1 );
}
# stop OpenDLP
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'\"$profile_info{path}\\sc.exe\" stop OpenDLP\'";
my $output = `$command`;
my $is_successful = 0;
if( $output =~ /(STOP_PENDING|STOPPED)/ )
{
$is_successful = 1;
}
if( $is_successful )
{
print "$ip: OpenDLP paused \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"stopped\" WHERE scan=? AND ip=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $ip );
}
else
{
print "$ip: Got unexpected response from command. The agent may be paused. Check the previous screen to verify. \n";
}
exit(0);
}
1 while waitpid(-1, WNOHANG) > 0;
}
}
$sth->finish();
$dbh->disconnect();
}
# pause specific system
elsif( $scanname ne "" && $system ne "" )
{
get_profile();
# get system's IP
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT ip FROM systems WHERE scan=? AND control=\"running\" AND tracker=?";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
my $results = $sth->fetchrow_arrayref();
my $ip = $$results[0];
if( $ip eq "" )
{
print "Agent is not running, so nothing will be paused.
\n";
}
else
{
print "$ip: Attempting to pause agent... \n";
my $escape_user = "";
my $length_user = length( $profile_info{username} );
my $x = 0;
for( $x = 0; $x < $length_user; $x++ )
{
$escape_user .= "\\" . substr( $profile_info{username}, $x, 1 );
}
my $escape_pass = "";
my $length_pass = length( $profile_info{password} );
my $x = 0;
for( $x = 0; $x < $length_pass; $x++ )
{
$escape_pass .= "\\" . substr( $profile_info{password}, $x, 1 );
}
# stop OpenDLP
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'\"$profile_info{path}\\sc.exe\" stop OpenDLP\'";
my $output = `$command`;
my $is_successful = 0;
if( $output =~ /(STOP_PENDING|STOPPED)/ )
{
$is_successful = 1;
}
if( $is_successful )
{
print "$ip: OpenDLP paused \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"stopped\" WHERE scan=? AND ip=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $ip );
}
else
{
print "$ip: Got unexpected response from command. The agent may be paused. Check the previous screen to verify. \n";
}
}
$sth->finish();
$dbh->disconnect();
}
}
elsif( $action eq "resume" )
{
print "Resume Agents
\n";
# if no arguments are given
if( $system eq "" && $scanname eq "" )
{
print "No action will be taken: You must at least specify a scan name.
\n";
}
elsif( $scanname ne "" && $system eq "" )
{
print "Attempting to resume agents... \n";
get_profile();
# get all systems in "stopped" state
my @systems = ();
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT ip FROM systems WHERE scan=? AND control=\"stopped\"";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
push @systems, $$results[0];
}
my $length_of_systems = @systems;
if( $length_of_systems == 0 )
{
print "No agents are paused, so nothing will be resumed.
\n";
}
else
{
Proc::Queue::size( $profile_info{concurrent} );
foreach my $ip( @systems )
{
$length_of_systems--;
my $f = fork;
if( defined ($f) and $f == 0 )
{
print "Trying to resume agent on $ip ($length_of_systems systems remain in queue) \n";
my $escape_user = "";
my $length_user = length( $profile_info{username} );
my $x = 0;
for( $x = 0; $x < $length_user; $x++ )
{
$escape_user .= "\\" . substr( $profile_info{username}, $x, 1 );
}
my $escape_pass = "";
my $length_pass = length( $profile_info{password} );
my $x = 0;
for( $x = 0; $x < $length_pass; $x++ )
{
$escape_pass .= "\\" . substr( $profile_info{password}, $x, 1 );
}
# start OpenDLP
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'\"$profile_info{path}\\sc.exe\" start OpenDLP\'";
my $output = `$command`;
my $is_successful = 0;
if( $output =~ /(START_PENDING|RUNNING)/ )
{
$is_successful = 1;
}
if( $is_successful )
{
print "$ip: OpenDLP resumed \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"running\" WHERE scan=? AND ip=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $ip );
}
else
{
print "$ip: Got unexpected response from command. The agent may be resumed. Check the previous screen to verify. \n";
}
exit(0);
}
1 while waitpid(-1, WNOHANG) > 0;
}
}
$sth->finish();
$dbh->disconnect();
}
# resume specific system
elsif( $scanname ne "" && $system ne "" )
{
get_profile();
# get system's IP
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT ip FROM systems WHERE scan=? AND control=\"stopped\" AND tracker=?";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
my $results = $sth->fetchrow_arrayref();
my $ip = $$results[0];
if( $ip eq "" )
{
print "Agent is not running, so nothing will be paused.
\n";
}
else
{
print "$ip: Attempting to resume agent... \n";
my $escape_user = "";
my $length_user = length( $profile_info{username} );
my $x = 0;
for( $x = 0; $x < $length_user; $x++ )
{
$escape_user .= "\\" . substr( $profile_info{username}, $x, 1 );
}
my $escape_pass = "";
my $length_pass = length( $profile_info{password} );
my $x = 0;
for( $x = 0; $x < $length_pass; $x++ )
{
$escape_pass .= "\\" . substr( $profile_info{password}, $x, 1 );
}
# start OpenDLP
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'\"$profile_info{path}\\sc.exe\" start OpenDLP\'";
my $output = `$command`;
my $is_successful = 0;
if( $output =~ /(START_PENDING|RUNNING)/ )
{
$is_successful = 1;
}
if( $is_successful )
{
print "$ip: OpenDLP resumed \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"running\" WHERE scan=? AND ip=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $ip );
}
else
{
print "$ip: Got unexpected response from command. The agent may be resumed. Check the previous screen to verify. \n";
}
}
$sth->finish();
$dbh->disconnect();
}
}
elsif( $action eq "uninstall" )
{
print "Uninstall Agents
\n";
# if no arguments are given
if( $system eq "" && $scanname eq "" )
{
print "No action will be taken: You must at least specify a scan name.
\n";
}
elsif( $scanname ne "" && $system eq "" )
{
print "Attempting to stop and uninstall agents... \n";
get_profile();
# get all systems in "running" state
my @systems = ();
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT ip FROM systems WHERE scan=? AND control=\"running\"";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
push @systems, $$results[0];
}
# get all systems in "stopped" state
my $string = "SELECT ip FROM systems WHERE scan=? AND control=\"stopped\"";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
push @systems, $$results[0];
}
# uniq @systems
my %seen = ();
@systems = grep {! $seen{$_}++} @systems;
my $length_of_systems = @systems;
if( $length_of_systems == 0 )
{
print "No agents are running or paused, so nothing will be stopped and uninstalled.
\n";
}
else
{
Proc::Queue::size( $profile_info{concurrent} );
foreach my $ip( @systems )
{
$length_of_systems--;
my $f = fork;
if( defined ($f) and $f == 0 )
{
print "Trying to stop and uninstall agent on $ip ($length_of_systems systems remain in queue) \n";
my $escape_user = "";
my $length_user = length( $profile_info{username} );
my $x = 0;
for( $x = 0; $x < $length_user; $x++ )
{
$escape_user .= "\\" . substr( $profile_info{username}, $x, 1 );
}
my $escape_pass = "";
my $length_pass = length( $profile_info{password} );
my $x = 0;
for( $x = 0; $x < $length_pass; $x++ )
{
$escape_pass .= "\\" . substr( $profile_info{password}, $x, 1 );
}
# stop OpenDLP
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'\"$profile_info{path}\\sc.exe\" stop OpenDLP\'";
my $output = `$command`;
my $is_successful = 0;
if( $output =~ /(STOP_PENDING|STOPPED)/ )
{
$is_successful = 2;
}
elsif( $output =~ /The\ service\ has\ not\ been\ started/ )
{
$is_successful = 1;
}
if( $is_successful == 2 )
{
print "$ip: OpenDLP stopped \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"stopped\" WHERE scan=? AND ip=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $ip );
}
elsif( $is_successful == 1 )
{
print "$ip: OpenDLP already stopped \n";
}
else
{
print "$ip: Got unexpected response from command. The agent may be stopped. Check the previous screen to verify. \n";
}
# give Windows a few seconds to clean up and become sane
sleep(10);
# delete OpenDLP service
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'\"$profile_info{path}\\sc.exe\" delete OpenDLP\'";
my $output = `$command`;
my $is_successful = 0;
if( $output =~ /DeleteService\ SUCCESS/ )
{
$is_successful = 1;
}
if( $is_successful == 1 )
{
print "$ip: OpenDLP service deleted \n";
}
else
{
print "$ip: Got unexpected response from command. The agent may be stopped. Check the previous screen to verify. \n";
}
# delete all files in OpenDLP directory
# my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'cmd.exe /c del /Q \"$profile_info{path}\\*.*\"\'";
# `$command`;
# rm -rf OpenDLP
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'cmd.exe /c rd \"$profile_info{path}\" /Q /S\'";
`$command`;
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"uninstalled\" WHERE scan=? AND ip=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $ip );
print "$ip: OpenDLP stopped and uninstalled \n";
exit(0);
}
1 while waitpid(-1, WNOHANG) > 0;
}
}
$sth->finish();
$dbh->disconnect();
}
# uninstall specific system
elsif( $scanname ne "" && $system ne "" )
{
get_profile();
# get system's IP
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT ip FROM systems WHERE scan=? AND tracker=? AND (control=\"stopped\" or control=\"running\")";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
my $results = $sth->fetchrow_arrayref();
my $ip = $$results[0];
if( $ip eq "" )
{
print "Agent is not running or paused, so nothing will be stopped and uninstalled.
\n";
}
else
{
print "$ip: Attempting to stop and uninstall agent... \n";
my $escape_user = "";
my $length_user = length( $profile_info{username} );
my $x = 0;
for( $x = 0; $x < $length_user; $x++ )
{
$escape_user .= "\\" . substr( $profile_info{username}, $x, 1 );
}
my $escape_pass = "";
my $length_pass = length( $profile_info{password} );
my $x = 0;
for( $x = 0; $x < $length_pass; $x++ )
{
$escape_pass .= "\\" . substr( $profile_info{password}, $x, 1 );
}
# stop OpenDLP
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'\"$profile_info{path}\\sc.exe\" stop OpenDLP\'";
my $output = `$command`;
my $is_successful = 0;
if( $output =~ /(STOP_PENDING|STOPPED)/ )
{
$is_successful = 2;
}
elsif( $output =~ /The\ service\ has\ not\ been\ started/ )
{
$is_successful = 1;
}
if( $is_successful == 2 )
{
print "$ip: OpenDLP stopped \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"stopped\" WHERE scan=? AND ip=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $ip );
}
elsif( $is_successful == 1 )
{
print "$ip: OpenDLP already stopped \n";
}
else
{
print "$ip: Got unexpected response from command. The agent may be stopped. Check the previous screen to verify. \n";
}
# give Windows a few seconds to clean up and become sane
sleep(10);
# delete OpenDLP service
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'\"$profile_info{path}\\sc.exe\" delete OpenDLP\'";
my $output = `$command`;
my $is_successful = 0;
if( $output =~ /DeleteService\ SUCCESS/ )
{
$is_successful = 1;
}
if( $is_successful == 1 )
{
print "$ip: OpenDLP service deleted \n";
}
else
{
print "$ip: Got unexpected response from command. The agent may be stopped. Check the previous screen to verify. \n";
}
# delete all files in OpenDLP directory
# my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'cmd.exe /c del /Q \"$profile_info{path}\\*.*\"\'";
# `$command`;
# rm -rf OpenDLP
my $command = "winexe --user=\'$profile_info{domain}\'\\$escape_user --password=$escape_pass //$ip \'cmd.exe /c rd \"$profile_info{path}\" /Q /S\"\'";
`$command`;
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"uninstalled\" WHERE scan=? AND ip=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $ip );
print "$ip: OpenDLP stopped and uninstalled \n";
}
$sth->finish();
$dbh->disconnect();
}
}
}
elsif( $scantype =~ /^(mssql_agentless|mysql_agentless|oracle_agentless|win_agentless|unix_agentless|win_share)$/ )
{
my $scantype_print = "";
if( $scantype eq "mssql_agentless" )
{
$scantype_print = "MSSQL database";
}
elsif( $scantype eq "unix_agentless" )
{
$scantype_print = "UNIX agentless";
}
elsif( $scantype eq "mysql_agentless" )
{
$scantype_print = "MySQL database";
}
elsif( $scantype eq "oracle_agentless" )
{
$scantype_print = "Oracle database";
}
elsif( $scantype =~ /^(win_agentless)$/ )
{
$scantype_print = "Windows agentless";
}
elsif( $scantype =~ /^(win_share)$/ )
{
$scantype_print = "Windows share";
}
if( $action eq "pause" )
{
print "Pause $scantype_print scans
\n";
get_profile();
# if no arguments are given
if( $system eq "" && $scanname eq "" )
{
print "No action will be taken: You must at least specify a scan name.
\n";
}
elsif( $scanname ne "" && $system eq "" )
{
print "Attempting to pause $scantype_print scans... \n";
# get all systems in "running" state
my @pids = ();
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT pid FROM systems WHERE scan=? AND control=\"running\"";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
push @pids, $$results[0];
}
my $length_of_pids = @pids;
if( $length_of_pids == 0 )
{
print "No $scantype_print scans are running, so nothing will be paused.
\n";
}
else
{
Proc::Queue::size( $profile_info{concurrent} );
foreach my $pid( @pids )
{
$length_of_pids--;
my $f = fork;
if( defined ($f) and $f == 0 )
{
print "Trying to pause $scantype_print scan on PID $pid ($length_of_pids $scantype_print scans remain in queue) \n";
# pause OpenDLP
my $command = "kill -STOP $pid";
my $output = `$command`;
print "$pid: OpenDLP $scantype_print scan paused \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"stopped\" WHERE scan=? AND pid=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $pid );
exit(0);
}
1 while waitpid(-1, WNOHANG) > 0;
}
}
$sth->finish();
$dbh->disconnect();
}
# pause specific system
elsif( $scanname ne "" && $system ne "" )
{
# get system's PID
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT pid FROM systems WHERE scan=? AND control=\"running\" AND tracker=?";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
my $results = $sth->fetchrow_arrayref();
my $pid = $$results[0];
if( $pid eq "" )
{
print "$scantype_print scan is not running, so nothing will be paused.
\n";
}
else
{
print "$pid: Attempting to pause $scantype_print scan... \n";
# pause OpenDLP remote scan
my $command = "kill -STOP $pid";
my $output = `$command`;
print "$pid: OpenDLP paused \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"stopped\" WHERE scan=? AND pid=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $pid );
}
$sth->finish();
$dbh->disconnect();
}
}
elsif( $action eq "resume" )
{
print "Resume $scantype_print scans
\n";
# if no arguments are given
if( $system eq "" && $scanname eq "" )
{
print "No action will be taken: You must at least specify a scan name.
\n";
}
elsif( $scanname ne "" && $system eq "" )
{
print "Attempting to resume $scantype_print scans... \n";
get_profile();
# get all systems in "stopped" state
my @pids = ();
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT pid FROM systems WHERE scan=? AND control=\"stopped\"";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
push @pids, $$results[0];
}
my $length_of_pids = @pids;
if( $length_of_pids == 0 )
{
print "No $scantype_print scans are paused, so nothing will be resumed.
\n";
}
else
{
Proc::Queue::size( $profile_info{concurrent} );
foreach my $pid( @pids )
{
$length_of_pids--;
my $f = fork;
if( defined ($f) and $f == 0 )
{
print "Trying to resume $scantype_print scan on PID $pid ($length_of_pids $scantype_print scans remain in queue) \n";
# resume OpenDLP scan
my $command = "kill -CONT $pid";
my $output = `$command`;
print "$pid: OpenDLP $scantype_print scan resumed \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"running\" WHERE scan=? AND pid=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $pid );
exit(0);
}
1 while waitpid(-1, WNOHANG) > 0;
}
}
$sth->finish();
$dbh->disconnect();
}
# resume specific scan
elsif( $scanname ne "" && $system ne "" )
{
get_profile();
# get system's PID
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT pid FROM systems WHERE scan=? AND control=\"stopped\" AND tracker=?";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
my $results = $sth->fetchrow_arrayref();
my $pid = $$results[0];
if( $pid eq "" )
{
print "$scantype_print scan is not running, so nothing will be paused.
\n";
}
else
{
print "$pid: Attempting to resume $scantype_print scan... \n";
# start OpenDLP
my $command = "kill -CONT $pid";
my $output = `$command`;
print "$pid: OpenDLP $scantype_print scan resumed \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"running\" WHERE scan=? AND pid=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $pid );
}
$sth->finish();
$dbh->disconnect();
}
}
elsif( $action eq "uninstall" )
{
print "Permanently stop $scantype_print scans
\n";
# if no arguments are given
if( $system eq "" && $scanname eq "" )
{
print "No action will be taken: You must at least specify a scan name.
\n";
}
elsif( $scanname ne "" && $system eq "" )
{
print "Attempting to permanently stop $scantype_print scans... \n";
get_profile();
# get all PIDs in "running" state
my @pids = ();
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT pid FROM systems WHERE scan=? AND control=\"running\"";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
push @pids, $$results[0];
}
# get all PIDs in "stopped" state
my $string = "SELECT pid FROM systems WHERE scan=? AND control=\"stopped\"";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
push @pids, $$results[0];
}
# uniq @pids
my %seen = ();
@pids = grep {! $seen{$_}++} @pids;
my $length_of_pids = @pids;
if( $length_of_pids == 0 )
{
print "No $scantype_print scans are running or paused, so nothing will be permanently stopped.
\n";
}
else
{
Proc::Queue::size( $profile_info{concurrent} );
foreach my $pid( @pids )
{
$length_of_pids--;
my $f = fork;
if( defined ($f) and $f == 0 )
{
print "Trying to permanently stop $scantype_print scan with PID $pid ($length_of_pids $scantype_print scans remain in queue) \n";
# stop OpenDLP scan
my $command = "kill -9 $pid";
my $output = `$command`;
print "$pid: OpenDLP $scantype_print scan permanently stopped \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"uninstalled\" WHERE scan=? AND pid=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $pid );
# delete any files in agentless table
if( $scantype eq "win_agentless" || $scantype eq "unix_agentless" || $scantype eq "win_share" )
{
my $string = "DELETE FROM agentless where scan=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname );
# delete any unzip temp directories for entire scan
my $string = "SELECT unzipdir FROM agentless_zip WHERE scan=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
my $dir = $$results[0];
remove_tree( $dir );
}
# delete all entries from DB
my $string = "DELETE FROM agentless_zip WHERE scan=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname );
}
if( $scantype eq "unix_agentless" )
{
# unmount/rmdir any sshfs file systems
my $string = "SELECT mountdir FROM agentless_mount WHERE scan=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname );
while( my $results = $sth->fetchrow_arrayref() )
{
my $dir = $$results[0];
`fusermount -u $dir`;
sleep(5);
rmdir $dir;
}
# delete its entry in DB
my $string = "DELETE FROM agentless_mount WHERE scan=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname );
}
exit(0);
}
1 while waitpid(-1, WNOHANG) > 0;
}
}
$sth->finish();
$dbh->disconnect();
}
# uninstall specific system
elsif( $scanname ne "" && $system ne "" )
{
get_profile();
# get system's PID
my $dbh = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
my $string = "SELECT pid FROM systems WHERE scan=? AND tracker=? AND (control=\"stopped\" or control=\"running\")";
my $sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
my $results = $sth->fetchrow_arrayref();
my $pid = $$results[0];
if( $pid eq "" )
{
print "$scantype_print scan is not running or paused, so nothing will be stopped and uninstalled.
\n";
}
else
{
print "$pid: Attempting to permanently stop $scantype_print scan... \n";
# permanently stop OpenDLP scan
my $command = "kill -9 $pid";
my $output = `$command`;
print "$pid: OpenDLP $scantype_print scan permanently stopped \n";
# update "control" in "systems" table
my $string = "UPDATE systems SET control=\"uninstalled\" WHERE scan=? AND pid=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $pid );
if( $scantype eq "win_agentless" || $scantype eq "unix_agentless" || $scantype eq "win_share" )
{
# delete any files in agentless table
my $string = "DELETE FROM agentless where scan=? AND tracker=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
# delete any unzip temp directories for entire scan
my $string = "SELECT unzipdir FROM agentless_zip WHERE scan=? AND tracker=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
while( my $results = $sth->fetchrow_arrayref() )
{
my $dir = $$results[0];
remove_tree( $dir );
}
# delete all entries from DB
my $string = "DELETE FROM agentless_zip WHERE scan=? AND tracker=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
}
if( $scantype eq "unix_agentless" )
{
# unmount/rmdir any sshfs file systems
my $string = "SELECT mountdir FROM agentless_mount WHERE scan=? AND tracker=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
while( my $results = $sth->fetchrow_arrayref() )
{
my $dir = $$results[0];
`fusermount -u $dir`;
sleep(5);
rmdir $dir;
}
# delete its entry in DB
my $string = "DELETE FROM agentless_mount WHERE scan=? AND tracker=?";
$sth = $dbh->prepare( $string );
$sth->execute( $scanname, $system );
}
}
$sth->finish();
$dbh->disconnect();
}
}
}
}
#footer();
sub get_profile
{
my $dbh_profile = DBI->connect("DBI:mysql:database=OpenDLP;host=localhost",$db_username,$db_password);
# first get profile for scanname
my $string = "SELECT profile FROM systems WHERE scan=? LIMIT 1";
my $sth_profile = $dbh_profile->prepare( $string );
$sth_profile->execute( $scanname );
my $results = $sth_profile->fetchrow_arrayref();
my $profile = $$results[0];
my $string = "SELECT username,password,domain,path,concurrent,hash from profiles where profile=?";
$sth_profile = $dbh_profile->prepare( $string );
$sth_profile->execute( $profile );
my $results = $sth_profile->fetchrow_arrayref();
$profile_info{username} = $$results[0];
$profile_info{password} = $$results[1];
$profile_info{domain} = $$results[2];
$profile_info{path} = $$results[3];
$profile_info{concurrent} = $$results[4];
# If smbhash is not blank, set the environment variable SMBHASH
# to hold the value that will be passed to the host
if($$results[5] ne "")
{
$ENV{'SMBHASH'} = $$results[5];
}
$sth_profile->finish();
$dbh_profile->disconnect();
}
sub header
{
print "Content-type: text/html\n\n";
print "\n\n";
print "OpenDLP $version\n";
print "\n";
print "\n";
print "\n";
print "\n";
print "\n";
# make a fancy false positive interface in the next release
# print qq {
#
#
# };
print "\n";
print "\n";
print '
' . "\n";
}
sub footer
{
print "
\n";
}
sub get_version
{
open( V, "<../etc/version" );
my $v = ;
close( V );
chomp $v;
return $v;
}