Changeset 1420

Show
Ignore:
Timestamp:
04/02/08 16:36:25 (4 months ago)
Author:
kindlund
Message:

Incremental updates.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • honeyclient/branches/exp/kindlund-simpler_agent/etc/honeyclient.xml

    r1401 r1420  
    187187        <Database> 
    188188            <enable description="Enables database operations. 1 enables, 0 disables." default="1"> 
    189                 1 
     189                0 
    190190            </enable> 
    191191            <!-- TODO: Update this. --> 
  • honeyclient/branches/exp/kindlund-simpler_agent/lib/HoneyClient/LWA.pm

    r1419 r1420  
    100100    # Check to make sure our environment is Cygwin-based. 
    101101    if ($Config{osname} !~ /^cygwin$/) { 
    102         Carp::croak "Error: " . __PACKAGE__ . " will only run on Win32 platforms!\n"; 
     102        Carp::croak "Error: " . __PACKAGE__ . " will only run on Cygwin platforms!\n"; 
    103103    } 
    104104 
     
    116116 
    117117# Make sure the module loads properly, with the exportable 
     118A 
    118119# functions shared. 
    119120BEGIN { use_ok('HoneyClient::Agent') or diag("Can't load HoneyClient::Agent package.  Check to make sure the package library is correctly listed within the path."); } 
     
    152153use MIME::Base64 qw(encode_base64 decode_base64); 
    153154 
     155# Make sure Win32::Job loads. 
     156BEGIN { use_ok('Win32::Job') or diag("Can't load Win32::Job package.  Check to make sure the package library is correctly listed within the path."); } 
     157require_ok('Win32::Job'); 
     158use Win32::Job; 
     159 
    154160# Global test variables. 
    155161our $PORT = getVar(name      => "port", 
     
    172178# Include Thread Libraries 
    173179#use threads; 
    174 # TODO: Remove all ": shared" refs! 
    175180#use threads::shared; 
    176181#use Thread::Semaphore; 
     
    191196use MIME::Base64 qw(encode_base64 decode_base64); 
    192197 
     198# Include Win32 Job Library 
     199use Win32::Job; 
     200 
    193201# Include Logging Library 
    194202use Log::Log4perl qw(:easy); 
     
    198206 
    199207# Complete URL of SOAP server, when initialized. 
    200 our $URL_BASE       : shared = undef; 
    201 our $URL            : shared = undef; 
     208our $URL_BASE       = undef; 
     209our $URL            = undef; 
    202210 
    203211# The process ID of the SOAP server daemon, once created. 
    204 our $DAEMON_PID     : shared = undef; 
     212our $DAEMON_PID     = undef; 
    205213 
    206214# Global array, to indicate which implemented Drivers the 
     
    210218# Global value, to indicate if the Agent should perform 
    211219# any integrity checks. 
    212 our $PERFORM_INTEGRITY_CHECKS : shared
     220our $PERFORM_INTEGRITY_CHECKS
    213221    getVar(name => "perform_integrity_checks"); 
    214222 
     
    617625=head1 EXTERNAL SOAP FUNCTIONS 
    618626 
    619 =head2 run(driver_name => $driverName) 
     627=head2 drive(driver_name => $driverName, 
     628             parameters => $params, 
     629             timeout => $timeout) 
    620630 
    621631=over 4 
     
    627637=item 1) 
    628638 
    629 The specified Driver is driven for multiple work units, where each 
    630 consecutive drive operation contacts the same network resources 
    631 (aka. "targets").  The Driver ceases its operation, as soon as 
    632 it has exhausted all targets or until it is ready to contact a 
    633 different set of targets. 
     639The specified target application (Driver) is driven for a single work unit, 
     640by executing the application with the supplied arguments for a specified 
     641period of time. 
    634642 
    635643=item 2) 
     
    638646Integrity check. 
    639647 
     648=item 3) 
     649 
     650The results of this Integrity check are then returned. 
     651 
    640652=back  
    641653 
    642 # XXX: Fill this in
     654# XXX: Verify this
    643655 
    644656I<Inputs>:  
    645657 B<$driverName> is the name of the Driver to use, when running this  
    646658cycle. 
     659 B<$params> are the optional parameters to supply to the driven 
     660application, as arguments. 
     661 B<$timeout> is an optional argument, specifying how long the Agent 
     662should wait after executing the driven application before it performs 
     663an Integrity check. 
     664 
     665# XXX: Describe this hashtable output. 
    647666  
    648 I<Output>: Returns true if the Agent successfully started a new cycle; 
    649 returns false, if the Agent is still running an existing cycle and 
    650 has not finished yet. 
    651  
    652 I<Notes>: 
    653 During a single run() cycle, it is expected that the driven application 
    654 will only contact the same targets.  This allows the Manager to update 
    655 firewall rules between cycles. 
     667I<Output>: 
    656668 
    657669=back 
     
    665677=cut 
    666678 
    667 sub run
     679sub drive
    668680    # Extract arguments. 
    669681    my ($class, %args) = @_; 
     
    685697        # Die if no valid argument is supplied. 
    686698        $LOG->warn("No Driver name specified."); 
    687         die SOAP::Fault->faultcode(__PACKAGE__ . "->run()") 
     699        die SOAP::Fault->faultcode(__PACKAGE__ . "->drive()") 
    688700                       ->faultstring("No Driver name specified."); 
    689701    } 
     
    695707    unless (defined($driverName)) { 
    696708        $LOG->warn("Not allowed to run Driver (" . $args{'driver_name'} . ")."); 
    697         die SOAP::Fault->faultcode(__PACKAGE__ . "->run()") 
     709        die SOAP::Fault->faultcode(__PACKAGE__ . "->drive()") 
    698710                       ->faultstring("Not allowed to run Driver (" . $args{'driver_name'} . ")."); 
    699711    } 
    700  
    701     # Temporary variable, used to hold thawed driver data. 
    702     my $data = undef; 
    703  
    704     # Temporary variable, used to hold thread IDs. 
    705     my $tid = undef; 
    706  
    707     # Temporary variable, used to hold thread objects. 
    708     my $thread = undef; 
    709  
    710     if (defined($driverName)) { 
    711  
    712         # Acquire data lock. 
    713         $data = _lock(); 
    714  
    715         # Read the TID. 
    716         $tid = $data->{$driverName}->{'thread_id'}; 
    717  
    718 # XXX: Delete this, eventually. 
    719 print $driverName . " - Checking TID = " . Dumper($tid) . "\n"; 
    720 if (defined(threads->object($tid))) { 
    721     print $driverName . " - Thread defined.\n"; 
    722     if (threads->object($tid)->is_running()) { 
    723         print $driverName . " - Thread is running.\n"; 
    724     } else { 
    725         print $driverName . " - Thread is NOT running.\n"; 
    726     } 
    727 } else { 
    728     print $driverName . " - Thread NOT defined.\n"; 
    729 
    730          
    731         # Sanity check: Return false, if we already have a 
    732         # driver thread running. 
    733         if (defined($tid) && 
    734             defined($thread = threads->object($tid)) && 
    735             $thread->is_running()) { 
    736  
    737             # Release data lock. 
    738             _unlock(); 
    739  
    740             return 0; 
    741         } else { 
    742             # XXX: Remove this, eventually. 
    743             print $driverName . " - Creating a new run() child thread...\n"; 
    744         } 
    745  
    746         # Quickly define a temporary thread ID. 
    747         # This value is simply a placeholder that will 
    748         # get redefined later on in this function to 
    749         # the thread's valid ID, once the thread has been 
    750         # initialized. 
    751         # 
    752         # By defining a placeholder valid here, we avoid 
    753         # a potential race condition, where multiple calls 
    754         # to run() are made consecutively. 
    755         # 
    756         # Temporarily set the driver thread to be the 
    757         # main thread. 
    758         $data->{$driverName}->{'thread_id'} = 0; 
    759          
    760         # Release data lock. 
    761         _unlock($data); 
    762  
    763         $thread = threads->create(\&worker, 
    764                                   { 
    765                                     'driver_name' => $driverName, 
    766                                     'integrity'   => $integrityData, 
    767                                   } 
    768                                  ); 
    769              
    770         # Acquire data lock. 
    771         $data = _lock(); 
    772              
    773         # Set the valid thread ID. 
    774         $data->{$driverName}->{'thread_id'} = $thread->tid(); 
    775         if ($thread->is_running()) { 
    776             # XXX: Debugging, remove eventually.  
    777             print $driverName . " - Thread ID = " . $thread->tid() . "\n"; 
    778         } else { 
    779             # XXX: Debugging, remove eventually.  
    780             print $driverName . " - Thread ID = " . $thread->tid() . " (NOT RUNNING)\n"; 
    781         } 
    782  
    783         # Release data lock. 
    784         _unlock($data); 
    785     } 
    786  
    787     # XXX: Debugging, remove eventually.  
    788     print "Run thread(s) initialized.\n"; 
    789  
    790     # At this point, the driver thread is initialized and running, 
    791     # return true. 
     712    
     713    # Sanity check for optional arguments. 
     714    if (!$argsExist || 
     715        !exists($args{'parameters'}) || 
     716        !defined($args{'parameters'})) { 
     717        $args{'parameters'} = ""; 
     718    } 
     719    if (!$argsExist || 
     720        !exists($args{'timeout'}) || 
     721        !defined($args{'timeout'})) { 
     722        $args{'timeout'} = getVar(name => "timeout", 
     723                                  namespace => $args{'driver_name'}); 
     724    } 
     725 
     726    # Create a new Job. 
     727    my $job = Win32::Job->new(); 
     728 
     729    # Sanity check. 
     730    if (!defined($job)) { 
     731        $LOG->error("Error: Unable to spawn a new process - " . $^E . "."); 
     732        die SOAP::Fault->faultcode(__PACKAGE__ . "->drive()") 
     733                       ->faultstring("Error: Unable to spawn a new process - " . $^E . "."); 
     734    } 
     735 
     736    # Spawn the job. 
     737    my $processExec = getVar(name => "process_exec", 
     738                             namespace => $args{'driver_name'}); 
     739    my $processName = getVar(name => "process_name", 
     740                             namespace => $args{'driver_name'}); 
     741    my $status = $job->spawn($processExec, $processName . " " . $args{'parameters'}); 
     742 
     743    # Sanity check. 
     744    if (!defined($status)) { 
     745        $LOG->error("Error: Unable to execute '" . $processExec . "'"); 
     746        die SOAP::Fault->faultcode(__PACKAGE__ . "->drive()") 
     747                       ->faultstring("Error: Unable to execute '" . $processExec . "'"); 
     748    } 
     749 
     750    # Run the job. 
     751    $job->run($args{'timeout'}); 
     752 
     753    # Check to see if run fails. 
     754    $status = $job->status(); 
     755 
     756    # Sanity check. 
     757    if (!defined($status) || 
     758        !scalar(%{$status})) { 
     759        $LOG->error("Error: Unable to retrieve job status from spawned process."); 
     760        die SOAP::Fault->faultcode(__PACKAGE__ . "->drive()") 
     761                       ->faultstring("Error: Unable to retrieve job status from spawned process."); 
     762    } 
     763 
     764    # Figure out the correct Process ID. 
     765    my @keys = keys(%{$status}); 
     766    my $processID = pop(@keys); 
     767 
     768    # Sanity checks. 
     769    if (!defined($processID) || 
     770        !exists($status->{$processID}->{'exitcode'}) || 
     771        !defined($status->{$processID}->{'exitcode'})) { 
     772        $LOG->error("Error: Unable to retrieve job status from spawned process."); 
     773        die SOAP::Fault->faultcode(__PACKAGE__ . "->drive()") 
     774                       ->faultstring("Error: Unable to retrieve job status from spawned process."); 
     775    } 
     776 
     777    # Check to make sure the exitcode is '293', meaning, that the 
     778    # application didn't unexpectedly die early. 
     779    if ($status->{$processID}->{'exitcode'} != 293) { 
     780        $LOG->warn("Unexpected: '" . $processName . "' process (ID = " . $processID . ") terminated early!"); 
     781    } 
     782 
    792783    return 1; 
    793784}