diff --git a/Core/build.xml b/Core/build.xml index c698835266..73bda54795 100644 --- a/Core/build.xml +++ b/Core/build.xml @@ -54,6 +54,11 @@ + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/Bundle.properties deleted file mode 100644 index 15698d736c..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/Bundle.properties +++ /dev/null @@ -1,4 +0,0 @@ -ILeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. -ILeappAnalyzerIngestModule.processing.file=Processing file {0} -ILeappAnalyzerIngestModule.parsing.file=Parsing file {0} -ILeappAnalyzerIngestModule.processing.filesystem=Processing filesystem \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/Bundle.properties-MERGED deleted file mode 100644 index b4e8226a91..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/Bundle.properties-MERGED +++ /dev/null @@ -1,30 +0,0 @@ -ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed -ILeappAnalyzerIngestModule.error.creating.output.dir=Error creating iLeapp module output directory. -ILeappAnalyzerIngestModule.error.ileapp.file.processor.init=Failure to initialize ILeappProcessFile -ILeappAnalyzerIngestModule.error.running.iLeapp=Error running iLeapp, see log file. -ILeappAnalyzerIngestModule.executable.not.found=iLeapp Executable Not Found. -ILeappAnalyzerIngestModule.has.run=iLeapp -ILeappAnalyzerIngestModule.iLeapp.cancelled=iLeapp run was canceled -ILeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. -ILeappAnalyzerIngestModule.processing.file=Processing file {0} -ILeappAnalyzerIngestModule.parsing.file=Parsing file {0} -ILeappAnalyzerIngestModule.processing.filesystem=Processing filesystem -ILeappAnalyzerIngestModule.report.name=iLeapp Html Report -ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows. -ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp -ILeappAnalyzerIngestModule.starting.iLeapp=Starting iLeapp -ILeappAnalyzerModuleFactory_moduleDesc=Uses iLEAPP to analyze logical acquisitions of iOS devices. -ILeappAnalyzerModuleFactory_moduleName=iOS Analyzer (iLEAPP) -ILeappFileProcessor.cannot.load.artifact.xml=Cannor load xml artifact file. -ILeappFileProcessor.cannotBuildXmlParser=Cannot buld an XML parser. -ILeappFileProcessor.completed=iLeapp Processing Completed -ILeappFileProcessor.error.creating.new.artifacts=Error creating new artifacts. -ILeappFileProcessor.error.creating.output.dir=Error creating iLeapp module output directory. -ILeappFileProcessor.error.reading.iLeapp.directory=Error reading iLeapp Output Directory -ILeappFileProcessor.error.running.iLeapp=Error running iLeapp, see log file. -ILeappFileProcessor.has.run=iLeapp -ILeappFileProcessor.iLeapp.cancelled=iLeapp run was canceled -ILeappFileProcessor.postartifacts_error=Error posting Blackboard Artifact -ILeappFileProcessor.running.iLeapp=Running iLeapp -ILeappFileProcessor.starting.iLeapp=Starting iLeapp -ILeappFileProcessor_cannotParseXml=Cannot Parse XML file. diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java new file mode 100644 index 0000000000..e82215a7de --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java @@ -0,0 +1,492 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.modules.leappanalyzers; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.ArrayList; +import java.util.Locale; +import java.util.logging.Level; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.commons.io.FilenameUtils; +import org.openide.modules.InstalledFileLocator; +import org.openide.util.NbBundle; +import org.sleuthkit.autopsy.casemodule.Case; +import static org.sleuthkit.autopsy.casemodule.Case.getCurrentCase; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.casemodule.services.FileManager; +import org.sleuthkit.autopsy.coreutils.ExecUtil; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.PlatformUtil; +import org.sleuthkit.autopsy.datamodel.ContentUtils; +import org.sleuthkit.autopsy.ingest.DataSourceIngestModule; +import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator; +import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; +import org.sleuthkit.autopsy.ingest.IngestJobContext; +import org.sleuthkit.autopsy.ingest.IngestMessage; +import org.sleuthkit.autopsy.ingest.IngestServices; +import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.LocalFilesDataSource; +import org.sleuthkit.datamodel.ReadContentInputStream; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Data source ingest module that runs aLeapp against logical iOS files. + */ +public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { + + private static final Logger logger = Logger.getLogger(ALeappAnalyzerIngestModule.class.getName()); + private static final String MODULE_NAME = ALeappAnalyzerModuleFactory.getModuleName(); + + private static final String ALEAPP = "aLeapp"; //NON-NLS + private static final String ALEAPP_FS = "fs_"; //NON-NLS + private static final String ALEAPP_EXECUTABLE = "aleapp.exe";//NON-NLS + private static final String ALEAPP_PATHS_FILE = "aLeapp_paths.txt"; //NON-NLS + + private static final String XMLFILE = "aleap-artifact-attribute-reference.xml"; //NON-NLS + + + private File aLeappExecutable; + + private IngestJobContext context; + + private LeappFileProcessor aLeappFileProcessor; + + ALeappAnalyzerIngestModule() { + // This constructor is intentionally empty. Nothing special is needed here. + } + + @NbBundle.Messages({ + "ALeappAnalyzerIngestModule.executable.not.found=aLeapp Executable Not Found.", + "ALeappAnalyzerIngestModule.requires.windows=aLeapp module requires windows.", + "ALeappAnalyzerIngestModule.error.ileapp.file.processor.init=Failure to initialize aLeappProcessFile"}) + @Override + public void startUp(IngestJobContext context) throws IngestModuleException { + this.context = context; + + if (false == PlatformUtil.isWindowsOS()) { + throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_requires_windows()); + } + + try { + aLeappFileProcessor = new LeappFileProcessor(XMLFILE); + } catch (IOException | IngestModuleException | NoCurrentCaseException ex) { + throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex); + } + + try { + aLeappExecutable = locateExecutable(ALEAPP_EXECUTABLE); + } catch (FileNotFoundException exception) { + logger.log(Level.WARNING, "aLeapp executable not found.", exception); //NON-NLS + throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_executable_not_found(), exception); + } + + } + + @NbBundle.Messages({ + "ALeappAnalyzerIngestModule.error.running.aLeapp=Error running aLeapp, see log file.", + "ALeappAnalyzerIngestModule.error.creating.output.dir=Error creating aLeapp module output directory.", + "ALeappAnalyzerIngestModule.starting.aLeapp=Starting aLeapp", + "ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp", + "ALeappAnalyzerIngestModule.has.run=aLeapp", + "ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp run was canceled", + "ALeappAnalyzerIngestModule.completed=aLeapp Processing Completed", + "ALeappAnalyzerIngestModule.report.name=aLeapp Html Report"}) + @Override + public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) { + + Case currentCase = Case.getCurrentCase(); + Path tempOutputPath = Paths.get(currentCase.getTempDirectory(), ALEAPP, ALEAPP_FS + dataSource.getId()); + try { + Files.createDirectories(tempOutputPath); + } catch (IOException ex) { + logger.log(Level.SEVERE, String.format("Error creating aLeapp output directory %s", tempOutputPath.toString()), ex); + return ProcessResult.ERROR; + } + + List aLeappPathsToProcess = new ArrayList<>(); + ProcessBuilder aLeappCommand = buildaLeappListCommand(tempOutputPath); + try { + int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); + if (result != 0) { + logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search for result is %d", result)); + return ProcessResult.ERROR; + } + aLeappPathsToProcess = loadIleappPathFile(tempOutputPath); + } catch (IOException ex) { + logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search"), ex); + return ProcessResult.ERROR; + } + + statusHelper.progress(Bundle.ALeappAnalyzerIngestModule_starting_aLeapp(), 0); + + List aLeappFilesToProcess = new ArrayList<>(); + + if (!(context.getDataSource() instanceof LocalFilesDataSource)) { + extractFilesFromImage(dataSource, aLeappPathsToProcess, tempOutputPath); + statusHelper.switchToDeterminate(aLeappFilesToProcess.size()); + processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); + } else { + aLeappFilesToProcess = findaLeappFilesToProcess(dataSource); + statusHelper.switchToDeterminate(aLeappFilesToProcess.size()); + + Integer filesProcessedCount = 0; + for (AbstractFile aLeappFile : aLeappFilesToProcess) { + processALeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, aLeappFile); + filesProcessedCount++; + } + // Process the logical image as a fs in aLeapp to make sure this is not a logical fs that was added + extractFilesFromImage(dataSource, aLeappPathsToProcess, tempOutputPath); + processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); + } + + IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.DATA, + Bundle.ALeappAnalyzerIngestModule_has_run(), + Bundle.ALeappAnalyzerIngestModule_completed()); + IngestServices.getInstance().postMessage(message); + return ProcessResult.OK; + } + + /** + * Process a file from a logical image using the aLeapp program + * @param dataSource datasource to process + * @param currentCase current case that is being worked on + * @param statusHelper show progress and update what is being processed + * @param filesProcessedCount number of files that have been processed + * @param aLeappFile the abstract file to process + */ + private void processALeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount, + AbstractFile aLeappFile) { + String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS + Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime); + try { + Files.createDirectories(moduleOutputPath); + } catch (IOException ex) { + logger.log(Level.SEVERE, String.format("Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex); + return; + } + + statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.file", aLeappFile.getName()), filesProcessedCount); + ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, aLeappFile.getLocalAbsPath(), aLeappFile.getNameExtension()); + try { + int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); + if (result != 0) { + logger.log(Level.WARNING, String.format("Error when trying to execute aLeapp program getting file paths to search for result is %d", result)); + return; + } + + addILeappReportToReports(moduleOutputPath, currentCase); + + } catch (IOException ex) { + logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program against file %s", aLeappFile.getLocalAbsPath()), ex); + return; + } + + if (context.dataSourceIngestIsCancelled()) { + logger.log(Level.INFO, "ILeapp Analyser ingest module run was canceled"); //NON-NLS + return; + } + + ProcessResult fileProcessorResult = aLeappFileProcessor.processFiles(dataSource, moduleOutputPath, aLeappFile); + + if (fileProcessorResult == ProcessResult.ERROR) { + return; + } + } + + /** + * Process a image/directory using the aLeapp program + * @param dataSource datasource to process + * @param currentCase current case being procesed + * @param statusHelper show progress and update what is being processed + * @param directoryToProcess directory to run aLeapp against + */ + private void processALeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess) { + String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS + Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime); + try { + Files.createDirectories(moduleOutputPath); + } catch (IOException ex) { + logger.log(Level.SEVERE, String.format("Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex); + return; + } + + statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.filesystem")); + ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, directoryToProcess, "fs"); + try { + int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); + if (result != 0) { + logger.log(Level.WARNING, String.format("Error when trying to execute aLeapp program getting file paths to search for result is %d", result)); + return; + } + + addILeappReportToReports(moduleOutputPath, currentCase); + + } catch (IOException ex) { + logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program against file system"), ex); + return; + } + + if (context.dataSourceIngestIsCancelled()) { + logger.log(Level.INFO, "ILeapp Analyser ingest module run was canceled"); //NON-NLS + return; + } + + ProcessResult fileProcessorResult = aLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath); + + if (fileProcessorResult == ProcessResult.ERROR) { + return; + } + + } + + /** + * Find the files that will be processed by the aLeapp program + * + * @param dataSource + * + * @return List of abstract files to process. + */ + private List findaLeappFilesToProcess(Content dataSource) { + + List aLeappFiles = new ArrayList<>(); + + FileManager fileManager = getCurrentCase().getServices().getFileManager(); + + // findFiles use the SQL wildcard % in the file name + try { + aLeappFiles = fileManager.findFiles(dataSource, "%", "/"); //NON-NLS + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "No files found to process"); //NON-NLS + return aLeappFiles; + } + + List aLeappFilesToProcess = new ArrayList<>(); + for (AbstractFile aLeappFile : aLeappFiles) { + if (((aLeappFile.getLocalAbsPath() != null) + && (!aLeappFile.getNameExtension().isEmpty() && (!aLeappFile.isVirtual()))) + && ((aLeappFile.getName().toLowerCase().contains(".zip") || (aLeappFile.getName().toLowerCase().contains(".tar"))) + || aLeappFile.getName().toLowerCase().contains(".tgz"))) { + aLeappFilesToProcess.add(aLeappFile); + + } + } + + return aLeappFilesToProcess; + } + + /** + * Build the aLeapp command to run + * + * @param moduleOutputPath output path for the aLeapp program. + * @param sourceFilePath where the source files to process reside. + * @param aLeappFileSystemType the filesystem type to process + * + * @return the command to execute + */ + private ProcessBuilder buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType) { + + ProcessBuilder processBuilder = buildProcessWithRunAsInvoker( + "\"" + aLeappExecutable + "\"", //NON-NLS + "-t", aLeappFileSystemType, //NON-NLS + "-i", sourceFilePath, //NON-NLS + "-o", moduleOutputPath.toString() + ); + processBuilder.redirectError(moduleOutputPath.resolve("aLeapp_err.txt").toFile()); //NON-NLS + processBuilder.redirectOutput(moduleOutputPath.resolve("aLeapp_out.txt").toFile()); //NON-NLS + return processBuilder; + } + + private ProcessBuilder buildaLeappListCommand(Path moduleOutputPath) { + + ProcessBuilder processBuilder = buildProcessWithRunAsInvoker( + "\"" + aLeappExecutable + "\"", //NON-NLS + "-p" + ); + processBuilder.redirectError(moduleOutputPath.resolve("aLeapp_paths_error.txt").toFile()); //NON-NLS + processBuilder.redirectOutput(moduleOutputPath.resolve("aLeapp_paths.txt").toFile()); //NON-NLS + return processBuilder; + } + + static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) { + ProcessBuilder processBuilder = new ProcessBuilder(commandLine); + /* + * Add an environment variable to force aLeapp to run with + * the same permissions Autopsy uses. + */ + processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS + return processBuilder; + } + + private static File locateExecutable(String executableName) throws FileNotFoundException { + String executableToFindName = Paths.get(ALEAPP, executableName).toString(); + + File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, ALeappAnalyzerIngestModule.class.getPackage().getName(), false); + if (null == exeFile || exeFile.canExecute() == false) { + throw new FileNotFoundException(executableName + " executable not found."); + } + return exeFile; + } + + /** + * Find the index.html file in the aLeapp output directory so it can be + * added to reports + */ + private void addILeappReportToReports(Path aLeappOutputDir, Case currentCase) { + List allIndexFiles = new ArrayList<>(); + + try (Stream walk = Files.walk(aLeappOutputDir)) { + + allIndexFiles = walk.map(x -> x.toString()) + .filter(f -> f.toLowerCase().endsWith("index.html")).collect(Collectors.toList()); + + if (!allIndexFiles.isEmpty()) { + // Check for existance of directory that holds report data if does not exist then report contains no data + String filePath = FilenameUtils.getFullPathNoEndSeparator(allIndexFiles.get(0)); + File dataFilesDir = new File(Paths.get(filePath, "_TSV Exports").toString()); + if (dataFilesDir.exists()) { + currentCase.addReport(allIndexFiles.get(0), MODULE_NAME, Bundle.ALeappAnalyzerIngestModule_report_name()); + } + } + + } catch (IOException | UncheckedIOException | TskCoreException ex) { + // catch the error and continue on as report is not added + logger.log(Level.WARNING, String.format("Error finding index file in path %s", aLeappOutputDir.toString()), ex); + } + + } + + /* + * Reads the aLeapp paths file to get the paths that we want to extract + * + */ + private List loadIleappPathFile(Path moduleOutputPath) throws FileNotFoundException, IOException { + List aLeappPathsToProcess = new ArrayList<>(); + + Path filePath = Paths.get(moduleOutputPath.toString(), ALEAPP_PATHS_FILE); + + try (BufferedReader reader = new BufferedReader(new FileReader(filePath.toString()))) { + String line = reader.readLine(); + while (line != null) { + if (line.contains("path list generation") || line.length() < 2) { + line = reader.readLine(); + continue; + } + aLeappPathsToProcess.add(line.trim()); + line = reader.readLine(); + } + } + + return aLeappPathsToProcess; + } + + private void extractFilesFromImage(Content dataSource, List aLeappPathsToProcess, Path moduleOutputPath) { + FileManager fileManager = getCurrentCase().getServices().getFileManager(); + + for (String fullFilePath : aLeappPathsToProcess) { + + if (context.dataSourceIngestIsCancelled()) { + logger.log(Level.INFO, "aLeapp Analyser ingest module run was canceled"); //NON-NLS + break; + } + + String ffp = fullFilePath.replaceAll("\\*", "%"); + ffp = FilenameUtils.normalize(ffp, true); + String fileName = FilenameUtils.getName(ffp); + String filePath = FilenameUtils.getPath(ffp); + + List aLeappFiles = new ArrayList<>(); + try { + if (filePath.isEmpty()) { + aLeappFiles = fileManager.findFiles(dataSource, fileName); //NON-NLS + } else { + aLeappFiles = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS + } + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "No files found to process"); //NON-NLS + return; + } + + for (AbstractFile aLeappFile : aLeappFiles) { + Path parentPath = Paths.get(moduleOutputPath.toString(), aLeappFile.getParentPath()); + File fileParentPath = new File(parentPath.toString()); + + extractFileToOutput(dataSource, aLeappFile, fileParentPath, parentPath); + } + } + } + + private void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath) { + if (fileParentPath.exists()) { + if (!aLeappFile.isDir()) { + writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString()); + } else { + try { + Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName())); + } catch (IOException ex) { + logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); + } + } + } else { + try { + Files.createDirectories(parentPath); + } catch (IOException ex) { + logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); + } + if (!aLeappFile.isDir()) { + writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString()); + } else { + try { + Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName())); + } catch (IOException ex) { + logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); + } + } + } + } + + private void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath) { + String fileName = aLeappFile.getName().replace(":", "-"); + if (!fileName.matches(".") && !fileName.matches("..") && !fileName.toLowerCase().endsWith("-slack")) { + Path filePath = Paths.get(parentPath, fileName); + File localFile = new File(filePath.toString()); + try { + ContentUtils.writeToFile(aLeappFile, localFile, context::dataSourceIngestIsCancelled); + } catch (ReadContentInputStream.ReadContentInputStreamException ex) { + logger.log(Level.WARNING, String.format("Error reading file '%s' (id=%d).", + aLeappFile.getName(), aLeappFile.getId()), ex); //NON-NLS + } catch (IOException ex) { + logger.log(Level.WARNING, String.format("Error writing file local file '%s' (id=%d).", + filePath.toString(), aLeappFile.getId()), ex); //NON-NLS + } + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerModuleFactory.java new file mode 100644 index 0000000000..2e4066d874 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerModuleFactory.java @@ -0,0 +1,67 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.modules.leappanalyzers; + +import org.openide.util.NbBundle; +import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.coreutils.Version; +import org.sleuthkit.autopsy.ingest.DataSourceIngestModule; +import org.sleuthkit.autopsy.ingest.IngestModuleFactory; +import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter; +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; + +/** + * A factory that creates data source ingest modules that will run aLeapp + * against logical files and saves the output to module output. + */ +@ServiceProvider(service = IngestModuleFactory.class) +public class ALeappAnalyzerModuleFactory extends IngestModuleFactoryAdapter { + + @NbBundle.Messages({"ALeappAnalyzerModuleFactory_moduleName=Android Analyzer (aLEAPP)"}) + static String getModuleName() { + return Bundle.ALeappAnalyzerModuleFactory_moduleName(); + } + + @Override + public String getModuleDisplayName() { + return getModuleName(); + } + + @NbBundle.Messages({"ALeappAnalyzerModuleFactory_moduleDesc=Uses aLEAPP to analyze logical acquisitions of Android devices."}) + @Override + public String getModuleDescription() { + return Bundle.ALeappAnalyzerModuleFactory_moduleDesc(); + } + + @Override + public String getModuleVersionNumber() { + return Version.getVersion(); + } + + @Override + public boolean isDataSourceIngestModuleFactory() { + return true; + } + + @Override + public DataSourceIngestModule createDataSourceIngestModule(IngestModuleIngestJobSettings ingestJobOptions) { + return new ALeappAnalyzerIngestModule(); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties new file mode 100644 index 0000000000..4236fad631 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties @@ -0,0 +1,8 @@ +ILeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. +ILeappAnalyzerIngestModule.processing.file=Processing file {0} +ILeappAnalyzerIngestModule.parsing.file=Parsing file {0} +ILeappAnalyzerIngestModule.processing.filesystem=Processing filesystem +ALeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. +ALeappAnalyzerIngestModule.processing.file=Processing file {0} +ALeappAnalyzerIngestModule.parsing.file=Parsing file {0} +ALeappAnalyzerIngestModule.processing.filesystem=Processing filesystem \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED new file mode 100644 index 0000000000..b23a428107 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED @@ -0,0 +1,47 @@ +ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp run was canceled +ALeappAnalyzerIngestModule.completed=aLeapp Processing Completed +ALeappAnalyzerIngestModule.error.creating.output.dir=Error creating aLeapp module output directory. +ALeappAnalyzerIngestModule.error.ileapp.file.processor.init=Failure to initialize aLeappProcessFile +ALeappAnalyzerIngestModule.error.running.aLeapp=Error running aLeapp, see log file. +ALeappAnalyzerIngestModule.executable.not.found=aLeapp Executable Not Found. +ALeappAnalyzerIngestModule.has.run=aLeapp +ALeappAnalyzerIngestModule.report.name=aLeapp Html Report +ALeappAnalyzerIngestModule.requires.windows=aLeapp module requires windows. +ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp +ALeappAnalyzerIngestModule.starting.aLeapp=Starting aLeapp +ALeappAnalyzerModuleFactory_moduleDesc=Uses aLEAPP to analyze logical acquisitions of Android devices. +ALeappAnalyzerModuleFactory_moduleName=Android Analyzer (aLEAPP) +ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed +ILeappAnalyzerIngestModule.error.creating.output.dir=Error creating iLeapp module output directory. +ILeappAnalyzerIngestModule.error.ileapp.file.processor.init=Failure to initialize ILeappProcessFile +ILeappAnalyzerIngestModule.error.running.iLeapp=Error running iLeapp, see log file. +ILeappAnalyzerIngestModule.executable.not.found=iLeapp Executable Not Found. +ILeappAnalyzerIngestModule.has.run=iLeapp +ILeappAnalyzerIngestModule.iLeapp.cancelled=iLeapp run was canceled +ILeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. +ILeappAnalyzerIngestModule.processing.file=Processing file {0} +ILeappAnalyzerIngestModule.parsing.file=Parsing file {0} +ILeappAnalyzerIngestModule.processing.filesystem=Processing filesystem +ALeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. +ALeappAnalyzerIngestModule.processing.file=Processing file {0} +ALeappAnalyzerIngestModule.parsing.file=Parsing file {0} +ALeappAnalyzerIngestModule.processing.filesystem=Processing filesystem +ILeappAnalyzerIngestModule.report.name=iLeapp Html Report +ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows. +ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp +ILeappAnalyzerIngestModule.starting.iLeapp=Starting iLeapp +ILeappAnalyzerModuleFactory_moduleDesc=Uses iLEAPP to analyze logical acquisitions of iOS devices. +ILeappAnalyzerModuleFactory_moduleName=iOS Analyzer (iLEAPP) +LeappFileProcessor.cannot.load.artifact.xml=Cannor load xml artifact file. +LeappFileProcessor.cannotBuildXmlParser=Cannot buld an XML parser. +LeappFileProcessor.completed=Leapp Processing Completed +LeappFileProcessor.error.creating.new.artifacts=Error creating new artifacts. +LeappFileProcessor.error.creating.output.dir=Error creating Leapp module output directory. +LeappFileProcessor.error.reading.Leapp.directory=Error reading Leapp Output Directory +LeappFileProcessor.error.running.Leapp=Error running Leapp, see log file. +LeappFileProcessor.has.run=Leapp +LeappFileProcessor.Leapp.cancelled=Leapp run was canceled +LeappFileProcessor.postartifacts_error=Error posting Blackboard Artifact +LeappFileProcessor.running.Leapp=Running Leapp +LeappFileProcessor.starting.Leapp=Starting Leapp +LeappFileProcessor_cannotParseXml=Cannot Parse XML file. diff --git a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ILeappAnalyzerIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java similarity index 98% rename from Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ILeappAnalyzerIngestModule.java rename to Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java index abec90e6c0..e583064978 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ILeappAnalyzerIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.modules.ileappanalyzer; +package org.sleuthkit.autopsy.modules.leappanalyzers; import java.io.BufferedReader; import java.io.File; @@ -71,11 +71,14 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { private static final String ILEAPP_EXECUTABLE = "ileapp.exe";//NON-NLS private static final String ILEAPP_PATHS_FILE = "iLeapp_paths.txt"; //NON-NLS + private static final String XMLFILE = "ileap-artifact-attribute-reference.xml"; //NON-NLS + + private File iLeappExecutable; private IngestJobContext context; - private ILeappFileProcessor iLeappFileProcessor; + private LeappFileProcessor iLeappFileProcessor; ILeappAnalyzerIngestModule() { // This constructor is intentionally empty. Nothing special is needed here. @@ -94,7 +97,7 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { } try { - iLeappFileProcessor = new ILeappFileProcessor(); + iLeappFileProcessor = new LeappFileProcessor(XMLFILE); } catch (IOException | IngestModuleException | NoCurrentCaseException ex) { throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_error_ileapp_file_processor_init(), ex); } diff --git a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ILeappAnalyzerModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerModuleFactory.java similarity index 97% rename from Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ILeappAnalyzerModuleFactory.java rename to Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerModuleFactory.java index 166c455d55..167afee3a0 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ILeappAnalyzerModuleFactory.java +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerModuleFactory.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.modules.ileappanalyzer; +package org.sleuthkit.autopsy.modules.leappanalyzers; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; diff --git a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ILeappFileProcessor.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java similarity index 79% rename from Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ILeappFileProcessor.java rename to Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java index 058b0aa28d..93e99edba3 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ILeappFileProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.modules.ileappanalyzer; +package org.sleuthkit.autopsy.modules.leappanalyzers; import java.io.BufferedReader; import java.io.File; @@ -63,14 +63,14 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** - * Find and process output from iLeapp program and bring into Autopsy + * Find and process output from Leapp program and bring into Autopsy */ -public final class ILeappFileProcessor { +public final class LeappFileProcessor { - private static final Logger logger = Logger.getLogger(ILeappFileProcessor.class.getName()); + private static final Logger logger = Logger.getLogger(LeappFileProcessor.class.getName()); private static final String MODULE_NAME = ILeappAnalyzerModuleFactory.getModuleName(); - private static final String XMLFILE = "ileap-artifact-attribute-reference.xml"; //NON-NLS + private final String xmlFile; //NON-NLS private final Map tsvFiles; private final Map tsvFileArtifacts; @@ -79,11 +79,12 @@ public final class ILeappFileProcessor { Blackboard blkBoard; - public ILeappFileProcessor() throws IOException, IngestModuleException, NoCurrentCaseException { + public LeappFileProcessor(String xmlFile) throws IOException, IngestModuleException, NoCurrentCaseException { this.tsvFiles = new HashMap<>(); this.tsvFileArtifacts = new HashMap<>(); this.tsvFileArtifactComments = new HashMap<>(); this.tsvFileAttributes = new HashMap<>(); + this.xmlFile = xmlFile; blkBoard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard(); @@ -93,22 +94,22 @@ public final class ILeappFileProcessor { } @NbBundle.Messages({ - "ILeappFileProcessor.error.running.iLeapp=Error running iLeapp, see log file.", - "ILeappFileProcessor.error.creating.output.dir=Error creating iLeapp module output directory.", - "ILeappFileProcessor.starting.iLeapp=Starting iLeapp", - "ILeappFileProcessor.running.iLeapp=Running iLeapp", - "ILeappFileProcessor.has.run=iLeapp", - "ILeappFileProcessor.iLeapp.cancelled=iLeapp run was canceled", - "ILeappFileProcessor.completed=iLeapp Processing Completed", - "ILeappFileProcessor.error.reading.iLeapp.directory=Error reading iLeapp Output Directory"}) + "LeappFileProcessor.error.running.Leapp=Error running Leapp, see log file.", + "LeappFileProcessor.error.creating.output.dir=Error creating Leapp module output directory.", + "LeappFileProcessor.starting.Leapp=Starting Leapp", + "LeappFileProcessor.running.Leapp=Running Leapp", + "LeappFileProcessor.has.run=Leapp", + "LeappFileProcessor.Leapp.cancelled=Leapp run was canceled", + "LeappFileProcessor.completed=Leapp Processing Completed", + "LeappFileProcessor.error.reading.Leapp.directory=Error reading Leapp Output Directory"}) - public ProcessResult processFiles(Content dataSource, Path moduleOutputPath, AbstractFile iLeappFile) { + public ProcessResult processFiles(Content dataSource, Path moduleOutputPath, AbstractFile LeappFile) { try { - List iLeappTsvOutputFiles = findTsvFiles(moduleOutputPath); - processiLeappFiles(iLeappTsvOutputFiles, iLeappFile); + List LeappTsvOutputFiles = findTsvFiles(moduleOutputPath); + processLeappFiles(LeappTsvOutputFiles, LeappFile); } catch (IOException | IngestModuleException ex) { - logger.log(Level.SEVERE, String.format("Error trying to process iLeapp output files in directory %s. ", moduleOutputPath.toString()), ex); //NON-NLS + logger.log(Level.SEVERE, String.format("Error trying to process Leapp output files in directory %s. ", moduleOutputPath.toString()), ex); //NON-NLS return ProcessResult.ERROR; } @@ -118,10 +119,10 @@ public final class ILeappFileProcessor { public ProcessResult processFileSystem(Content dataSource, Path moduleOutputPath) { try { - List iLeappTsvOutputFiles = findTsvFiles(moduleOutputPath); - processiLeappFiles(iLeappTsvOutputFiles, dataSource); + List LeappTsvOutputFiles = findTsvFiles(moduleOutputPath); + processLeappFiles(LeappTsvOutputFiles, dataSource); } catch (IOException | IngestModuleException ex) { - logger.log(Level.SEVERE, String.format("Error trying to process iLeapp output files in directory %s. ", moduleOutputPath.toString()), ex); //NON-NLS + logger.log(Level.SEVERE, String.format("Error trying to process Leapp output files in directory %s. ", moduleOutputPath.toString()), ex); //NON-NLS return ProcessResult.ERROR; } @@ -129,14 +130,14 @@ public final class ILeappFileProcessor { } /** - * Find the tsv files in the iLeapp output directory and match them to files + * Find the tsv files in the Leapp output directory and match them to files * we know we want to process and return the list to process those files. */ - private List findTsvFiles(Path iLeappOutputDir) throws IngestModuleException { + private List findTsvFiles(Path LeappOutputDir) throws IngestModuleException { List allTsvFiles = new ArrayList<>(); List foundTsvFiles = new ArrayList<>(); - try (Stream walk = Files.walk(iLeappOutputDir)) { + try (Stream walk = Files.walk(LeappOutputDir)) { allTsvFiles = walk.map(x -> x.toString()) .filter(f -> f.toLowerCase().endsWith(".tsv")).collect(Collectors.toList()); @@ -148,7 +149,7 @@ public final class ILeappFileProcessor { } } catch (IOException | UncheckedIOException e) { - throw new IngestModuleException(Bundle.ILeappFileProcessor_error_reading_iLeapp_directory() + iLeappOutputDir.toString(), e); + throw new IngestModuleException(Bundle.LeappFileProcessor_error_reading_Leapp_directory() + LeappOutputDir.toString(), e); } return foundTsvFiles; @@ -156,26 +157,26 @@ public final class ILeappFileProcessor { } /** - * Process the iLeapp files that were found that match the xml mapping file + * Process the Leapp files that were found that match the xml mapping file * - * @param iLeappFilesToProcess List of files to process - * @param iLeappImageFile Abstract file to create artifact for + * @param LeappFilesToProcess List of files to process + * @param LeappImageFile Abstract file to create artifact for * * @throws FileNotFoundException * @throws IOException */ - private void processiLeappFiles(List iLeappFilesToProcess, AbstractFile iLeappImageFile) throws FileNotFoundException, IOException, IngestModuleException { + private void processLeappFiles(List LeappFilesToProcess, AbstractFile LeappImageFile) throws FileNotFoundException, IOException, IngestModuleException { List bbartifacts = new ArrayList<>(); - for (String iLeappFileName : iLeappFilesToProcess) { - String fileName = FilenameUtils.getName(iLeappFileName); - File iLeappFile = new File(iLeappFileName); + for (String LeappFileName : LeappFilesToProcess) { + String fileName = FilenameUtils.getName(LeappFileName); + File LeappFile = new File(LeappFileName); if (tsvFileAttributes.containsKey(fileName)) { List> attrList = tsvFileAttributes.get(fileName); try { BlackboardArtifact.Type artifactType = Case.getCurrentCase().getSleuthkitCase().getArtifactType(tsvFileArtifacts.get(fileName)); - processFile(iLeappFile, attrList, fileName, artifactType, bbartifacts, iLeappImageFile); + processFile(LeappFile, attrList, fileName, artifactType, bbartifacts, LeappImageFile); } catch (TskCoreException ex) { throw new IngestModuleException(String.format("Error getting Blackboard Artifact Type for %s", tsvFileArtifacts.get(fileName)), ex); @@ -191,26 +192,26 @@ public final class ILeappFileProcessor { } /** - * Process the iLeapp files that were found that match the xml mapping file + * Process the Leapp files that were found that match the xml mapping file * - * @param iLeappFilesToProcess List of files to process - * @param iLeappImageFile Abstract file to create artifact for + * @param LeappFilesToProcess List of files to process + * @param LeappImageFile Abstract file to create artifact for * * @throws FileNotFoundException * @throws IOException */ - private void processiLeappFiles(List iLeappFilesToProcess, Content dataSource) throws FileNotFoundException, IOException, IngestModuleException { + private void processLeappFiles(List LeappFilesToProcess, Content dataSource) throws FileNotFoundException, IOException, IngestModuleException { List bbartifacts = new ArrayList<>(); - for (String iLeappFileName : iLeappFilesToProcess) { - String fileName = FilenameUtils.getName(iLeappFileName); - File iLeappFile = new File(iLeappFileName); + for (String LeappFileName : LeappFilesToProcess) { + String fileName = FilenameUtils.getName(LeappFileName); + File LeappFile = new File(LeappFileName); if (tsvFileAttributes.containsKey(fileName)) { List> attrList = tsvFileAttributes.get(fileName); try { BlackboardArtifact.Type artifactType = Case.getCurrentCase().getSleuthkitCase().getArtifactType(tsvFileArtifacts.get(fileName)); - processFile(iLeappFile, attrList, fileName, artifactType, bbartifacts, dataSource); + processFile(LeappFile, attrList, fileName, artifactType, bbartifacts, dataSource); } catch (TskCoreException ex) { throw new IngestModuleException(String.format("Error getting Blackboard Artifact Type for %s", tsvFileArtifacts.get(fileName)), ex); @@ -225,10 +226,10 @@ public final class ILeappFileProcessor { } - private void processFile(File iLeappFile, List> attrList, String fileName, BlackboardArtifact.Type artifactType, + private void processFile(File LeappFile, List> attrList, String fileName, BlackboardArtifact.Type artifactType, List bbartifacts, Content dataSource) throws FileNotFoundException, IOException, IngestModuleException, TskCoreException { - try (BufferedReader reader = new BufferedReader(new FileReader(iLeappFile))) { + try (BufferedReader reader = new BufferedReader(new FileReader(LeappFile))) { String line = reader.readLine(); // Check first line, if it is null then no heading so nothing to match to, close and go to next file. if (line != null) { @@ -236,6 +237,10 @@ public final class ILeappFileProcessor { line = reader.readLine(); while (line != null) { Collection bbattributes = processReadLine(line, columnNumberToProcess, fileName); + if (artifactType == null) { + logger.log(Level.SEVERE, "Error trying to process Leapp output files in directory . "); //NON-NLS + + } if (!bbattributes.isEmpty() && !blkBoard.artifactExists(dataSource, BlackboardArtifact.ARTIFACT_TYPE.fromID(artifactType.getTypeID()), bbattributes)) { BlackboardArtifact bbartifact = createArtifactWithAttributes(artifactType.getTypeID(), dataSource, bbattributes); if (bbartifact != null) { @@ -354,11 +359,11 @@ public final class ILeappFileProcessor { } @NbBundle.Messages({ - "ILeappFileProcessor.cannot.load.artifact.xml=Cannor load xml artifact file.", - "ILeappFileProcessor.cannotBuildXmlParser=Cannot buld an XML parser.", - "ILeappFileProcessor_cannotParseXml=Cannot Parse XML file.", - "ILeappFileProcessor.postartifacts_error=Error posting Blackboard Artifact", - "ILeappFileProcessor.error.creating.new.artifacts=Error creating new artifacts." + "LeappFileProcessor.cannot.load.artifact.xml=Cannor load xml artifact file.", + "LeappFileProcessor.cannotBuildXmlParser=Cannot buld an XML parser.", + "LeappFileProcessor_cannotParseXml=Cannot Parse XML file.", + "LeappFileProcessor.postartifacts_error=Error posting Blackboard Artifact", + "LeappFileProcessor.error.creating.new.artifacts=Error creating new artifacts." }) /** @@ -367,18 +372,18 @@ public final class ILeappFileProcessor { private void loadConfigFile() throws IngestModuleException { Document xmlinput; try { - String path = PlatformUtil.getUserConfigDirectory() + File.separator + XMLFILE; + String path = PlatformUtil.getUserConfigDirectory() + File.separator + xmlFile; File f = new File(path); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); xmlinput = db.parse(f); } catch (IOException e) { - throw new IngestModuleException(Bundle.ILeappFileProcessor_cannot_load_artifact_xml() + e.getLocalizedMessage(), e); //NON-NLS + throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_load_artifact_xml() + e.getLocalizedMessage(), e); //NON-NLS } catch (ParserConfigurationException pce) { - throw new IngestModuleException(Bundle.ILeappFileProcessor_cannotBuildXmlParser() + pce.getLocalizedMessage(), pce); //NON-NLS + throw new IngestModuleException(Bundle.LeappFileProcessor_cannotBuildXmlParser() + pce.getLocalizedMessage(), pce); //NON-NLS } catch (SAXException sxe) { - throw new IngestModuleException(Bundle.ILeappFileProcessor_cannotParseXml() + sxe.getLocalizedMessage(), sxe); //NON-NLS + throw new IngestModuleException(Bundle.LeappFileProcessor_cannotParseXml() + sxe.getLocalizedMessage(), sxe); //NON-NLS } getFileNode(xmlinput); @@ -466,7 +471,7 @@ public final class ILeappFileProcessor { bbart.addAttributes(bbattributes); return bbart; } catch (TskException ex) { - logger.log(Level.WARNING, Bundle.ILeappFileProcessor_error_creating_new_artifacts(), ex); //NON-NLS + logger.log(Level.WARNING, Bundle.LeappFileProcessor_error_creating_new_artifacts(), ex); //NON-NLS } return null; } @@ -490,7 +495,7 @@ public final class ILeappFileProcessor { bbart.addAttributes(bbattributes); return bbart; } catch (TskException ex) { - logger.log(Level.WARNING, Bundle.ILeappFileProcessor_error_creating_new_artifacts(), ex); //NON-NLS + logger.log(Level.WARNING, Bundle.LeappFileProcessor_error_creating_new_artifacts(), ex); //NON-NLS } return null; } @@ -509,17 +514,17 @@ public final class ILeappFileProcessor { try { Case.getCurrentCase().getSleuthkitCase().getBlackboard().postArtifacts(artifacts, MODULE_NAME); } catch (Blackboard.BlackboardException ex) { - logger.log(Level.SEVERE, Bundle.ILeappFileProcessor_postartifacts_error(), ex); //NON-NLS + logger.log(Level.SEVERE, Bundle.LeappFileProcessor_postartifacts_error(), ex); //NON-NLS } } /** - * Extract the iLeapp config xml file to the user directory to process + * Extract the Leapp config xml file to the user directory to process * * @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException */ private void configExtractor() throws IOException { - PlatformUtil.extractResourceToUserConfigDir(ILeappFileProcessor.class, XMLFILE, true); + PlatformUtil.extractResourceToUserConfigDir(LeappFileProcessor.class, xmlFile, true); } } diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/aleap-artifact-attribute-reference.xml b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/aleap-artifact-attribute-reference.xml new file mode 100644 index 0000000000..b11fbd3714 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/aleap-artifact-attribute-reference.xml @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ileap-artifact-attribute-reference.xml b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ileap-artifact-attribute-reference.xml similarity index 100% rename from Core/src/org/sleuthkit/autopsy/modules/ileappanalyzer/ileap-artifact-attribute-reference.xml rename to Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ileap-artifact-attribute-reference.xml diff --git a/thirdparty/aLeapp/LICENSE b/thirdparty/aLeapp/LICENSE new file mode 100644 index 0000000000..ae8fc549fc --- /dev/null +++ b/thirdparty/aLeapp/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Brigs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/thirdparty/aLeapp/aleapp.exe b/thirdparty/aLeapp/aleapp.exe new file mode 100644 index 0000000000..7ed46c4689 Binary files /dev/null and b/thirdparty/aLeapp/aleapp.exe differ