Autopsy  4.1
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 2011-2016 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.Collections;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.logging.Level;
33 import org.openide.util.NbBundle;
34 import org.openide.util.io.NbObjectInputStream;
35 import org.openide.util.io.NbObjectOutputStream;
36 import org.python.util.PythonObjectInputStream;
40 
47 public class IngestJobSettings {
48 
49  private static final String ENABLED_MODULES_KEY = "Enabled_Ingest_Modules"; //NON-NLS
50  private static final String DISABLED_MODULES_KEY = "Disabled_Ingest_Modules"; //NON-NLS
51  private static final String PARSE_UNALLOC_SPACE_KEY = "Process_Unallocated_Space"; //NON-NLS
52  private static final String PROCESS_UNALLOC_SPACE_DEFAULT = "true"; //NON-NLS
53  private static final String MODULE_SETTINGS_FOLDER = "IngestModuleSettings"; //NON-NLS
54  private static final String MODULE_SETTINGS_FOLDER_PATH = Paths.get(PlatformUtil.getUserConfigDirectory(), IngestJobSettings.MODULE_SETTINGS_FOLDER).toAbsolutePath().toString();
55  private static final String MODULE_SETTINGS_FILE_EXT = ".settings"; //NON-NLS
56  private static final Logger logger = Logger.getLogger(IngestJobSettings.class.getName());
57  private final String executionContext;
58  private final IngestType ingestType;
59  private String moduleSettingsFolderPath;
60  private static final CharSequence pythonModuleSettingsPrefixCS = "org.python.proxies.".subSequence(0, "org.python.proxies.".length() - 1); //NON-NLS
61  private final List<IngestModuleTemplate> moduleTemplates;
62  private boolean processUnallocatedSpace;
63  private final List<String> warnings;
64 
68  public enum IngestType {
69 
81  FILES_ONLY
82  }
83 
92  public IngestJobSettings(String executionContext) {
93  this.executionContext = executionContext;
94  this.ingestType = IngestType.ALL_MODULES;
95  this.moduleTemplates = new ArrayList<>();
96  this.processUnallocatedSpace = Boolean.parseBoolean(IngestJobSettings.PROCESS_UNALLOC_SPACE_DEFAULT);
97  this.warnings = new ArrayList<>();
99  this.load();
100  }
101 
111  public IngestJobSettings(String context, IngestType ingestType) {
112  this.ingestType = ingestType;
113 
114  if (this.ingestType.equals(IngestType.ALL_MODULES)) {
115  this.executionContext = context;
116  } else {
117  this.executionContext = context + "." + this.ingestType.name();
118  }
119 
120  this.moduleTemplates = new ArrayList<>();
121  this.processUnallocatedSpace = Boolean.parseBoolean(IngestJobSettings.PROCESS_UNALLOC_SPACE_DEFAULT);
122  this.warnings = new ArrayList<>();
124  this.load();
125  }
126 
130  public void save() {
131  this.store();
132  }
133 
142  String getExecutionContext() {
143  return this.executionContext;
144  }
145 
152  public List<String> getWarnings() {
153  List<String> warningMessages = new ArrayList<>(this.warnings);
154  this.warnings.clear();
155  return warningMessages;
156  }
157 
163  List<IngestModuleTemplate> getIngestModuleTemplates() {
164  return Collections.unmodifiableList(this.moduleTemplates);
165  }
166 
173  List<IngestModuleTemplate> getEnabledIngestModuleTemplates() {
174  List<IngestModuleTemplate> enabledModuleTemplates = new ArrayList<>();
175  for (IngestModuleTemplate moduleTemplate : this.moduleTemplates) {
176  if (moduleTemplate.isEnabled()) {
177  enabledModuleTemplates.add(moduleTemplate);
178  }
179  }
180  return enabledModuleTemplates;
181  }
182 
188  void setIngestModuleTemplates(List<IngestModuleTemplate> moduleTemplates) {
189  this.moduleTemplates.clear();
190  this.moduleTemplates.addAll(moduleTemplates);
191  }
192 
199  boolean getProcessUnallocatedSpace() {
200  return this.processUnallocatedSpace;
201  }
202 
208  void setProcessUnallocatedSpace(boolean processUnallocatedSpace) {
209  this.processUnallocatedSpace = processUnallocatedSpace;
210  }
211 
218  return Paths.get(IngestJobSettings.MODULE_SETTINGS_FOLDER_PATH, executionContext);
219  }
220 
226  try {
227  Path folder = getSavedModuleSettingsFolder();
228  Files.createDirectories(folder);
229  this.moduleSettingsFolderPath = folder.toAbsolutePath().toString();
230  } catch (IOException | SecurityException ex) {
231  logger.log(Level.SEVERE, "Failed to create ingest module settings directory " + this.moduleSettingsFolderPath, ex); //NON-NLS
232  this.warnings.add(NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.createModuleSettingsFolder.warning")); //NON-NLS
233  }
234  }
235 
239  private void load() {
244  List<IngestModuleFactory> moduleFactories = new ArrayList<>();
245  List<IngestModuleFactory> allModuleFactories = IngestModuleFactoryLoader.getIngestModuleFactories();
246  HashSet<String> loadedModuleNames = new HashSet<>();
247 
248  // Add modules that are going to be used for this ingest depending on type.
249  for (IngestModuleFactory moduleFactory : allModuleFactories) {
250  if (this.ingestType.equals(IngestType.ALL_MODULES)) {
251  moduleFactories.add(moduleFactory);
252  } else if (this.ingestType.equals(IngestType.DATA_SOURCE_ONLY) && moduleFactory.isDataSourceIngestModuleFactory()) {
253  moduleFactories.add(moduleFactory);
254  } else if (this.ingestType.equals(IngestType.FILES_ONLY) && moduleFactory.isFileIngestModuleFactory()) {
255  moduleFactories.add(moduleFactory);
256  }
257  }
258 
259  for (IngestModuleFactory moduleFactory : moduleFactories) {
260  loadedModuleNames.add(moduleFactory.getModuleDisplayName());
261  }
262 
267  HashSet<String> enabledModuleNames = getModulesNamesFromSetting(IngestJobSettings.ENABLED_MODULES_KEY, makeCommaSeparatedValuesList(loadedModuleNames));
268  HashSet<String> disabledModuleNames = getModulesNamesFromSetting(IngestJobSettings.DISABLED_MODULES_KEY, ""); //NON-NLS
269 
273  List<String> missingModuleNames = new ArrayList<>();
274  for (String moduleName : enabledModuleNames) {
275  if (!loadedModuleNames.contains(moduleName)) {
276  missingModuleNames.add(moduleName);
277  }
278  }
279  for (String moduleName : disabledModuleNames) {
280  if (!loadedModuleNames.contains(moduleName)) {
281  missingModuleNames.add(moduleName);
282  }
283  }
284  for (String moduleName : missingModuleNames) {
285  enabledModuleNames.remove(moduleName);
286  disabledModuleNames.remove(moduleName);
287  String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.missingModule.warning", moduleName); //NON-NLS
288  logger.log(Level.WARNING, warning);
289  this.warnings.add(warning);
290  }
291 
296  for (IngestModuleFactory moduleFactory : moduleFactories) {
297  IngestModuleTemplate moduleTemplate = new IngestModuleTemplate(moduleFactory, loadModuleSettings(moduleFactory));
298  String moduleName = moduleTemplate.getModuleName();
299  if (enabledModuleNames.contains(moduleName)) {
300  moduleTemplate.setEnabled(true);
301  } else if (disabledModuleNames.contains(moduleName)) {
302  moduleTemplate.setEnabled(false);
303  } else {
304  // The module factory was loaded, but the module name does not
305  // appear in the enabled/disabled module settings. Treat the
306  // module as a new module and enable it by default.
307  moduleTemplate.setEnabled(true);
308  enabledModuleNames.add(moduleName);
309  }
310  this.moduleTemplates.add(moduleTemplate);
311  }
312 
319 
320  // Get the process unallocated space flag setting. If the setting does
321  // not exist yet, default it to true.
322  if (ModuleSettings.settingExists(this.executionContext, IngestJobSettings.PARSE_UNALLOC_SPACE_KEY) == false) {
324  }
325  this.processUnallocatedSpace = Boolean.parseBoolean(ModuleSettings.getConfigSetting(this.executionContext, IngestJobSettings.PARSE_UNALLOC_SPACE_KEY));
326  }
327 
336  private HashSet<String> getModulesNamesFromSetting(String key, String defaultSetting) {
337  if (ModuleSettings.settingExists(this.executionContext, key) == false) {
338  ModuleSettings.setConfigSetting(this.executionContext, key, defaultSetting);
339  }
340  HashSet<String> moduleNames = new HashSet<>();
341  String modulesSetting = ModuleSettings.getConfigSetting(this.executionContext, key);
342  if (!modulesSetting.isEmpty()) {
343  String[] settingNames = modulesSetting.split(", ");
344  for (String name : settingNames) {
345  // Map some old core module names to the current core module names.
346  switch (name) {
347  case "Thunderbird Parser": //NON-NLS
348  case "MBox Parser": //NON-NLS
349  moduleNames.add("Email Parser"); //NON-NLS
350  break;
351  case "File Extension Mismatch Detection": //NON-NLS
352  moduleNames.add("Extension Mismatch Detector"); //NON-NLS
353  break;
354  case "EWF Verify": //NON-NLS
355  case "E01 Verify": //NON-NLS
356  moduleNames.add("E01 Verifier"); //NON-NLS
357  break;
358  case "Archive Extractor": //NON-NLS
359  moduleNames.add("Embedded File Extractor"); //NON-NLS
360  break;
361  default:
362  moduleNames.add(name);
363  }
364  }
365  }
366  return moduleNames;
367  }
368 
379  private boolean isPythonModuleSettingsFile(String moduleSettingsFilePath) {
380  return moduleSettingsFilePath.contains(pythonModuleSettingsPrefixCS);
381  }
382 
392  IngestModuleIngestJobSettings settings = null;
393  String moduleSettingsFilePath = getModuleSettingsFilePath(factory);
394  File settingsFile = new File(moduleSettingsFilePath);
395  if (settingsFile.exists()) {
396  if (!isPythonModuleSettingsFile(moduleSettingsFilePath)) {
397  try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(settingsFile.getAbsolutePath()))) {
398  settings = (IngestModuleIngestJobSettings) in.readObject();
399  } catch (IOException | ClassNotFoundException ex) {
400  String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.moduleSettingsLoad.warning", factory.getModuleDisplayName(), this.executionContext); //NON-NLS
401  logger.log(Level.WARNING, warning, ex);
402  this.warnings.add(warning);
403  }
404  } else {
405  try (PythonObjectInputStream in = new PythonObjectInputStream(new FileInputStream(settingsFile.getAbsolutePath()))) {
406  settings = (IngestModuleIngestJobSettings) in.readObject();
407  } catch (IOException | ClassNotFoundException exception) {
408  String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.moduleSettingsLoad.warning", factory.getModuleDisplayName(), this.executionContext); //NON-NLS
409  logger.log(Level.WARNING, warning, exception);
410  this.warnings.add(warning);
411  }
412  }
413  }
414  if (settings == null) {
415  settings = factory.getDefaultIngestJobSettings();
416  }
417  return settings;
418  }
419 
429  String fileName = factory.getClass().getCanonicalName() + IngestJobSettings.MODULE_SETTINGS_FILE_EXT;
430  Path path = Paths.get(this.moduleSettingsFolderPath, fileName);
431  return path.toAbsolutePath().toString();
432  }
433 
437  private void store() {
441  HashSet<String> enabledModuleNames = new HashSet<>();
442  HashSet<String> disabledModuleNames = new HashSet<>();
443  for (IngestModuleTemplate moduleTemplate : moduleTemplates) {
444  saveModuleSettings(moduleTemplate.getModuleFactory(), moduleTemplate.getModuleSettings());
445  String moduleName = moduleTemplate.getModuleName();
446  if (moduleTemplate.isEnabled()) {
447  enabledModuleNames.add(moduleName);
448  } else {
449  disabledModuleNames.add(moduleName);
450  }
451  }
452  ModuleSettings.setConfigSetting(this.executionContext, ENABLED_MODULES_KEY, makeCommaSeparatedValuesList(enabledModuleNames));
453  ModuleSettings.setConfigSetting(this.executionContext, DISABLED_MODULES_KEY, makeCommaSeparatedValuesList(disabledModuleNames));
454 
458  String processUnalloc = Boolean.toString(this.processUnallocatedSpace);
459  ModuleSettings.setConfigSetting(this.executionContext, PARSE_UNALLOC_SPACE_KEY, processUnalloc);
460  }
461 
470  String moduleSettingsFilePath = Paths.get(this.moduleSettingsFolderPath, FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) + MODULE_SETTINGS_FILE_EXT).toString();
471  try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(moduleSettingsFilePath))) {
472  out.writeObject(settings);
473  } catch (IOException ex) {
474  String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.moduleSettingsSave.warning", factory.getModuleDisplayName(), this.executionContext); //NON-NLS
475  logger.log(Level.SEVERE, warning, ex);
476  this.warnings.add(warning);
477  }
478  }
479 
488  private static String makeCommaSeparatedValuesList(HashSet<String> input) {
489  if (input == null || input.isEmpty()) {
490  return "";
491  }
492 
493  ArrayList<String> list = new ArrayList<>();
494  list.addAll(input);
495  StringBuilder csvList = new StringBuilder();
496  for (int i = 0; i < list.size() - 1; ++i) {
497  csvList.append(list.get(i)).append(", ");
498  }
499  csvList.append(list.get(list.size() - 1));
500  return csvList.toString();
501  }
502 
503 }
void saveModuleSettings(IngestModuleFactory factory, IngestModuleIngestJobSettings settings)
static String makeCommaSeparatedValuesList(HashSet< String > input)
IngestModuleIngestJobSettings getDefaultIngestJobSettings()
HashSet< String > getModulesNamesFromSetting(String key, String defaultSetting)
final List< IngestModuleTemplate > moduleTemplates
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
IngestModuleIngestJobSettings loadModuleSettings(IngestModuleFactory factory)
String getModuleSettingsFilePath(IngestModuleFactory factory)
static String getConfigSetting(String moduleName, String settingName)
synchronized static Logger getLogger(String name)
Definition: Logger.java:161
boolean isPythonModuleSettingsFile(String moduleSettingsFilePath)
static boolean settingExists(String moduleName, String settingName)
IngestJobSettings(String context, IngestType ingestType)

Copyright © 2012-2016 Basis Technology. Generated on: Mon Jan 2 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.