diff --git a/.gitignore b/.gitignore index 1400fb33be..0f00c6c00f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ /Core/build/ /Core/dist/ /Core/nbproject/* +/Core/test/qa-functional/data/* !/Core/nbproject/project.xml !/Core/nbproject/project.properties diff --git a/Core/build.xml b/Core/build.xml index 0b5e9e1298..cb9a2acecd 100644 --- a/Core/build.xml +++ b/Core/build.xml @@ -39,6 +39,11 @@ + + + + + @@ -84,14 +89,15 @@ - + + - + diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java index d09c170110..9e78e0d58e 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/SevenZipExtractor.java @@ -218,7 +218,7 @@ class SevenZipExtractor { */ private ArchiveFormat get7ZipOptions(AbstractFile archiveFile) { // try to get the file type from the BB - String detectedFormat = null; + String detectedFormat; detectedFormat = archiveFile.getMIMEType(); if (detectedFormat == null) { @@ -434,11 +434,11 @@ class SevenZipExtractor { result = item.extractSlow(unpackStream, password); } if (result != ExtractOperationResult.OK) { - logger.log(Level.WARNING, "Extraction of : " + localAbsPath + " encountered error " + result); //NON-NLS + logger.log(Level.WARNING, "Extraction of : {0} encountered error {1}", new Object[]{localAbsPath, result}); //NON-NLS return null; } - } catch (Exception e) { + } catch (SevenZipException e) { //could be something unexpected with this file, move on logger.log(Level.WARNING, "Could not extract file from archive: " + localAbsPath, e); //NON-NLS } finally { @@ -492,7 +492,7 @@ class SevenZipExtractor { final ProgressHandle progress = ProgressHandle.createHandle(Bundle.EmbeddedFileExtractorIngestModule_ArchiveExtractor_moduleName()); //recursion depth check for zip bomb final long archiveId = archiveFile.getId(); - SevenZipExtractor.ArchiveDepthCountTree.Archive parentAr = null; + SevenZipExtractor.ArchiveDepthCountTree.Archive parentAr; try { blackboard = Case.getCurrentCaseThrows().getServices().getBlackboard(); } catch (NoCurrentCaseException ex) { @@ -717,7 +717,7 @@ class SevenZipExtractor { String encryptionType = fullEncryption ? ENCRYPTION_FULL : ENCRYPTION_FILE_LEVEL; try { BlackboardArtifact artifact = archiveFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED); - artifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, EmbeddedFileExtractorModuleFactory.getModuleName(), encryptionType)); + artifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, EmbeddedFileExtractorModuleFactory.getModuleName(), encryptionType)); try { // index the artifact for keyword search diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java index 215d1fe4da..6af0ec81f9 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/EmbeddedFileTest.java @@ -62,7 +62,7 @@ public class EmbeddedFileTest extends NbTestCase { @Override public void setUp() { - CaseUtils.createCase(CASE_DIRECTORY_PATH, CASE_NAME); + CaseUtils.createCase(CASE_NAME); ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); IngestUtils.addDataSource(dataSourceProcessor, IMAGE_PATH); @@ -92,7 +92,6 @@ public class EmbeddedFileTest extends NbTestCase { @Override public void tearDown() { CaseUtils.closeCase(); - CaseUtils.deleteCaseDir(CASE_DIRECTORY_PATH); } public void testEncryption() { diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java index 810c682798..7be3e4f794 100644 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/ingest/IngestFileFiltersTest.java @@ -72,8 +72,7 @@ public class IngestFileFiltersTest extends NbTestCase { } public void testBasicDir() { - Path casePath = Paths.get(System.getProperty("java.io.tmpdir"), "testBasicDir"); - CaseUtils.createCase(casePath, "testBasicDir"); + CaseUtils.createCase("testBasicDir"); ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); IngestUtils.addDataSource(dataSourceProcessor, IMAGE_PATH); @@ -115,8 +114,7 @@ public class IngestFileFiltersTest extends NbTestCase { } public void testExtAndDirWithOneRule() { - Path casePath = Paths.get(System.getProperty("java.io.tmpdir"), "testExtAndDirWithOneRule"); - CaseUtils.createCase(casePath, "testExtAndDirWithOneRule"); + CaseUtils.createCase("testExtAndDirWithOneRule"); ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); IngestUtils.addDataSource(dataSourceProcessor, IMAGE_PATH); @@ -151,8 +149,7 @@ public class IngestFileFiltersTest extends NbTestCase { } public void testExtAndDirWithTwoRules() { - Path casePath = Paths.get(System.getProperty("java.io.tmpdir"), "testExtAndDirWithTwoRules"); - CaseUtils.createCase(casePath, "testExtAndDirWithTwoRules"); + CaseUtils.createCase("testExtAndDirWithTwoRules"); ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); IngestUtils.addDataSource(dataSourceProcessor, IMAGE_PATH); @@ -196,8 +193,7 @@ public class IngestFileFiltersTest extends NbTestCase { } public void testFullFileNameRule() { - Path casePath = Paths.get(System.getProperty("java.io.tmpdir"), "testFullFileNameRule"); - CaseUtils.createCase(casePath, "testFullFileNameRule"); + CaseUtils.createCase("testFullFileNameRule"); ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); IngestUtils.addDataSource(dataSourceProcessor, IMAGE_PATH); @@ -232,8 +228,7 @@ public class IngestFileFiltersTest extends NbTestCase { } public void testCarvingWithExtRuleAndUnallocSpace() { - Path casePath = Paths.get(System.getProperty("java.io.tmpdir"), "testCarvingWithExtRuleAndUnallocSpace"); - CaseUtils.createCase(casePath, "testCarvingWithExtRuleAndUnallocSpace"); + CaseUtils.createCase("testCarvingWithExtRuleAndUnallocSpace"); ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); IngestUtils.addDataSource(dataSourceProcessor, IMAGE_PATH); @@ -281,8 +276,7 @@ public class IngestFileFiltersTest extends NbTestCase { } public void testCarvingNoUnallocatedSpace() { - Path casePath = Paths.get(System.getProperty("java.io.tmpdir"), "testCarvingNoUnallocatedSpace"); - CaseUtils.createCase(casePath, "testCarvingNoUnallocatedSpace"); + CaseUtils.createCase("testCarvingNoUnallocatedSpace"); ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); IngestUtils.addDataSource(dataSourceProcessor, IMAGE_PATH); @@ -315,8 +309,7 @@ public class IngestFileFiltersTest extends NbTestCase { } public void testEmbeddedModule() { - Path casePath = Paths.get(System.getProperty("java.io.tmpdir"), "testEmbeddedModule"); - CaseUtils.createCase(casePath, "testEmbeddedModule"); + CaseUtils.createCase("testEmbeddedModule"); LocalFilesDSProcessor dataSourceProcessor = new LocalFilesDSProcessor(); IngestUtils.addDataSource(dataSourceProcessor, ZIPFILE_PATH); diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/modules/encryptiondetection/EncryptionDetectionTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/modules/encryptiondetection/EncryptionDetectionTest.java index e003b491a5..0463642f90 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/modules/encryptiondetection/EncryptionDetectionTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/modules/encryptiondetection/EncryptionDetectionTest.java @@ -44,6 +44,7 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; +import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Volume; import org.sleuthkit.datamodel.VolumeSystem; @@ -57,7 +58,13 @@ public class EncryptionDetectionTest extends NbTestCase { private final Path BITLOCKER_IMAGE_PATH = Paths.get(this.getDataDir().toString(), "encryption_detection_bitlocker_test.vhd"); private final Path PASSWORD_IMAGE_PATH = Paths.get(this.getDataDir().toString(), "password_detection_test.img"); - + + private static final String PASSWORD_DETECTION_CASE_NAME = "PasswordDetectionTest"; + private static final String VERACRYPT_DETECTION_CASE_NAME = "VeraCryptDetectionTest"; + + private final Path PASSWORD_DETECTION_IMAGE_PATH = Paths.get(this.getDataDir().toString(), "password_detection_test.img"); + private final Path VERACRYPT_DETECTION_IMAGE_PATH = Paths.get(this.getDataDir().toString(), "veracrypt_detection_test.vhd"); + public static Test suite() { NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(EncryptionDetectionTest.class). clusters(".*"). @@ -79,7 +86,7 @@ public class EncryptionDetectionTest extends NbTestCase { */ public void testBitlockerEncryption() { try { - CaseUtils.createCase(BITLOCKER_CASE_DIRECTORY_PATH, BITLOCKER_CASE_NAME); + CaseUtils.createCase(BITLOCKER_CASE_NAME); ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); IngestUtils.addDataSource(dataSourceProcessor, BITLOCKER_IMAGE_PATH); Case openCase = Case.getCurrentCaseThrows(); @@ -150,44 +157,45 @@ public class EncryptionDetectionTest extends NbTestCase { */ public void testPasswordProtection() { try { - CaseUtils.createCase(PASSWORD_CASE_DIRECTORY_PATH, PASSWORD_CASE_NAME); + CaseUtils.createCase(PASSWORD_DETECTION_CASE_NAME); + ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); - IngestUtils.addDataSource(dataSourceProcessor, PASSWORD_IMAGE_PATH); - Case openCase = Case.getCurrentCaseThrows(); - + List errorMessages = IngestUtils.addDataSource(dataSourceProcessor, PASSWORD_DETECTION_IMAGE_PATH); + String joinedErrors = String.join(System.lineSeparator(), errorMessages); + assertEquals(joinedErrors, 0, errorMessages.size()); + + Case openCase = Case.getCurrentCaseThrows(); + /* * Create ingest job settings. */ - IngestModuleFactory ingestModuleFactory = new EncryptionDetectionModuleFactory(); - IngestModuleIngestJobSettings settings = ingestModuleFactory.getDefaultIngestJobSettings(); - IngestModuleTemplate template = new IngestModuleTemplate(ingestModuleFactory, settings); - template.setEnabled(true); - List templates = new ArrayList<>(); - templates.add(template); - IngestJobSettings ingestJobSettings = new IngestJobSettings(EncryptionDetectionTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates); + + ArrayList templates = new ArrayList<>(); + templates.add(IngestUtils.getIngestModuleTemplate(new EncryptionDetectionModuleFactory())); + IngestJobSettings ingestJobSettings = new IngestJobSettings(PASSWORD_DETECTION_CASE_NAME, IngestType.FILES_ONLY, templates); IngestUtils.runIngestJob(openCase.getDataSources(), ingestJobSettings); - + /* * Purge specific files to be tested. */ FileManager fileManager = openCase.getServices().getFileManager(); List> allResults = new ArrayList<>(0); - + List ole2Results = fileManager.findFiles("%%", "ole2"); assertEquals("Unexpected number of OLE2 results.", 11, ole2Results.size()); - + List ooxmlResults = fileManager.findFiles("%%", "ooxml"); assertEquals("Unexpected number of OOXML results.", 13, ooxmlResults.size()); - + List pdfResults = fileManager.findFiles("%%", "pdf"); assertEquals("Unexpected number of PDF results.", 6, pdfResults.size()); - + List mdbResults = fileManager.findFiles("%%", "mdb"); assertEquals("Unexpected number of MDB results.", 25, mdbResults.size()); - + List accdbResults = fileManager.findFiles("%%", "accdb"); assertEquals("Unexpected number of ACCDB results.", 10, accdbResults.size()); - + allResults.add(ole2Results); allResults.add(ooxmlResults); allResults.add(pdfResults); @@ -201,8 +209,8 @@ public class EncryptionDetectionTest extends NbTestCase { */ if (file.isFile() && !file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)) { /* - * Determine which assertions to use for the file based on - * its name. + * Determine which assertions to use for the file based + * on its name. */ boolean fileProtected = file.getName().split("\\.")[0].endsWith("-protected"); List artifactsList = file.getAllArtifacts(); @@ -234,4 +242,67 @@ public class EncryptionDetectionTest extends NbTestCase { Assert.fail(ex); } } + + /** + * Test the Encryption Detection module's detection of veracrypt encrypted + * container files and partitions. + * + * Test passes if the following are true. + * + * 1. A partition was detected without a file system by checking for the + * error. 2. Only 1 data source exsists in the case, to ensure a stale case + * did not get used. 3. One volume has a TSK_ENCRYPTION_SUSPECTED artifact + * associated with it. 4. A single file named veracrpytContainerFile exists. + * 5. The file named veracrpytContainerFile has a TSK_ENCRYPTION_SUSPECTED + * artifact associated with it. + */ + public void testVeraCryptSupport() { + try { + CaseUtils.createCase(VERACRYPT_DETECTION_CASE_NAME); + ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); + List errorMessages = IngestUtils.addDataSource(dataSourceProcessor, VERACRYPT_DETECTION_IMAGE_PATH); + String joinedErrors; + if (errorMessages.isEmpty()) { + joinedErrors = "Encrypted partition did not cause error, it was expected to"; + } else { + joinedErrors = String.join(System.lineSeparator(), errorMessages); + } + //there will be 1 expected error regarding the encrypted partition not having a file system + assertEquals(joinedErrors, 1, errorMessages.size()); + + Case openCase = Case.getCurrentCaseThrows(); + ArrayList templates = new ArrayList<>(); + templates.add(IngestUtils.getIngestModuleTemplate(new EncryptionDetectionModuleFactory())); + //image includes an encrypted container file with size greater than 5 mb so default settings detect it + IngestJobSettings ingestJobSettings = new IngestJobSettings(VERACRYPT_DETECTION_CASE_NAME, IngestType.ALL_MODULES, templates); + + assertEquals("Expected only one data source to exist in the Case", 1, openCase.getDataSources().size()); + IngestUtils.runIngestJob(openCase.getDataSources(), ingestJobSettings); + + //check that one of the partitions has an encrypted volume + int numberOfEncryptedVolumes = 0; + for (Content datasource : openCase.getDataSources()) { //data source + for (Content volumeSystem : datasource.getChildren()) { //volume system + for (Content volume : volumeSystem.getChildren()) { //volumes + numberOfEncryptedVolumes += volume.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED).size(); + } + } + } + assertEquals("One volume should exist with an encryption suspsected artifact", 1, numberOfEncryptedVolumes); + + //ensure the encrypyted container file was also detected correctly + FileManager fileManager = openCase.getServices().getFileManager(); + List results = fileManager.findFiles("veracryptContainerFile"); + assertEquals("Expected 1 file named veracryptContainerFile to exist in test image", 1, results.size()); + int numberOfEncryptedContainers = 0; + for (AbstractFile file : results) { + numberOfEncryptedContainers += file.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED).size(); + } + assertEquals("Encrypted Container file should have one encyption suspected artifact", 1, numberOfEncryptedContainers); + } catch (NoCurrentCaseException | TskCoreException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + } + } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/CaseUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/CaseUtils.java index 5eecf425bd..17b0c2168b 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/CaseUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/CaseUtils.java @@ -18,8 +18,10 @@ */ package org.sleuthkit.autopsy.testutils; +import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.nio.file.Paths; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import org.apache.commons.io.FileUtils; @@ -30,44 +32,43 @@ import org.sleuthkit.autopsy.casemodule.CaseActionException; import org.sleuthkit.autopsy.casemodule.CaseDetails; /** - * Common case utility methods. + * Class with common methods for testing related to the creation and elimination + * of cases. */ public final class CaseUtils { /** - * CaseUtils constructor. Since this class is not meant to allow for - * instantiation, this constructor is 'private'. - */ - private CaseUtils() { - } - - /** - * Create a new case. If the case already exists at the specified path, the - * existing case will be removed prior to creation of the new case. + * Create a case case directory and case for the given case name. * - * @param caseDirectoryPath The path to the case data. - * @param caseDisplayName The display name for the case. + * @param caseName the name for the case and case directory to have */ - public static void createCase(Path caseDirectoryPath, String caseDisplayName) { - //Make sure the test is starting with a clean state. So delete the test directory, if it exists. - deleteCaseDir(caseDirectoryPath); - assertFalse("Unable to delete existing test directory", caseDirectoryPath.toFile().exists()); - + public static void createCase(String caseName) { + //Make sure the case is starting with a clean state. So delete the case directory, if it exists. + Path caseDirectoryPath = Paths.get(System.getProperty("java.io.tmpdir"), caseName); + File caseDir = new File(caseDirectoryPath.toString()); + try { + deleteCaseDir(caseDir); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + Assert.fail(ex); + } + assertFalse("Unable to delete existing test directory", caseDir.exists()); // Create the test directory - caseDirectoryPath.toFile().mkdirs(); - assertTrue("Unable to create test directory", caseDirectoryPath.toFile().exists()); + caseDir.mkdirs(); + assertTrue("Unable to create test directory", caseDir.exists()); try { - Case.createAsCurrentCase(Case.CaseType.SINGLE_USER_CASE, caseDirectoryPath.toString(), new CaseDetails(caseDisplayName)); + Case.createAsCurrentCase(Case.CaseType.SINGLE_USER_CASE, caseDirectoryPath.toString(), new CaseDetails(caseName)); } catch (CaseActionException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } - assertTrue(caseDirectoryPath.toFile().exists()); + + assertTrue(caseDir.exists()); } /** - * Close the currently opened case. + * Close the current case, fails test if case was unable to be closed. */ public static void closeCase() { try { @@ -85,20 +86,25 @@ public final class CaseUtils { } /** - * Delete a case at the specified path. + * Delete the case directory if it exists, thows exception if unable to + * delete case dir to allow the user to determine failure with. * - * @param caseDirectoryPath The path to the case to be removed. + * @param caseDirectory the case directory to delete + * + * @throws IOException thrown if there was an problem deleting the case + * directory */ - public static void deleteCaseDir(Path caseDirectoryPath) { - if (!caseDirectoryPath.toFile().exists()) { + public static void deleteCaseDir(File caseDirectory) throws IOException { + if (!caseDirectory.exists()) { return; } - try { - FileUtils.deleteDirectory(caseDirectoryPath.toFile()); - } catch (IOException ex) { - //We just want to make sure the case directory doesn't exist when the test starts. It shouldn't cause failure if the case directory couldn't be deleted after a test finished. - System.out.println("INFO: Unable to delete case directory: " + caseDirectoryPath.toString()); - } + FileUtils.deleteDirectory(caseDirectory); } + /** + * Private constructor to prevent utility class instantiation. + */ + private CaseUtils() { + } + } diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/IngestUtils.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/IngestUtils.java index e2edbe3741..aac48890ca 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/IngestUtils.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/testutils/IngestUtils.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.testutils; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import static junit.framework.Assert.assertEquals; import org.openide.util.Exceptions; @@ -26,13 +27,14 @@ import org.python.icu.impl.Assert; import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleError; -import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter; +import org.sleuthkit.autopsy.ingest.IngestModuleFactory; import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; import org.sleuthkit.datamodel.Content; /** - * Common image utility methods. + * Class with common methods for testing related to adding and ingesting + * datasources. */ public final class IngestUtils { @@ -44,39 +46,48 @@ public final class IngestUtils { } /** - * Add a data source for the data source processor. + * Add the specified datasource to the case current case and processes it. + * Causes failure if it was unable to add and process the datasource. * - * @param dataSourceProcessor The data source processor. - * @param dataSourcePath The path to the data source to be added. + * @param dataSourceProcessor the datasource processer to use to process the + * datasource + * @param dataSourcePath the path to the datasource which is being + * added + * + * @return errorMessages a list of all error messages as strings which + * encountered while processing the data source */ - public static void addDataSource(AutoIngestDataSourceProcessor dataSourceProcessor, Path dataSourcePath) { + public static List addDataSource(AutoIngestDataSourceProcessor dataSourceProcessor, Path dataSourcePath) { + List errorMessages = new ArrayList<>(); try { + if (!dataSourcePath.toFile().exists()) { + Assert.fail("Data source not found: " + dataSourcePath.toString()); + } DataSourceProcessorRunner.ProcessorCallback callBack = DataSourceProcessorRunner.runDataSourceProcessor(dataSourceProcessor, dataSourcePath); - /* - * Ignore the callback error messages. Sometimes it's perfectly - * valid for it to not be able to detect a file system, which is one - * of the errors that can be returned. - */ + errorMessages = callBack.getErrorMessages(); } catch (AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException | InterruptedException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); } + return errorMessages; } /** - * Run an ingest job. + * Run ingest on the specified datasources with the specified ingest job + * settings. Causes failure if there are any errors or other problems while + * running ingest. * - * @param dataSourceList The list of data sources to process. - * @param ingestJobSettings The ingest job settings to use for ingest. + * @param datasources - the datasources to run ingest on + * @param ingestJobSettings - the ingest job settings to use for ingest */ - public static void runIngestJob(List dataSourceList, IngestJobSettings ingestJobSettings) { + public static void runIngestJob(List datasources, IngestJobSettings ingestJobSettings) { try { - List ingestModuleErrorsList = IngestJobRunner.runIngestJob(dataSourceList, ingestJobSettings); - for (IngestModuleError err : ingestModuleErrorsList) { - System.out.println(String.format("Error: %s: %s.", err.getModuleDisplayName(), err.toString())); - } - String errorMessage = String.format("The ingest job runner produced %d error messages.", ingestModuleErrorsList.size()); - assertEquals(errorMessage, 0, ingestModuleErrorsList.size()); + List errs = IngestJobRunner.runIngestJob(datasources, ingestJobSettings); + StringBuilder joinedErrors = new StringBuilder(""); + errs.forEach((err) -> { + joinedErrors.append(String.format("Error: %s: %s.", err.getModuleDisplayName(), err.toString())).append(System.lineSeparator()); + }); + assertEquals(joinedErrors.toString(), 0, errs.size()); } catch (InterruptedException ex) { Exceptions.printStackTrace(ex); Assert.fail(ex); @@ -84,17 +95,18 @@ public final class IngestUtils { } /** - * Build a new ingest module template based on the given factory. + * Get the ingest module template for the the specified factories default + * ingest job settings. * - * @param factory The ingest module factory. + * @param factory the factory to get the ingest job settings from * - * @return The ingest module template. + * @return template - the IngestModuleTemplate created with the factory and + * it's default settings. */ - public static IngestModuleTemplate getIngestModuleTemplate(IngestModuleFactoryAdapter factory) { + public static IngestModuleTemplate getIngestModuleTemplate(IngestModuleFactory factory) { IngestModuleIngestJobSettings settings = factory.getDefaultIngestJobSettings(); IngestModuleTemplate template = new IngestModuleTemplate(factory, settings); template.setEnabled(true); return template; } - } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index 38cad58ce5..9774106659 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -218,6 +218,7 @@ KeywordSearchJobSettingsPanel.languagesLabel.text=Scripts enabled for string ext KeywordSearchGlobalLanguageSettingsPanel.enableUTF8Checkbox.text=Enable UTF8 text extraction KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text=Ingest settings for string extraction from unknown file types (changes effective on next ingest): KeywordSearchGlobalLanguageSettingsPanel.enableUTF16Checkbox.text=Enable UTF16LE and UTF16BE string extraction +KeywordSearchGlobalLanguageSettingsPanel.enableOcrCheckbox.text=Enable Optical Character Recognition (OCR) KeywordSearchGlobalLanguageSettingsPanel.languagesLabel.text=Enabled scripts (languages): KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText=20 mins. (fastest ingest time) KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text=20 minutes (slowest feedback, fastest ingest) @@ -309,3 +310,4 @@ ExtractedContentPanel.pageOfLabel.text=of ExtractedContentPanel.pageTotalLabel.text=- ExtractedContentPanel.pageButtonsLabel.text=Page ExtractedContentPanel.pagesLabel.text=Page: + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchGlobalLanguageSettingsPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchGlobalLanguageSettingsPanel.form index 563fa4c57b..c6f133161b 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchGlobalLanguageSettingsPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchGlobalLanguageSettingsPanel.form @@ -16,21 +16,26 @@ - - + - - - + + + + + + + + + + + + + - - - - @@ -42,13 +47,15 @@ + + - - - + + + @@ -86,7 +93,7 @@ - + @@ -120,5 +127,15 @@ + + + + + + + + + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchGlobalLanguageSettingsPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchGlobalLanguageSettingsPanel.java index 9e58235318..513b26ea30 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchGlobalLanguageSettingsPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchGlobalLanguageSettingsPanel.java @@ -40,7 +40,7 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem private final Map scripts = new HashMap<>(); private ActionListener updateLanguagesAction; private List