Merge branch 'rc-280' of https://github.com/sleuthkit/autopsy into keyword_class_2495

This commit is contained in:
Eugene Livis 2017-04-12 13:53:56 -04:00
commit 8252e81b1f
374 changed files with 555 additions and 491 deletions

30
.gitignore vendored
View File

@ -3,20 +3,23 @@
/*/build/ /*/build/
*/nbproject/private/* */nbproject/private/*
/nbproject/private/* /nbproject/private/*
/Core/release/
/Core/src/org/sleuthkit/autopsy/coreutils/Version.properties /Core/src/org/sleuthkit/autopsy/coreutils/Version.properties
/Core/src/org/sleuthkit/autopsy/casemodule/docs/QuickStart.html
/Core/src/org/sleuthkit/autopsy/casemodule/docs/screenshot.png
/Core/src/org/sleuthkit/autopsy/datamodel/ranges.csv
/Core/build/ /Core/build/
/Core/dist/ /Core/dist/
/Core/nbproject/* /Core/nbproject/*
!/Core/nbproject/project.xml !/Core/nbproject/project.xml
!/Core/nbproject/project.properties !/Core/nbproject/project.properties
/CoreLibs/release/
/CoreLibs/build/ /CoreLibs/build/
/CoreLibs/dist/ /CoreLibs/dist/
/CoreLibs/nbproject/* /CoreLibs/nbproject/*
!/CoreLibs/nbproject/project.xml !/CoreLibs/nbproject/project.xml
!/CoreLibs/nbproject/project.properties !/CoreLibs/nbproject/project.properties
KeywordSearch/release/
/KeywordSearch/build/ /KeywordSearch/build/
/KeywordSearch/dist/ /KeywordSearch/dist/
/KeywordSearch/nbproject/* /KeywordSearch/nbproject/*
@ -46,6 +49,8 @@ genfiles.properties
/test/script/DBDump.txt /test/script/DBDump.txt
/test/script/SortedData-Diff.txt /test/script/SortedData-Diff.txt
/test/script/SortedData.txt /test/script/SortedData.txt
/test/script/myconfig.xml
/test/script/*/*.xml
/test/build/ /test/build/
/test/dist/ /test/dist/
/test/nbproject/* /test/nbproject/*
@ -59,19 +64,12 @@ genfiles.properties
/jdiff-logs/* /jdiff-logs/*
/gen_version.txt /gen_version.txt
hs_err_pid*.log hs_err_pid*.log
Core/src/org/sleuthkit/autopsy/casemodule/docs/QuickStart.html
Core/src/org/sleuthkit/autopsy/casemodule/docs/screenshot.png
Core/src/org/sleuthkit/autopsy/datamodel/ranges.csv
/test/script/myconfig.xml
/test/script/*/*.xml
.DS_Store .DS_Store
.*.swp .*.swp
/ImageGallery/release/
/RecentActivity/release/
Core/release/ /Experimental/release/
CoreLibs/release/ /thunderbirdparser/release/
Experimental/release/
ImageGallery/release/
KeywordSearch/release/
thunderbirdparser/release/

View File

