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 
ILEAPP = 
"iLeapp"; 
 
   74     private static final String 
XMLFILE = 
"ileap-artifact-attribute-reference.xml"; 
 
   88         "ILeappAnalyzerIngestModule.executable.not.found=iLeapp Executable Not Found.",
 
   89         "ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows.",
 
   90         "ILeappAnalyzerIngestModule.error.ileapp.file.processor.init=Failure to initialize ILeappProcessFile"})
 
   96             throw new IngestModuleException(NbBundle.getMessage(
this.getClass(), 
"IleappAnalyzerIngestModule.not.64.bit.os"));
 
  106             throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex);
 
  111         } 
catch (FileNotFoundException exception) {
 
  112             logger.log(Level.WARNING, 
"iLeapp executable not found.", exception); 
 
  113             throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_executable_not_found(), exception);
 
  119         "ILeappAnalyzerIngestModule.error.running.iLeapp=Error running iLeapp, see log file.",
 
  120         "ILeappAnalyzerIngestModule.error.creating.output.dir=Error creating iLeapp module output directory.",
 
  121         "ILeappAnalyzerIngestModule.starting.iLeapp=Starting iLeapp",
 
  122         "ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp",
 
  123         "ILeappAnalyzerIngestModule.has.run=iLeapp",
 
  124         "ILeappAnalyzerIngestModule.iLeapp.cancelled=iLeapp run was canceled",
 
  125         "ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed",
 
  126         "ILeappAnalyzerIngestModule.report.name=iLeapp Html Report"})
 
  133             Files.createDirectories(tempOutputPath);
 
  134         } 
