Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ReportingConfigLoader.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019-2020 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.report.infrastructure;
20 
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.util.Arrays;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Map.Entry;
34 import java.util.Set;
35 import java.util.TreeSet;
36 import java.util.logging.Level;
37 import org.apache.commons.io.FileUtils;
38 import org.openide.util.io.NbObjectInputStream;
39 import org.openide.util.io.NbObjectOutputStream;
43 
49 final class ReportingConfigLoader {
50 
51  private static final Logger logger = Logger.getLogger(ReportingConfigLoader.class.getName());
52  private static final String REPORT_CONFIG_FOLDER = "ReportingConfigs"; //NON-NLS
53 
54  private static final String REPORT_CONFIG_FOLDER_PATH_LEGACY = Paths.get(
55  PlatformUtil.getUserConfigDirectory(),
56  ReportingConfigLoader.REPORT_CONFIG_FOLDER
57  ).toAbsolutePath().toString();
58 
59  private static final String REPORT_CONFIG_FOLDER_PATH = Paths.get(
60  PlatformUtil.getModuleConfigDirectory(),
61  ReportingConfigLoader.REPORT_CONFIG_FOLDER
62  ).toAbsolutePath().toString();
63 
64  private static final String REPORT_SETTINGS_FILE_EXTENSION = ".settings";
65  private static final String TABLE_REPORT_CONFIG_FILE = "TableReportSettings.settings";
66  private static final String FILE_REPORT_CONFIG_FILE = "FileReportSettings.settings";
67  private static final String GENERAL_REPORT_CONFIG_FILE = "GeneralReportSettings.settings";
68  private static final String MODULE_CONFIG_FILE = "ModuleConfigs.settings";
69 
70  // Collection of standard report modules that are no longer in Autopsy. We keep
71  // track to suppress any errors when searching for the module since it may still
72  // existing in the configuration file.
73  private static final List<String> DELETED_REPORT_MODULES = Arrays.asList("org.sleuthkit.autopsy.report.modules.stix.STIXReportModule");
74 
87  @SuppressWarnings("unchecked")
88  static synchronized ReportingConfig loadConfig(String configName) throws ReportConfigException {
89 
90  // construct the configuration directory path
91  Path reportDirPath = Paths.get(ReportingConfigLoader.REPORT_CONFIG_FOLDER_PATH, configName);
92  File reportDirectory = reportDirPath.toFile();
93 
94  // Return null if a reporting configuration for the given name does not exist.
95  if (!reportDirectory.exists()) {
96  throw new ReportConfigException("Unable to find report configuration folder for " + reportDirPath.toString() + ". Please configure in the application Options panel.");
97  }
98 
99  if (!reportDirectory.isDirectory() || !reportDirectory.canRead()) {
100  throw new ReportConfigException("Unable to read reporting configuration directory " + reportDirPath.toString());
101  }
102 
103  // read in the configuration
104  ReportingConfig config = new ReportingConfig(configName);
105 
106  // read table report settings
107  String filePath = reportDirPath.toString() + File.separator + TABLE_REPORT_CONFIG_FILE;
108  try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(filePath))) {
109  config.setTableReportSettings((TableReportSettings) in.readObject());
110  } catch (IOException | ClassNotFoundException ex) {
111  throw new ReportConfigException("Unable to read table report settings " + filePath, ex);
112  }
113 
114  // read file report settings
115  filePath = reportDirPath.toString() + File.separator + FILE_REPORT_CONFIG_FILE;
116  try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(filePath))) {
117  config.setFileReportSettings((FileReportSettings) in.readObject());
118  } catch (IOException | ClassNotFoundException ex) {
119  throw new ReportConfigException("Unable to read file report settings " + filePath, ex);
120  }
121 
122  filePath = reportDirPath.resolve(GENERAL_REPORT_CONFIG_FILE).toString();
123  try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(filePath))) {
124  config.setGeneralReportSettings((GeneralReportSettings) in.readObject());
125  } catch (IOException | ClassNotFoundException ex) {
126  throw new ReportConfigException("Unable to read general report settings " + filePath, ex);
127  }
128 
129  // read map of module configuration objects
130  Map<String, ReportModuleConfig> moduleConfigs = null;
131  filePath = reportDirPath.toString() + File.separator + MODULE_CONFIG_FILE;
132  try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(filePath))) {
133  moduleConfigs = (Map<String, ReportModuleConfig>) in.readObject();
134  } catch (IOException | ClassNotFoundException ex) {
135  throw new ReportConfigException("Unable to read module configurations map " + filePath, ex);
136  }
137 
138  if (moduleConfigs == null || moduleConfigs.isEmpty()) {
139  return config;
140  }
141 
142  // read each ReportModuleSettings object individually
143  for (Iterator<Entry<String, ReportModuleConfig>> iterator = moduleConfigs.entrySet().iterator(); iterator.hasNext();) {
144  ReportModuleConfig moduleConfig = iterator.next().getValue();
145  if (DELETED_REPORT_MODULES.contains(moduleConfig.getModuleClassName())) {
146  // Don't try to load settings for known deleted modules
147  continue;
148  }
149  filePath = reportDirPath.toString() + File.separator + moduleConfig.getModuleClassName() + REPORT_SETTINGS_FILE_EXTENSION;
150  try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(filePath))) {
151  moduleConfig.setModuleSettings((ReportModuleSettings) in.readObject());
152  } catch (IOException | ClassNotFoundException ex) {
153  /*
154  * NOTE: we do not want to re-throw the exception because we do
155  * not want a single error while reading in a (3rd party) report
156  * module to prevent us from reading the entire reporting
157  * configuration.
158  */
159  logger.log(Level.SEVERE, "Unable to read module settings " + filePath, ex);
160  iterator.remove();
161  }
162  }
163 
164  config.setModuleConfigs(moduleConfigs);
165 
166  return config;
167  }
168 
178  static synchronized void saveConfig(ReportingConfig reportConfig) throws ReportConfigException {
179 
180  if (reportConfig == null) {
181  throw new ReportConfigException("Reporting configuration is NULL");
182  }
183 
184  // construct the configuration directory path
185  Path pathToConfigDir = Paths.get(ReportingConfigLoader.REPORT_CONFIG_FOLDER_PATH, reportConfig.getName());
186 
187  // create configuration directory
188  try {
189  Files.createDirectories(pathToConfigDir); // does not throw if directory already exists
190  } catch (IOException | SecurityException ex) {
191  throw new ReportConfigException("Failed to create reporting configuration directory " + pathToConfigDir.toString(), ex);
192  }
193 
194  // save table report settings
195  String filePath = pathToConfigDir.toString() + File.separator + TABLE_REPORT_CONFIG_FILE;
196  try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) {
197  out.writeObject(reportConfig.getTableReportSettings());
198  } catch (IOException ex) {
199  throw new ReportConfigException("Unable to save table report configuration " + filePath, ex);
200  }
201 
202  // save file report settings
203  filePath = pathToConfigDir.toString() + File.separator + FILE_REPORT_CONFIG_FILE;
204  try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) {
205  out.writeObject(reportConfig.getFileReportSettings());
206  } catch (IOException ex) {
207  throw new ReportConfigException("Unable to save file report configuration " + filePath, ex);
208  }
209 
210  filePath = pathToConfigDir.resolve(GENERAL_REPORT_CONFIG_FILE).toString();
211  try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) {
212  out.writeObject(reportConfig.getGeneralReportSettings());
213  } catch (IOException ex) {
214  throw new ReportConfigException("Unable to save general report configuration " + filePath, ex);
215  }
216 
217  // save map of module configuration objects
218  filePath = pathToConfigDir.toString() + File.separator + MODULE_CONFIG_FILE;
219  try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) {
220  out.writeObject(reportConfig.getModuleConfigs());
221  } catch (IOException ex) {
222  throw new ReportConfigException("Unable to save module configurations map " + filePath, ex);
223  }
224 
225  // save each ReportModuleSettings object individually
226  /*
227  * NOTE: This is done to protect us from errors in reading/writing 3rd
228  * party report module settings. If we were to serialize the entire
229  * ReportingConfig object, then a single error while reading in a 3rd
230  * party report module would prevent us from reading the entire
231  * reporting configuration.
232  */
233  if (reportConfig.getModuleConfigs() == null) {
234  return;
235  }
236  for (ReportModuleConfig moduleConfig : reportConfig.getModuleConfigs().values()) {
237  ReportModuleSettings settings = moduleConfig.getModuleSettings();
238  filePath = pathToConfigDir.toString() + File.separator + moduleConfig.getModuleClassName() + REPORT_SETTINGS_FILE_EXTENSION;
239  try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) {
240  out.writeObject(settings);
241  } catch (IOException ex) {
242  throw new ReportConfigException("Unable to save module settings " + filePath, ex);
243  }
244  }
245  }
246 
254  static synchronized Set<String> getListOfReportConfigs() {
255  File reportDirPath = new File(ReportingConfigLoader.REPORT_CONFIG_FOLDER_PATH);
256  Set<String> reportNameList = new TreeSet<>();
257 
258  if (!reportDirPath.exists()) {
259  return reportNameList;
260  }
261 
262  for (File file : reportDirPath.listFiles()) {
263  reportNameList.add(file.getName());
264  }
265 
266  return reportNameList;
267  }
268 
278  static synchronized boolean configExists(String configName) {
279  // construct the configuration directory path
280  Path reportDirPath = Paths.get(ReportingConfigLoader.REPORT_CONFIG_FOLDER_PATH, configName);
281  File reportDirectory = reportDirPath.toFile();
282 
283  return reportDirectory.exists();
284  }
285 
286  static void upgradeConfig() throws IOException {
287  File oldPath = new File(REPORT_CONFIG_FOLDER_PATH_LEGACY);
288  File newPath = new File(REPORT_CONFIG_FOLDER_PATH);
289 
290  if (oldPath.exists() && Files.list(oldPath.toPath()).findFirst().isPresent()
291  && (!newPath.exists() || !Files.list(newPath.toPath()).findFirst().isPresent())) {
292  newPath.mkdirs();
293  FileUtils.copyDirectory(oldPath, newPath);
294  }
295 
296  }
297 
298 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.