@ -20,17 +20,30 @@ package org.sleuthkit.autopsy.casemodule;
import java.awt.Color; import java.awt.Color;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import org.openide.WizardDescriptor; import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx; import org.openide.util.HelpCtx;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor; import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel;
import org.sleuthkit.datamodel.Content;
/** /**
* The final panel of the add image wizard. It displays a progress bar and * The final panel of the add image wizard. It displays a progress bar and
@ -42,21 +55,35 @@ import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescript
*/ */
class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel { class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
private boolean readyToIngest = false;
// task that will clean up the created database file if the wizard is cancelled before it finishes
private AddImageAction.CleanupTask cleanupTask;
private final AddImageAction addImageAction;
private DataSourceProcessor dsProcessor = null;
private boolean cancelled;
/** /**
* flag to indicate that the image adding process is finished and this panel * flag to indicate that the image adding process is finished and this panel
* is completed(valid) * is completed(valid)
*/ */
private boolean imgAdded = false; private boolean imgAdded = false;
private boolean ingested = false;
/** /**
* The visual component that displays this panel. If you need to access the * The visual component that displays this panel. If you need to access the
* component from this class, just use getComponent(). * component from this class, just use getComponent().
*/ */
private AddImageWizardAddingProgressVisual component; private AddImageWizardAddingProgressVisual component;
private final Set<ChangeListener> listeners = new HashSet<>(1); // or can use ChangeSupport in NB 6.0 private final Set<ChangeListener> listeners = new HashSet<>(1); // or can use ChangeSupport in NB 6.0
private final List<Content> newContents = Collections.synchronizedList(new ArrayList<Content>());
private final DSPProgressMonitorImpl dspProgressMonitorImpl = new DSPProgressMonitorImpl(); private final DSPProgressMonitorImpl dspProgressMonitorImpl = new DSPProgressMonitorImpl();
private IngestJobSettings ingestJobSettings;
public DSPProgressMonitorImpl getDSPProgressMonitorImpl() { AddImageWizardAddingProgressPanel(AddImageAction action) {
this.addImageAction = action;
}
DSPProgressMonitorImpl getDSPProgressMonitorImpl() {
return dspProgressMonitorImpl; return dspProgressMonitorImpl;
} }
@ -209,12 +236,24 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
*/ */
@Override @Override
public void readSettings(WizardDescriptor settings) { public void readSettings(WizardDescriptor settings) {
// Start ingest if it hasn't already been started
startIngest();
settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, WizardDescriptor.CANCEL_OPTION}); settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, WizardDescriptor.CANCEL_OPTION});
if (imgAdded) { if (imgAdded) {
getComponent().setStateFinished(); getComponent().setStateFinished();
} }
} }
void resetReadyToIngest() {
this.readyToIngest = false;
}
void setIngestJobSettings(IngestJobSettings ingestSettings) {
showWarnings(ingestSettings);
this.readyToIngest = true;
this.ingestJobSettings = ingestSettings;
}
/** /**
* this doesn't appear to store anything? plus, there are no settings in * this doesn't appear to store anything? plus, there are no settings in
* this panel -jm * this panel -jm
@ -240,4 +279,136 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel {
getComponent().showErrors(errorString, critical); getComponent().showErrors(errorString, critical);
} }
/**
* Start ingest after verifying we have a new image, we are ready to ingest,
* and we haven't already ingested.
*/
private void startIngest() {
if (!newContents.isEmpty() && readyToIngest && !ingested) {
ingested = true;
IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettings);
setStateFinished();
}
}
private static void showWarnings(IngestJobSettings ingestJobSettings) {
List<String> warnings = ingestJobSettings.getWarnings();
if (warnings.isEmpty() == false) {
StringBuilder warningMessage = new StringBuilder();
for (String warning : warnings) {
warningMessage.append(warning).append("\n");
}
JOptionPane.showMessageDialog(null, warningMessage.toString());
}
}
/**
* Starts the Data source processing by kicking off the selected
* DataSourceProcessor
*/
void startDataSourceProcessing(DataSourceProcessor dsp) {
if (dsProcessor == null) { //this can only be run once
final UUID dataSourceId = UUID.randomUUID();
newContents.clear();
cleanupTask = null;
readyToIngest = false;
dsProcessor = dsp;
// Add a cleanup task to interrupt the background process if the
// wizard exits while the background process is running.
cleanupTask = addImageAction.new CleanupTask() {
@Override
void cleanup() throws Exception {
cancelDataSourceProcessing(dataSourceId);
cancelled = true;
}
};
cleanupTask.enable();
new Thread(() -> {
Case.getCurrentCase().notifyAddingDataSource(dataSourceId);
}).start();
DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback() {
@Override
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
dataSourceProcessorDone(dataSourceId, result, errList, contents);
}
};
setStateStarted();
// Kick off the DSProcessor
dsProcessor.run(getDSPProgressMonitorImpl(), cbObj);
}
}
/*
* Cancels the data source processing - in case the users presses 'Cancel'
*/
private void cancelDataSourceProcessing(UUID dataSourceId) {
dsProcessor.cancel();
}
/*
* Callback for the data source processor. Invoked by the DSP on the EDT
* thread, when it finishes processing the data source.
*/
private void dataSourceProcessorDone(UUID dataSourceId, DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
// disable the cleanup task
cleanupTask.disable();
// Get attention for the process finish
// this caused a crash on OS X
if (PlatformUtil.isWindowsOS() == true) {
java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP!
}
AddImageWizardAddingProgressVisual panel = getComponent();
if (panel != null) {
Window w = SwingUtilities.getWindowAncestor(panel);
if (w != null) {
w.toFront();
}
}
// Tell the panel we're done
setStateFinished();
//check the result and display to user
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS) {
getComponent().setProgressBarTextAndColor(
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text"), 100, Color.black);
} else {
getComponent().setProgressBarTextAndColor(
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.errs.text"), 100, Color.red);
}
//if errors, display them on the progress panel
boolean critErr = false;
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
critErr = true;
}
for (String err : errList) {
// TBD: there probably should be an error level for each error
addErrors(err, critErr);
}
//notify the UI of the new content added to the case
new Thread(() -> {
if (!contents.isEmpty()) {
Case.getCurrentCase().notifyDataSourceAdded(contents.get(0), dataSourceId);
} else {
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
}
}).start();
if (!cancelled) {
newContents.clear();
newContents.addAll(contents);
setStateStarted();
startIngest();
} else {
cancelled = false;
}
}
} }

View File