catch (IOException ex) {
 
  135             logger.log(Level.SEVERE, String.format(
"Error creating iLeapp output directory %s", tempOutputPath.toString()), ex);
 
  139         List<String> iLeappPathsToProcess = 
new ArrayList<>();
 
  144                 logger.log(Level.SEVERE, String.format(
"Error when trying to execute iLeapp 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 iLeapp program getting file paths to search"), ex);
 
  153         statusHelper.
progress(Bundle.ILeappAnalyzerIngestModule_starting_iLeapp(), 0);
 
  155         List<AbstractFile> iLeappFilesToProcess = 
new ArrayList<>();
 
  157         if (!(context.
getDataSource() instanceof LocalFilesDataSource)) {
 
  160             processILeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
 
  165             Integer filesProcessedCount = 0;
 
  166             for (AbstractFile iLeappFile : iLeappFilesToProcess) {
 
  167                 processILeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, iLeappFile);
 
  168                 filesProcessedCount++;
 
  172             processILeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
 
  176                 Bundle.ILeappAnalyzerIngestModule_has_run(),
 
  177                 Bundle.ILeappAnalyzerIngestModule_completed());
 
  191             AbstractFile iLeappFile) {
 
  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 iLeapp output directory %s", moduleOutputPath.toString()), ex);
 
  201         statusHelper.
progress(NbBundle.getMessage(
this.getClass(), 
"ILeappAnalyzerIngestModule.processing.file", iLeappFile.getName()), filesProcessedCount);
 
  202         ProcessBuilder iLeappCommand = 
buildiLeappCommand(moduleOutputPath, iLeappFile.getLocalAbsPath(), iLeappFile.getNameExtension());
 
  206                 logger.log(Level.WARNING, String.format(
"Error when trying to execute iLeapp 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 iLeapp program against file %s", iLeappFile.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 iLeapp output directory %s", moduleOutputPath.toString()), ex);
 
  246         statusHelper.
progress(NbBundle.getMessage(
this.getClass(), 
"ILeappAnalyzerIngestModule.processing.filesystem"));
 
  247         ProcessBuilder iLeappCommand = 
buildiLeappCommand(moduleOutputPath, directoryToProcess, 
"fs");
 
  251                 logger.log(Level.WARNING, String.format(
"Error when trying to execute iLeapp 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 iLeapp program against file system"), ex);
 
  263             logger.log(Level.INFO, 
"ILeapp Analyser ingest module run was canceled"); 
 
  282     private ProcessBuilder 
buildiLeappCommand(Path moduleOutputPath, String sourceFilePath, String iLeappFileSystemType) {
 
  285                 "\"" + iLeappExecutable + 
"\"", 
 
  286                 "-t", iLeappFileSystemType, 
 
  287                 "-i", sourceFilePath, 
 
  288                 "-o", moduleOutputPath.toString()
 
  290         processBuilder.redirectError(moduleOutputPath.resolve(
"iLeapp_err.txt").toFile());  
 
  291         processBuilder.redirectOutput(moduleOutputPath.resolve(
"iLeapp_out.txt").toFile());  
 
  292         return processBuilder;
 
  303                 "\"" + iLeappExecutable + 
"\"", 
 
  306         processBuilder.redirectError(moduleOutputPath.resolve(
"iLeapp_paths_error.txt").toFile());  
 
  307         processBuilder.redirectOutput(moduleOutputPath.resolve(
"iLeapp_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(ILEAPP, executableName).toString();
 
  324         File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, 
ILeappAnalyzerIngestModule.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(iLeappOutputDir)) { 
 
  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.ILeappAnalyzerIngestModule_report_name());
 
  352         } 
catch (IOException | UncheckedIOException | TskCoreException ex) {
 
  354             logger.log(Level.WARNING, String.format(
"Error finding index file in path %s", iLeappOutputDir.toString()), ex);
 
  364     private List<String> 
loadIleappPathFile(Path moduleOutputPath) 
throws FileNotFoundException, IOException {
 
  365         List<String> iLeappPathsToProcess = 
new ArrayList<>();
 
  369         try (BufferedReader reader = 
new BufferedReader(
new FileReader(filePath.toString()))) {
 
  370             String line = reader.readLine();
 
  371             while (line != null) {
 
  372                 if (line.contains(
"path list generation") || line.length() < 2) {
 
  373                     line = reader.readLine();
 
  376                 iLeappPathsToProcess.add(line.trim());
 
  377                 line = reader.readLine();
 
  381         return iLeappPathsToProcess;
 
  391         FileManager fileManager = getCurrentCase().getServices().getFileManager();
 
  393         for (String fullFilePath : iLeappPathsToProcess) {
 
  396                 logger.log(Level.INFO, 
"ILeapp Analyser ingest module run was canceled"); 
 
  400             String ffp = fullFilePath.replaceAll(
"\\*", 
"%");
 
  401             ffp = FilenameUtils.normalize(ffp, 
true);
 
  402             String fileName = FilenameUtils.getName(ffp);
 
  403             String filePath = FilenameUtils.getPath(ffp);
 
  405             List<AbstractFile> iLeappFiles = 
new ArrayList<>();
 
  407                 if (filePath.isEmpty()) {
 
  408                     iLeappFiles = fileManager.
findFiles(dataSource, fileName); 
 
  410                     iLeappFiles = fileManager.
findFiles(dataSource, fileName, filePath); 
 
  412             } 
catch (TskCoreException ex) {
 
  413                 logger.log(Level.WARNING, 
"No files found to process"); 
 
  417             for (AbstractFile iLeappFile : iLeappFiles) {
 
  418                 Path parentPath = Paths.get(moduleOutputPath.toString(), iLeappFile.getParentPath());
 
  419                 File fileParentPath = 
new File(parentPath.toString());
 
  433     private void extractFileToOutput(Content dataSource, AbstractFile iLeappFile, File fileParentPath, Path parentPath) {
 
  434         if (fileParentPath.exists()) {
 
  435                     if (!iLeappFile.isDir()) {
 
  439                             Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName()));
 
  440                         } 
catch (IOException ex) {
 
  441                             logger.log(Level.INFO, String.format(
"Error creating iLeapp output directory %s", parentPath.toString()), ex);
 
  446                         Files.createDirectories(parentPath);
 
  447                     } 
catch (IOException ex) {
 
  448                         logger.log(Level.INFO, String.format(
"Error creating iLeapp output directory %s", parentPath.toString()), ex);
 
  450                     if (!iLeappFile.isDir()) {
 
  454                             Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName()));
 
  455                         } 
catch (IOException ex) {
 
  456                             logger.log(Level.INFO, String.format(
"Error creating iLeapp output directory %s", parentPath.toString()), ex);
 
  468     private void writeiLeappFile(Content dataSource, AbstractFile iLeappFile, String parentPath) {
 
  469         String fileName = iLeappFile.getName().replace(
":", 
"-");
 
  470         if (!fileName.matches(
".") && !fileName.matches(
"..") && !fileName.toLowerCase().endsWith(
"-slack")) {
 
  471             Path filePath = Paths.get(parentPath, fileName);
 
  472             File localFile = 
new File(filePath.toString());
 
  475             } 
catch (ReadContentInputStream.ReadContentInputStreamException ex) {
 
  476                 logger.log(Level.WARNING, String.format(
"Error reading file '%s' (id=%d).",
 
  477                         iLeappFile.getName(), iLeappFile.getId()), ex); 
 
  478             } 
catch (IOException ex) {
 
  479                 logger.log(Level.WARNING, String.format(
"Error writing file local file '%s' (id=%d).",
 
  480                         filePath.toString(), iLeappFile.getId()), ex); 
 
ProcessBuilder buildiLeappListCommand(Path moduleOutputPath)
 
void extractFilesFromImage(Content dataSource, List< String > iLeappPathsToProcess, Path moduleOutputPath)
 
void processILeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess)
 
static int execute(ProcessBuilder processBuilder)
 
String getTempDirectory()
 
List< AbstractFile > findFiles(String fileName)
 
static final String ILEAPP
 
void extractFileToOutput(Content dataSource, AbstractFile iLeappFile, File fileParentPath, Path parentPath)
 
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)
 
void addReport(String localPath, String srcModuleName, String reportName)
 
static final String MODULE_NAME
 
static final String ILEAPP_EXECUTABLE
 
static ProcessBuilder buildProcessWithRunAsInvoker(String...commandLine)
 
static final String ILEAPP_FS
 
ProcessBuilder buildiLeappCommand(Path moduleOutputPath, String sourceFilePath, String iLeappFileSystemType)
 
static final String XMLFILE
 
static final Logger logger
 
ProcessResult processFileSystem(Content dataSource, Path moduleOutputPath)
 
static File locateExecutable(String executableName)
 
ProcessResult processFiles(Content dataSource, Path moduleOutputPath, AbstractFile LeappFile)
 
void postMessage(final IngestMessage message)
 
String getModuleDirectory()
 
void addILeappReportToReports(Path iLeappOutputDir, Case currentCase)
 
boolean dataSourceIngestIsCancelled()
 
void startUp(IngestJobContext context)
 
void switchToDeterminate(int workUnits)
 
static Case getCurrentCase()
 
synchronized static Logger getLogger(String name)
 
ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper)
 
static final String ILEAPP_PATHS_FILE
 
void processILeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount, AbstractFile iLeappFile)
 
LeappFileProcessor iLeappFileProcessor
 
void writeiLeappFile(Content dataSource, AbstractFile iLeappFile, String parentPath)
 
List< String > loadIleappPathFile(Path moduleOutputPath)
 
void progress(int workUnits)
 
static synchronized IngestServices getInstance()