Autopsy  4.19.3
Graphical digital forensics platform for The Sleuth Kit and other tools.
IngestJobSettings.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2014-2021 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.ingest;
20 
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.nio.file.Paths;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Objects;
35 import java.util.logging.Level;
36 import org.openide.util.NbBundle;
37 import org.openide.util.io.NbObjectInputStream;
38 import org.openide.util.io.NbObjectOutputStream;
45 
49 public final class IngestJobSettings {
50 
51  private static final String ENABLED_MODULES_PROPERTY = "Enabled_Ingest_Modules"; //NON-NLS
52  private static final String DISABLED_MODULES_PROPERTY = "Disabled_Ingest_Modules"; //NON-NLS
53  private static final String LAST_FILE_INGEST_FILTER_PROPERTY = "Last_File_Ingest_Filter"; //NON-NLS
54  private static final String MODULE_SETTINGS_FOLDER_NAME = "IngestSettings"; //NON-NLS
55 
56  private static final String MODULE_SETTINGS_FOLDER = Paths.get(
57  Paths.get(PlatformUtil.getUserConfigDirectory()).relativize(Paths.get(PlatformUtil.getModuleConfigDirectory())).toString(),
59  ).toString();
60 
61  private static final String MODULE_SETTINGS_FOLDER_PATH = Paths.get(
64  ).toAbsolutePath().toString();
65 
66  private static final String MODULE_SETTINGS_FILE_EXT = ".settings"; //NON-NLS
67  private static final CharSequence PYTHON_CLASS_PROXY_PREFIX = "org.python.proxies.".subSequence(0, "org.python.proxies.".length() - 1); //NON-NLS
68  private static final Logger logger = Logger.getLogger(IngestJobSettings.class.getName());
69  private final IngestType ingestType;
70  private final List<IngestModuleTemplate> moduleTemplates = new ArrayList<>();
71  private final List<String> warnings = new ArrayList<>();
72  private String executionContext;
74  private String moduleSettingsFolderPath;
75 
79  static String getBaseSettingsPath() {
81  }
82 
91  static String getModuleSettingsResource(String executionContext) {
92  return Paths.get(MODULE_SETTINGS_FOLDER, executionContext).toString();
93  }
94 
107  static Path getSavedModuleSettingsFolder(String executionContext) {
108  return Paths.get(getBaseSettingsPath(), executionContext);
109  }
110 
122  public IngestJobSettings(final String executionContext) {
124  }
125 
140  public IngestJobSettings(String executionContext, IngestType ingestType) {
141  this.ingestType = ingestType;
142  if (this.ingestType.equals(IngestType.ALL_MODULES)) {
143  this.executionContext = executionContext;
144  } else {
145  this.executionContext = executionContext + "." + this.ingestType.name();
146  }
148  this.load();
149  }
150 
164  public IngestJobSettings(String executionContext, IngestType ingestType, Collection<IngestModuleTemplate> moduleTemplates) {
165  this.ingestType = ingestType;
166  if (this.ingestType.equals(IngestType.ALL_MODULES)) {
167  this.executionContext = executionContext;
168  } else {
169  this.executionContext = executionContext + "." + this.ingestType.name();
170  }
171  this.moduleTemplates.addAll(moduleTemplates);
172  }
173 
188  public IngestJobSettings(String executionContext, IngestType ingestType, Collection<IngestModuleTemplate> moduleTemplates, FilesSet fileFilter) {
190  this.setFileFilter(fileFilter);
191  }
192 
200  return getSavedModuleSettingsFolder(executionContext);
201  }
202 
206  public void save() {
208  this.store();
209  }
210 
220  public void saveAs(String executionContext) {
221  this.executionContext = executionContext;
223  this.store();
224  }
225 
232  public List<String> getWarnings() {
233  List<String> warningMessages = new ArrayList<>(this.warnings);
234  this.warnings.clear();
235  return warningMessages;
236  }
237 
247  public String getExecutionContext() {
248  return this.executionContext;
249  }
250 
257  if (fileFilter == null) {
258  fileFilter = FilesSetsManager.getDefaultFilter();
259  }
260  return fileFilter;
261  }
262 
268  public void setFileFilter(FilesSet fileIngestFilter) {
269  this.fileFilter = fileIngestFilter;
270  }
271 
277  public List<IngestModuleTemplate> getIngestModuleTemplates() {
278  return Collections.unmodifiableList(this.moduleTemplates);
279  }
280 
286  public void setIngestModuleTemplates(List<IngestModuleTemplate> moduleTemplates) {
287  this.moduleTemplates.clear();
288  this.moduleTemplates.addAll(moduleTemplates);
289  }
290 
296  public List<IngestModuleTemplate> getEnabledIngestModuleTemplates() {
297  List<IngestModuleTemplate> enabledModuleTemplates = new ArrayList<>();
298  for (IngestModuleTemplate moduleTemplate : this.moduleTemplates) {
299  if (moduleTemplate.isEnabled()) {
300  enabledModuleTemplates.add(moduleTemplate);
301  }
302  }
303  return enabledModuleTemplates;
304  }
305 
312  public boolean getProcessUnallocatedSpace() {
313  boolean processUnallocated = true;
314  if (!Objects.isNull(this.fileFilter)) {
315  processUnallocated = (this.fileFilter.ingoresUnallocatedSpace() == false);
316  }
317  return processUnallocated;
318  }
319 
325  try {
326  Path folder = getSavedModuleSettingsFolder();
327  Files.createDirectories(folder);
328  this.moduleSettingsFolderPath = folder.toAbsolutePath().toString();
329  } catch (IOException | SecurityException ex) {
330  logger.log(Level.SEVERE, "Failed to create ingest module settings directory " + this.moduleSettingsFolderPath, ex); //NON-NLS
331  this.warnings.add(NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.createModuleSettingsFolder.warning")); //NON-NLS
332  }
333  }
334 
339  private void load() {
344  List<IngestModuleFactory> moduleFactories = new ArrayList<>();
345  List<IngestModuleFactory> allModuleFactories = IngestModuleFactoryLoader.getIngestModuleFactories();
346  HashSet<String> loadedModuleNames = new HashSet<>();
347 
348  // Add modules that are going to be used for this ingest depending on type.
349  for (IngestModuleFactory moduleFactory : allModuleFactories) {
350  if (moduleFactory.isDataArtifactIngestModuleFactory() || ingestType.equals(IngestType.ALL_MODULES)) {
351  moduleFactories.add(moduleFactory);
352  } else if (this.ingestType.equals(IngestType.DATA_SOURCE_ONLY) && moduleFactory.isDataSourceIngestModuleFactory()) {
353  moduleFactories.add(moduleFactory);
354  } else if (this.ingestType.equals(IngestType.FILES_ONLY) && moduleFactory.isFileIngestModuleFactory()) {
355  moduleFactories.add(moduleFactory);
356  }
357  }
358 
359  for (IngestModuleFactory moduleFactory : moduleFactories) {
360  loadedModuleNames.add(moduleFactory.getModuleDisplayName());
361  }
362 
370  final String plasoModuleName = "Plaso";
371  boolean plasoLoaded = loadedModuleNames.contains(plasoModuleName);
372  if (plasoLoaded) {
373  loadedModuleNames.remove(plasoModuleName);
374  }
375 
380  HashSet<String> enabledModuleNames = getModulesNames(this.executionContext, IngestJobSettings.ENABLED_MODULES_PROPERTY, makeCsvList(loadedModuleNames));
381  HashSet<String> disabledModuleNames = getModulesNames(this.executionContext, IngestJobSettings.DISABLED_MODULES_PROPERTY, plasoModuleName); //NON-NLS
382 
383  // If plaso was loaded, but appears in neither the enabled nor the
384  // disabled list, add it to the disabled list.
385  if (!enabledModuleNames.contains(plasoModuleName) && !disabledModuleNames.contains(plasoModuleName)) {
386  disabledModuleNames.add(plasoModuleName);
387  }
388 
389  //Put plaso back into loadedModuleNames
390  if (plasoLoaded) {
391  loadedModuleNames.add(plasoModuleName);
392  }
393 
397  List<String> missingModuleNames = new ArrayList<>();
398  for (String moduleName : enabledModuleNames) {
399  if (!loadedModuleNames.contains(moduleName)) {
400  missingModuleNames.add(moduleName);
401  }
402  }
403  for (String moduleName : disabledModuleNames) {
404  if (!loadedModuleNames.contains(moduleName)) {
405  missingModuleNames.add(moduleName);
406  }
407  }
408  for (String moduleName : missingModuleNames) {
409  enabledModuleNames.remove(moduleName);
410  disabledModuleNames.remove(moduleName);
411  String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.missingModule.warning", moduleName); //NON-NLS
412  logger.log(Level.WARNING, warning);
413  this.warnings.add(warning);
414  }
415 
420  for (IngestModuleFactory moduleFactory : moduleFactories) {
421  IngestModuleTemplate moduleTemplate = new IngestModuleTemplate(moduleFactory, loadModuleSettings(moduleFactory));
422  String moduleName = moduleTemplate.getModuleName();
423  if (enabledModuleNames.contains(moduleName)) {
424  moduleTemplate.setEnabled(true);
425  } else if (disabledModuleNames.contains(moduleName)) {
426  moduleTemplate.setEnabled(false);
427  } else {
428  // The module factory was loaded, but the module name does not
429  // appear in the enabled/disabled module settings. Treat the
430  // module as a new module and enable it by default.
431  moduleTemplate.setEnabled(true);
432  enabledModuleNames.add(moduleName);
433  }
434  this.moduleTemplates.add(moduleTemplate);
435  }
436 
441  String ingestModuleResource = getModuleSettingsResource(this.executionContext);
442  ModuleSettings.setConfigSetting(ingestModuleResource, IngestJobSettings.ENABLED_MODULES_PROPERTY, makeCsvList(enabledModuleNames));
443  ModuleSettings.setConfigSetting(ingestModuleResource, IngestJobSettings.DISABLED_MODULES_PROPERTY, makeCsvList(disabledModuleNames));
444 
450  }
451  try {
452  Map<String, FilesSet> fileIngestFilters = FilesSetsManager.getInstance()
455  fileIngestFilters.put(fSet.getName(), fSet);
456  }
457  this.fileFilter = fileIngestFilters.get(ModuleSettings.getConfigSetting(ingestModuleResource, IngestJobSettings.LAST_FILE_INGEST_FILTER_PROPERTY));
459  this.fileFilter = FilesSetsManager.getDefaultFilter();
460  logger.log(Level.SEVERE, "Failed to get file filter from .properties file, default filter being used", ex); //NON-NLS
461  }
462  }
463 
475  private static HashSet<String> getModulesNames(String executionContext, String propertyName, String defaultSetting) {
476  String ingestModuleResource = getModuleSettingsResource(executionContext);
477  if (ModuleSettings.settingExists(ingestModuleResource, propertyName) == false) {
478  ModuleSettings.setConfigSetting(ingestModuleResource, propertyName, defaultSetting);
479  }
480  HashSet<String> moduleNames = new HashSet<>();
481  String modulesSetting = ModuleSettings.getConfigSetting(ingestModuleResource, propertyName);
482  if (!modulesSetting.isEmpty()) {
483  String[] settingNames = modulesSetting.split(", ");
484  for (String name : settingNames) {
485  /*
486  * Map some obsolete core ingest module names to the current
487  * core ingest module names.
488  */
489  switch (name) {
490  case "Thunderbird Parser": //NON-NLS
491  case "MBox Parser": //NON-NLS
492  moduleNames.add("Email Parser"); //NON-NLS
493  break;
494  case "File Extension Mismatch Detection": //NON-NLS
495  moduleNames.add("Extension Mismatch Detector"); //NON-NLS
496  break;
497  case "EWF Verify": //NON-NLS
498  case "E01 Verify": //NON-NLS
499  case "E01 Verifier": // NON-NLS
500  moduleNames.add("Data Source Integrity"); //NON-NLS
501  break;
502  case "Archive Extractor": //NON-NLS
503  moduleNames.add("Embedded File Extractor"); //NON-NLS
504  break;
505  case "Correlation Engine": //NON-NLS
506  moduleNames.add("Central Repository"); //NON-NLS
507  break;
508  case "Exif Parser": //NON-NLS
509  moduleNames.add("Picture Analyzer"); //NON-NLS
510  break;
511  case "Drone Analyzer":
512  moduleNames.add("DJI Drone Analyzer");
513  break;
514  default:
515  moduleNames.add(name);
516  }
517  }
518  }
519  return moduleNames;
520  }
521 
530  static List<String> getEnabledModules(String context) {
531  return new ArrayList<>(getModulesNames(context, ENABLED_MODULES_PROPERTY, ""));
532  }
533 
544  private boolean isPythonModuleSettingsFile(String moduleSettingsFilePath) {
545  return moduleSettingsFilePath.contains(PYTHON_CLASS_PROXY_PREFIX);
546  }
547 
556  IngestModuleIngestJobSettings settings = null;
557  String moduleSettingsFilePath = getModuleSettingsFilePath(factory);
558  File settingsFile = new File(moduleSettingsFilePath);
559  if (settingsFile.exists()) {
560  try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(settingsFile.getAbsolutePath()))) {
561  settings = (IngestModuleIngestJobSettings) in.readObject();
562  } catch (IOException | ClassNotFoundException ex) {
563  String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.moduleSettingsLoad.warning", factory.getModuleDisplayName(), this.executionContext); //NON-NLS
564  logger.log(Level.WARNING, warning, ex);
565  this.warnings.add(warning);
566  }
567  }
568  if (settings == null) {
569  settings = factory.getDefaultIngestJobSettings();
570  }
571  return settings;
572  }
573 
583  String fileName = FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) + IngestJobSettings.MODULE_SETTINGS_FILE_EXT;
584  Path path = Paths.get(this.moduleSettingsFolderPath, fileName);
585  return path.toAbsolutePath().toString();
586  }
587 
591  private void store() {
595  HashSet<String> enabledModuleNames = new HashSet<>();
596  HashSet<String> disabledModuleNames = new HashSet<>();
597  for (IngestModuleTemplate moduleTemplate : moduleTemplates) {
598  saveModuleSettings(moduleTemplate.getModuleFactory(), moduleTemplate.getModuleSettings());
599  String moduleName = moduleTemplate.getModuleName();
600  if (moduleTemplate.isEnabled()) {
601  enabledModuleNames.add(moduleName);
602  } else {
603  disabledModuleNames.add(moduleName);
604  }
605  }
606 
607  String ingestModuleResource = getModuleSettingsResource(this.executionContext);
608  ModuleSettings.setConfigSetting(ingestModuleResource, IngestJobSettings.ENABLED_MODULES_PROPERTY, makeCsvList(enabledModuleNames));
609  ModuleSettings.setConfigSetting(ingestModuleResource, IngestJobSettings.DISABLED_MODULES_PROPERTY, makeCsvList(disabledModuleNames));
610 
614  ModuleSettings.setConfigSetting(ingestModuleResource, LAST_FILE_INGEST_FILTER_PROPERTY, fileFilter.getName());
615  }
616 
624  String moduleSettingsFilePath = getModuleSettingsFilePath(factory);
625  try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(moduleSettingsFilePath))) {
626  out.writeObject(settings);
627  } catch (IOException ex) {
628  String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.moduleSettingsSave.warning", factory.getModuleDisplayName(), this.executionContext); //NON-NLS
629  logger.log(Level.SEVERE, warning, ex);
630  this.warnings.add(warning);
631  }
632  }
633 
642  private static String makeCsvList(Collection<String> collection) {
643  if (collection == null || collection.isEmpty()) {
644  return "";
645  }
646 
647  ArrayList<String> list = new ArrayList<>();
648  list.addAll(collection);
649  StringBuilder csvList = new StringBuilder();
650  for (int i = 0; i < list.size() - 1; ++i) {
651  csvList.append(list.get(i)).append(", ");
652  }
653  csvList.append(list.get(list.size() - 1));
654  return csvList.toString();
655  }
656 
660  public enum IngestType {
661 
673  FILES_ONLY
674  }
675 
676 }
static synchronized String getConfigSetting(String moduleName, String settingName)
IngestJobSettings(final String executionContext)
void saveModuleSettings(IngestModuleFactory factory, IngestModuleIngestJobSettings settings)
List< IngestModuleTemplate > getEnabledIngestModuleTemplates()
static HashSet< String > getModulesNames(String executionContext, String propertyName, String defaultSetting)
static String makeCsvList(Collection< String > collection)
void setIngestModuleTemplates(List< IngestModuleTemplate > moduleTemplates)
static synchronized boolean settingExists(String moduleName, String settingName)
final List< IngestModuleTemplate > moduleTemplates
IngestJobSettings(String executionContext, IngestType ingestType, Collection< IngestModuleTemplate > moduleTemplates, FilesSet fileFilter)
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
IngestModuleIngestJobSettings loadModuleSettings(IngestModuleFactory factory)
String getModuleSettingsFilePath(IngestModuleFactory factory)
default IngestModuleIngestJobSettings getDefaultIngestJobSettings()
List< IngestModuleTemplate > getIngestModuleTemplates()
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
IngestJobSettings(String executionContext, IngestType ingestType, Collection< IngestModuleTemplate > moduleTemplates)
boolean isPythonModuleSettingsFile(String moduleSettingsFilePath)
IngestJobSettings(String executionContext, IngestType ingestType)

Copyright © 2012-2022 Basis Technology. Generated on: Fri Sep 30 2022
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.