@ -50,7 +50,6 @@ class AddImageWizardDataSourceSettingsPanel extends ShortcutWizardDescriptorPane
// paths to any set hash lookup databases (can be null) // paths to any set hash lookup databases (can be null)
AddImageWizardDataSourceSettingsPanel() { AddImageWizardDataSourceSettingsPanel() {
} }
/** /**
@ -169,7 +168,7 @@ class AddImageWizardDataSourceSettingsPanel extends ShortcutWizardDescriptorPane
public void readSettings(WizardDescriptor settings) { public void readSettings(WizardDescriptor settings) {
// Prepopulate the image directory from the properties file // Prepopulate the image directory from the properties file
try { try {
// If there is a process object in the settings, revert it and remove it from the settings // If there is a process object in the settings, revert it and remove it from the settings
AddImageAction.CleanupTask cleanupTask = (AddImageAction.CleanupTask) settings.getProperty(AddImageAction.IMAGECLEANUPTASK_PROP); AddImageAction.CleanupTask cleanupTask = (AddImageAction.CleanupTask) settings.getProperty(AddImageAction.IMAGECLEANUPTASK_PROP);
if (cleanupTask != null) { if (cleanupTask != null) {
@ -184,7 +183,7 @@ class AddImageWizardDataSourceSettingsPanel extends ShortcutWizardDescriptorPane
} }
} catch (Exception e) { } catch (Exception e) {
} }
component.setDspSelection((String)settings.getProperty("SelectedDsp")); //NON-NLS magic string used SelectDataSourceProcessorPanel component.setDspSelection((String) settings.getProperty("SelectedDsp")); //NON-NLS magic string used SelectDataSourceProcessorPanel
} }
/** /**
@ -197,7 +196,7 @@ class AddImageWizardDataSourceSettingsPanel extends ShortcutWizardDescriptorPane
* @param settings the setting to be stored to * @param settings the setting to be stored to
*/ */
@Override @Override
public void storeSettings(WizardDescriptor settings) { public void storeSettings(WizardDescriptor settings) {
} }
/** /**

View File

@ -19,28 +19,17 @@
package org.sleuthkit.autopsy.casemodule; package org.sleuthkit.autopsy.casemodule;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.UUID;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import org.openide.WizardDescriptor; import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx; import org.openide.util.HelpCtx;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel; import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.IngestProfileSelectionWizardPanel; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.IngestProfileSelectionWizardPanel;
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel;
@ -60,24 +49,10 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
*/ */
private Component component = null; private Component component = null;
private String lastProfileUsed = AddImageWizardIngestConfigPanel.class.getCanonicalName(); private String lastProfileUsed = AddImageWizardIngestConfigPanel.class.getCanonicalName();
private final List<Content> newContents = Collections.synchronizedList(new ArrayList<Content>());
private boolean ingested = false;
private boolean readyToIngest = false;
// task that will clean up the created database file if the wizard is cancelled before it finishes
private AddImageAction.CleanupTask cleanupTask;
private final AddImageAction addImageAction;
private final AddImageWizardAddingProgressPanel progressPanel; private final AddImageWizardAddingProgressPanel progressPanel;
private final AddImageWizardDataSourceSettingsPanel dataSourcePanel;
private DataSourceProcessor dsProcessor; AddImageWizardIngestConfigPanel(AddImageWizardAddingProgressPanel proPanel) {
private boolean cancelled;
AddImageWizardIngestConfigPanel(AddImageWizardDataSourceSettingsPanel dsPanel, AddImageAction action, AddImageWizardAddingProgressPanel proPanel) {
this.addImageAction = action;
this.progressPanel = proPanel; this.progressPanel = proPanel;
this.dataSourcePanel = dsPanel;
IngestJobSettings ingestJobSettings = new IngestJobSettings(AddImageWizardIngestConfigPanel.class.getCanonicalName()); IngestJobSettings ingestJobSettings = new IngestJobSettings(AddImageWizardIngestConfigPanel.class.getCanonicalName());
showWarnings(ingestJobSettings); showWarnings(ingestJobSettings);
//When this panel is viewed by the user it will always be displaying the //When this panel is viewed by the user it will always be displaying the
@ -170,12 +145,6 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text")); NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text"));
cancel.setEnabled(false); cancel.setEnabled(false);
settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, cancel}); settings.setOptions(new Object[]{WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, cancel});
cleanupTask = null;
readyToIngest = false;
newContents.clear();
// Start processing the data source by handing it off to the selected DSP,
// so it gets going in the background while the user is still picking the Ingest modules
startDataSourceProcessing();
} }
/** /**
@ -190,12 +159,8 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
@Override @Override
public void storeSettings(WizardDescriptor settings) { public void storeSettings(WizardDescriptor settings) {
IngestJobSettings ingestJobSettings = ingestJobSettingsPanel.getSettings(); IngestJobSettings ingestJobSettings = ingestJobSettingsPanel.getSettings();
ingestJobSettings.save(); ingestJobSettings.save();
showWarnings(ingestJobSettings); progressPanel.setIngestJobSettings(ingestJobSettings); //prepare ingest for being started
// Start ingest if it hasn't already been started
readyToIngest = true;
startIngest();
} }
private static void showWarnings(IngestJobSettings ingestJobSettings) { private static void showWarnings(IngestJobSettings ingestJobSettings) {
@ -222,132 +187,7 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
} }
//Because this panel kicks off ingest during the wizard we need to //Because this panel kicks off ingest during the wizard we need to
//swap out the ingestJobSettings for the ones of the chosen profile before //swap out the ingestJobSettings for the ones of the chosen profile before
//we start processing
IngestJobSettings ingestJobSettings = new IngestJobSettings(lastProfileUsed); IngestJobSettings ingestJobSettings = new IngestJobSettings(lastProfileUsed);
ingestJobSettingsPanel = new IngestJobSettingsPanel(ingestJobSettings); progressPanel.setIngestJobSettings(ingestJobSettings); //prepare ingest for being started
showWarnings(ingestJobSettings);
component = new AddImageWizardIngestConfigVisual(this.ingestJobSettingsPanel);
readyToIngest = true;
startDataSourceProcessing();
}
/**
* Start ingest after verifying we have a new image, we are ready to ingest,
* and we haven't already ingested.
*/
private void startIngest() {
if (!newContents.isEmpty() && readyToIngest && !ingested) {
ingested = true;
IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettingsPanel.getSettings());
progressPanel.setStateFinished();
}
}
/**
* Starts the Data source processing by kicking off the selected
* DataSourceProcessor
*/
private void startDataSourceProcessing() {
final UUID dataSourceId = UUID.randomUUID();
// Add a cleanup task to interrupt the background process if the
// wizard exits while the background process is running.
cleanupTask = addImageAction.new CleanupTask() {
@Override
void cleanup() throws Exception {
cancelDataSourceProcessing(dataSourceId);
cancelled = true;
}
};
cleanupTask.enable();
// get the selected DSProcessor
dsProcessor = dataSourcePanel.getComponent().getCurrentDSProcessor();
new Thread(() -> {
Case.getCurrentCase().notifyAddingDataSource(dataSourceId);
}).start();
DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback() {
@Override
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
dataSourceProcessorDone(dataSourceId, result, errList, contents);
}
};
progressPanel.setStateStarted();
// Kick off the DSProcessor
dsProcessor.run(progressPanel.getDSPProgressMonitorImpl(), cbObj);
}
/*
* Cancels the data source processing - in case the users presses 'Cancel'
*/
private void cancelDataSourceProcessing(UUID dataSourceId) {
dsProcessor.cancel();
}
/*
* Callback for the data source processor. Invoked by the DSP on the EDT
* thread, when it finishes processing the data source.
*/
private void dataSourceProcessorDone(UUID dataSourceId, DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
// disable the cleanup task
cleanupTask.disable();
// Get attention for the process finish
// this caused a crash on OS X
if (PlatformUtil.isWindowsOS() == true) {
java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP!
}
AddImageWizardAddingProgressVisual panel = progressPanel.getComponent();
if (panel != null) {
Window w = SwingUtilities.getWindowAncestor(panel);
if (w != null) {
w.toFront();
}
}
// Tell the panel we're done
progressPanel.setStateFinished();
//check the result and display to user
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS) {
progressPanel.getComponent().setProgressBarTextAndColor(
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text"), 100, Color.black);
} else {
progressPanel.getComponent().setProgressBarTextAndColor(
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.errs.text"), 100, Color.red);
}
//if errors, display them on the progress panel
boolean critErr = false;
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
critErr = true;
}
for (String err : errList) {
// TBD: there probably should be an error level for each error
progressPanel.addErrors(err, critErr);
}
//notify the UI of the new content added to the case
new Thread(() -> {
if (!contents.isEmpty()) {
Case.getCurrentCase().notifyDataSourceAdded(contents.get(0), dataSourceId);
} else {
Case.getCurrentCase().notifyFailedAddingDataSource(dataSourceId);
}
}).start();
if (!cancelled) {
newContents.clear();
newContents.addAll(contents);
progressPanel.setStateStarted();
startIngest();
} else {
cancelled = false;
}
} }
} }

