root/honeyclient/tags/exp/UP2-kindlund-dynamic_updates/lib/HoneyClient/Manager.pm

Revision 796, 26.8 kB (checked in by kindlund, 1 year ago)

Version bump.

  • Property svn:keywords set to Id "$file"
Line 
1 #######################################################################
2 # Created on:  May 11, 2006
3 # Package:     HoneyClient::Manager
4 # File:        Manager.pm
5 # Description: Central library used for manager-based operations.
6 #
7 # CVS: $Id$
8 #
9 # @author knwang, ttruong, jdurick, kindlund
10 #
11 # Copyright (C) 2007 The MITRE Corporation.  All rights reserved.
12 #
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation, using version 2
16 # of the License.
17 #
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 # GNU General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 # 02110-1301, USA.
27 #
28 #######################################################################
29
30 =pod
31
32 =head1 NAME
33
34 # XXX: Fill this in.
35
36 =head1 VERSION
37
38 This documentation refers to HoneyClient::Manager version 0.99.
39
40 =head1 SYNOPSIS
41
42 =head2 CREATING THE SOAP SERVER
43
44 # XXX: Fill this in.
45
46 =head2 INTERACTING WITH THE SOAP SERVER
47
48 # XXX: Fill this in.
49
50 =head1 DESCRIPTION
51
52 # XXX: Fill this in.
53
54 =cut
55
56 package HoneyClient::Manager;
57
58 # XXX: Disabled version check, Honeywall does not have Perl v5.8 installed.
59 #use 5.008006;
60 use strict;
61 use warnings FATAL => 'all';
62 use Config;
63 use Carp ();
64
65 #######################################################################
66 # Module Initialization                                               #
67 #######################################################################
68
69 BEGIN {
70     # Defines which functions can be called externally.
71     require Exporter;
72     our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION, @DRIVERS);
73
74     # Set our package version.
75     $VERSION = 0.99;
76
77     @ISA = qw(Exporter);
78
79     # Symbols to export automatically
80     @EXPORT = qw(init destroy);
81
82     # Items to export into callers namespace by default. Note: do not export
83     # names by default without a very good reason. Use EXPORT_OK instead.
84     # Do not simply export all your public functions/methods/constants.
85
86     # This allows declaration use HoneyClient::Manager ':all';
87     # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
88     # will save memory.
89
90     %EXPORT_TAGS = (
91         'all' => [ qw(init destroy) ],
92     );
93
94     # Symbols to autoexport (when qw(:all) tag is used)
95     @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
96
97     # Check to see if ithreads are compiled into this version of Perl.
98     $Config{useithreads} or Carp::croak "Error: Recompile Perl with ithread support, in order to use this module.\n";
99
100     $SIG{PIPE} = 'IGNORE'; # Do not exit on broken pipes.
101 }
102 our (@EXPORT_OK, $VERSION);
103
104 =pod
105
106 =begin testing
107
108 # Make sure the module loads properly, with the exportable
109 # functions shared.
110 BEGIN { use_ok('HoneyClient::Manager', qw(init destroy)) or diag("Can't load HoneyClient::Manager package.  Check to make sure the package library is correctly listed within the path."); }
111 require_ok('HoneyClient::Manager');
112 can_ok('HoneyClient::Manager', 'init');
113 can_ok('HoneyClient::Manager', 'destroy');
114 use HoneyClient::Manager qw(init destroy);
115
116 # Make sure HoneyClient::Util::SOAP loads.
117 BEGIN { use_ok('HoneyClient::Util::SOAP', qw(getServerHandle getClientHandle)) or diag("Can't load HoneyClient::Util::SOAP package.  Check to make sure the package library is correctly listed within the path."); }
118 require_ok('HoneyClient::Util::SOAP');
119 can_ok('HoneyClient::Util::SOAP', 'getServerHandle');
120 can_ok('HoneyClient::Util::SOAP', 'getClientHandle');
121 use HoneyClient::Util::SOAP qw(getServerHandle getClientHandle);
122
123 # Make sure HoneyClient::Util::Config loads.
124 BEGIN { use_ok('HoneyClient::Util::Config', qw(getVar)) or diag("Can't load HoneyClient::Util::Config package.  Check to make sure the package library is correctly listed within the path."); }
125 require_ok('HoneyClient::Util::Config');
126 can_ok('HoneyClient::Util::Config', 'getVar');
127 use HoneyClient::Util::Config qw(getVar);
128
129 # Make sure Storable loads.
130 BEGIN { use_ok('Storable', qw(nfreeze thaw)) or diag("Can't load Storable package.  Check to make sure the package library is correctly listed within the path."); }
131 require_ok('Storable');
132 can_ok('Storable', 'nfreeze');
133 can_ok('Storable', 'thaw');
134 use Storable qw(nfreeze thaw);
135
136 # Make sure MIME::Base64 loads.
137 BEGIN { use_ok('MIME::Base64', qw(encode_base64 decode_base64)) or diag("Can't load MIME::Base64 package.  Check to make sure the package library is correctly listed within the path."); }
138 require_ok('MIME::Base64');
139 can_ok('MIME::Base64', 'encode_base64');
140 can_ok('MIME::Base64', 'decode_base64');
141 use MIME::Base64 qw(encode_base64 decode_base64);
142
143 =end testing
144
145 =cut
146
147 #######################################################################
148
149 # Include the SOAP Utility Library
150 use HoneyClient::Util::SOAP qw(getClientHandle getServerHandle);
151
152 # Include Thread Libraries
153 use threads;
154 use threads::shared;
155 use Thread::Semaphore;
156 use Thread::Queue;
157
158 # Include utility access to global configuration.
159 use HoneyClient::Util::Config qw(getVar);
160
161 # Include the VM Utility Library
162 # TODO: Include unit tests.
163 use HoneyClient::Manager::VM qw();
164
165 # Check if DB support is enabled.
166 our $DB_ENABLE = getVar(name      => "enable",
167                         namespace => "HoneyClient::DB");
168
169 if ($DB_ENABLE) {
170     # Include DB Utility Library
171     # TODO: Include unit tests.
172     require HoneyClient::DB::Fingerprint;
173 }
174
175 # XXX: Remove this, eventually.
176 use Data::Dumper;
177
178 # Make Dumper format more verbose.
179 $Data::Dumper::Terse = 0;
180 $Data::Dumper::Indent = 2;
181
182 # Include Hash Serialization Utility Libraries
183 use Storable qw(nfreeze thaw);
184
185 # Include Base64 Libraries
186 use MIME::Base64 qw(encode_base64 decode_base64);
187
188 # Include FW Utility Library
189 # TODO: Include unit tests.
190 #use HoneyClient::Manager::FW;
191
192 # Include Hash Serialization Utility Libraries
193 # TODO: Include unit tests.
194 use Storable qw(nfreeze thaw);
195
196 # Include VmPerl Constants.
197 # TODO: Include unit tests.
198 use VMware::VmPerl qw(VM_EXECUTION_STATE_ON
199                       VM_EXECUTION_STATE_OFF
200                       VM_EXECUTION_STATE_STUCK
201                       VM_EXECUTION_STATE_SUSPENDED);
202
203 # TODO: Include unit tests.
204 use IO::File;
205
206 # TODO: Include unit tests.
207 # Include Logging Library
208 use Log::Log4perl qw(:easy);
209
210 # The global logging object.
211 our $LOG = get_logger();
212
213 # Complete URL of SOAP server, when initialized.
214 our $URL_BASE       : shared = undef;
215 our $URL            : shared = undef;
216
217 # The process ID of the SOAP server daemon, once created.
218 our $DAEMON_PID     : shared = undef;
219
220 # XXX: These will be migrated somewhere else, eventually.
221 our $vmStateTable = { };
222 our $vmCloneConfig      = undef;
223 our $stubVM             = undef;
224 our $stubAgent          = undef;
225 our $stubFW             = undef;
226
227 # This is a temporary, shared variable, used to print out the
228 # state of the agent, when _cleanup() occurs.
229 # XXX: This variable and all reference to it will be deleted,
230 # eventually.
231 our $globalAgentState   = undef;
232
233 # This static variable may contain a filename that the Manager
234 # would use to dump its entire state information, upon termination.
235 # XXX: May want to change this format/usage, eventually.
236 our $STATE_FILE = getVar(name => "manager_state");
237
238 # Temporary variable, used to indicate to the fault handler whether
239 # or not errors/warnings should be suppressed.
240 our $SUPPRESS_ERRORS = 0;
241
242 #######################################################################
243 # Daemon Initialization / Destruction                                 #
244 #######################################################################
245
246 =pod
247
248 =head1 EXPORTED FUNCTIONS
249
250 The following init() and destroy() functions are the only direct
251 calls required to startup and shutdown the SOAP server.
252
253 All other interactions with this daemon should be performed as
254 C<SOAP::Lite> function calls, in order to ensure consistency across
255 client sessions.  See the L<"EXTERNAL SOAP FUNCTIONS"> section, for
256 more details.
257
258 =head2 HoneyClient::Manager->init()
259
260 =over 4
261
262 Starts a new SOAP server, within a child process.
263
264 I<Inputs>:
265
266 # XXX: Finish this.
267
268 I<Output>:
269
270 # XXX: Finish this.
271
272 =back
273
274 =begin testing
275
276 # XXX: Test init() method.
277
278 =end testing
279
280 =cut
281
282 sub init {
283     # Extract arguments.
284     # Hash-based arguments are used, since HoneyClient::Util::SOAP is unable to handle
285     # hash references directly.  Thus, flat hashtables are used throughout the code
286     # for consistency.
287     my ($class, %args) = @_;
288    
289     # XXX: Finish this.
290 }
291
292 =pod
293
294 =head2 HoneyClient::Manager->destroy()
295
296 =over 4
297
298 Terminates the SOAP server within the child process.
299
300 I<Output>: True if successful, false otherwise.
301
302 =back
303
304 =begin testing
305
306 # XXX: Test destroy() method.
307
308 # TODO: delete this.
309 #exit;
310
311 =end testing
312
313 =cut
314
315 sub destroy {
316     my $ret = undef;
317    
318     # XXX: Finish this.
319     
320     return $ret;
321 }
322
323 #######################################################################
324 # Private Methods Implemented                                         #
325 #######################################################################
326
327 sub _handleFault {
328
329     # Extract arguments.
330     my ($class, $res) = @_;
331
332     # Construct error message.
333     # Figure out if the error occurred in transport or over
334     # on the other side.
335     my $errMsg = $class->transport->status; # Assume transport error.
336
337     if (ref $res) {
338         $errMsg = $res->faultcode . ": ".  $res->faultstring . "\n";
339     }
340
341     if (!$SUPPRESS_ERRORS) {
342         $LOG->warn("Error occurred during processing. " . $errMsg);
343         Carp::carp __PACKAGE__ . "->_handleFault(): Error occurred during processing.\n" . $errMsg;
344     }
345 }
346
347 sub _handleFaultAndCleanup {
348
349     # Extract arguments.
350     my ($class, $res) = @_;
351
352     # Print fault.
353     _handleFault($class, $res);
354    
355     # Cleanup before dying.
356     _cleanup();
357 }
358
359 sub _cleanup {
360
361     $LOG->info("Cleaning up.");
362
363     # Mask all possible signals, so that we don't call this function multiple times.
364     $SIG{HUP}     = sub { };
365     $SIG{INT}     = sub { };
366     $SIG{QUIT}    = sub { };
367     $SIG{ABRT}    = sub { };
368     $SIG{PIPE}    = sub { };
369     $SIG{TERM}    = sub { };
370
371     HoneyClient::Manager::VM->destroy();
372
373     # XXX: Need to clean this up.
374     my $stubFW = getClientHandle(namespace     => "HoneyClient::Manager::FW");
375
376     # XXX: Change this to fwInit(), eventually.
377     # Reset the firewall, to allow everything open.
378     $stubFW->testConnect();
379
380     # Check to see if a clone was created...
381     if (defined($vmCloneConfig)) {
382         # We sleep for a bit, to make sure that the previous VM daemon was
383         # properly destroyed and released the previous port that was in use.
384         sleep (10);
385
386         # We reinstantiate a new VM daemon, because if the user had hit CTRL-C
387         # or called any other signal, then that signal would propagate to all
388         # processes, causing the VM daemon's signal handler to self terminate.
389         #
390         # Hence, rather than fight the VM daemon's natural self termination,
391         # we let the daemon die, but the create a new one, for the sole purpose
392         # of cleanup up the clones.
393         HoneyClient::Manager::VM->init();
394         $LOG->info("Calling suspendVM(config => " . $vmCloneConfig . ").");
395         my $stubVM = getClientHandle(namespace => "HoneyClient::Manager::VM");
396         $stubVM->suspendVM(config => $vmCloneConfig);
397         print "Done!\n";
398         HoneyClient::Manager::VM->destroy();
399     }
400
401     # XXX: May want to change this format/usage, eventually.
402     if (length($STATE_FILE) > 0 &&
403         defined($globalAgentState)) {
404         $LOG->info("Saving state to '" . $STATE_FILE . "'.");
405         my $dump_file = new IO::File($STATE_FILE, "a");
406
407         # XXX: Delete this block, eventually.
408         $Data::Dumper::Terse = 0;
409         $Data::Dumper::Indent = 2;
410         print $dump_file Dumper(thaw(decode_base64($globalAgentState)));
411     }
412
413     exit;
414 }
415
416 # XXX: Install the cleanup handler, in case the parent process dies
417 # unexpectedly.
418 $SIG{HUP} = sub { _cleanup(); };
419 $SIG{INT}  = sub { _cleanup(); };
420 $SIG{QUIT} = sub { _cleanup(); };
421 $SIG{ABRT} = sub { _cleanup(); };
422 $SIG{PIPE} = sub { _cleanup(); };
423 $SIG{TERM} = sub { _cleanup(); };
424
425 #######################################################################
426 # Public Methods Implemented                                          #
427 #######################################################################
428
429 =pod
430
431 =head1 EXPORTS
432
433 =head2 run()
434
435 =over 4
436
437 # XXX: Fill this in.
438
439 I<Inputs>:
440  B<$arg> is an optional argument.
441
442 driver
443 master_vm_config
444 start_state
445  
446 I<Output>: XXX: Fill this in.
447
448 =back
449
450 =begin testing
451
452 # XXX: Fill this in.
453
454 =end testing
455
456 =cut
457
458 sub run {
459     # Extract arguments.
460     # Hash-based arguments are used, since HoneyClient::Util::SOAP is unable to handle
461     # hash references directly.  Thus, flat hashtables are used throughout the code
462     # for consistency.
463     my ($class, %args) = @_;
464     my $agentState = undef;
465
466     # Sanity check, make sure the master_vm_config has
467     # been specified.
468     my $argsExist = scalar(%args);
469     if (!$argsExist ||
470         !exists($args{'master_vm_config'}) ||
471         !defined($args{'master_vm_config'})) {
472         # Get the master_vm_config from the configuration file.
473         $args{'master_vm_config'} = getVar(name      => "master_vm_config",
474                                            namespace => "HoneyClient::Manager::VM");
475     }
476
477     for (;;) {
478         print "Starting new session...\n";
479         $agentState = $class->runSession(%args);
480         $args{'agent_state'} = $agentState;
481
482         # XXX: Delete this, eventually.
483         $globalAgentState = $agentState;
484
485         #$Data::Dumper::Terse = 0;
486         #$Data::Dumper::Indent = 2;
487         #print Dumper(thaw(decode_base64($agentState)));
488     }
489 }
490
491 sub runSession {
492
493     # Extract arguments.
494     # Hash-based arguments are used, since HoneyClient::Util::SOAP is unable to handle
495     # hash references directly.  Thus, flat hashtables are used throughout the code
496     # for consistency.
497     my ($class, %args) = @_;
498
499     my $som       = undef;
500     my $ret       = undef;
501     my $vmIP      = undef;
502     my $vmMAC     = undef;
503     my $vmName    = undef;
504     my $URL       = undef;
505     my $vmState   = undef;
506     my $vmCompromised = 0;
507
508     # Get a stub connection to the firewall.
509     $stubFW = getClientHandle(namespace     => "HoneyClient::Manager::FW",
510                               fault_handler => \&_handleFaultAndCleanup);
511
512     # Open up the firewall initially, to allow the Agent to do an SVN update.
513     $stubFW->testConnect();
514
515     $URL = HoneyClient::Manager::VM->init();
516     print "VM Daemon Listening On: " . $URL . "\n";
517    
518     $stubVM = getClientHandle(namespace     => "HoneyClient::Manager::VM",
519                               fault_handler => \&_handleFaultAndCleanup);
520    
521     print "Calling setMasterVM()...\n";
522     $som = $stubVM->setMasterVM(config => $args{'master_vm_config'});
523     print "Result: " . $som->result() . "\n";
524
525     print "Calling quickCloneVM()...\n";
526     $som = $stubVM->quickCloneVM();
527     print "Result: " . $som->result() . "\n";
528     $vmCloneConfig = $som->result();
529
530     # Make sure the VM is fully cloned, before trying to make any subsequent calls.
531     print "Calling isRegisteredVM()...\n";
532     $som = $stubVM->isRegisteredVM(config => $vmCloneConfig);
533     $ret = $som->result();
534
535     if (defined($ret)) {
536         print "Result: " . $ret . "\n";
537     }
538
539     while (!defined($ret)) {
540         sleep (3);
541         print "Calling isRegisteredVM()...\n";
542         $som = $stubVM->isRegisteredVM(config => $vmCloneConfig);
543         $ret = $som->result();
544         if (defined($ret)) {
545             print "Result: " . $ret . "\n";
546         }
547     }
548
549     print "Calling getStateVM()...\n";
550     $som = $stubVM->getStateVM(config => $vmCloneConfig);
551     $vmState = $som->result();
552
553     if ($vmState == VM_EXECUTION_STATE_ON) {
554         print "ON\n";
555     } elsif ($vmState == VM_EXECUTION_STATE_OFF) {
556         print "OFF\n";
557     } elsif ($vmState == VM_EXECUTION_STATE_SUSPENDED) {
558         print "SUSPENDED\n";
559     } elsif ($vmState == VM_EXECUTION_STATE_STUCK) {
560         print "STUCK\n";
561     } else {
562         print "UNKNOWN\n";
563     }
564
565     while ($vmState != VM_EXECUTION_STATE_ON) {
566         sleep (3);
567
568         print "Calling getStateVM()...\n";
569         $som = $stubVM->getStateVM(config => $vmCloneConfig);
570         $vmState = $som->result();
571
572         if ($vmState == VM_EXECUTION_STATE_ON) {
573             print "ON\n";
574         } elsif ($vmState == VM_EXECUTION_STATE_OFF) {
575             print "OFF\n";
576         } elsif ($vmState == VM_EXECUTION_STATE_SUSPENDED) {
577             print "SUSPENDED\n";
578         } elsif ($vmState == VM_EXECUTION_STATE_STUCK) {
579             print "STUCK\n";
580         } else {
581             print "UNKNOWN\n";
582         }
583     }
584
585     print "Calling getMACaddrVM()...\n";
586     $som = $stubVM->getMACaddrVM(config => $vmCloneConfig);
587     print "Result: " . $som->result() . "\n";
588     $vmMAC = $som->result();
589
590     # Figure out when the Agent on the VM is alive and well.
591     $ret = undef;
592     my $logMsgPrinted = 0;
593     while (!$ret) {
594         sleep (3);
595         print "Calling getIPaddrVM()...\n";
596         $som = $stubVM->getIPaddrVM(config => $vmCloneConfig);
597         if (defined($som->result())) {
598             print "Result: " . $som->result() . "\n";
599         }
600         $vmIP = $som->result();
601
602         print "Calling getNameVM()...\n";
603         $som = $stubVM->getNameVM(config => $vmCloneConfig);
604         print "Result: " . $som->result() . "\n";
605         $vmName = $som->result();
606
607         if (defined($vmIP) && defined($vmName)) {
608             if (!$logMsgPrinted) {
609                 $LOG->info("Created clone VM (" . $vmName . ") using IP (" . $vmIP . ") and MAC (" . $vmMAC . ").");
610                 $logMsgPrinted = 1;
611             }
612
613             # Try contacting the Agent; ignore any faults.
614             $SUPPRESS_ERRORS = 1;
615             $stubAgent = getClientHandle(namespace     => "HoneyClient::Agent",
616                                          address       => $vmIP,
617                                          fault_handler => \&_handleFault);
618
619             eval {
620                 print "Calling getStatus()...\n";
621                 $som = $stubAgent->getStatus();
622                 $ret = thaw(decode_base64($som->result()));
623                 print "Result:\n";
624                 # Make Dumper format more verbose.
625                 $Data::Dumper::Terse = 0;
626                 $Data::Dumper::Indent = 2;
627                 print Dumper($ret);
628
629             };
630             # Clear returned state, if any fault occurs.
631             if ($@) {
632                 $ret = undef;
633             }
634             $SUPPRESS_ERRORS = 0;
635         }
636     }
637
638     # Build our VM's connection table.
639     # Note: We assume our VM has a single MAC address
640     # and a single IP address.
641     $vmStateTable->{$vmName}->{sources}->{$vmMAC}->{$vmIP} = {
642         # XXX: We assume we can't pinpoint what source TCP ports the
643         # corresponding driver will need.  (We may want to get this
644         # information eventually from the Agent, as part of Driver::next().)
645         'tcp' => undef,
646     };
647
648     print "VM State Table:\n";
649     # Make Dumper format more verbose.
650     $Data::Dumper::Terse = 0;
651     $Data::Dumper::Indent = 2;
652     print Dumper($vmStateTable) . "\n";
653  
654     # Initialize the firewall.
655     $stubFW->fwInit();
656
657     # Add new chain, per cloned VM.
658     $stubFW->addChain($vmStateTable);
659    
660     sleep (2);
661
662     # Recreate the client stub; handle faults.
663     $stubAgent = getClientHandle(namespace     => "HoneyClient::Agent",
664                                  address       => $vmIP,
665                                  fault_handler => \&_handleFaultAndCleanup);
666
667     # Call updateState() first, to seed initial data.
668     # TODO: Need to support asynchronous updates (url adding)
669     # from user input.
670     print "Calling updateState()...\n";
671     $som = $stubAgent->updateState($args{'agent_state'});
672
673     # Recreate the client stub; ignore faults.
674     $stubAgent = getClientHandle(namespace     => "HoneyClient::Agent",
675                                  address       => $vmIP,
676                                  fault_handler => \&_handleFault);
677
678     # Recreate the firewall stub; ignore faults.
679     $stubFW = getClientHandle(namespace     => "HoneyClient::Manager::FW",
680                               fault_handler => \&_handleFault);
681
682     for (my $counter = 1;; $counter++) {
683
684         # From this point on, catch all errors generated and
685         # assume that the Agent's watchdog process will recover.
686         eval {
687             print "Calling getState()...\n";
688             $som = $stubAgent->getState();
689             $args{'agent_state'} = $som->result();
690
691             # XXX: Delete this, eventually.
692             $globalAgentState = $args{'agent_state'};
693
694             print "Calling getStatus()...\n";
695             $som = $stubAgent->getStatus();
696             print "Result:\n";
697             $ret = thaw(decode_base64($som->result()));
698             # Make Dumper format more verbose.
699             $Data::Dumper::Terse = 0;
700             $Data::Dumper::Indent = 2;
701             print Dumper($ret->{$args{'driver'}}->{status});
702             #print Dumper($ret);
703
704             # Check to see if Agent::run() thread has stopped
705             # and that a compromise was detected.
706             if (!$ret->{$args{'driver'}}->{status}->{is_running}) {
707                 if ($ret->{$args{'driver'}}->{status}->{is_compromised}) {
708                     # Check to see if the VM has been compromised.
709                     print "WARNING: VM HAS BEEN COMPROMISED!\n";
710                     $LOG->info("Calling suspendVM(config => " . $vmCloneConfig . ").");
711                     $som = $stubVM->suspendVM(config => $vmCloneConfig);
712                     HoneyClient::Manager::VM->destroy();
713                     $vmCompromised = 1;
714
715                     # Insert Compromised Fingerprint into DB.
716                     my $fingerprint = $ret->{$args{'driver'}}->{status}->{fingerprint};
717                     $LOG->warn("VM Compromised.  Last Resource (" . $fingerprint->{'last_resource'} . ")");
718                     $fingerprint->{'lasturl'} = delete($fingerprint->{'last_resource'});
719                     $fingerprint->{vmid} = $vmName;
720                     print "Fingerprint:\n";
721                     print Dumper($fingerprint) . "\n";
722                     if ($DB_ENABLE) {
723                         $LOG->info("Inserting Fingerprint Into Database.");
724                         my $fp = HoneyClient::DB::Fingerprint->new($fingerprint);
725                         $fp->insert();
726                         $LOG->info("Database Insert Successful.");
727                     }
728                     return; # Return out of eval block.
729                 } else {
730                     print "VM Integrity Check: OK!\n";
731
732                     # Check to see if any links remain to be processed by the
733                     # Agent.
734                     if (!$ret->{$args{'driver'}}->{status}->{links_remaining}) {
735
736                         $LOG->info("All URLs exhausted.  Shutting down Manager.");
737                         # Get a local copy of the configuration and kill the global copy.
738                         my $vmCfg = $vmCloneConfig;
739                         $vmCloneConfig = undef;
740                         $LOG->info("Calling suspendVM(config => " . $vmCfg . ").");
741                         $stubVM->suspendVM(config => $vmCfg);
742                         print "Done!\n";
743                         _cleanup();
744
745                     } else {
746                         # The Agent::run() thread has stopped; we assume
747                         # it's because the Agent is waiting for the firewall
748                         # to allow access to the new targets.
749                 
750                         # Delete the old firewall rules, based upon existing
751                         # targets.
752                         $stubFW->deleteRules($vmStateTable);
753
754                         # Get the new targets from the Agent.
755                         $vmStateTable->{$vmName}->{targets} = $ret->{$args{'driver'}}->{next}->{targets};
756
757                         print "VM State Table:\n";
758                         # Make Dumper format more verbose.
759                         $Data::Dumper::Terse = 0;
760                         $Data::Dumper::Indent = 2;
761                         print Dumper($vmStateTable) . "\n";
762
763                         # Add the new targets from the Agent.
764                         $stubFW->addRules($vmStateTable);
765
766                         print "Calling run()...\n";
767                         $som = $stubAgent->run(driver_name => $args{'driver'});
768                     }
769                 }
770             }
771         };
772         if ($@) {
773             print "Error: $@\n";
774             my $resetSuccessful = 0;
775             while (!$resetSuccessful) {
776                 print "Resetting firewall...\n";
777                 eval {
778                     # We assume the error was caused by some sort of communications
779                     # problem with the Agent.  Assume the Agent's watchdog will restart
780                     # the daemon, in which case, we indefinately try to reset the
781                     # firewall accordingly.
782                     $stubFW->fwInit();
783                     $stubFW->addChain($vmStateTable);
784                     $stubFW->addRules($vmStateTable);
785                 };
786                 if (!$@) {
787                     $resetSuccessful = 1;
788                 } else {
789                     sleep (3);
790                 }
791             }   
792         }
793         if ($vmCompromised) {
794             # Reset the FW state table.
795             $vmStateTable = { };
796             return $args{'agent_state'};
797         }
798         print "Sleeping for 10s...\n";
799         sleep (10);
800     }
801 }
802
803 #######################################################################
804
805 1;
806
807 #######################################################################
808 # Additional Module Documentation                                     #
809 #######################################################################
810
811 __END__
812
813 =head1 BUGS & ASSUMPTIONS
814
815 # XXX: Fill this in.
816
817 =head1 SEE ALSO
818
819 L<http://www.honeyclient.org/trac>
820
821 =head1 REPORTING BUGS
822
823 L<http://www.honeyclient.org/trac/newticket>
824
825 =head1 ACKNOWLEDGEMENTS
826
827 Paul Kulchenko for developing the SOAP::Lite module.
828
829 =head1 AUTHORS
830
831 Kathy Wang, E<lt>knwang@mitre.orgE<gt>
832
833 Thanh Truong, E<lt>ttruong@mitre.orgE<gt>
834
835 Darien Kindlund, E<lt>kindlund@mitre.orgE<gt>
836
837 =head1 COPYRIGHT & LICENSE
838
839 Copyright (C) 2007 The MITRE Corporation.  All rights reserved.
840
841 This program is free software; you can redistribute it and/or
842 modify it under the terms of the GNU General Public License
843 as published by the Free Software Foundation, using version 2
844 of the License.
845  
846 This program is distributed in the hope that it will be useful,
847 but WITHOUT ANY WARRANTY; without even the implied warranty of
848 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
849 GNU General Public License for more details.
850  
851 You should have received a copy of the GNU General Public License
852 along with this program; if not, write to the Free Software
853 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
854 02110-1301, USA.
855
856
857 =cut
Note: See TracBrowser for help on using the browser.