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 = 
"ileapp-artifact-attribute-reference.xml"; 
 
   87         "ILeappAnalyzerIngestModule.executable.not.found=iLeapp Executable Not Found.",
 
   88         "ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows.",
 
   89         "ILeappAnalyzerIngestModule.error.ileapp.file.processor.init=Failure to initialize ILeappProcessFile"})
 
   95             throw new IngestModuleException(NbBundle.getMessage(
this.getClass(), 
"IleappAnalyzerIngestModule.not.64.bit.os"));
 
  105             throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex);
 
  110         } 
catch (FileNotFoundException exception) {
 
  111             logger.log(Level.WARNING, 
"iLeapp executable not found.", exception); 
 
  112             throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_executable_not_found(), exception);
 
  118         "ILeappAnalyzerIngestModule.error.running.iLeapp=Error running iLeapp, see log file.",
 
  119         "ILeappAnalyzerIngestModule.error.creating.output.dir=Error creating iLeapp module output directory.",
 
  120         "ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp",
 
  121         "ILeappAnalyzerIngestModule_processing_iLeapp_results=Processing iLeapp results",
 
  122         "ILeappAnalyzerIngestModule.has.run=iLeapp",
 
  123         "ILeappAnalyzerIngestModule.iLeapp.cancelled=iLeapp run was canceled",
 
  124         "ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed",
 
  125         "ILeappAnalyzerIngestModule.report.name=iLeapp Html Report"})
 
  130         statusHelper.
progress(Bundle.ILeappAnalyzerIngestModule_running_iLeapp());
 
  135             Files.createDirectories(tempOutputPath);
 
  136         } 
catch (IOException ex) {
 
  137             logger.log(Level.SEVERE, String.format(
"Error creating iLeapp output directory %s", tempOutputPath.toString()), ex);
 
  142         List<String> iLeappPathsToProcess;
 
  147                 logger.log(Level.SEVERE, String.format(
"Error when trying to execute iLeapp program getting file paths to search for result is %d", result));
 
  152             if (iLeappPathsToProcess.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 iLeapp program getting file paths to search"), ex);
 
  169             List<AbstractFile> iLeappFilesToProcess = 
LeappFileProcessor.findLeappFilesToProcess(dataSource);
 
  170             if (!iLeappFilesToProcess.isEmpty()) {
 
  172                 Integer filesProcessedCount = 0;
 
  174                     processILeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, iLeappFile);
 
  175                     filesProcessedCount++;
 
  181         statusHelper.
progress(Bundle.ILeappAnalyzerIngestModule_processing_iLeapp_results());
 
  183         processILeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
 
  186                 Bundle.ILeappAnalyzerIngestModule_has_run(),
 
  187                 Bundle.ILeappAnalyzerIngestModule_completed());
 
  204         statusHelper.
progress(NbBundle.getMessage(
this.getClass(), 
"ILeappAnalyzerIngestModule.processing.file", iLeappFile.
getName()), filesProcessedCount);
 
  206         String currentTime = 
new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());
 
  209             Files.createDirectories(moduleOutputPath);
 
  210         } 
catch (IOException ex) {
 
  211             logger.log(Level.SEVERE, String.format(
"Error creating iLeapp output directory %s", moduleOutputPath.toString()), ex);
 
  219                 logger.log(Level.WARNING, String.format(
"Error when trying to execute iLeapp program getting file paths to search for result is %d", result));
 
  225         } 