View File

@ -56,10 +56,10 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
panels = new ArrayList<>(); panels = new ArrayList<>();
AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel(); AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel();
panels.add(dspSelection); panels.add(dspSelection);
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel(); AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel(action);
AddImageWizardDataSourceSettingsPanel dsPanel = new AddImageWizardDataSourceSettingsPanel(); AddImageWizardDataSourceSettingsPanel dsPanel = new AddImageWizardDataSourceSettingsPanel();
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(dsPanel, action, progressPanel); AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(progressPanel);
panels.add(dsPanel); panels.add(dsPanel);
List<IngestProfiles.IngestProfile> profiles = IngestProfiles.getIngestProfiles(); List<IngestProfiles.IngestProfile> profiles = IngestProfiles.getIngestProfiles();
if (!profiles.isEmpty()) { if (!profiles.isEmpty()) {
@ -174,7 +174,13 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
if (!hasNext()) { if (!hasNext()) {
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
// Start processing the data source by handing it off to the selected DSP,
// so it gets going in the background while the user is still picking the Ingest modules
// This will occur when the next button is clicked on the panel where you have chosen your data to process
if (index == dsPanelIndex) {
((AddImageWizardAddingProgressPanel) panels.get(progressPanelIndex)).
startDataSourceProcessing(((AddImageWizardDataSourceSettingsPanel) panels.get(dsPanelIndex)).getComponent().getCurrentDSProcessor());
}
boolean panelEnablesSkipping = current().panelEnablesSkipping(); boolean panelEnablesSkipping = current().panelEnablesSkipping();
boolean skipNextPanel = current().skipNextPanel(); boolean skipNextPanel = current().skipNextPanel();
index++; index++;

View File

@ -180,7 +180,7 @@ NewCaseWizardAction.newCase.windowTitle.text=New Case Information
NewCaseWizardAction.getName.text=New Case Wizard NewCaseWizardAction.getName.text=New Case Wizard
NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case creation. NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case creation.
NewCaseWizardAction.databaseProblem2.text=Error NewCaseWizardAction.databaseProblem2.text=Error
NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols\: \\ / \: * ? " < > | NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols\: \\ / \: * ? " &lt; > |
NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists. NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists.
NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\ NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\
Do you want to create that directory? Do you want to create that directory?

View File

@ -135,7 +135,7 @@ NewCaseVisualPanel1.caseDirBrowse.selectButton.text=\u9078\u629e
NewCaseVisualPanel2.getName.text=\u4ed8\u52a0\u60c5\u5831 NewCaseVisualPanel2.getName.text=\u4ed8\u52a0\u60c5\u5831
NewCaseWizardAction.newCase.windowTitle.text=\u65b0\u898f\u30b1\u30fc\u30b9\u60c5\u5831 NewCaseWizardAction.newCase.windowTitle.text=\u65b0\u898f\u30b1\u30fc\u30b9\u60c5\u5831
NewCaseWizardAction.getName.text=\u65b0\u898f\u30b1\u30fc\u30b9\u30a6\u30a3\u30b6\u30fc\u30c9 NewCaseWizardAction.getName.text=\u65b0\u898f\u30b1\u30fc\u30b9\u30a6\u30a3\u30b6\u30fc\u30c9
NewCaseWizardPanel1.validate.errMsg.invalidSymbols=\u30b1\u30fc\u30b9\u540d\u306b\u306f\u6b21\u306e\u8a18\u53f7\u3092\u542b\u3081\u307e\u305b\u3093\uff1a\\ / \: * ? " < > | NewCaseWizardPanel1.validate.errMsg.invalidSymbols=\u30b1\u30fc\u30b9\u540d\u306b\u306f\u6b21\u306e\u8a18\u53f7\u3092\u542b\u3081\u307e\u305b\u3093\uff1a\\ / \: * ? " &lt; > |
NewCaseWizardPanel1.validate.errMsg.dirExists=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea''{0}''\u306f\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059\u3002 NewCaseWizardPanel1.validate.errMsg.dirExists=\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea''{0}''\u306f\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059\u3002
NewCaseWizardPanel1.validate.confMsg.createDir.msg=\u30d9\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea''{0}''\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002\n\n\ NewCaseWizardPanel1.validate.confMsg.createDir.msg=\u30d9\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea''{0}''\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002\n\n\
\u3053\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u3057\u307e\u3059\u304b\uff1f \u3053\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u3057\u307e\u3059\u304b\uff1f

View File

@ -116,7 +116,7 @@ public class Case {
private static final int NAME_LOCK_TIMOUT_HOURS = 12; private static final int NAME_LOCK_TIMOUT_HOURS = 12;
private static final int SHARED_DIR_LOCK_TIMOUT_HOURS = 12; private static final int SHARED_DIR_LOCK_TIMOUT_HOURS = 12;
private static final int RESOURCE_LOCK_TIMOUT_HOURS = 12; private static final int RESOURCE_LOCK_TIMOUT_HOURS = 12;
private static final int MAX_SANITIZED_CASE_NAME_LEN = 47; private static final int MAX_CASEDB_NAME_LEN_MINUS_TIMESTAMP = 47; //Truncate to 63-16=47 chars to accomodate the timestamp
private static final String SINGLE_USER_CASE_DB_NAME = "autopsy.db"; private static final String SINGLE_USER_CASE_DB_NAME = "autopsy.db";
private static final String EVENT_CHANNEL_NAME = "%s-Case-Events"; //NON-NLS private static final String EVENT_CHANNEL_NAME = "%s-Case-Events"; //NON-NLS
private static final String CACHE_FOLDER = "Cache"; //NON-NLS private static final String CACHE_FOLDER = "Cache"; //NON-NLS
@ -725,56 +725,83 @@ public class Case {
} }
/** /**
* Cleans up the display name for a case to make a suitable case name for * Transforms the display name for a case to make a suitable case name for
* use in case direcotry paths, coordination service locks, PostgreSQL * use in case directory paths, coordination service locks, Active MQ
* database names, Active MQ message message channels, etc. * message channels, etc.
*
* PostgreSQL:
* http://www.postgresql.org/docs/9.4/static/sql-syntax-lexical.html 63
* chars max, must start with a-z or _ following chars can be letters _ or
* digits
* *
* ActiveMQ: * ActiveMQ:
* http://activemq.2283324.n4.nabble.com/What-are-limitations-restrictions-on-destination-name-td4664141.html * http://activemq.2283324.n4.nabble.com/What-are-limitations-restrictions-on-destination-name-td4664141.html
* may not be ? * may not be ?
* *
* @param caseName A candidate case name. * @param caseDisplayName A case display name.
* *
* @return The sanitized case name. * @return The case display name transformed into a corresponding case name.
* *
* @throws org.sleuthkit.autopsy.casemodule.Case.IllegalCaseNameException * @throws org.sleuthkit.autopsy.casemodule.Case.IllegalCaseNameException
*/ */
public static String displayNameToCaseName(String caseName) throws IllegalCaseNameException { public static String displayNameToCaseName(String caseDisplayName) throws IllegalCaseNameException {
String result; /*
* Remove all non-ASCII characters.
*/
String caseName = caseDisplayName.replaceAll("[^\\p{ASCII}]", "_"); //NON-NLS
// Remove all non-ASCII characters /*
result = caseName.replaceAll("[^\\p{ASCII}]", "_"); //NON-NLS * Remove all control characters.
*/
caseName = caseName.replaceAll("[\\p{Cntrl}]", "_"); //NON-NLS
// Remove all control characters /*
result = result.replaceAll("[\\p{Cntrl}]", "_"); //NON-NLS * Remove /, \, :, ?, space, ' ".
*/
caseName = caseName.replaceAll("[ /?:'\"\\\\]", "_"); //NON-NLS
// Remove / \ : ? space ' " /*
result = result.replaceAll("[ /?:'\"\\\\]", "_"); //NON-NLS * Make it all lowercase.
*/
caseName = caseName.toLowerCase();
// Make it all lowercase if (caseName.isEmpty()) {
result = result.toLowerCase(); throw new IllegalCaseNameException(String.format("Failed to convert case name '%s'", caseDisplayName));
// Must start with letter or underscore for PostgreSQL. If not, prepend an underscore.
if (result.length() > 0 && !(Character.isLetter(result.codePointAt(0))) && !(result.codePointAt(0) == '_')) {
result = "_" + result;
} }
// Chop to 63-16=47 left (63 max for PostgreSQL, taking 16 for the date _20151225_123456) return caseName;
if (result.length() > MAX_SANITIZED_CASE_NAME_LEN) { }
result = result.substring(0, MAX_SANITIZED_CASE_NAME_LEN);
/**
* Transforms a case name into a name for a PostgreSQL database that can be
* safely used in SQL commands as described at
* http://www.postgresql.org/docs/9.4/static/sql-syntax-lexical.html: 63
* chars max, must start with a letter or underscore, following chars can be
* letters, underscores, or digits. A timestamp suffix is added to ensure
* uniqueness.
*
* @param caseName The case name.
*
* @return The case name transformed into a corresponding PostgreSQL
* case database name.
*/
private static String caseNameToCaseDbName(String caseName) throws IllegalCaseNameException {
/*
* Must start with letter or underscore. If not, prepend an underscore.
*/
String dbName = caseName;
if (dbName.length() > 0 && !(Character.isLetter(dbName.codePointAt(0))) && !(dbName.codePointAt(0) == '_')) {
dbName = "_" + dbName;
} }
if (result.isEmpty()) { /*
throw new IllegalCaseNameException(String.format("Failed to sanitize case name '%s'", caseName)); * Truncate to 63-16=47 chars to accomodate the timestamp, then add the
* timestamp.
*/
if (dbName.length() > MAX_CASEDB_NAME_LEN_MINUS_TIMESTAMP) {
dbName = dbName.substring(0, MAX_CASEDB_NAME_LEN_MINUS_TIMESTAMP);
} }
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
Date date = new Date();
dbName = dbName + "_" + dateFormat.format(date);
return result; return dbName;
} }
/** /**
@ -1740,6 +1767,7 @@ public class Case {
@Messages({ @Messages({
"Case.progressMessage.creatingCaseDirectory=Creating case directory...", "Case.progressMessage.creatingCaseDirectory=Creating case directory...",
"Case.progressMessage.creatingCaseDatabase=Creating case database...", "Case.progressMessage.creatingCaseDatabase=Creating case database...",
"Case.exceptionMessage.couldNotCreateCaseDatabaseName=Failed to create case database name from case name.",
"Case.progressMessage.creatingCaseMetadataFile=Creating case metadata file...", "Case.progressMessage.creatingCaseMetadataFile=Creating case metadata file...",
"Case.exceptionMessage.couldNotCreateMetadataFile=Failed to create case metadata file.", "Case.exceptionMessage.couldNotCreateMetadataFile=Failed to create case metadata file.",
"Case.exceptionMessage.couldNotCreateCaseDatabase=Failed to create case database." "Case.exceptionMessage.couldNotCreateCaseDatabase=Failed to create case database."
@ -1775,25 +1803,27 @@ public class Case {
*/ */
progressIndicator.progress(Bundle.Case_progressMessage_creatingCaseDatabase()); progressIndicator.progress(Bundle.Case_progressMessage_creatingCaseDatabase());
String dbName = null; String dbName = null;
try {
if (CaseType.SINGLE_USER_CASE == caseType) {
dbName = SINGLE_USER_CASE_DB_NAME;
} else if (CaseType.MULTI_USER_CASE == caseType) {
dbName = caseNameToCaseDbName(caseName);
}
} catch (IllegalCaseNameException ex) {
throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseDatabaseName(), ex);
}
try { try {
if (CaseType.SINGLE_USER_CASE == caseType) { if (CaseType.SINGLE_USER_CASE == caseType) {
/* /*
* For single-user cases, the case database is a SQLite database * For single-user cases, the case database is a SQLite database
* with a fixed name and is physically located in the root of * physically located in the root of the case directory.
* the case directory.
*/ */
dbName = SINGLE_USER_CASE_DB_NAME;
this.caseDb = SleuthkitCase.newCase(Paths.get(caseDir, SINGLE_USER_CASE_DB_NAME).toString()); this.caseDb = SleuthkitCase.newCase(Paths.get(caseDir, SINGLE_USER_CASE_DB_NAME).toString());
} else if (CaseType.MULTI_USER_CASE == caseType) { } else if (CaseType.MULTI_USER_CASE == caseType) {
/* /*
* For multi-user cases, the case database is a PostgreSQL * For multi-user cases, the case database is a PostgreSQL
* database with a name consiting of the case name with a time * database physically located on the database server.
* stamp suffix and is physically located on the database
* server.
*/ */
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
Date date = new Date();
dbName = caseName + "_" + dateFormat.format(date);
this.caseDb = SleuthkitCase.newCase(dbName, UserPreferences.getDatabaseConnectionInfo(), caseDir); this.caseDb = SleuthkitCase.newCase(dbName, UserPreferences.getDatabaseConnectionInfo(), caseDir);
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {

View File

@ -7,11 +7,6 @@
<import file="nbproject/build-impl.xml"/> <import file="nbproject/build-impl.xml"/>
<import file="../BootstrapIvy.xml"/> <import file="../BootstrapIvy.xml"/>
<property name="thirdparty.dir" value="${basedir}/../thirdparty" />
<property name="lib.dir" value="${basedir}/release/modules/lib" />
<condition property="os.family" value="unix"> <condition property="os.family" value="unix">
<os family="unix"/> <os family="unix"/>
</condition> </condition>
@ -23,6 +18,8 @@
</condition> </condition>
<import file="build-${os.family}.xml"/> <import file="build-${os.family}.xml"/>
<property name="thirdparty.dir" value="${basedir}/../thirdparty" />
<property name="lib.dir" value="${basedir}/release/modules/lib" />
<target name="get-deps" description="retrieve dependencies using ivy" depends="init-ivy,build-native-libs"> <target name="get-deps" description="retrieve dependencies using ivy" depends="init-ivy,build-native-libs">
<ivy:settings file="ivysettings.xml" /> <ivy:settings file="ivysettings.xml" />
@ -31,7 +28,7 @@
</target> </target>
<target name="init" depends="get-deps,harness.init"/> <target name="init" depends="get-deps,harness.init"/>
<target name="clean" depends="projectized-common.clean"> <target name="clean" depends="projectized-common.clean">
<!--Override clean to delete jars, etc downloaded with Ivy, <!--Override clean to delete jars, etc downloaded with Ivy,
or copied in from thirdparty folder. This way we don't end up with or copied in from thirdparty folder. This way we don't end up with

View File

@ -57,6 +57,7 @@ import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil; import org.openide.filesystems.FileUtil;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.CallableSystemAction;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.CaseNewAction; import org.sleuthkit.autopsy.casemodule.CaseNewAction;
import org.sleuthkit.autopsy.casemodule.CaseOpenAction; import org.sleuthkit.autopsy.casemodule.CaseOpenAction;
import org.sleuthkit.autopsy.core.ServicesMonitor; import org.sleuthkit.autopsy.core.ServicesMonitor;
@ -181,7 +182,8 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
* controlling automated ingest for a single node within the cluster. * controlling automated ingest for a single node within the cluster.
*/ */
private AutoIngestDashboard() { private AutoIngestDashboard() {
disableUiMenuActions(); //Disable the main window so they can only use the dashboard (if we used setVisible the taskBar icon would go away)
WindowManager.getDefault().getMainWindow().setEnabled(false);
manager = AutoIngestManager.getInstance(); manager = AutoIngestManager.getInstance();
@ -224,36 +226,6 @@ public final class AutoIngestDashboard extends JPanel implements Observer {
*/ */
UIManager.put("PopupMenu.consumeEventOnClose", false); UIManager.put("PopupMenu.consumeEventOnClose", false);
} }
private void disableUiMenuActions() {
/*
* Disable the new case action in auto ingest mode.
*/
CallableSystemAction.get(CaseNewAction.class).setEnabled(false);
/*
* Disable the new case action in auto ingest mode.
*/
CallableSystemAction.get(CaseOpenAction.class).setEnabled(false);
CallableSystemAction.get(AutoIngestCaseOpenAction.class).setEnabled(false);
/*
* Permanently delete the "Open Recent Cases" item in the "Case" menu.
* This is quite drastic, as it also affects Autopsy standalone mode on
* this machine, but we need to make sure a user can't open case in
* automated ingest mode. "Open Recent Cases" item can't be disabled via
* CallableSystemAction because of how it is defined in layer.xml, i.e.
* it is defined as "folder", not "file".
*/
FileObject root = FileUtil.getConfigRoot();
FileObject openRecentCasesMenu = root.getFileObject("Menu/Case/OpenRecentCase");
if (openRecentCasesMenu != null) {
try {
openRecentCasesMenu.delete();
} catch (IOException ignore) {
}
}
}
/** /**
* Queries the services monitor and sets the text for the services status * Queries the services monitor and sets the text for the services status

View File

@ -2,7 +2,37 @@
<!-- You may freely edit this file. See harness/README in the NetBeans platform --> <!-- You may freely edit this file. See harness/README in the NetBeans platform -->
<!-- for some information on what you could do (e.g. targets to override). --> <!-- for some information on what you could do (e.g. targets to override). -->
<!-- If you delete this file and reopen the project it will be recreated. --> <!-- If you delete this file and reopen the project it will be recreated. -->
<project name="org.sleuthkit.autopsy.recentactivity" default="netbeans" basedir="."> <project name="org.sleuthkit.autopsy.recentactivity" default="netbeans" basedir="." xmlns:ivy="antlib:org.apache.ivy.ant">
<description>Builds, tests, and runs the project org.sleuthkit.autopsy.recentactivity.</description> <description>Builds, tests, and runs the project org.sleuthkit.autopsy.recentactivity.</description>
<import file="nbproject/build-impl.xml"/> <import file="nbproject/build-impl.xml"/>
<import file="../BootstrapIvy.xml"/>
<property name="thirdparty.dir" value="${basedir}/../thirdparty"/>
<target name="get-thirdparty-tools" >
<copy todir="${basedir}/release/pasco2">
<fileset dir="${thirdparty.dir}/pasco2/lib/" />
</copy>
<copy todir="${basedir}/release/rr">
<fileset dir="${thirdparty.dir}/rr/" />
</copy>
<copy todir="${basedir}/release/rr-full" >
<fileset dir="${thirdparty.dir}/rr-full/" />
</copy>
</target>
<target name="get-deps" depends="init-ivy,get-thirdparty-tools">
<!-- fetch all the dependencies from Ivy and stick them in the right places -->
<ivy:resolve/>
<ivy:retrieve conf="recent-activity" pattern="${basedir}/release/modules/ext/[artifact]-[revision](-[classifier]).[ext]" />
</target>
<target name="init" depends="get-deps,harness.init"/>
<target name="clean" depends="projectized-common.clean">
<!--Override clean to delete jars, etc downloaded with Ivy
or copied in from thirdparty folder. This way we don't end up with
out-of-date/unneeded stuff in the installer-->
<delete dir="${basedir}/release" />
</target>
</project> </project>

12
RecentActivity/ivy.xml Normal file
View File

@ -0,0 +1,12 @@
<ivy-module version="2.0">
<info organisation="org.sleuthkit.autopsy" module="keywordsearch"/>
<configurations >
<!-- module dependencies -->
<conf name="recent-activity"/>
</configurations>
<dependencies>
<dependency conf="recent-activity->default" org="com.google.code.gson" name="gson" rev="2.1"/>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,9 @@
<ivysettings>
<settings defaultResolver="main"/>
<resolvers>
<chain name="main">
<ibiblio name="central" m2compatible="true"/>
<ibiblio name="maven.restlet.org" root="http://maven.restlet.com" m2compatible="true" />
</chain>
</resolvers>
</ivysettings>

View File

View File

View File

View File

@ -1,6 +1,6 @@
# 20120528 *ALL* Plugins that apply on any HIVES, alphabetical order # 20120528 *ALL* Plugins that apply on any HIVES, alphabetical order
baseline baseline
findexes findexes
regtime regtime
rlo rlo
del del

View File

View File

Some files were not shown because too many files have changed in this diff Show More