From 991f211da748929d549fefdce545aa83d7d47b93 Mon Sep 17 00:00:00 2001 From: "eugene.livis" Date: Mon, 22 Aug 2022 09:15:22 -0400 Subject: [PATCH 1/7] CL returns error when invalid report config name is used --- .../ReportGenerationException.java | 47 ++++++++ .../infrastructure/ReportGenerator.java | 106 ++++++++++-------- .../infrastructure/ReportWizardAction.java | 9 +- 3 files changed, 115 insertions(+), 47 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportGenerationException.java diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportGenerationException.java b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportGenerationException.java new file mode 100755 index 0000000000..4002abc1e1 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportGenerationException.java @@ -0,0 +1,47 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2022 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.report.infrastructure; + +/** + * Instances of this exception class are thrown when there is an error while + * generating a report. + */ +public final class ReportGenerationException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Constructs a new exception with the specified message. + * + * @param message The message. + */ + public ReportGenerationException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified message and cause. + * + * @param message The message. + * @param cause The cause. + */ + public ReportGenerationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportGenerator.java b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportGenerator.java index 3894af6e2e..12b2a1e4bc 100644 --- a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportGenerator.java +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportGenerator.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2020 Basis Technology Corp. + * Copyright 2013-2022 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -107,7 +107,7 @@ public class ReportGenerator { this.reportGenerationPanel = null; this.configName = configName; } - + /** * Constructs a report generator that generates one or more reports by * running user-selected report modules and uses a report generation panel @@ -121,12 +121,15 @@ public class ReportGenerator { this.progressIndicator = panel.getProgressPanel(); this.configName = configName; } - + /** - * Generates the reports specified by the reporting configuration passed - * in via the constructor. Does lookup of all existing report modules. + * Generates the reports specified by the reporting configuration passed in + * via the constructor. Does lookup of all existing report modules. + * + * @throws ReportGenerationException if an error occurred while generating + * the report. */ - public void generateReports() { + public void generateReports() throws ReportGenerationException { // load all report modules Map modules = new HashMap<>(); for (TableReportModule module : ReportModuleLoader.getTableReportModules()) { @@ -143,38 +146,51 @@ public class ReportGenerator { // special case for PortableCaseReportModule modules.put(FactoryClassNameNormalizer.normalize(PortableCaseReportModule.class.getCanonicalName()), new PortableCaseReportModule()); - + generateReports(modules); } + @NbBundle.Messages({ + "ReportGenerator.error.noReportModules=No report modules found", + "# {0} - report configuration name", "ReportGenerator.error.unableToLoadConfig=Unable to load reporting configuration {0}.", + "# {0} - report module name", "ReportGenerator.error.moduleNotFound=Report module {0} not found", + "# {0} - report module name", "ReportGenerator.error.noTableReportSettings=No table report settings for report module {0}", + "# {0} - report module name", "ReportGenerator.error.noFileReportSettings=No file report settings for report module {0}", + "# {0} - report module name", "ReportGenerator.error.invalidSettings=Invalid settings for report module {0}", + "# {0} - report module name", "ReportGenerator.error.unsupportedType=Report module {0} has unsupported report module type", + "# {0} - report module name", "ReportGenerator.error.exception=Exception while running report module {0}"}) /** * Generates the reports specified by the reporting configuration passed in - * via the constructor. - * - * @param modules Map of report module objects to use. This is useful when we want to - * re-use the module instances or limit which reports are generated. + * via the constructor. + * + * @param modules Map of report module objects to use. This is useful when + * we want to re-use the module instances or limit which + * reports are generated. + * + * @throws ReportGenerationException if an error occurred while generating + * the report. */ - public void generateReports(Map modules) { - + public void generateReports(Map modules) throws ReportGenerationException { + if (modules == null || modules.isEmpty()) { - logger.log(Level.SEVERE, "No report modules found"); - progressIndicator.updateStatusLabel("No report modules found. Exiting"); - return; + logger.log(Level.SEVERE, Bundle.ReportGenerator_error_noReportModules()); + progressIndicator.updateStatusLabel(Bundle.ReportGenerator_error_noReportModules()); + throw new ReportGenerationException(Bundle.ReportGenerator_error_noReportModules()); } - + ReportingConfig config = null; try { config = ReportingConfigLoader.loadConfig(configName); } catch (ReportConfigException ex) { - logger.log(Level.SEVERE, "Unable to load reporting configuration " + configName + ". Exiting", ex); - progressIndicator.updateStatusLabel("Unable to load reporting configuration " + configName + ". Exiting"); - return; + logger.log(Level.SEVERE, Bundle.ReportGenerator_error_unableToLoadConfig(configName), ex); + progressIndicator.updateStatusLabel(Bundle.ReportGenerator_error_unableToLoadConfig(configName)); + throw new ReportGenerationException(Bundle.ReportGenerator_error_unableToLoadConfig(configName)); } if (config == null) { - logger.log(Level.SEVERE, "Unable to load reporting configuration {0}. Exiting", configName); - progressIndicator.updateStatusLabel("Unable to load reporting configuration " + configName + ". Exiting"); - return; + logger.log(Level.SEVERE, Bundle.ReportGenerator_error_unableToLoadConfig(configName)); + progressIndicator.updateStatusLabel(Bundle.ReportGenerator_error_unableToLoadConfig(configName)); + throw new ReportGenerationException(Bundle.ReportGenerator_error_unableToLoadConfig(configName)); } try { @@ -189,8 +205,8 @@ public class ReportGenerator { String moduleName = entry.getKey(); ReportModule module = modules.get(moduleName); if (module == null) { - logger.log(Level.SEVERE, "Report module {0} not found", moduleName); - progressIndicator.updateStatusLabel("Report module " + moduleName + " not found"); + logger.log(Level.SEVERE, Bundle.ReportGenerator_error_moduleNotFound(moduleName)); + progressIndicator.updateStatusLabel(Bundle.ReportGenerator_error_moduleNotFound(moduleName)); continue; } @@ -216,8 +232,8 @@ public class ReportGenerator { // get table report settings TableReportSettings tableSettings = config.getTableReportSettings(); if (tableSettings == null) { - logger.log(Level.SEVERE, "No table report settings for report module {0}", moduleName); - progressIndicator.updateStatusLabel("No table report settings for report module " + moduleName); + logger.log(Level.SEVERE, Bundle.ReportGenerator_error_noTableReportSettings(moduleName)); + progressIndicator.updateStatusLabel(Bundle.ReportGenerator_error_noTableReportSettings(moduleName)); continue; } @@ -228,8 +244,8 @@ public class ReportGenerator { // get file report settings FileReportSettings fileSettings = config.getFileReportSettings(); if (fileSettings == null) { - logger.log(Level.SEVERE, "No file report settings for report module {0}", moduleName); - progressIndicator.updateStatusLabel("No file report settings for report module " + moduleName); + logger.log(Level.SEVERE, Bundle.ReportGenerator_error_noFileReportSettings(moduleName)); + progressIndicator.updateStatusLabel(Bundle.ReportGenerator_error_noFileReportSettings(moduleName)); continue; } @@ -240,20 +256,20 @@ public class ReportGenerator { if (settings instanceof NoReportModuleSettings) { settings = new PortableCaseReportModuleSettings(); } else if (!(settings instanceof PortableCaseReportModuleSettings)) { - logger.log(Level.SEVERE, "Invalid settings for report module {0}", moduleName); - progressIndicator.updateStatusLabel("Invalid settings for report module " + moduleName); + logger.log(Level.SEVERE, Bundle.ReportGenerator_error_invalidSettings(moduleName)); + progressIndicator.updateStatusLabel(Bundle.ReportGenerator_error_invalidSettings(moduleName)); continue; } generatePortableCaseReport((PortableCaseReportModule) module, (PortableCaseReportModuleSettings) settings); } else { - logger.log(Level.SEVERE, "Report module {0} has unsupported report module type", moduleName); - progressIndicator.updateStatusLabel("Report module " + moduleName + " has unsupported report module type"); + logger.log(Level.SEVERE, Bundle.ReportGenerator_error_unsupportedType(moduleName)); + progressIndicator.updateStatusLabel(Bundle.ReportGenerator_error_unsupportedType(moduleName)); } } catch (IOException e) { - logger.log(Level.SEVERE, "Exception while running report module {0}: {1}", new Object[]{moduleName, e.getMessage()}); - progressIndicator.updateStatusLabel("Exception while running report module " + moduleName); + logger.log(Level.SEVERE, Bundle.ReportGenerator_error_exception(moduleName)); + progressIndicator.updateStatusLabel(Bundle.ReportGenerator_error_exception(moduleName)); } } } finally { @@ -321,15 +337,15 @@ public class ReportGenerator { TableReportGenerator generator = new TableReportGenerator(tableReportSettings, progressIndicator, tableReport); generator.execute(); tableReport.endReport(); - + // finish progress, wrap up errorList = generator.getErrorList(); - + // if error list is empty, the operation has completed successfully. If not there is an error - ReportProgressPanel.ReportStatus finalStatus = (errorList == null || errorList.isEmpty()) ? - ReportProgressPanel.ReportStatus.COMPLETE : - ReportProgressPanel.ReportStatus.ERROR; - + ReportProgressPanel.ReportStatus finalStatus = (errorList == null || errorList.isEmpty()) + ? ReportProgressPanel.ReportStatus.COMPLETE + : ReportProgressPanel.ReportStatus.ERROR; + progressIndicator.complete(finalStatus); } } @@ -368,10 +384,10 @@ public class ReportGenerator { int i = 0; // Add files to report. for (AbstractFile file : files) { - if(shouldFilterFromReport(file, fileReportSettings)) { + if (shouldFilterFromReport(file, fileReportSettings)) { continue; } - + // Check to see if any reports have been cancelled. if (progressIndicator.getStatus() == ReportStatus.CANCELED) { return; @@ -393,9 +409,9 @@ public class ReportGenerator { progressIndicator.complete(ReportStatus.COMPLETE); } } - + private boolean shouldFilterFromReport(AbstractFile file, FileReportSettings fileReportSettings) { - if(fileReportSettings.getSelectedDataSources() == null) { + if (fileReportSettings.getSelectedDataSources() == null) { return false; } // Filter if the data source id is not in the list to process diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportWizardAction.java b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportWizardAction.java index f2c419eee7..c15a5ceef9 100644 --- a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportWizardAction.java +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportWizardAction.java @@ -2,7 +2,7 @@ * * Autopsy Forensic Browser * - * Copyright 2012-2020 Basis Technology Corp. + * Copyright 2012-2022 Basis Technology Corp. * * Copyright 2012 42six Solutions. * Contact: aebadirad 42six com @@ -108,7 +108,12 @@ public final class ReportWizardAction extends CallableSystemAction implements Pr Map modules = (Map) wiz.getProperty("modules"); ReportGenerator generator = new ReportGenerator(configName, panel); //NON-NLS ReportWorker worker = new ReportWorker(() -> { - generator.generateReports(modules); + try { + generator.generateReports(modules); + } catch (ReportGenerationException ex) { + // do nothing. the error message will be logged and + // displayed by the progress panel. + } }); worker.execute(); generator.displayProgressPanel(); From 41d928b6fcd73779d0d46e5033ea0925f0910211 Mon Sep 17 00:00:00 2001 From: "eugene.livis" Date: Mon, 22 Aug 2022 11:49:02 -0400 Subject: [PATCH 2/7] CL returns error when invalid report config name is used --- .../autopsy/commandlineingest/CommandLineIngestManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java index 37edf58aa4..610833fde2 100755 --- a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java +++ b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java @@ -77,7 +77,7 @@ public class CommandLineIngestManager extends CommandLineManager { static int CL_SUCCESS = 0; static int CL_RUN_FAILURE = -1; - static int CL_PROCESS_FAILURE = 1; + static int CL_PROCESS_FAILURE = -2; public CommandLineIngestManager() { } From efbf423f9ab0bdf4fb086563a09f0c4d1ab79598 Mon Sep 17 00:00:00 2001 From: "eugene.livis" Date: Mon, 22 Aug 2022 16:19:28 -0400 Subject: [PATCH 3/7] Minor --- .../autopsy/commandlineingest/CommandLineIngestManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java index 610833fde2..c9bcd6ee68 100755 --- a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java +++ b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java @@ -75,9 +75,9 @@ public class CommandLineIngestManager extends CommandLineManager { private Case caseForJob = null; private AutoIngestDataSource dataSource = null; - static int CL_SUCCESS = 0; - static int CL_RUN_FAILURE = -1; - static int CL_PROCESS_FAILURE = -2; + private static final int CL_SUCCESS = 0; + private static final int CL_RUN_FAILURE = -1; + private static final int CL_PROCESS_FAILURE = -2; public CommandLineIngestManager() { } From 77c99666ea2d6073df4016374189c39bb9018a8e Mon Sep 17 00:00:00 2001 From: "eugene.livis" Date: Tue, 23 Aug 2022 10:28:09 -0400 Subject: [PATCH 4/7] Minor --- .../autopsy/commandlineingest/CommandLineIngestManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java index c9bcd6ee68..e277a0e9bc 100755 --- a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java +++ b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java @@ -75,9 +75,9 @@ public class CommandLineIngestManager extends CommandLineManager { private Case caseForJob = null; private AutoIngestDataSource dataSource = null; - private static final int CL_SUCCESS = 0; - private static final int CL_RUN_FAILURE = -1; - private static final int CL_PROCESS_FAILURE = -2; + static final int CL_SUCCESS = 0; + static final int CL_RUN_FAILURE = -1; + static final int CL_PROCESS_FAILURE = -2; public CommandLineIngestManager() { } From 98400fcb0deff90186b14a3cc88e727737237667 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 31 Aug 2022 10:33:13 -0400 Subject: [PATCH 5/7] deterministic ordering of jython modules --- Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java b/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java index dab8969c94..beb3e71207 100644 --- a/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java +++ b/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java @@ -43,6 +43,7 @@ import org.sleuthkit.autopsy.ingest.IngestModuleFactory; import org.sleuthkit.autopsy.report.GeneralReportModule; import java.io.BufferedReader; import java.io.FileReader; +import java.util.Comparator; /** * Finds and loads Autopsy modules written using the Jython variant of the @@ -124,6 +125,8 @@ public final class JythonModuleLoader { } } } + + Collections.sort(objects, Comparator.comparing((T obj) -> obj.getClass().getSimpleName(), (s1, s2) -> s1.compareToIgnoreCase(s2))); return objects; } From 3fd7600864e1f3ff083fc495056cbca5eb4fa922 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 31 Aug 2022 12:33:56 -0400 Subject: [PATCH 6/7] hardcoding property file location to avoid qa functional classloader issues --- .../datamodel/CentralRepoDatamodelTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java index d4b188d7db..c2c122f1fa 100755 --- a/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDatamodelTest.java @@ -43,7 +43,6 @@ import org.sleuthkit.autopsy.casemodule.CaseDetails; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.CentralRepoSettings; import org.sleuthkit.autopsy.coreutils.FileUtil; /** @@ -57,7 +56,10 @@ import org.sleuthkit.autopsy.coreutils.FileUtil; */ public class CentralRepoDatamodelTest extends TestCase { - private static final String PROPERTIES_FILE = CentralRepoSettings.getInstance().getModuleSettingsKey(); + // Classloader for qa functional tests is having trouble with loading NbBundle. + // Path is hard-coded to avoid that issue instead of using + // CentralRepoSettings.getInstance().getModuleSettingsKey() + private static final String PROPERTIES_FILE = "ModuleConfig/CentralRepository/CentralRepository"; private static final String CR_DB_NAME = "testcentralrepo.db"; private static final Path testDirectory = Paths.get(System.getProperty("java.io.tmpdir"), "CentralRepoDatamodelTest"); From 1e62607cc6e42aa45ed1f45972535212e7efd98c Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 31 Aug 2022 14:40:20 -0400 Subject: [PATCH 7/7] commenting --- .../autopsy/centralrepository/CentralRepoSettings.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/CentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/CentralRepoSettings.java index b7ec071f27..d24b6245a6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/CentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/CentralRepoSettings.java @@ -44,6 +44,8 @@ public class CentralRepoSettings { private static final String DEFAULT_DB_PARENT_PATH = Paths.get(CENTRAL_REPO_BASE_PATH, "LocalDatabase").toString(); private static final String DEFAULT_DB_NAME = "central_repository.db"; + + // NOTE: if this changes, an equivalent fix will be needed in CentralRepoDatamodelTest for the String PROPERTIES_FILE private static final String MODULE_SETTINGS_KEY = Paths.get( Paths.get(PlatformUtil.getUserConfigDirectory()).relativize(Paths.get(PlatformUtil.getModuleConfigDirectory())).toString(), CENTRAL_REPOSITORY_FOLDER,