mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 10:17:41 +00:00
Added support for new command -runUI
This commit is contained in:
parent
708a4fa906
commit
2cad38f9c7
@ -24,6 +24,7 @@ import java.util.logging.Level;
|
||||
import org.netbeans.spi.sendopts.OptionProcessor;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.commandlineingest.CommandLineIngestManager;
|
||||
import org.sleuthkit.autopsy.commandlineingest.CommandLineOpenCaseManager;
|
||||
import org.sleuthkit.autopsy.commandlineingest.CommandLineOptionProcessor;
|
||||
import org.sleuthkit.autopsy.commandlineingest.CommandLineStartupWindow;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -58,6 +59,12 @@ public class StartupWindowProvider implements StartupWindowInterface {
|
||||
|
||||
private void init() {
|
||||
if (startupWindowToUse == null) {
|
||||
|
||||
if (openCaseInUI()) {
|
||||
new CommandLineOpenCaseManager().start();
|
||||
return;
|
||||
}
|
||||
|
||||
// first check whether we are running from command line
|
||||
if (isRunningFromCommandLine()) {
|
||||
// Autopsy is running from command line
|
||||
@ -131,6 +138,27 @@ public class StartupWindowProvider implements StartupWindowInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether Autopsy was launched from the command line with the option
|
||||
* to open an existing case.
|
||||
*
|
||||
* @return True if opening an existing case.
|
||||
*/
|
||||
private boolean openCaseInUI() {
|
||||
// first look up all OptionProcessors and see if running from command line option is set
|
||||
Collection<? extends OptionProcessor> optionProcessors = Lookup.getDefault().lookupAll(OptionProcessor.class);
|
||||
Iterator<? extends OptionProcessor> optionsIterator = optionProcessors.iterator();
|
||||
while (optionsIterator.hasNext()) {
|
||||
// find CommandLineOptionProcessor
|
||||
OptionProcessor processor = optionsIterator.next();
|
||||
if ((processor instanceof CommandLineOptionProcessor)) {
|
||||
// check if we are running from command line
|
||||
return ((CommandLineOptionProcessor) processor).openCaseInUI();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
if (startupWindowToUse != null) {
|
||||
|
@ -34,7 +34,8 @@ class CommandLineCommand {
|
||||
ADD_DATA_SOURCE,
|
||||
RUN_INGEST,
|
||||
LIST_ALL_DATA_SOURCES,
|
||||
GENERATE_REPORTS;
|
||||
GENERATE_REPORTS,
|
||||
OPEN_CASE_IN_UI;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
* cause Autopsy to create a case, add a specified data source, run ingest on
|
||||
* that data source, list all data sources in the case, and generate reports.
|
||||
*/
|
||||
public class CommandLineIngestManager {
|
||||
public class CommandLineIngestManager extends CommandLineManager{
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CommandLineIngestManager.class.getName());
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED);
|
||||
@ -184,7 +184,7 @@ public class CommandLineIngestManager {
|
||||
// open the case, if it hasn't been already opened by CREATE_CASE command
|
||||
if (caseForJob == null) {
|
||||
String caseDirPath = inputs.get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
openCase(caseDirPath);
|
||||
caseForJob = CommandLineIngestManager.this.openCase(caseDirPath);
|
||||
}
|
||||
|
||||
String dataSourcePath = inputs.get(CommandLineCommand.InputType.DATA_SOURCE_PATH.name());
|
||||
@ -210,7 +210,7 @@ public class CommandLineIngestManager {
|
||||
// open the case, if it hasn't been already opened by CREATE_CASE or ADD_DATA_SOURCE commands
|
||||
if (caseForJob == null) {
|
||||
String caseDirPath = inputs.get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
openCase(caseDirPath);
|
||||
caseForJob = CommandLineIngestManager.this.openCase(caseDirPath);
|
||||
}
|
||||
|
||||
// populate the AutoIngestDataSource structure, if that hasn't been done by ADD_DATA_SOURCE command
|
||||
@ -265,7 +265,7 @@ public class CommandLineIngestManager {
|
||||
// open the case, if it hasn't been already opened by previous command
|
||||
if (caseForJob == null) {
|
||||
String caseDirPath = inputs.get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
openCase(caseDirPath);
|
||||
caseForJob = CommandLineIngestManager.this.openCase(caseDirPath);
|
||||
}
|
||||
|
||||
String outputDirPath = getOutputDirPath(caseForJob);
|
||||
@ -288,7 +288,7 @@ public class CommandLineIngestManager {
|
||||
// open the case, if it hasn't been already opened by previous command
|
||||
if (caseForJob == null) {
|
||||
String caseDirPath = inputs.get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
openCase(caseDirPath);
|
||||
caseForJob = CommandLineIngestManager.this.openCase(caseDirPath);
|
||||
}
|
||||
|
||||
// generate reports
|
||||
@ -369,55 +369,6 @@ public class CommandLineIngestManager {
|
||||
LOGGER.log(Level.INFO, "Opened case {0}", caseForJob.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens existing case.
|
||||
*
|
||||
* @param caseFolderPath full path to case directory
|
||||
*
|
||||
* @throws CaseActionException
|
||||
*/
|
||||
private void openCase(String caseFolderPath) throws CaseActionException {
|
||||
|
||||
LOGGER.log(Level.INFO, "Opening case in directory {0}", caseFolderPath);
|
||||
|
||||
String metadataFilePath = findAutFile(caseFolderPath);
|
||||
Case.openAsCurrentCase(metadataFilePath);
|
||||
|
||||
caseForJob = Case.getCurrentCase();
|
||||
LOGGER.log(Level.INFO, "Opened case {0}", caseForJob.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the .aut file for the specified case directory.
|
||||
*
|
||||
* @param caseDirectory the directory to check for a .aut file
|
||||
*
|
||||
* @return the path to the first .aut file found in the directory
|
||||
*
|
||||
* @throws CaseActionException if there was an issue finding a .aut file
|
||||
*/
|
||||
private String findAutFile(String caseDirectory) throws CaseActionException {
|
||||
File caseFolder = Paths.get(caseDirectory).toFile();
|
||||
if (caseFolder.exists()) {
|
||||
/*
|
||||
* Search for '*.aut' files.
|
||||
*/
|
||||
File[] fileArray = caseFolder.listFiles();
|
||||
if (fileArray == null) {
|
||||
throw new CaseActionException("No files found in case directory");
|
||||
}
|
||||
String autFilePath = null;
|
||||
for (File file : fileArray) {
|
||||
String name = file.getName().toLowerCase();
|
||||
if (autFilePath == null && name.endsWith(getFileExtension())) {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
throw new CaseActionException("No .aut files found in case directory");
|
||||
}
|
||||
throw new CaseActionException("Case directory was not found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes the data source for the current job through a data source
|
||||
* processor that adds it to the case database.
|
||||
|
87
Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineManager.java
Executable file
87
Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineManager.java
Executable file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> 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.commandlineingest;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||
import static org.sleuthkit.autopsy.casemodule.CaseMetadata.getFileExtension;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Base class for the command line managers.
|
||||
*/
|
||||
abstract class CommandLineManager {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CommandLineOpenCaseManager.class.getName());
|
||||
|
||||
/**
|
||||
* Opens existing case.
|
||||
*
|
||||
* @param caseFolderPath full path to case directory
|
||||
*
|
||||
* @throws CaseActionException
|
||||
*/
|
||||
Case openCase(String caseFolderPath) throws CaseActionException {
|
||||
|
||||
LOGGER.log(Level.INFO, "Opening case in directory {0}", caseFolderPath);
|
||||
|
||||
String metadataFilePath = findAutFile(caseFolderPath);
|
||||
Case.openAsCurrentCase(metadataFilePath);
|
||||
|
||||
Case newCase = Case.getCurrentCase();
|
||||
LOGGER.log(Level.INFO, "Opened case {0}", newCase.getName());
|
||||
|
||||
return newCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the .aut file for the specified case directory.
|
||||
*
|
||||
* @param caseDirectory the directory to check for a .aut file
|
||||
*
|
||||
* @return the path to the first .aut file found in the directory
|
||||
*
|
||||
* @throws CaseActionException if there was an issue finding a .aut file
|
||||
*/
|
||||
private String findAutFile(String caseDirectory) throws CaseActionException {
|
||||
File caseFolder = Paths.get(caseDirectory).toFile();
|
||||
if (caseFolder.exists()) {
|
||||
/*
|
||||
* Search for '*.aut' files.
|
||||
*/
|
||||
File[] fileArray = caseFolder.listFiles();
|
||||
if (fileArray == null) {
|
||||
throw new CaseActionException("No files found in case directory");
|
||||
}
|
||||
String autFilePath = null;
|
||||
for (File file : fileArray) {
|
||||
String name = file.getName().toLowerCase();
|
||||
if (autFilePath == null && name.endsWith(getFileExtension())) {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
throw new CaseActionException("No .aut files found in case directory");
|
||||
}
|
||||
throw new CaseActionException("Case directory was not found");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> 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.commandlineingest;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import org.netbeans.spi.sendopts.OptionProcessor;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.casemodule.CaseActionException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Handles the opening of a case from the command line.
|
||||
*
|
||||
*/
|
||||
public class CommandLineOpenCaseManager extends CommandLineManager{
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CommandLineOpenCaseManager.class.getName());
|
||||
|
||||
/**
|
||||
* Starts the thread to open the case.
|
||||
*/
|
||||
public void start() {
|
||||
new Thread(new CommandLineOpenCaseManager.JobProcessingTask()).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* A runnable class that open the given class in the list of command line
|
||||
* options.
|
||||
*/
|
||||
private final class JobProcessingTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<CommandLineCommand> commands = null;
|
||||
|
||||
// first look up all OptionProcessors and get input data from CommandLineOptionProcessor
|
||||
Collection<? extends OptionProcessor> optionProcessors = Lookup.getDefault().lookupAll(OptionProcessor.class);
|
||||
Iterator<? extends OptionProcessor> optionsIterator = optionProcessors.iterator();
|
||||
while (optionsIterator.hasNext()) {
|
||||
// find CommandLineOptionProcessor
|
||||
OptionProcessor processor = optionsIterator.next();
|
||||
if (processor instanceof CommandLineOptionProcessor) {
|
||||
// check if we are running from command line
|
||||
commands = ((CommandLineOptionProcessor) processor).getCommands();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (commands == null || commands.isEmpty()) {
|
||||
LOGGER.log(Level.SEVERE, "No command line commands specified");
|
||||
System.err.println("No command line commands specified");
|
||||
return;
|
||||
}
|
||||
|
||||
String casePath;
|
||||
for (CommandLineCommand command : commands) {
|
||||
CommandLineCommand.CommandType type = command.getType();
|
||||
if(type.equals(CommandLineCommand.CommandType.OPEN_CASE_IN_UI)) {
|
||||
try {
|
||||
Map<String, String> inputs = command.getInputs();
|
||||
casePath = inputs.get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
CommandLineOpenCaseManager.this.openCase(casePath);
|
||||
} catch (CaseActionException ex) {
|
||||
String baseCaseName = command.getInputs().get(CommandLineCommand.InputType.CASE_FOLDER_PATH.name());
|
||||
LOGGER.log(Level.SEVERE, "Error opening case " + baseCaseName, ex);
|
||||
System.err.println("Error opening case " + baseCaseName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -52,8 +52,10 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
||||
private final Option ingestProfileOption = Option.requiredArgument('p', "ingestProfile");
|
||||
private final Option listAllDataSourcesCommandOption = Option.withoutArgument('l', "listAllDataSources");
|
||||
private final Option generateReportsOption = Option.withoutArgument('g', "generateReports");
|
||||
private final Option runUICommandOption = Option.requiredArgument('u', "runUI");
|
||||
|
||||
private boolean runFromCommandLine = false;
|
||||
private boolean openCaseInUI = false;
|
||||
|
||||
private final List<CommandLineCommand> commands = new ArrayList<>();
|
||||
|
||||
@ -75,6 +77,7 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
||||
set.add(ingestProfileOption);
|
||||
set.add(listAllDataSourcesCommandOption);
|
||||
set.add(generateReportsOption);
|
||||
set.add(runUICommandOption);
|
||||
return set;
|
||||
}
|
||||
|
||||
@ -87,7 +90,8 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
||||
// input arguments must contain at least one command
|
||||
if (!(values.containsKey(createCaseCommandOption) || values.containsKey(addDataSourceCommandOption)
|
||||
|| values.containsKey(runIngestCommandOption) || values.containsKey(listAllDataSourcesCommandOption)
|
||||
|| values.containsKey(generateReportsOption))) {
|
||||
|| values.containsKey(generateReportsOption)
|
||||
|| values.containsKey(runUICommandOption))) {
|
||||
// not running from command line
|
||||
logger.log(Level.INFO, "No command line commands passed in as inputs. Not running from command line."); //NON-NLS
|
||||
System.err.println("No command line commands passed in as inputs. Not running from command line.");
|
||||
@ -373,7 +377,21 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
||||
newCommand.addInputValue(CommandLineCommand.InputType.CASE_FOLDER_PATH.name(), caseDir);
|
||||
commands.add(newCommand);
|
||||
runFromCommandLine = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(values.containsKey(runUICommandOption)) {
|
||||
argDirs = values.get(runUICommandOption);
|
||||
if (argDirs.length < 1) {
|
||||
logger.log(Level.SEVERE, "Missing argument 'runUI'");
|
||||
System.err.println("Missing argument 'runUI'");
|
||||
return;
|
||||
}
|
||||
String casePath = argDirs[0];
|
||||
CommandLineCommand newCommand = new CommandLineCommand(CommandLineCommand.CommandType.OPEN_CASE_IN_UI);
|
||||
newCommand.addInputValue(CommandLineCommand.InputType.CASE_FOLDER_PATH.name(), casePath);
|
||||
commands.add(newCommand);
|
||||
openCaseInUI = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -384,6 +402,15 @@ public class CommandLineOptionProcessor extends OptionProcessor {
|
||||
public boolean isRunFromCommandLine() {
|
||||
return runFromCommandLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether Autopsy should open existing case in the user interface.
|
||||
*
|
||||
* @return true if opening an existing case, false otherwise.
|
||||
*/
|
||||
public boolean openCaseInUI() {
|
||||
return openCaseInUI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of all commands passed in via command line.
|
||||
|
@ -199,3 +199,4 @@ FileReportDataTypes.hash.text=Hash Value
|
||||
FileReportDataTypes.knownStatus.text=Known Status
|
||||
FileReportDataTypes.perms.text=Permissions
|
||||
FileReportDataTypes.path.text=Full Path
|
||||
ReportWizardPortableCaseOptionsVisualPanel.includeAppCheckbox.text=Include application in folder (may add up to 1GB of files)
|
||||
|
@ -220,4 +220,5 @@ FileReportDataTypes.knownStatus.text=Known Status
|
||||
FileReportDataTypes.perms.text=Permissions
|
||||
FileReportDataTypes.path.text=Full Path
|
||||
ReportWizardPortableCaseOptionsVisualPanel.getName.title=Choose Portable Case settings
|
||||
ReportWizardPortableCaseOptionsVisualPanel.includeAppCheckbox.text=Include application in folder (may add up to 1GB of files)
|
||||
TableReportGenerator.StatusColumn.Header=Review Status
|
||||
|
@ -18,7 +18,7 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="463" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="mainPanel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -26,27 +26,32 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="259" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="mainPanel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Container class="javax.swing.JPanel" name="mainPanel">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="listPanel" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="compressCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chunkSizeComboBox" min="-2" pref="187" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="compressCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chunkSizeComboBox" min="-2" pref="187" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="includeAppCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="41" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="listPanel" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
@ -60,6 +65,8 @@
|
||||
<Component id="errorLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="includeAppCheckbox" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -106,11 +113,21 @@
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="217" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="190" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Container>
|
||||
<Component class="javax.swing.JCheckBox" name="includeAppCheckbox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/report/infrastructure/Bundle.properties" key="ReportWizardPortableCaseOptionsVisualPanel.includeAppCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="includeAppCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
|
@ -119,6 +119,15 @@ class ReportWizardPortableCaseOptionsVisualPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the include application option.
|
||||
*/
|
||||
private void updateIncludeApplication() {
|
||||
if (settings != null) {
|
||||
settings.setIncludeApplication(includeAppCheckbox.isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user-selected settings.
|
||||
*
|
||||
@ -137,11 +146,12 @@ class ReportWizardPortableCaseOptionsVisualPanel extends javax.swing.JPanel {
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
mainPanel = new javax.swing.JPanel();
|
||||
chunkSizeComboBox = new javax.swing.JComboBox<>();
|
||||
compressCheckbox = new javax.swing.JCheckBox();
|
||||
errorLabel = new javax.swing.JLabel();
|
||||
listPanel = new javax.swing.JPanel();
|
||||
includeAppCheckbox = new javax.swing.JCheckBox();
|
||||
|
||||
chunkSizeComboBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
@ -168,32 +178,44 @@ class ReportWizardPortableCaseOptionsVisualPanel extends javax.swing.JPanel {
|
||||
);
|
||||
listPanelLayout.setVerticalGroup(
|
||||
listPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 217, Short.MAX_VALUE)
|
||||
.addGap(0, 190, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(compressCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chunkSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 187, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(errorLabel)
|
||||
.addContainerGap(41, Short.MAX_VALUE))
|
||||
org.openide.awt.Mnemonics.setLocalizedText(includeAppCheckbox, org.openide.util.NbBundle.getMessage(ReportWizardPortableCaseOptionsVisualPanel.class, "ReportWizardPortableCaseOptionsVisualPanel.includeAppCheckbox.text")); // NOI18N
|
||||
includeAppCheckbox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
includeAppCheckboxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
|
||||
mainPanel.setLayout(mainPanelLayout);
|
||||
mainPanelLayout.setHorizontalGroup(
|
||||
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(listPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(mainPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(mainPanelLayout.createSequentialGroup()
|
||||
.addComponent(compressCheckbox)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chunkSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 187, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(errorLabel))
|
||||
.addComponent(includeAppCheckbox))
|
||||
.addContainerGap(41, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
mainPanelLayout.setVerticalGroup(
|
||||
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(mainPanelLayout.createSequentialGroup()
|
||||
.addComponent(listPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(compressCheckbox)
|
||||
.addComponent(chunkSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(errorLabel))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(includeAppCheckbox)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
@ -203,13 +225,13 @@ class ReportWizardPortableCaseOptionsVisualPanel extends javax.swing.JPanel {
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 463, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 259, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@ -222,12 +244,17 @@ class ReportWizardPortableCaseOptionsVisualPanel extends javax.swing.JPanel {
|
||||
updateCompression();
|
||||
}//GEN-LAST:event_compressCheckboxActionPerformed
|
||||
|
||||
private void includeAppCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_includeAppCheckboxActionPerformed
|
||||
updateIncludeApplication();
|
||||
}//GEN-LAST:event_includeAppCheckboxActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JComboBox<ChunkSize> chunkSizeComboBox;
|
||||
private javax.swing.JCheckBox compressCheckbox;
|
||||
private javax.swing.JLabel errorLabel;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JCheckBox includeAppCheckbox;
|
||||
private javax.swing.JPanel listPanel;
|
||||
private javax.swing.JPanel mainPanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ PortableCaseReportModule.generateReport.copyingFiles=Copying files tagged as {0}
|
||||
PortableCaseReportModule.generateReport.copyingTags=Copying tags...
|
||||
PortableCaseReportModule.generateReport.creatingCase=Creating portable case database...
|
||||
PortableCaseReportModule.generateReport.errorCopyingArtifacts=Error copying tagged artifacts
|
||||
PortableCaseReportModule.generateReport.errorCopyingAutopsy=Error copying application
|
||||
PortableCaseReportModule.generateReport.errorCopyingFiles=Error copying tagged files
|
||||
PortableCaseReportModule.generateReport.errorCopyingInterestingFiles=Error copying interesting files
|
||||
PortableCaseReportModule.generateReport.errorCopyingInterestingResults=Error copying interesting results
|
||||
|
@ -29,6 +29,7 @@ import java.util.logging.Level;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
@ -50,6 +51,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
|
||||
import org.sleuthkit.autopsy.casemodule.services.contentviewertags.ContentViewerTagManager;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
@ -206,6 +208,7 @@ public class PortableCaseReportModule implements ReportModule {
|
||||
"PortableCaseReportModule.generateReport.errorCopyingInterestingFiles=Error copying interesting files",
|
||||
"PortableCaseReportModule.generateReport.errorCopyingInterestingResults=Error copying interesting results",
|
||||
"PortableCaseReportModule.generateReport.errorCreatingImageTagTable=Error creating image tags table",
|
||||
"PortableCaseReportModule.generateReport.errorCopyingAutopsy=Error copying application",
|
||||
"# {0} - attribute type name",
|
||||
"PortableCaseReportModule.generateReport.errorLookingUpAttrType=Error looking up attribute type {0}",
|
||||
"PortableCaseReportModule.generateReport.compressingCase=Compressing case..."
|
||||
@ -436,6 +439,15 @@ public class PortableCaseReportModule implements ReportModule {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(options.includeApplication()) {
|
||||
try {
|
||||
copyApplication(getApplicationBasePath(), reportPath, "autopsy");
|
||||
createAppLaunchBatFile(reportPath);
|
||||
} catch (IOException ex) {
|
||||
handleError("Error copying autopsy", Bundle.PortableCaseReportModule_generateReport_errorCopyingAutopsy(), ex, progressPanel); // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
// Close the case connections and clear out the maps
|
||||
cleanup();
|
||||
@ -1142,6 +1154,76 @@ public class PortableCaseReportModule implements ReportModule {
|
||||
}
|
||||
return UNKNOWN_FILE_TYPE_FOLDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns base path of the users autopsy installation.
|
||||
*
|
||||
* @return Path of autopsy installation.
|
||||
*/
|
||||
private Path getApplicationBasePath() {
|
||||
return getAutopsyExePath().getParent().getParent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the path of the installed version of autopsy.
|
||||
*
|
||||
* @return Path to the installed autopsy.exe.
|
||||
*/
|
||||
private Path getAutopsyExePath() {
|
||||
// If this is an installed version, there should be an <appName>64.exe file in the bin folder
|
||||
String exeName = getAutopsyExeName();
|
||||
String installPath = PlatformUtil.getInstallPath();
|
||||
|
||||
return Paths.get(installPath, "bin", exeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the name of the autopsy exe.
|
||||
*
|
||||
* @return The name of the autopsy exe.
|
||||
*/
|
||||
private String getAutopsyExeName() {
|
||||
String appName = UserPreferences.getAppName();
|
||||
return appName + "64.exe";
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the sorceFolder to destBaseFolder\appName.
|
||||
*
|
||||
* @param sourceFolder Autopsy installation directory.
|
||||
* @param destBaseFolder Report base direction.
|
||||
* @param appName Name of the application being copied.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private void copyApplication(Path sourceFolder, String destBaseFolder, String appName) throws IOException {
|
||||
|
||||
// Create an appName folder in the destination
|
||||
Path destAppFolder = Paths.get(destBaseFolder, appName);
|
||||
if (!destAppFolder.toFile().exists()) {
|
||||
if (!destAppFolder.toFile().mkdirs()) {
|
||||
throw new IOException("Failed to create directory " + destAppFolder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Now copy the files
|
||||
FileUtils.copyDirectory(sourceFolder.toFile(), destAppFolder.toFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a bat file at destBaseFolder that will launch the portable case.
|
||||
*
|
||||
* @param destBaseFolder
|
||||
* @throws IOException
|
||||
*/
|
||||
private void createAppLaunchBatFile(String destBaseFolder) throws IOException {
|
||||
Path filePath = Paths.get(destBaseFolder, "open.bat");
|
||||
String exePath = "\"%~dp0autopsy\\bin\\" + getAutopsyExeName() + "\"";
|
||||
String casePath = ".\\" + caseName ;
|
||||
try(FileWriter writer = new FileWriter(filePath.toFile())) {
|
||||
writer.write(exePath + " --caseDir \" " + casePath + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out the maps and other fields and close the database connections.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Copyright 2019-2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -36,6 +36,7 @@ public class PortableCaseReportModuleSettings implements ReportModuleSettings {
|
||||
private ChunkSize chunkSize;
|
||||
private boolean allTagsSelected;
|
||||
private boolean allSetsSelected;
|
||||
private boolean includeApplication;
|
||||
|
||||
/**
|
||||
* Enum for storing the display name for each chunk type and the
|
||||
@ -141,6 +142,10 @@ public class PortableCaseReportModuleSettings implements ReportModuleSettings {
|
||||
public boolean areAllSetsSelected() {
|
||||
return allSetsSelected;
|
||||
}
|
||||
|
||||
public boolean includeApplication() {
|
||||
return includeApplication;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allTagsSelected the allTagsSelected to set
|
||||
@ -155,5 +160,9 @@ public class PortableCaseReportModuleSettings implements ReportModuleSettings {
|
||||
public void setAllSetsSelected(boolean allSetsSelected) {
|
||||
this.allSetsSelected = allSetsSelected;
|
||||
}
|
||||
|
||||
public void setIncludeApplication(boolean includeApplication) {
|
||||
this.includeApplication = includeApplication;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user