19 package org.sleuthkit.autopsy.modules.leappanalyzers;
21 import java.io.BufferedReader;
23 import java.io.FileNotFoundException;
24 import java.io.FileReader;
25 import java.io.IOException;
26 import java.io.UncheckedIOException;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.nio.file.Paths;
30 import java.text.SimpleDateFormat;
31 import java.util.List;
32 import java.util.ArrayList;
33 import java.util.Locale;
34 import java.util.logging.Level;
35 import java.util.stream.Collectors;
36 import java.util.stream.Stream;
37 import org.apache.commons.io.FilenameUtils;
38 import org.openide.modules.InstalledFileLocator;
39 import org.openide.util.NbBundle;
69 private static final String
ALEAPP =
"aLeapp";
74 private static final String
XMLFILE =
"aleapp-artifact-attribute-reference.xml";
87 "ALeappAnalyzerIngestModule.executable.not.found=aLeapp Executable Not Found.",
88 "ALeappAnalyzerIngestModule.requires.windows=aLeapp module requires windows.",
89 "ALeappAnalyzerIngestModule.error.aleapp.file.processor.init=Failure to initialize aLeappProcessFile"})
95 throw new IngestModuleException(NbBundle.getMessage(
this.getClass(),
"AleappAnalyzerIngestModule.not.64.bit.os"));
105 throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_error_aleapp_file_processor_init(), ex);
110 }
catch (FileNotFoundException exception) {
111 logger.log(Level.WARNING,
"aLeapp executable not found.", exception);
112 throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_executable_not_found(), exception);
118 "ALeappAnalyzerIngestModule.error.running.aLeapp=Error running aLeapp, see log file.",
119 "ALeappAnalyzerIngestModule.error.creating.output.dir=Error creating aLeapp module output directory.",
120 "ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp",
121 "ALeappAnalyzerIngestModule_processing_aLeapp_results=Processing aLeapp results",
122 "ALeappAnalyzerIngestModule.has.run=aLeapp",
123 "ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp run was canceled",
124 "ALeappAnalyzerIngestModule.completed=aLeapp Processing Completed",
125 "ALeappAnalyzerIngestModule.report.name=aLeapp Html Report"})
130 statusHelper.
progress(Bundle.ALeappAnalyzerIngestModule_running_aLeapp());
135 Files.createDirectories(tempOutputPath);
136 }
catch (IOException ex) {
137 logger.log(Level.SEVERE, String.format(
"Error creating aLeapp output directory %s", tempOutputPath.toString()), ex);
142 List<String> aLeappPathsToProcess;
147 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
152 if (aLeappPathsToProcess.isEmpty()) {
153 logger.log(Level.SEVERE, String.format(
"Error getting file paths to search, list is empty"));
157 }
catch (IOException ex) {
158 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program getting file paths to search"), ex);
163 if ((context.
getDataSource() instanceof LocalFilesDataSource)) {
169 List<AbstractFile> aLeappFilesToProcess =
LeappFileProcessor.findLeappFilesToProcess(dataSource);
170 if (!aLeappFilesToProcess.isEmpty()) {
172 Integer filesProcessedCount = 0;
173 for (AbstractFile aLeappFile : aLeappFilesToProcess) {
174 processALeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, aLeappFile);
175 filesProcessedCount++;
181 statusHelper.
progress(Bundle.ALeappAnalyzerIngestModule_processing_aLeapp_results());
183 processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
186 Bundle.ALeappAnalyzerIngestModule_has_run(),
187 Bundle.ALeappAnalyzerIngestModule_completed());
203 AbstractFile aLeappFile) {
204 statusHelper.
progress(NbBundle.getMessage(
this.getClass(),
"ALeappAnalyzerIngestModule.processing.file", aLeappFile.getName()), filesProcessedCount);
205 String currentTime =
new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());
208 Files.createDirectories(moduleOutputPath);
209 }
catch (IOException ex) {
210 logger.log(Level.SEVERE, String.format(
"Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex);
214 ProcessBuilder aLeappCommand =
buildaLeappCommand(moduleOutputPath, aLeappFile.getLocalAbsPath(), aLeappFile.getNameExtension());
218 logger.log(Level.WARNING, String.format(
"Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
224 }
catch (IOException ex) {
225 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program against file %s", aLeappFile.getLocalAbsPath()), ex);
230 logger.log(Level.INFO,
"aLeapp Analyser ingest module run was canceled");
234 aLeappFileProcessor.
processFiles(dataSource, moduleOutputPath, aLeappFile, statusHelper);
247 statusHelper.
progress(NbBundle.getMessage(
this.getClass(),
"ALeappAnalyzerIngestModule.processing.filesystem"));
248 String currentTime =
new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());
251 Files.createDirectories(moduleOutputPath);
252 }
catch (IOException ex) {
253 logger.log(Level.SEVERE, String.format(
"Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex);
257 ProcessBuilder aLeappCommand =
buildaLeappCommand(moduleOutputPath, directoryToProcess,
"fs");
261 logger.log(Level.WARNING, String.format(
"Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
267 }
catch (IOException ex) {
268 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program against file system"), ex);
273 logger.log(Level.INFO,
"aLeapp Analyser ingest module run was canceled");
277 aLeappFileProcessor.
processFileSystem(dataSource, moduleOutputPath, statusHelper);
289 private ProcessBuilder
buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType) {
292 "\"" + aLeappExecutable +
"\"",
293 "-t", aLeappFileSystemType,
294 "-i", sourceFilePath,
295 "-o", moduleOutputPath.toString(),
298 processBuilder.redirectError(moduleOutputPath.resolve(
"aLeapp_err.txt").toFile());
299 processBuilder.redirectOutput(moduleOutputPath.resolve(
"aLeapp_out.txt").toFile());
300 return processBuilder;
306 "\"" + aLeappExecutable +
"\"",
309 processBuilder.redirectError(moduleOutputPath.resolve(
"aLeapp_paths_error.txt").toFile());
310 processBuilder.redirectOutput(moduleOutputPath.resolve(
"aLeapp_paths.txt").toFile());
311 return processBuilder;
315 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
320 processBuilder.environment().put(
"__COMPAT_LAYER",
"RunAsInvoker");
321 return processBuilder;
325 String executableToFindName = Paths.get(ALEAPP, executableName).toString();
327 File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName,
ALeappAnalyzerIngestModule.class.getPackage().getName(),
false);
328 if (null == exeFile || exeFile.canExecute() ==
false) {
329 throw new FileNotFoundException(executableName +
" executable not found.");
339 List<String> allIndexFiles =
new ArrayList<>();
341 try (Stream<Path> walk = Files.walk(aLeappOutputDir)) {
343 allIndexFiles = walk.map(x -> x.toString())
344 .filter(f -> f.toLowerCase().endsWith(
"index.html")).collect(Collectors.toList());
346 if (!allIndexFiles.isEmpty()) {
348 String filePath = FilenameUtils.getFullPathNoEndSeparator(allIndexFiles.get(0));
349 File dataFilesDir =
new File(Paths.get(filePath,
"_TSV Exports").toString());
350 if (dataFilesDir.exists()) {
351 currentCase.
addReport(allIndexFiles.get(0),
MODULE_NAME, Bundle.ALeappAnalyzerIngestModule_report_name());
355 }
catch (IOException | UncheckedIOException | TskCoreException ex) {
357 logger.log(Level.WARNING, String.format(
"Error finding index file in path %s", aLeappOutputDir.toString()), ex);
366 private List<String>
loadAleappPathFile(Path moduleOutputPath)
throws FileNotFoundException, IOException {
367 List<String> aLeappPathsToProcess =
new ArrayList<>();
371 try (BufferedReader reader =
new BufferedReader(
new FileReader(filePath.toString()))) {
372 String line = reader.readLine();
373 while (line != null) {
374 if (line.contains(
"path list generation") || line.length() < 2) {
375 line = reader.readLine();
378 aLeappPathsToProcess.add(line.trim());
379 line = reader.readLine();
383 return aLeappPathsToProcess;
387 FileManager fileManager = getCurrentCase().getServices().getFileManager();
389 for (String fullFilePath : aLeappPathsToProcess) {
392 logger.log(Level.INFO,
"aLeapp Analyser ingest module run was canceled");
396 String ffp = fullFilePath.replaceAll(
"\\*",
"%");
397 ffp = FilenameUtils.normalize(ffp,
true);
398 String fileName = FilenameUtils.getName(ffp);
399 String filePath = FilenameUtils.getPath(ffp);
401 List<AbstractFile> aLeappFiles =
new ArrayList<>();
403 if (filePath.isEmpty()) {
404 aLeappFiles = fileManager.
findFiles(dataSource, fileName);
406 aLeappFiles = fileManager.
findFiles(dataSource, fileName, filePath);
408 }
catch (TskCoreException ex) {
409 logger.log(Level.WARNING,
"No files found to process");
413 for (AbstractFile aLeappFile : aLeappFiles) {
414 Path parentPath = Paths.get(moduleOutputPath.toString(), aLeappFile.getParentPath());
415 File fileParentPath =
new File(parentPath.toString());
422 private void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath) {
423 if (fileParentPath.exists()) {
424 if (!aLeappFile.isDir()) {
428 Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
429 }
catch (IOException ex) {
430 logger.log(Level.INFO, String.format(
"Error creating aLeapp output directory %s", parentPath.toString()), ex);
435 Files.createDirectories(parentPath);
436 }
catch (IOException ex) {
437 logger.log(Level.INFO, String.format(
"Error creating aLeapp output directory %s", parentPath.toString()), ex);
439 if (!aLeappFile.isDir()) {
443 Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
444 }
catch (IOException ex) {
445 logger.log(Level.INFO, String.format(
"Error creating aLeapp output directory %s", parentPath.toString()), ex);
451 private void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath) {
452 String fileName = aLeappFile.getName().replace(
":",
"-");
453 if (!fileName.matches(
".") && !fileName.matches(
"..") && !fileName.toLowerCase().endsWith(
"-slack")) {
454 Path filePath = Paths.get(parentPath, fileName);
455 File localFile =
new File(filePath.toString());
458 }
catch (ReadContentInputStream.ReadContentInputStreamException ex) {
459 logger.log(Level.WARNING, String.format(
"Error reading file '%s' (id=%d).",
460 aLeappFile.getName(), aLeappFile.getId()), ex);
461 }
catch (IOException ex) {
462 logger.log(Level.WARNING, String.format(
"Error writing file local file '%s' (id=%d).",
463 filePath.toString(), aLeappFile.getId()), ex);
475 Bundle.ALeappAnalyzerIngestModule_error_running_aLeapp());
LeappFileProcessor aLeappFileProcessor
void addALeappReportToReports(Path aLeappOutputDir, Case currentCase)
static final Logger logger
static int execute(ProcessBuilder processBuilder)
void processALeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount, AbstractFile aLeappFile)
String getTempDirectory()
List< AbstractFile > findFiles(String fileName)
static final String ALEAPP
void startUp(IngestJobContext context)
void extractFilesFromDataSource(Content dataSource, List< String > aLeappPathsToProcess, Path moduleOutputPath)
static IngestMessage createMessage(MessageType messageType, String source, String subject, String detailsHtml)
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
ProcessBuilder buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType)
void addReport(String localPath, String srcModuleName, String reportName)
void processALeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess)
void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath)
static final String ALEAPP_PATHS_FILE
static final String MODULE_NAME
static final String XMLFILE
void switchToIndeterminate()
void writeErrorMsgToIngestInbox()
List< String > loadAleappPathFile(Path moduleOutputPath)
ProcessBuilder buildaLeappListCommand(Path moduleOutputPath)
void postMessage(final IngestMessage message)
static final String ALEAPP_EXECUTABLE
static final String ALEAPP_FS
String getModuleDirectory()
ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper)
boolean dataSourceIngestIsCancelled()
ProcessResult processFileSystem(Content dataSource, Path moduleOutputPath, DataSourceIngestModuleProgress progress)
void switchToDeterminate(int workUnits)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
static File locateExecutable(String executableName)
void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath)
static ProcessBuilder buildProcessWithRunAsInvoker(String...commandLine)
void progress(int workUnits)
ProcessResult processFiles(Content dataSource, Path moduleOutputPath, AbstractFile LeappFile, DataSourceIngestModuleProgress progress)
static synchronized IngestServices getInstance()