catch (IOException ex) {
 
  226             logger.log(Level.SEVERE, String.format(
"Error when trying to execute iLeapp program against file %s", iLeappFile.
getLocalAbsPath()), ex);
 
  231             logger.log(Level.INFO, 
"ILeapp Analyser ingest module run was canceled"); 
 
  235         iLeappFileProcessor.
processFiles(dataSource, moduleOutputPath, iLeappFile, statusHelper);
 
  247         statusHelper.
progress(NbBundle.getMessage(
this.getClass(), 
"ILeappAnalyzerIngestModule.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 iLeapp output directory %s", moduleOutputPath.toString()), ex);
 
  257         ProcessBuilder iLeappCommand = 
buildiLeappCommand(moduleOutputPath, directoryToProcess, 
"fs");
 
  261                 logger.log(Level.WARNING, String.format(
"Error when trying to execute iLeapp 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 iLeapp program against file system"), ex);
 
  273             logger.log(Level.INFO, 
"ILeapp Analyser ingest module run was canceled"); 
 
  277         iLeappFileProcessor.
processFileSystem(dataSource, moduleOutputPath, statusHelper);
 
  289     private ProcessBuilder 
buildiLeappCommand(Path moduleOutputPath, String sourceFilePath, String iLeappFileSystemType) {
 
  292                 iLeappExecutable.getAbsolutePath(), 
 
  293                 "-t", iLeappFileSystemType, 
 
  294                 "-i", sourceFilePath, 
 
  295                 "-o", moduleOutputPath.toString()
 
  297         processBuilder.directory(moduleOutputPath.toFile());
 
  298         processBuilder.redirectError(moduleOutputPath.resolve(
"iLeapp_err.txt").toFile());  
 
  299         processBuilder.redirectOutput(moduleOutputPath.resolve(
"iLeapp_out.txt").toFile());  
 
  300         return processBuilder;
 
  313                 iLeappExecutable.getAbsolutePath(), 
 
  317         processBuilder.directory(moduleOutputPath.toFile());
 
  318         processBuilder.redirectError(moduleOutputPath.resolve(
"iLeapp_paths_error.txt").toFile());  
 
  319         processBuilder.redirectOutput(moduleOutputPath.resolve(
"iLeapp_paths.txt").toFile());  
 
  320         return processBuilder;
 
  324         ProcessBuilder processBuilder = 
new ProcessBuilder(commandLine);
 
  329         processBuilder.environment().put(
"__COMPAT_LAYER", 
"RunAsInvoker"); 
 
  330         return processBuilder;
 
  334         String executableToFindName = Paths.get(ILEAPP, executableName).toString();
 
  336         File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, 
ILeappAnalyzerIngestModule.class.getPackage().getName(), 
false);
 
  337         if (null == exeFile || exeFile.canExecute() == 
false) {
 
  338             throw new FileNotFoundException(executableName + 
" executable not found.");
 
  348         List<String> allIndexFiles;
 
  350         try (Stream<Path> walk = Files.walk(iLeappOutputDir)) {
 
  352             allIndexFiles = walk.map(x -> x.toString())
 
  353                     .filter(f -> f.toLowerCase().endsWith(
"index.html")).collect(Collectors.toList());
 
  355             if (!allIndexFiles.isEmpty()) {
 
  357                 String filePath = FilenameUtils.getFullPathNoEndSeparator(allIndexFiles.get(0));
 
  358                 File dataFilesDir = 
new File(Paths.get(filePath, 
"_TSV Exports").toString());
 
  359                 if (dataFilesDir.exists()) {
 
  360                     currentCase.
addReport(allIndexFiles.get(0), 
MODULE_NAME, Bundle.ILeappAnalyzerIngestModule_report_name());
 
  366             logger.log(Level.WARNING, String.format(
"Error finding index file in path %s", iLeappOutputDir.toString()), ex);
 
  376     private List<String> 
loadIleappPathFile(Path moduleOutputPath) 
throws FileNotFoundException, IOException {
 
  377         List<String> iLeappPathsToProcess = 
new ArrayList<>();
 
  381         try (BufferedReader reader = 
new BufferedReader(
new FileReader(filePath.toString()))) {
 
  382             String line = reader.readLine();
 
  383             while (line != null) {
 
  384                 if (line.contains(
"path list generation") || line.length() < 2) {
 
  385                     line = reader.readLine();
 
  388                 iLeappPathsToProcess.add(line.trim());
 
  389                 line = reader.readLine();
 
  393         return iLeappPathsToProcess;
 
  404         FileManager fileManager = getCurrentCase().getServices().getFileManager();
 
  406         for (String fullFilePath : iLeappPathsToProcess) {
 
  409                 logger.log(Level.INFO, 
"ILeapp Analyser ingest module run was canceled"); 
 
  413             String ffp = fullFilePath.replaceAll(
"\\*", 
"%");
 
  414             ffp = FilenameUtils.normalize(ffp, 
true);
 
  415             String fileName = FilenameUtils.getName(ffp);
 
  416             String filePath = FilenameUtils.getPath(ffp);
 
  418             List<AbstractFile> iLeappFiles;
 
  420                 if (filePath.isEmpty()) {
 
  421                     iLeappFiles = fileManager.
findFiles(dataSource, fileName); 
 
  423                     iLeappFiles = fileManager.
findFiles(dataSource, fileName, filePath); 
 
  426                 logger.log(Level.WARNING, 
"No files found to process"); 
 
  431                 Path parentPath = Paths.get(moduleOutputPath.toString(), iLeappFile.getParentPath());
 
  432                 File fileParentPath = 
new File(parentPath.toString());
 
  448         if (fileParentPath.exists()) {
 
  449             if (!iLeappFile.
isDir()) {
 
  453                     Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.
getName()));
 
  454                 } 
catch (IOException ex) {
 
  455                     logger.log(Level.INFO, String.format(
"Error creating iLeapp output directory %s", parentPath.toString()), ex);
 
  460                 Files.createDirectories(parentPath);
 
  461             } 
catch (IOException ex) {
 
  462                 logger.log(Level.INFO, String.format(
"Error creating iLeapp output directory %s", parentPath.toString()), ex);
 
  464             if (!iLeappFile.
isDir()) {
 
  468                     Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.
getName()));
 
  469                 } 
catch (IOException ex) {
 
  470                     logger.log(Level.INFO, String.format(
"Error creating iLeapp output directory %s", parentPath.toString()), ex);
 
  484         String fileName = iLeappFile.
getName().replace(
":", 
"-");
 
  485         if (!fileName.matches(
".") && !fileName.matches(
"..") && !fileName.toLowerCase().endsWith(
"-slack")) {
 
  486             Path filePath = Paths.get(parentPath, fileName);
 
  487             File localFile = 
new File(filePath.toString());
 
  491                 logger.log(Level.WARNING, String.format(
"Error reading file '%s' (id=%d).",
 
  493             } 
catch (IOException ex) {
 
  494                 logger.log(Level.WARNING, String.format(
"Error writing file local file '%s' (id=%d).",
 
  495                         filePath.toString(), iLeappFile.
getId()), ex); 
 
  507                 Bundle.ILeappAnalyzerIngestModule_error_running_iLeapp());
 
ProcessBuilder buildiLeappListCommand(Path moduleOutputPath)
void processILeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess)
void writeErrorMsgToIngestInbox()
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)
String getNameExtension()
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
String toString(boolean preserveState)
static ProcessBuilder buildProcessWithRunAsInvoker(String...commandLine)
static final String ILEAPP_FS
ProcessBuilder buildiLeappCommand(Path moduleOutputPath, String sourceFilePath, String iLeappFileSystemType)
static final String XMLFILE
void switchToIndeterminate()
static final Logger logger
void extractFilesFromDataSource(Content dataSource, List< String > iLeappPathsToProcess, Path moduleOutputPath)
static File locateExecutable(String executableName)
void postMessage(final IngestMessage message)
String getModuleDirectory()
void addILeappReportToReports(Path iLeappOutputDir, Case currentCase)
boolean dataSourceIngestIsCancelled()
ProcessResult processFileSystem(Content dataSource, Path moduleOutputPath, DataSourceIngestModuleProgress progress)
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)
ProcessResult processFiles(Content dataSource, Path moduleOutputPath, AbstractFile LeappFile, DataSourceIngestModuleProgress progress)
static synchronized IngestServices getInstance()