Autopsy  4.16.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ILeappAnalyzerIngestModule.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 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.modules.ileappanalyzer;
20 
21 import java.io.File;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.UncheckedIOException;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.nio.file.Paths;
28 import java.text.SimpleDateFormat;
29 import java.util.List;
30 import java.util.ArrayList;
31 import java.util.Locale;
32 import java.util.logging.Level;
33 import java.util.stream.Collectors;
34 import java.util.stream.Stream;
35 import org.openide.modules.InstalledFileLocator;
36 import org.openide.util.NbBundle;
50 import org.sleuthkit.datamodel.AbstractFile;
51 import org.sleuthkit.datamodel.Content;
52 import org.sleuthkit.datamodel.LocalFilesDataSource;
53 import org.sleuthkit.datamodel.TskCoreException;
54 
59 
60  private static final Logger logger = Logger.getLogger(ILeappAnalyzerIngestModule.class.getName());
61  private static final String MODULE_NAME = ILeappAnalyzerModuleFactory.getModuleName();
62 
63  private static final String ILEAPP = "iLeapp"; //NON-NLS
64  private static final String ILEAPP_EXECUTABLE = "ileapp.exe";//NON-NLS
65 
66  private File iLeappExecutable;
67 
69 
71 
73  // This constructor is intentionally empty. Nothing special is needed here.
74  }
75 
76  @NbBundle.Messages({
77  "ILeappAnalyzerIngestModule.executable.not.found=iLeapp Executable Not Found.",
78  "ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows.",
79  "ILeappAnalyzerIngestModule.error.ileapp.file.processor.init=Failure to initialize ILeappProcessFile"})
80  @Override
81  public void startUp(IngestJobContext context) throws IngestModuleException {
82  this.context = context;
83 
84  if (false == PlatformUtil.isWindowsOS()) {
85  throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_requires_windows());
86  }
87 
88  try {
89  iLeappFileProcessor = new ILeappFileProcessor();
90  } catch (IOException | IngestModuleException ex) {
91  throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex);
92  }
93 
94  try {
95  iLeappExecutable = locateExecutable(ILEAPP_EXECUTABLE);
96  } catch (FileNotFoundException exception) {
97  logger.log(Level.WARNING, "iLeapp executable not found.", exception); //NON-NLS
98  throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_executable_not_found(), exception);
99  }
100 
101  }
102 
103  @NbBundle.Messages({
104  "ILeappAnalyzerIngestModule.error.running.iLeapp=Error running iLeapp, see log file.",
105  "ILeappAnalyzerIngestModule.error.creating.output.dir=Error creating iLeapp module output directory.",
106  "ILeappAnalyzerIngestModule.starting.iLeapp=Starting iLeapp",
107  "ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp",
108  "ILeappAnalyzerIngestModule.has.run=iLeapp",
109  "ILeappAnalyzerIngestModule.iLeapp.cancelled=iLeapp run was canceled",
110  "ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed",
111  "ILeappAnalyzerIngestModule.report.name=iLeapp Html Report"})
112  @Override
113  public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) {
114 
115  if (!(context.getDataSource() instanceof LocalFilesDataSource)) {
116  return ProcessResult.OK;
117  }
118 
119  statusHelper.progress(Bundle.ILeappAnalyzerIngestModule_starting_iLeapp(), 0);
120 
121  List<AbstractFile> iLeappFilesToProcess = findiLeappFilesToProcess(dataSource);
122 
123  statusHelper.switchToDeterminate(iLeappFilesToProcess.size());
124 
125  Integer filesProcessedCount = 0;
126 
127  Case currentCase = Case.getCurrentCase();
128  for (AbstractFile iLeappFile : iLeappFilesToProcess) {
129 
130  String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS
131  Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ILEAPP, currentTime);
132  try {
133  Files.createDirectories(moduleOutputPath);
134  } catch (IOException ex) {
135  logger.log(Level.SEVERE, String.format("Error creating iLeapp output directory %s", moduleOutputPath.toString()), ex);
136  return ProcessResult.ERROR;
137  }
138 
139  statusHelper.progress(NbBundle.getMessage(this.getClass(), "ILeappAnalyzerIngestModule.processing.file", iLeappFile.getName()), filesProcessedCount);
140  ProcessBuilder iLeappCommand = buildiLeappCommand(moduleOutputPath, iLeappFile.getLocalAbsPath(), iLeappFile.getNameExtension());
141  try {
142  int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context));
143  if (result != 0) {
144  logger.log(Level.SEVERE, String.format("Error running iLeapp, error code returned %d", result)); //NON-NLS
145  return ProcessResult.ERROR;
146  }
147 
148  addILeappReportToReports(moduleOutputPath, currentCase);
149 
150  } catch (IOException ex) {
151  logger.log(Level.SEVERE, String.format("Error when trying to execute iLeapp program against file %s", iLeappFile.getLocalAbsPath()), ex);
152  return ProcessResult.ERROR;
153  }
154 
155  if (context.dataSourceIngestIsCancelled()) {
156  logger.log(Level.INFO, "ILeapp Analyser ingest module run was canceled"); //NON-NLS
157  return ProcessResult.OK;
158  }
159 
160  ProcessResult fileProcessorResult = iLeappFileProcessor.processFiles(dataSource, moduleOutputPath, iLeappFile);
161 
162  if (fileProcessorResult == ProcessResult.ERROR) {
163  return ProcessResult.ERROR;
164  }
165 
166  filesProcessedCount++;
167  }
168 
170  Bundle.ILeappAnalyzerIngestModule_has_run(),
171  Bundle.ILeappAnalyzerIngestModule_completed());
173  return ProcessResult.OK;
174  }
175 
183  private List<AbstractFile> findiLeappFilesToProcess(Content dataSource) {
184 
185  List<AbstractFile> iLeappFiles = new ArrayList<>();
186 
187  FileManager fileManager = getCurrentCase().getServices().getFileManager();
188 
189  // findFiles use the SQL wildcard % in the file name
190  try {
191  iLeappFiles = fileManager.findFiles(dataSource, "%", "/"); //NON-NLS
192  } catch (TskCoreException ex) {
193  logger.log(Level.WARNING, "No files found to process"); //NON-NLS
194  return iLeappFiles;
195  }
196 
197  List<AbstractFile> iLeappFilesToProcess = new ArrayList<>();
198  for (AbstractFile iLeappFile : iLeappFiles) {
199  if ((iLeappFile.getName().toLowerCase().contains(".zip") || (iLeappFile.getName().toLowerCase().contains(".tar"))
200  || iLeappFile.getName().toLowerCase().contains(".tgz"))) {
201  iLeappFilesToProcess.add(iLeappFile);
202  }
203  }
204 
205  return iLeappFilesToProcess;
206  }
207 
208  private ProcessBuilder buildiLeappCommand(Path moduleOutputPath, String sourceFilePath, String iLeappFileSystemType) {
209 
210  ProcessBuilder processBuilder = buildProcessWithRunAsInvoker(
211  "\"" + iLeappExecutable + "\"", //NON-NLS
212  "-t", iLeappFileSystemType, //NON-NLS
213  "-i", sourceFilePath, //NON-NLS
214  "-o", moduleOutputPath.toString()
215  );
216  processBuilder.redirectError(moduleOutputPath.resolve("iLeapp_err.txt").toFile()); //NON-NLS
217  processBuilder.redirectOutput(moduleOutputPath.resolve("iLeapp_out.txt").toFile()); //NON-NLS
218  return processBuilder;
219  }
220 
221  static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) {
222  ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
223  /*
224  * Add an environment variable to force log2timeline/psort to run with
225  * the same permissions Autopsy uses.
226  */
227  processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
228  return processBuilder;
229  }
230 
231  private static File locateExecutable(String executableName) throws FileNotFoundException {
232  String executableToFindName = Paths.get(ILEAPP, executableName).toString();
233 
234  File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, ILeappAnalyzerIngestModule.class.getPackage().getName(), false);
235  if (null == exeFile || exeFile.canExecute() == false) {
236  throw new FileNotFoundException(executableName + " executable not found.");
237  }
238  return exeFile;
239  }
240 
245  private void addILeappReportToReports(Path iLeappOutputDir, Case currentCase) {
246  List<String> allIndexFiles = new ArrayList<>();
247 
248  try (Stream<Path> walk = Files.walk(iLeappOutputDir)) {
249 
250  allIndexFiles = walk.map(x -> x.toString())
251  .filter(f -> f.toLowerCase().endsWith("index.html")).collect(Collectors.toList());
252 
253  if (!allIndexFiles.isEmpty()) {
254  currentCase.addReport(allIndexFiles.get(0), MODULE_NAME, Bundle.ILeappAnalyzerIngestModule_report_name());
255  }
256 
257  } catch (IOException | UncheckedIOException | TskCoreException ex) {
258  // catch the error and continue on as report is not added
259  logger.log(Level.WARNING, String.format("Error finding index file in path %s", iLeappOutputDir.toString()), ex);
260  }
261 
262  }
263 
264 }
static int execute(ProcessBuilder processBuilder)
Definition: ExecUtil.java:145
ProcessBuilder buildiLeappCommand(Path moduleOutputPath, String sourceFilePath, String iLeappFileSystemType)
static IngestMessage createMessage(MessageType messageType, String source, String subject, String detailsHtml)
void addReport(String localPath, String srcModuleName, String reportName)
Definition: Case.java:1646
ProcessResult processFiles(Content dataSource, Path moduleOutputPath, AbstractFile iLeappFile)
void postMessage(final IngestMessage message)
synchronized List< AbstractFile > findFiles(String fileName)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper)
static synchronized IngestServices getInstance()

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