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"})
96 throw new IngestModuleException(NbBundle.getMessage(
this.getClass(),
"AleappAnalyzerIngestModule.not.64.bit.os"));
106 throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex);
111 }
catch (FileNotFoundException exception) {
112 logger.log(Level.WARNING,
"aLeapp executable not found.", exception);
113 throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_executable_not_found(), exception);
119 "ALeappAnalyzerIngestModule.error.running.aLeapp=Error running aLeapp, see log file.",
120 "ALeappAnalyzerIngestModule.error.creating.output.dir=Error creating aLeapp module output directory.",
121 "ALeappAnalyzerIngestModule.starting.aLeapp=Starting aLeapp",
122 "ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp",
123 "ALeappAnalyzerIngestModule.has.run=aLeapp",
124 "ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp run was canceled",
125 "ALeappAnalyzerIngestModule.completed=aLeapp Processing Completed",
126 "ALeappAnalyzerIngestModule.report.name=aLeapp Html Report"})
133 Files.createDirectories(tempOutputPath);
134 }
catch (IOException ex) {
135 logger.log(Level.SEVERE, String.format(
"Error creating aLeapp output directory %s", tempOutputPath.toString()), ex);
139 List<String> aLeappPathsToProcess =
new ArrayList<>();
144 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
148 }
catch (IOException ex) {
149 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program getting file paths to search"), ex);
153 statusHelper.
progress(Bundle.ALeappAnalyzerIngestModule_starting_aLeapp(), 0);
155 List<AbstractFile> aLeappFilesToProcess =
new ArrayList<>();
157 if (!(context.
getDataSource() instanceof LocalFilesDataSource)) {
160 processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
165 Integer filesProcessedCount = 0;
166 for (AbstractFile aLeappFile : aLeappFilesToProcess) {
167 processALeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, aLeappFile);
168 filesProcessedCount++;
172 processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
176 Bundle.ALeappAnalyzerIngestModule_has_run(),
177 Bundle.ALeappAnalyzerIngestModule_completed());
191 AbstractFile aLeappFile) {
192 String currentTime =
new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());
195 Files.createDirectories(moduleOutputPath);
196 }
catch (IOException ex) {
197 logger.log(Level.SEVERE, String.format(
"Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex);
201 statusHelper.
progress(NbBundle.getMessage(
this.getClass(),
"ALeappAnalyzerIngestModule.processing.file", aLeappFile.getName()), filesProcessedCount);
202 ProcessBuilder aLeappCommand =
buildaLeappCommand(moduleOutputPath, aLeappFile.getLocalAbsPath(), aLeappFile.getNameExtension());
206 logger.log(Level.WARNING, String.format(
"Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
212 }
catch (IOException ex) {
213 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program against file %s", aLeappFile.getLocalAbsPath()), ex);
218 logger.log(Level.INFO,
"ILeapp Analyser ingest module run was canceled");
237 String currentTime =
new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());
240 Files.createDirectories(moduleOutputPath);
241 }
catch (IOException ex) {
242 logger.log(Level.SEVERE, String.format(
"Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex);
246 statusHelper.
progress(NbBundle.getMessage(
this.getClass(),
"ALeappAnalyzerIngestModule.processing.filesystem"));
247 ProcessBuilder aLeappCommand =
buildaLeappCommand(moduleOutputPath, directoryToProcess,
"fs");
251 logger.log(Level.WARNING, String.format(
"Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
257 }
catch (IOException ex) {
258 logger.log(Level.SEVERE, String.format(
"Error when trying to execute aLeapp program against file system"), ex);
263 logger.log(Level.INFO,
"ILeapp Analyser ingest module run was canceled");
286 private ProcessBuilder
buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType) {
289 "\"" + aLeappExecutable +
"\"",
290 "-t", aLeappFileSystemType,
291 "-i", sourceFilePath,
292 "-o", moduleOutputPath.toString(),
295 processBuilder.redirectError(moduleOutputPath.resolve(
"aLeapp_err.txt").toFile());
296 processBuilder.redirectOutput(moduleOutputPath.resolve(
"aLeapp_out.txt").toFile());
297 return processBuilder;
303 "\"" + aLeappExecutable +
"\"",
306 processBuilder.redirectError(moduleOutputPath.resolve(
"aLeapp_paths_error.txt").toFile());
307 processBuilder.redirectOutput(moduleOutputPath.resolve(
"aLeapp_paths.txt").toFile());
308 return processBuilder;
312 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
317 processBuilder.environment().put(
"__COMPAT_LAYER",
"RunAsInvoker");
318 return processBuilder;
322 String executableToFindName = Paths.get(ALEAPP, executableName).toString();
324 File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName,
ALeappAnalyzerIngestModule.class.getPackage().getName(),
false);
325 if (null == exeFile || exeFile.canExecute() ==
false) {
326 throw new FileNotFoundException(executableName +
" executable not found.");
336 List<String> allIndexFiles =
new ArrayList<>();
338 try (Stream<Path> walk = Files.walk(aLeappOutputDir)) {
340 allIndexFiles = walk.map(x -> x.toString())
341 .filter(f -> f.toLowerCase().endsWith(
"index.html")).collect(Collectors.toList());
343 if (!allIndexFiles.isEmpty()) {
345 String filePath = FilenameUtils.getFullPathNoEndSeparator(allIndexFiles.get(0));
346 File dataFilesDir =
new File(Paths.get(filePath,
"_TSV Exports").toString());
347 if (dataFilesDir.exists()) {
348 currentCase.
addReport(allIndexFiles.get(0),
MODULE_NAME, Bundle.ALeappAnalyzerIngestModule_report_name());
352 }
catch (IOException | UncheckedIOException | TskCoreException ex) {
354 logger.log(Level.WARNING, String.format(
"Error finding index file in path %s", aLeappOutputDir.toString()), ex);
363 private List<String>
loadIleappPathFile(Path moduleOutputPath)
throws FileNotFoundException, IOException {
364 List<String> aLeappPathsToProcess =
new ArrayList<>();
368 try (BufferedReader reader =
new BufferedReader(
new FileReader(filePath.toString()))) {
369 String line = reader.readLine();
370 while (line != null) {
371 if (line.contains(
"path list generation") || line.length() < 2) {
372 line = reader.readLine();
375 aLeappPathsToProcess.add(line.trim());
376 line = reader.readLine();
380 return aLeappPathsToProcess;
384 FileManager fileManager = getCurrentCase().getServices().getFileManager();
386 for (String fullFilePath : aLeappPathsToProcess) {
389 logger.log(Level.INFO,
"aLeapp Analyser ingest module run was canceled");
393 String ffp = fullFilePath.replaceAll(
"\\*",
"%");
394 ffp = FilenameUtils.normalize(ffp,
true);
395 String fileName = FilenameUtils.getName(ffp);
396 String filePath = FilenameUtils.getPath(ffp);
398 List<AbstractFile> aLeappFiles =
new ArrayList<>();
400 if (filePath.isEmpty()) {
401 aLeappFiles = fileManager.
findFiles(dataSource, fileName);
403 aLeappFiles = fileManager.
findFiles(dataSource, fileName, filePath);
405 }
catch (TskCoreException ex) {
406 logger.log(Level.WARNING,
"No files found to process");
410 for (AbstractFile aLeappFile : aLeappFiles) {
411 Path parentPath = Paths.get(moduleOutputPath.toString(), aLeappFile.getParentPath());
412 File fileParentPath =
new File(parentPath.toString());
419 private void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath) {
420 if (fileParentPath.exists()) {
421 if (!aLeappFile.isDir()) {
425 Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
426 }
catch (IOException ex) {
427 logger.log(Level.INFO, String.format(
"Error creating aLeapp output directory %s", parentPath.toString()), ex);
432 Files.createDirectories(parentPath);
433 }
catch (IOException ex) {
434 logger.log(Level.INFO, String.format(
"Error creating aLeapp output directory %s", parentPath.toString()), ex);
436 if (!aLeappFile.isDir()) {
440 Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
441 }
catch (IOException ex) {
442 logger.log(Level.INFO, String.format(
"Error creating aLeapp output directory %s", parentPath.toString()), ex);
448 private void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath) {
449 String fileName = aLeappFile.getName().replace(
":",
"-");
450 if (!fileName.matches(
".") && !fileName.matches(
"..") && !fileName.toLowerCase().endsWith(
"-slack")) {
451 Path filePath = Paths.get(parentPath, fileName);
452 File localFile =
new File(filePath.toString());
455 }
catch (ReadContentInputStream.ReadContentInputStreamException ex) {
456 logger.log(Level.WARNING, String.format(
"Error reading file '%s' (id=%d).",
457 aLeappFile.getName(), aLeappFile.getId()), ex);
458 }
catch (IOException ex) {
459 logger.log(Level.WARNING, String.format(
"Error writing file local file '%s' (id=%d).",
460 filePath.toString(), aLeappFile.getId()), ex);
LeappFileProcessor aLeappFileProcessor
void addILeappReportToReports(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)
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)
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()