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 =
"aleap-artifact-attribute-reference.xml";
88 "ALeappAnalyzerIngestModule.executable.not.found=aLeapp Executable Not Found.",
89 "ALeappAnalyzerIngestModule.requires.windows=aLeapp module requires windows.",
90 "ALeappAnalyzerIngestModule.error.ileapp.file.processor.init=Failure to initialize aLeappProcessFile"})
102 throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex);
107 }
catch (FileNotFoundException exception) {
108 logger.log(Level.WARNING,
"aLeapp executable not found.", exception);
109 throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_executable_not_found(), exception);
115 "ALeappAnalyzerIngestModule.error.running.aLeapp=Error running aLeapp, see log file.",
116 "ALeappAnalyzerIngestModule.error.creating.output.dir=Error creating aLeapp module output directory.",
117 "ALeappAnalyzerIngestModule.starting.aLeapp=Starting aLeapp",
118 "ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp",
119 "ALeappAnalyzerIngestModule.has.run=aLeapp",
120 "ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp run was canceled",
121 "ALeappAnalyzerIngestModule.completed=aLeapp Processing Completed",
122 "ALeappAnalyzerIngestModule.report.name=aLeapp Html Report"})
129 Files.createDirectories(tempOutputPath);
130 }
catch (IOException ex) {
131 logger.log(Level.SEVERE, String.format(
"Error creating aLeapp output directory %s", tempOutputPath.toString()), ex);
135 List<String> aLeappPathsToProcess =
new ArrayList<>();
140 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
144 }
catch (IOException ex) {
145 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program getting file paths to search"), ex);
149 statusHelper.
progress(Bundle.ALeappAnalyzerIngestModule_starting_aLeapp(), 0);
151 List<AbstractFile> aLeappFilesToProcess =
new ArrayList<>();
153 if (!(context.
getDataSource() instanceof LocalFilesDataSource)) {
156 processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
161 Integer filesProcessedCount = 0;
162 for (AbstractFile aLeappFile : aLeappFilesToProcess) {
163 processALeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, aLeappFile);
164 filesProcessedCount++;
168 processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
172 Bundle.ALeappAnalyzerIngestModule_has_run(),
173 Bundle.ALeappAnalyzerIngestModule_completed());
187 AbstractFile aLeappFile) {
188 String currentTime =
new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());
191 Files.createDirectories(moduleOutputPath);
192 }
catch (IOException ex) {
193 logger.log(Level.SEVERE, String.format(
"Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex);
197 statusHelper.
progress(NbBundle.getMessage(
this.getClass(),
"ALeappAnalyzerIngestModule.processing.file", aLeappFile.getName()), filesProcessedCount);
198 ProcessBuilder aLeappCommand =
buildaLeappCommand(moduleOutputPath, aLeappFile.getLocalAbsPath(), aLeappFile.getNameExtension());
202 logger.log(Level.WARNING, String.format(
"Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
208 }
catch (IOException ex) {
209 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program against file %s", aLeappFile.getLocalAbsPath()), ex);
214 logger.log(Level.INFO,
"ILeapp Analyser ingest module run was canceled");
233 String currentTime =
new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());
236 Files.createDirectories(moduleOutputPath);
237 }
catch (IOException ex) {
238 logger.log(Level.SEVERE, String.format(
"Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex);
242 statusHelper.
progress(NbBundle.getMessage(
this.getClass(),
"ALeappAnalyzerIngestModule.processing.filesystem"));
243 ProcessBuilder aLeappCommand =
buildaLeappCommand(moduleOutputPath, directoryToProcess,
"fs");
247 logger.log(Level.WARNING, String.format(
"Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
253 }
catch (IOException ex) {
254 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program against file system"), ex);
259 logger.log(Level.INFO,
"ILeapp Analyser ingest module run was canceled");
280 List<AbstractFile> aLeappFiles =
new ArrayList<>();
282 FileManager fileManager = getCurrentCase().getServices().getFileManager();
286 aLeappFiles = fileManager.
findFiles(dataSource,
"%",
"/");
287 }
catch (TskCoreException ex) {
288 logger.log(Level.WARNING,
"No files found to process");
292 List<AbstractFile> aLeappFilesToProcess =
new ArrayList<>();
293 for (AbstractFile aLeappFile : aLeappFiles) {
294 if (((aLeappFile.getLocalAbsPath() != null)
295 && (!aLeappFile.getNameExtension().isEmpty() && (!aLeappFile.isVirtual())))
296 && ((aLeappFile.getName().toLowerCase().contains(
".zip") || (aLeappFile.getName().toLowerCase().contains(
".tar")))
297 || aLeappFile.getName().toLowerCase().contains(
".tgz"))) {
298 aLeappFilesToProcess.add(aLeappFile);
303 return aLeappFilesToProcess;
315 private ProcessBuilder
buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType) {
318 "\"" + aLeappExecutable +
"\"",
319 "-t", aLeappFileSystemType,
320 "-i", sourceFilePath,
321 "-o", moduleOutputPath.toString(),
324 processBuilder.redirectError(moduleOutputPath.resolve(
"aLeapp_err.txt").toFile());
325 processBuilder.redirectOutput(moduleOutputPath.resolve(
"aLeapp_out.txt").toFile());
326 return processBuilder;
332 "\"" + aLeappExecutable +
"\"",
335 processBuilder.redirectError(moduleOutputPath.resolve(
"aLeapp_paths_error.txt").toFile());
336 processBuilder.redirectOutput(moduleOutputPath.resolve(
"aLeapp_paths.txt").toFile());
337 return processBuilder;
341 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
346 processBuilder.environment().put(
"__COMPAT_LAYER",
"RunAsInvoker");
347 return processBuilder;
351 String executableToFindName = Paths.get(ALEAPP, executableName).toString();
353 File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName,
ALeappAnalyzerIngestModule.class.getPackage().getName(),
false);
354 if (null == exeFile || exeFile.canExecute() ==
false) {
355 throw new FileNotFoundException(executableName +
" executable not found.");
365 List<String> allIndexFiles =
new ArrayList<>();
367 try (Stream<Path> walk = Files.walk(aLeappOutputDir)) {
369 allIndexFiles = walk.map(x -> x.toString())
370 .filter(f -> f.toLowerCase().endsWith(
"index.html")).collect(Collectors.toList());
372 if (!allIndexFiles.isEmpty()) {
374 String filePath = FilenameUtils.getFullPathNoEndSeparator(allIndexFiles.get(0));
375 File dataFilesDir =
new File(Paths.get(filePath,
"_TSV Exports").toString());
376 if (dataFilesDir.exists()) {
377 currentCase.
addReport(allIndexFiles.get(0),
MODULE_NAME, Bundle.ALeappAnalyzerIngestModule_report_name());
381 }
catch (IOException | UncheckedIOException | TskCoreException ex) {
383 logger.log(Level.WARNING, String.format(
"Error finding index file in path %s", aLeappOutputDir.toString()), ex);
392 private List<String>
loadIleappPathFile(Path moduleOutputPath)
throws FileNotFoundException, IOException {
393 List<String> aLeappPathsToProcess =
new ArrayList<>();
397 try (BufferedReader reader =
new BufferedReader(
new FileReader(filePath.toString()))) {
398 String line = reader.readLine();
399 while (line != null) {
400 if (line.contains(
"path list generation") || line.length() < 2) {
401 line = reader.readLine();
404 aLeappPathsToProcess.add(line.trim());
405 line = reader.readLine();
409 return aLeappPathsToProcess;
413 FileManager fileManager = getCurrentCase().getServices().getFileManager();
415 for (String fullFilePath : aLeappPathsToProcess) {
418 logger.log(Level.INFO,
"aLeapp Analyser ingest module run was canceled");
422 String ffp = fullFilePath.replaceAll(
"\\*",
"%");
423 ffp = FilenameUtils.normalize(ffp,
true);
424 String fileName = FilenameUtils.getName(ffp);
425 String filePath = FilenameUtils.getPath(ffp);
427 List<AbstractFile> aLeappFiles =
new ArrayList<>();
429 if (filePath.isEmpty()) {
430 aLeappFiles = fileManager.
findFiles(dataSource, fileName);
432 aLeappFiles = fileManager.
findFiles(dataSource, fileName, filePath);
434 }
catch (TskCoreException ex) {
435 logger.log(Level.WARNING,
"No files found to process");
439 for (AbstractFile aLeappFile : aLeappFiles) {
440 Path parentPath = Paths.get(moduleOutputPath.toString(), aLeappFile.getParentPath());
441 File fileParentPath =
new File(parentPath.toString());
448 private void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath) {
449 if (fileParentPath.exists()) {
450 if (!aLeappFile.isDir()) {
454 Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
455 }
catch (IOException ex) {
456 logger.log(Level.INFO, String.format(
"Error creating aLeapp output directory %s", parentPath.toString()), ex);
461 Files.createDirectories(parentPath);
462 }
catch (IOException ex) {
463 logger.log(Level.INFO, String.format(
"Error creating aLeapp output directory %s", parentPath.toString()), ex);
465 if (!aLeappFile.isDir()) {
469 Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
470 }
catch (IOException ex) {
471 logger.log(Level.INFO, String.format(
"Error creating aLeapp output directory %s", parentPath.toString()), ex);
477 private void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath) {
478 String fileName = aLeappFile.getName().replace(
":",
"-");
479 if (!fileName.matches(
".") && !fileName.matches(
"..") && !fileName.toLowerCase().endsWith(
"-slack")) {
480 Path filePath = Paths.get(parentPath, fileName);
481 File localFile =
new File(filePath.toString());
484 }
catch (ReadContentInputStream.ReadContentInputStreamException ex) {
485 logger.log(Level.WARNING, String.format(
"Error reading file '%s' (id=%d).",
486 aLeappFile.getName(), aLeappFile.getId()), ex);
487 }
catch (IOException ex) {
488 logger.log(Level.WARNING, String.format(
"Error writing file local file '%s' (id=%d).",
489 filePath.toString(), aLeappFile.getId()), ex);
LeappFileProcessor aLeappFileProcessor
void addILeappReportToReports(Path aLeappOutputDir, Case currentCase)
List< AbstractFile > findaLeappFilesToProcess(Content dataSource)
static final Logger logger
static int execute(ProcessBuilder processBuilder)
void processALeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount, AbstractFile aLeappFile)
String getTempDirectory()
static final String ALEAPP
void startUp(IngestJobContext context)
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
ProcessResult processFileSystem(Content dataSource, Path moduleOutputPath)
ProcessBuilder buildaLeappListCommand(Path moduleOutputPath)
ProcessResult processFiles(Content dataSource, Path moduleOutputPath, AbstractFile LeappFile)
void postMessage(final IngestMessage message)
static final String ALEAPP_EXECUTABLE
static final String ALEAPP_FS
String getModuleDirectory()
ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper)
List< String > loadIleappPathFile(Path moduleOutputPath)
boolean dataSourceIngestIsCancelled()
void extractFilesFromImage(Content dataSource, List< String > aLeappPathsToProcess, Path moduleOutputPath)
void switchToDeterminate(int workUnits)
synchronized List< AbstractFile > findFiles(String fileName)
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)
static synchronized IngestServices getInstance()