Changeset 1461
- Timestamp:
- 04/04/08 22:21:25 (3 months ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
honeyclient/branches/exp/kindlund-simpler_agent/etc/honeyclient.xml
r1452 r1461 328 328 /var/log/messages 329 329 </dhcp_log> 330 <!-- HoneyClient::Manager::VM::Clone Options --> 331 <Clone> 332 <archive_upon_suspend description="If set to 1, then everytime a cloned VM is suspended, a copy of the VM will be archived in the 'snapshot_path' directory. Set this option to 0, if you discover errors during cloning operations, where the hard disk on the host system is overworked on slow systems." default="1"> 333 1 334 </archive_upon_suspend> 335 </Clone> 330 336 <!-- HoneyClient::Manager::VM::Test Options --> 331 337 <Test> honeyclient/branches/exp/kindlund-simpler_agent/lib/HoneyClient/Manager/VM/Clone.pm
r1460 r1461 71 71 my $name = $clone->{'name'}; 72 72 73 # Archive the cloned VM to the snapshot_path directory.74 $clone-> archive();73 # Suspend and archive the cloned VM to the snapshot_path directory. 74 $clone->suspend(perform_archive => 1); 75 75 76 76 # If you want the cloned VM to be suspended and no longer used, … … 315 315 use DateTime::HiRes; 316 316 317 # Make sure IO::File loads. 318 BEGIN { use_ok('IO::File') or diag("Can't load IO::File package. Check to make sure the package library is correctly listed within the path."); } 319 require_ok('IO::File'); 320 use IO::File; 321 317 322 =end testing 318 323 … … 371 376 # Include Base64 Libraries 372 377 use MIME::Base64 qw(encode_base64 decode_base64); 378 379 # Include IO::File Libraries 380 use IO::File; 373 381 374 382 =pod … … 776 784 # VM Clone object. 777 785 # 786 # Input: hashref 787 # 778 788 # Output: The updated Clone $object, reflecting the status change 779 789 # of the clone VM. Will croak if this operation fails. … … 821 831 HoneyClient::Manager::Database::set_client_suspended($self->{'database_id'}); 822 832 } elsif (/suspicious/) { 833 if (!$argsExist || 834 !exists($args{'fingerprint'}) || 835 !defined($args{'fingerprint'})) { 836 837 # Croak if no valid argument is supplied. 838 $LOG->error("Error: No fingerprint argument supplied."); 839 Carp::croak "Error: No fingerprint argument supplied."; 840 } 841 823 842 # TODO: Need to implement this properly. 843 $LOG->info("(" . $self->{'name'} . ") - Inserting Fingerprint Into Database."); 844 # Make sure the fingerprint contains a client_id. 845 $args{'fingerprint'}->{'client_id'} = $self->{'database_id'}; 846 my $fingerprint_id = undef; 847 eval { 848 $fingerprint_id = HoneyClient::Manager::Database::insert_fingerprint($args{'fingerprint'}); 849 }; 850 if ($@ || ($fingerprint_id == 0) || !defined($fingerprint_id)) { 851 $LOG->warn("(" . $self->{'name'} . ") - Failure Inserting Fingerprint: " . $@); 852 } else { 853 $LOG->info("(" . $self->{'name'} . ") - Database Insert Successful."); 854 } 824 855 } elsif (/compromised/) { 825 856 HoneyClient::Manager::Database::set_client_compromised($self->{'database_id'}); … … 838 869 sub _dumpFingerprint { 839 870 871 # Get the supplied fingerprint. 872 my ($self, $fingerprint) = @_; 873 840 874 # Dump the fingerprint to a file, if needed. 841 875 my $COMPROMISE_FILE = getVar(name => "fingerprint_dump"); … … 848 882 $Data::Dumper::Terse = 0; 849 883 $Data::Dumper::Indent = 2; 850 print $dump_file "\$vmName = \"" . $ vmName. "\";\n";884 print $dump_file "\$vmName = \"" . $self->{'name'} . "\";\n"; 851 885 print $dump_file Dumper($fingerprint); 852 886 $dump_file->close(); … … 1091 1125 =pod 1092 1126 1093 =head2 $object-> archive(snapshot_file => $snapshotFile)1127 =head2 $object->suspend(perform_archive => $boolean, snapshot_file => $snapshotFile) 1094 1128 1095 1129 =over 4 1096 1130 1097 Archives an existing Clone object, by suspending the VM and saving 1098 a tar.gz archive file containing the VM to the B<$SNAPSHOT_PATH> 1131 Suspends and optionally archives an existing Clone object, 1132 by suspending the VM and saving a tar.gz archive file 1133 containing the VM to the B<$SNAPSHOT_PATH> 1099 1134 directory, as specified in the <HoneyClient/><Manager/><VM/> 1100 1135 section of the etc/honeyclient.xml file. 1101 1136 1102 1137 I<Inputs>: 1138 B<$boolean> is an optional argument, indicating that the 1139 Clone object should be archived upon suspend. 1103 1140 B<$snapshotFile> is an optional argument, indicating the 1104 1141 full, absolute path and filename of where the snapshot 1105 1142 file should be stored. 1106 1143 1107 I<Output>: The archived Clone B<$object>.1144 I<Output>: The suspended/archived Clone B<$object>. 1108 1145 1109 1146 I<Notes>: … … 1116 1153 using ISO8601 date format variables. 1117 1154 1118 This operation destroys the Clone B<$object>. Do not1155 This operation alters the Clone B<$object>. Do not 1119 1156 expect to perform any additional operations with 1120 this object once this call is finished. 1157 this object once this call is finished, since the 1158 underlying VM has been suspended. 1121 1159 1122 1160 =back … … 1144 1182 my $question; 1145 1183 $question = prompt("#\n" . 1146 "# Note: Testing real archive operations will *ONLY* work\n" .1184 "# Note: Testing real suspend/archive operations will *ONLY* work\n" . 1147 1185 "# with a fully functional master VM that has the HoneyClient code\n" . 1148 1186 "# loaded upon boot-up.\n" . … … 1158 1196 1159 1197 # Archive the clone. 1160 $clone-> archive(snapshot_file => $snapshot);1161 1162 # Wait for the archive to complete.1198 $clone->suspend(perform_archive => 1, snapshot_file => $snapshot); 1199 1200 # Wait for the suspend/archive to complete. 1163 1201 sleep (45); 1164 1202 1165 # Test if the archiveworked.1166 is(-f $snapshot, 1, " archive(snapshot_file => '$snapshot')") or diag("The archive() call failed.");1203 # Test if the operations worked. 1204 is(-f $snapshot, 1, "suspend(perform_archive => 1, snapshot_file => '$snapshot')") or diag("The suspend() call failed."); 1167 1205 1168 1206 unlink $snapshot; … … 1189 1227 =cut 1190 1228 1191 sub archive{1229 sub suspend { 1192 1230 1193 1231 # Extract arguments. … … 1212 1250 # Sanity checks; check if any args were specified. 1213 1251 my $argsExist = scalar(%args); 1252 if (!$argsExist || 1253 !exists($args{'perform_archive'}) || 1254 !defined($args{'perform_archive'})) { 1255 $args{'perform_archive'} = getVar(name => "archive_upon_suspend"); 1256 } 1214 1257 1215 1258 # Extract the VM configuration file. … … 1220 1263 $self->{'config'} = undef; 1221 1264 1222 $LOG->debug(" Archiving clone VM (" . $vmConfig . ").");1265 $LOG->debug("Suspending clone VM (" . $vmConfig . ")."); 1223 1266 my $som = $self->{'_vm_handle'}->suspendVM(config => $vmConfig); 1224 if ($argsExist && 1225 exists($args{'snapshot_file'}) && 1226 defined($args{'snapshot_file'})) { 1227 $som = $self->{'_vm_handle'}->snapshotVM(config => $vmConfig, 1228 snapshot_file => $args{'snapshot_file'}); 1267 1268 if (!defined($som)) { 1269 $LOG->error("Unable to suspend VM (" . $self->{'config'} . ")."); 1270 $self->_changeStatus(status => "error"); 1229 1271 } else { 1230 $som = $self->{'_vm_handle'}->snapshotVM(config => $vmConfig); 1231 } 1232 if (!defined($som)) { 1233 $LOG->error("Unable to archive VM (" . $vmConfig . ")."); 1272 $self->_changeStatus(status => "suspended"); 1273 } 1274 1275 if ($args{'perform_archive'}) { 1276 if ($argsExist && 1277 exists($args{'snapshot_file'}) && 1278 defined($args{'snapshot_file'})) { 1279 $som = $self->{'_vm_handle'}->snapshotVM(config => $vmConfig, 1280 snapshot_file => $args{'snapshot_file'}); 1281 } else { 1282 $som = $self->{'_vm_handle'}->snapshotVM(config => $vmConfig); 1283 } 1284 if (!defined($som)) { 1285 $LOG->error("Unable to archive VM (" . $vmConfig . ")."); 1286 } 1234 1287 } 1235 1288 … … 1302 1355 1303 1356 # TODO: Fix this. 1304 1305 # Archive the clone. 1306 #$clone->archive(snapshot_file => $snapshot); 1307 1308 # Wait for the archive to complete. 1309 #sleep (45); 1310 1311 # Test if the archive worked. 1312 #is(-f $snapshot, 1, "archive(snapshot_file => '$snapshot')") or diag("The archive() call failed."); 1313 1314 #unlink $snapshot; 1315 #$clone = undef; 1316 1357 $clone = $clone->drive(work => { 'http://www.google.com/' => 1 }); 1358 isa_ok($clone, 'HoneyClient::Manager::VM::Clone', "drive(work => { 'http://www.google.com/' => 1})") or diag("The drive() call failed."); 1359 $clone = undef; 1360 1317 1361 # Connect to daemon as a client. 1318 1362 $stub = getClientHandle(namespace => "HoneyClient::Manager::VM"); … … 1372 1416 my $currentWork; 1373 1417 my $finishedWork = { 1374 'client_id' => $self->{'database_id'},1418 'client_id' => {}, 1375 1419 'links_visited' => {}, 1376 1420 'links_timed_out' => {}, … … 1380 1424 1381 1425 while (scalar(%{$args{'work'}})) { 1426 # Make sure the database_id is set to the client_id. 1427 $finishedWork->{'client_id'} = $self->{'database_id'}; 1382 1428 1383 1429 # Extract the highest priority work. … … 1396 1442 $LOG->warn("(" . $self->{'name'} . ") - " . $self->{'driver_name'} . " - Integrity Check: FAILED"); 1397 1443 # XXX: Test this. 1398 _dumpFingerprint($result->{'fingerprint'}); 1444 1445 # Dump the fingerprint to a file, if need be. 1446 $self->_dumpFingerprint($result->{'fingerprint'}); 1447 1448 # Suspend and archive the cloned VM. 1449 $self->suspend(); 1450 1451 # If possibile, insert work history. 1452 $finishedWork->{'links_visited'}->{$currentWork} = $result->{'time_at'}; 1453 if (defined($self->{'database_id'})) { 1454 $numWorkInserted = HoneyClient::Manager::Database::insert_history_urls($finishedWork); 1455 $LOG->info($numWorkInserted . " URL(s) Inserted."); 1456 } 1457 1458 # Mark the VM as suspicious and insert the fingerprint, if possible. 1459 $self->_changeStatus(status => "suspicious", fingerprint => $result->{'fingerprint'}); 1460 1399 1461 } else { 1400 1462 $LOG->info("(" . $self->{'name'} . ") - " . $self->{'driver_name'} . " - Integrity Check: PASSED"); 1463 # If possibile, insert work history. 1464 $finishedWork->{'links_visited'}->{$currentWork} = $result->{'time_at'}; 1465 if (defined($self->{'database_id'})) { 1466 $numWorkInserted = HoneyClient::Manager::Database::insert_history_urls($finishedWork); 1467 $LOG->info($numWorkInserted . " URL(s) Inserted."); 1468 } 1401 1469 } 1402 1403 $finishedWork->{'links_visited'}->{$currentWork} = $result->{'time_at'};1404 1405 $numWorkInserted = HoneyClient::Manager::Database::insert_history_urls($finishedWork);1406 $LOG->info($numWorkInserted . " URL(s) Inserted.");1407 1470 1408 1471 # Flush the work history, after committing to the database. 1409 1472 $finishedWork->{'links_visited'} = {}; 1410 1473 1411 } 1474 # Create a new clone, if a compromise was found and we still have work to do. 1475 if (scalar(@{$result->{'fingerprint'}->{os_processes}}) && 1476 scalar(%{$args{'work'}})) { 1477 # Be sure to carry over any customizations into the newly created 1478 # clones. 1479 $self = HoneyClient::Manager::VM::Clone->new( 1480 master_vm_config => $self->{'master_vm_config'}, 1481 driver_name => $self->{'driver_name'}, 1482 ); 1483 } 1484 } 1485 1486 return $self; 1412 1487 } 1413 1488 honeyclient/branches/exp/kindlund-simpler_agent/t/honeyclient_manager_vm_clone.t
r1451 r1461 86 86 87 87 # Make sure Storable loads. 88 BEGIN { use_ok('Storable', qw(dclone )) or diag("Can't load Storable package. Check to make sure the package library is correctly listed within the path."); }88 BEGIN { use_ok('Storable', qw(dclone thaw)) or diag("Can't load Storable package. Check to make sure the package library is correctly listed within the path."); } 89 89 require_ok('Storable'); 90 90 can_ok('Storable', 'dclone'); 91 use Storable qw(dclone); 91 can_ok('Storable', 'thaw'); 92 use Storable qw(dclone thaw); 93 94 # Make sure MIME::Base64 loads. 95 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."); } 96 require_ok('MIME::Base64'); 97 can_ok('MIME::Base64', 'encode_base64'); 98 can_ok('MIME::Base64', 'decode_base64'); 99 use MIME::Base64 qw(encode_base64 decode_base64); 92 100 93 101 # Make sure Data::Dumper loads … … 128 136 require_ok('DateTime::HiRes'); 129 137 use DateTime::HiRes; 138 139 # Make sure IO::File loads. 140 BEGIN { use_ok('IO::File') or diag("Can't load IO::File package. Check to make sure the package library is correctly listed within the path."); } 141 require_ok('IO::File'); 142 use IO::File; 130 143 } 131 144 … … 183 196 # Now, kill the VM daemon. 184 197 HoneyClient::Manager::VM->destroy(); 185 # XXX: See if this is still needed.186 #sleep (10);187 198 188 199 # Create a generic empty clone, with test state data. … … 218 229 # Kill the child daemon, if it still exists. 219 230 HoneyClient::Manager::VM->destroy(); 220 # XXX: See if this is still needed.221 #sleep (1);222 231 223 232 # Report any failure found. … … 251 260 my $question; 252 261 $question = prompt("#\n" . 253 "# Note: Testing real archive operations will *ONLY* work\n" .262 "# Note: Testing real suspend/archive operations will *ONLY* work\n" . 254 263 "# with a fully functional master VM that has the HoneyClient code\n" . 255 264 "# loaded upon boot-up.\n" . … … 257 266 "# Your master VM is: " . getVar(name => "master_vm_config", namespace => "HoneyClient::Manager::VM") . "\n" . 258 267 "#\n" . 259 "# Do you want to test cloning this master VM?", "no");268 "# Do you want to test cloning and archiving this master VM?", "no"); 260 269 if ($question =~ /^y.*/i) { 261 270 … … 265 274 266 275 # Archive the clone. 267 $clone-> archive(snapshot_file => $snapshot);268 269 # Wait for the archive to complete.276 $clone->suspend(perform_archive => 1, snapshot_file => $snapshot); 277 278 # Wait for the suspend/archive to complete. 270 279 sleep (45); 271 280 272 # Test if the archiveworked.273 is(-f $snapshot, 1, " archive(snapshot_file => '$snapshot')") or diag("The archive() call failed.");281 # Test if the operations worked. 282 is(-f $snapshot, 1, "suspend(perform_archive => 1, snapshot_file => '$snapshot')") or diag("The suspend() call failed."); 274 283 275 284 unlink $snapshot; … … 286 295 # Kill the child daemon, if it still exists. 287 296 HoneyClient::Manager::VM->destroy(); 288 # XXX: See if this is still needed.289 #sleep (1);290 297 291 298 # Report any failure found. … … 297 304 298 305 306 # =begin testing 307 { 308 # Shared test variables. 309 my ($stub, $som, $URL); 310 my $testVM = $ENV{PWD} . "/" . getVar(name => "test_vm_config", 311 namespace => "HoneyClient::Manager::VM::Test"); 312 313 # Catch all errors, in order to make sure child processes are 314 # properly killed. 315 eval { 316 317 # Pretend as though no other Clone objects have been created prior 318 # to this point. 319 $HoneyClient::Manager::VM::Clone::OBJECT_COUNT = -1; 320 321 my $question; 322 $question = prompt("#\n" . 323 "# Note: Testing real drive operations will *ONLY* work\n" . 324 "# with a fully functional master VM that has the HoneyClient code\n" . 325 "# loaded upon boot-up.\n" . 326 "#\n" . 327 "# Your master VM is: " . getVar(name => "master_vm_config", namespace => "HoneyClient::Manager::VM") . "\n" . 328 "#\n" . 329 "# Do you want to test cloning and driving this master VM?", "no"); 330 if ($question =~ /^y.*/i) { 331 332 # Create a generic empty clone, with test state data. 333 my $clone = HoneyClient::Manager::VM::Clone->new(); 334 my $cloneConfig = $clone->{config}; 335 336 # TODO: Fix this. 337 $clone = $clone->drive(work => { 'http://www.google.com/' => 1 }); 338 isa_ok($clone, 'HoneyClient::Manager::VM::Clone', "drive(work => { 'http://www.google.com/' => 1})") or diag("The drive() call failed."); 339 $clone = undef; 340 341 # Connect to daemon as a client. 342 $stub = getClientHandle(namespace => "HoneyClient::Manager::VM"); 343 344 # Destroy the clone VM. 345 $som = $stub->destroyVM(config => $cloneConfig); 346 } 347 }; 348 349 # Kill the child daemon, if it still exists. 350 HoneyClient::Manager::VM->destroy(); 351 352 # Report any failure found. 353 if ($@) { 354 fail($@); 355 } 356 } 357 358 359 299 360 300 361 1;
