Rsolve merge conflict in VisualizationPanel.java
@ -24,6 +24,17 @@ VisualizationPanel.jButton6.text=Hierarchy
|
||||
VisualizationPanel.jButton7.text=Circle
|
||||
VisualizationPanel.jButton8.text=Organic
|
||||
VisualizationPanel.fitGraphButton.text=
|
||||
VisualizationPanel.jTextArea1.text=Right-click an account in the Browse Accounts table, and select 'Visualize' to begin.
|
||||
VisualizationPanel.jLabel1.text=Layouts:
|
||||
VisualizationPanel.zoomLabel.text=100%
|
||||
VisualizationPanel.jLabel2.text=Zoom:
|
||||
VisualizationPanel.fitZoomButton.toolTipText=fit visualization
|
||||
VisualizationPanel.fitZoomButton.text=
|
||||
VisualizationPanel.zoomActualButton.toolTipText=reset zoom
|
||||
VisualizationPanel.zoomActualButton.text=
|
||||
VisualizationPanel.zoomInButton.toolTipText=Zoom in
|
||||
VisualizationPanel.zoomInButton.text=
|
||||
VisualizationPanel.zoomOutButton.toolTipText=Zoom out
|
||||
VisualizationPanel.zoomOutButton.text=
|
||||
# To change this license header, choose License Headers in Project Properties.
|
||||
# To change this template file, choose Tools | Templates
|
||||
@ -32,14 +43,4 @@ VisualizationPanel.circleLayoutButton.text=Circle
|
||||
VisualizationPanel.organicLayoutButton.text=Organic
|
||||
VisualizationPanel.fastOrganicLayoutButton.text=Fast Organic
|
||||
VisualizationPanel.hierarchyLayoutButton.text=Hierarchy
|
||||
VisualizationPanel.zoomLabel.text=100%
|
||||
VisualizationPanel.jLabel1.text=Layouts:
|
||||
VisualizationPanel.jLabel2.text=Zoom:
|
||||
VisualizationPanel.fitZoomButton.toolTipText=fit visualization
|
||||
VisualizationPanel.fitZoomButton.text=
|
||||
VisualizationPanel.jTextArea1.text=Right-click an account in the Browse Accounts table, and select 'Visualize' to begin.
|
||||
VisualizationPanel.zoomActualButton.toolTipText=reset zoom
|
||||
VisualizationPanel.zoomActualButton.text=
|
||||
VisualizationPanel.zoomInButton.toolTipText=Zoom in
|
||||
VisualizationPanel.zoomInButton.text=
|
||||
VisualizationPanel.zoomOutButton.toolTipText=Zoom out
|
||||
VisualizationPanel.clearVizButton.text_1=Clear Viz.
|
||||
|
@ -50,9 +50,49 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov
|
||||
private final DataResultPanel messagesResultPanel;
|
||||
/* lookup that will be exposed through the (Global Actions Context) */
|
||||
private final ModifiableProxyLookup proxyLookup = new ModifiableProxyLookup();
|
||||
/* Listener that keeps the proxyLookup in sync with the focused area of the
|
||||
* UI. */
|
||||
private final FocusPropertyListener focusPropertyListener = new FocusPropertyListener();
|
||||
|
||||
private final PropertyChangeListener focusPropertyListener = new PropertyChangeListener() {
|
||||
/**
|
||||
* Listener that keeps the proxyLookup in sync with the focused area of
|
||||
* the UI.
|
||||
*
|
||||
* Since the embedded MessageContentViewer (attachments panel) is not in
|
||||
* its own TopComponenet, its selection does not get proxied into the
|
||||
* Global Actions Context (GAC), and many of the available actions don't
|
||||
* work on it. Further, we can't put the selection from both the
|
||||
* Messages table and the Attachments table in the GAC because they
|
||||
* could both include AbstractFiles, muddling the selection seen by the
|
||||
* actions. Instead, depending on where the focus is in the window, we
|
||||
* want to put different Content in the Global Actions Context to be
|
||||
* picked up by, e.g., the tagging actions. The best way I could figure
|
||||
* to do this was to listen to all focus events and swap out what is in
|
||||
* the lookup appropriately. An alternative to this would be to
|
||||
* investigate using the ContextAwareAction interface.
|
||||
*
|
||||
* @see org.sleuthkit.autopsy.timeline.TimeLineTopComponent for a
|
||||
* similar situation and a similar solution.
|
||||
*
|
||||
* @param focusEvent The focus change event.
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(final PropertyChangeEvent focusEvent) {
|
||||
if (focusEvent.getPropertyName().equalsIgnoreCase("focusOwner")) {
|
||||
final Component newFocusOwner = (Component) focusEvent.getNewValue();
|
||||
|
||||
if (newFocusOwner == null) {
|
||||
return;
|
||||
}
|
||||
if (isDescendingFrom(newFocusOwner, messageDataContent)) {
|
||||
//if the focus owner is within the MessageContentViewer ( the attachments table)
|
||||
proxyLookup.setNewLookups(createLookup(messageDataContent.getExplorerManager(), getActionMap()));
|
||||
} else if (isDescendingFrom(newFocusOwner, messagesResultPanel)) {
|
||||
//... or if it is within the Messages table.
|
||||
proxyLookup.setNewLookups(createLookup(gacExplorerManager, getActionMap()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs the right hand side of the Communications Visualization Tool
|
||||
@ -78,11 +118,13 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov
|
||||
Bundle.MessageBrowser_DataResultViewerTable_title()));
|
||||
messagesResultPanel.open();
|
||||
|
||||
//add listener that maintains correct selection in the Global Actions Context
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||
.addPropertyChangeListener("focusOwner", focusPropertyListener);
|
||||
|
||||
this.tableEM.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
/**
|
||||
* Listener that pushes selections in the tableEM (the Accounts
|
||||
* table) into the Messages table.
|
||||
*
|
||||
* @param pce The ExplorerManager event.
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent pce) {
|
||||
if (pce.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) {
|
||||
@ -130,6 +172,14 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov
|
||||
return proxyLookup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
//add listener that maintains correct selection in the Global Actions Context
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||
.addPropertyChangeListener("focusOwner", focusPropertyListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
@ -178,38 +228,4 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov
|
||||
private javax.swing.JSplitPane splitPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* Since the embedded MessageContentViewer (attachments panel) is not in its
|
||||
* own TopComponenet, its selection does not get proxied into the Global
|
||||
* Actions Context (GAC), and many of the available actions don't work on
|
||||
* it. Further, we can't put the selection from both the Messages table and
|
||||
* the Attachments table in the GAC because they could include have
|
||||
* AbstractFiles, muddling the selection seen by the actions. Instead,
|
||||
* depending on where the focus is in the window, we want to put different
|
||||
* Content in the Global Actions Context to be picked up by, e.g., the
|
||||
* tagging actions. The best way I could figure to do this was to listen to
|
||||
* all focus events and swap out what is in the lookup appropriately. An
|
||||
* alternative to this would be to investigate using the ContextAwareAction
|
||||
* interface.
|
||||
*/
|
||||
private class FocusPropertyListener implements PropertyChangeListener {
|
||||
|
||||
@Override
|
||||
public void propertyChange(final PropertyChangeEvent focusEvent) {
|
||||
|
||||
if (focusEvent.getPropertyName().equalsIgnoreCase("focusOwner")) {
|
||||
final Component newFocusOwner = (Component) focusEvent.getNewValue();
|
||||
|
||||
if (newFocusOwner != null) {
|
||||
if (isDescendingFrom(newFocusOwner, messageDataContent)) {
|
||||
//if the focus owner is within the MessageContentViewer ( the attachments table)
|
||||
proxyLookup.setNewLookups(createLookup(messageDataContent.getExplorerManager(), getActionMap()));
|
||||
} else if (isDescendingFrom(newFocusOwner, messagesResultPanel)) {
|
||||
//... or if it is within the Messages table.
|
||||
proxyLookup.setNewLookups(createLookup(gacExplorerManager, getActionMap()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,12 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
|
||||
|
||||
/**
|
||||
* Extends MessageContentViewer so that it implements DataContent and can be set
|
||||
* as the only ContentViewer for a DataResultPanel
|
||||
* as the only ContentViewer for a DataResultPanel. In addition it provides an
|
||||
* ExplorerManager.
|
||||
*
|
||||
* @see org.sleuthkit.autopsy.timeline.DataContentExplorerPanel for another
|
||||
* solution to a very similar problem.
|
||||
*
|
||||
*/
|
||||
final class MessageDataContent extends MessageContentViewer implements DataContent, ExplorerManager.Provider {
|
||||
|
||||
|
@ -37,8 +37,8 @@ final class ModifiableProxyLookup extends ProxyLookup {
|
||||
*
|
||||
* @param lookups The new Lookups to delegate to.
|
||||
*/
|
||||
void setNewLookups(final Lookup... lookups) {
|
||||
/* default */
|
||||
public void setNewLookups(final Lookup... lookups) {
|
||||
|
||||
setLookups(lookups);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-111,0,0,3,32"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,110,0,0,3,65"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
@ -68,15 +68,15 @@
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextArea" name="jTextArea1">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="lineWrap" type="boolean" value="true"/>
|
||||
<Property name="rows" type="int" value="5"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.jTextArea1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="f0" green="f0" red="f0" type="rgb"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
@ -92,7 +92,11 @@
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="clearVizButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
|
||||
<Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="fastOrganicLayoutButton" min="-2" max="-2" attributes="0"/>
|
||||
@ -103,7 +107,11 @@
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="circleLayoutButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<Component id="jSeparator2" min="-2" pref="10" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="zoomLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="zoomOutButton" min="-2" pref="32" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
@ -112,11 +120,7 @@
|
||||
<Component id="zoomActualButton" min="-2" pref="33" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="fitZoomButton" min="-2" pref="32" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="zoomLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="12" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -137,6 +141,8 @@
|
||||
<Component id="fitZoomButton" alignment="2" max="32767" attributes="0"/>
|
||||
<Component id="jLabel2" alignment="2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="zoomLabel" alignment="2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="clearVizButton" alignment="2" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jSeparator2" alignment="2" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -204,6 +210,9 @@
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToolBar$Separator" name="jSeparator1">
|
||||
<Properties>
|
||||
<Property name="orientation" type="int" value="1"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="zoomOutButton">
|
||||
<Properties>
|
||||
@ -213,11 +222,11 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomOutButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomOutButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -232,11 +241,11 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomInButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomInButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -251,11 +260,11 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomActualButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.zoomActualButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -270,11 +279,11 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.fitZoomButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.fitZoomButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
@ -295,6 +304,24 @@
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="clearVizButton">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/communications/images/broom.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/communications/Bundle.properties" key="VisualizationPanel.clearVizButton.text_1" 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="clearVizButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JToolBar$Separator" name="jSeparator2">
|
||||
<Properties>
|
||||
<Property name="orientation" type="int" value="1"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
|
@ -39,6 +39,7 @@ import com.mxgraph.util.mxUndoableEdit;
|
||||
import com.mxgraph.view.mxGraph;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
@ -106,16 +107,16 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(VisualizationPanel.class.getName());
|
||||
private static final String BASE_IMAGE_PATH = "/org/sleuthkit/autopsy/communications/images";
|
||||
static final private ImageIcon pinIcon =
|
||||
new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--pin.png"));
|
||||
static final private ImageIcon addPinIcon =
|
||||
new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--plus.png"));
|
||||
static final private ImageIcon unpinIcon =
|
||||
new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--minus.png"));
|
||||
static final private ImageIcon unlockIcon =
|
||||
new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_unlocked.png"));
|
||||
static final private ImageIcon lockIcon =
|
||||
new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_locked.png"));
|
||||
static final private ImageIcon pinIcon
|
||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--pin.png"));
|
||||
static final private ImageIcon addPinIcon
|
||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--plus.png"));
|
||||
static final private ImageIcon unpinIcon
|
||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/marker--minus.png"));
|
||||
static final private ImageIcon unlockIcon
|
||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_unlocked.png"));
|
||||
static final private ImageIcon lockIcon
|
||||
= new ImageIcon(VisualizationPanel.class.getResource(BASE_IMAGE_PATH + "/lock_large_locked.png"));
|
||||
|
||||
private static final String CANCEL = Bundle.VisualizationPanel_cancelButton_text();
|
||||
|
||||
@ -168,13 +169,17 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
//install rubber band selection handler
|
||||
rubberband = new mxRubberband(graphComponent);
|
||||
|
||||
final mxEventSource.mxIEventListener scaleListener = (Object sender, mxEventObject evt) ->
|
||||
zoomLabel.setText(DecimalFormat.getPercentInstance().format(graph.getView().getScale()));
|
||||
final mxEventSource.mxIEventListener scaleListener = (Object sender, mxEventObject evt)
|
||||
-> zoomLabel.setText(DecimalFormat.getPercentInstance().format(graph.getView().getScale()));
|
||||
graph.getView().addListener(mxEvent.SCALE, scaleListener);
|
||||
graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, scaleListener);
|
||||
|
||||
//right click handler
|
||||
graphComponent.getGraphControl().addMouseWheelListener(new MouseAdapter() {
|
||||
/**
|
||||
* Translate mouse wheel events into zooming.
|
||||
*
|
||||
* @param event The MouseWheelEvent
|
||||
*/
|
||||
@Override
|
||||
public void mouseWheelMoved(final MouseWheelEvent event) {
|
||||
super.mouseWheelMoved(event);
|
||||
@ -187,6 +192,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
});
|
||||
|
||||
graphComponent.getGraphControl().addMouseListener(new MouseAdapter() {
|
||||
/**
|
||||
* Right click handler: show context menu.
|
||||
*
|
||||
* @param event The MouseEvent
|
||||
*/
|
||||
@Override
|
||||
public void mouseClicked(final MouseEvent event) {
|
||||
super.mouseClicked(event);
|
||||
@ -247,8 +257,8 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
|
||||
//feed selection to explorermanager
|
||||
graph.getSelectionModel().addListener(null, new SelectionListener());
|
||||
final mxEventSource.mxIEventListener undoListener = (Object sender, mxEventObject evt) ->
|
||||
undoManager.undoableEditHappened((mxUndoableEdit) evt.getProperty("edit"));
|
||||
final mxEventSource.mxIEventListener undoListener = (Object sender, mxEventObject evt)
|
||||
-> undoManager.undoableEditHappened((mxUndoableEdit) evt.getProperty("edit"));
|
||||
|
||||
graph.getModel().addListener(mxEvent.UNDO, undoListener);
|
||||
graph.getView().addListener(mxEvent.UNDO, undoListener);
|
||||
@ -341,11 +351,10 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
|
||||
try {
|
||||
commsManager = Case.getOpenCase().getSleuthkitCase().getCommunicationsManager();
|
||||
} catch (IllegalStateException ex) {
|
||||
logger.log(Level.SEVERE, "Can't get CommunicationsManager when there is no case open.", ex);
|
||||
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting CommunicationsManager for the current case.", ex);
|
||||
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
logger.log(Level.SEVERE, "Can't get CommunicationsManager when there is no case open.", ex);
|
||||
}
|
||||
|
||||
Case.addEventTypeSubscriber(EnumSet.of(CURRENT_CASE), evt -> {
|
||||
@ -400,6 +409,8 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
fitZoomButton = new JButton();
|
||||
jLabel2 = new JLabel();
|
||||
zoomLabel = new JLabel();
|
||||
clearVizButton = new JButton();
|
||||
jSeparator2 = new JToolBar.Separator();
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
@ -408,11 +419,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
|
||||
borderLayoutPanel.setLayout(new BorderLayout());
|
||||
|
||||
jTextArea1.setBackground(new Color(240, 240, 240));
|
||||
jTextArea1.setColumns(20);
|
||||
jTextArea1.setLineWrap(true);
|
||||
jTextArea1.setRows(5);
|
||||
jTextArea1.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.jTextArea1.text")); // NOI18N
|
||||
jTextArea1.setBackground(new Color(240, 240, 240));
|
||||
|
||||
GroupLayout placeHolderPanelLayout = new GroupLayout(placeHolderPanel);
|
||||
placeHolderPanel.setLayout(placeHolderPanelLayout);
|
||||
@ -473,11 +484,13 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
}
|
||||
});
|
||||
|
||||
jSeparator1.setOrientation(SwingConstants.VERTICAL);
|
||||
|
||||
zoomOutButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-out-red.png"))); // NOI18N
|
||||
zoomOutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.text")); // NOI18N
|
||||
zoomOutButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.toolTipText")); // NOI18N
|
||||
zoomOutButton.setFocusable(false);
|
||||
zoomOutButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||
zoomOutButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.toolTipText")); // NOI18N
|
||||
zoomOutButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||
zoomOutButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
@ -487,9 +500,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
|
||||
zoomInButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-in-green.png"))); // NOI18N
|
||||
zoomInButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.text")); // NOI18N
|
||||
zoomInButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.toolTipText")); // NOI18N
|
||||
zoomInButton.setFocusable(false);
|
||||
zoomInButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||
zoomInButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.toolTipText")); // NOI18N
|
||||
zoomInButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||
zoomInButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
@ -499,9 +512,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
|
||||
zoomActualButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-actual.png"))); // NOI18N
|
||||
zoomActualButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.text")); // NOI18N
|
||||
zoomActualButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.toolTipText")); // NOI18N
|
||||
zoomActualButton.setFocusable(false);
|
||||
zoomActualButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||
zoomActualButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.toolTipText")); // NOI18N
|
||||
zoomActualButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||
zoomActualButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
@ -511,9 +524,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
|
||||
fitZoomButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-fit.png"))); // NOI18N
|
||||
fitZoomButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.text")); // NOI18N
|
||||
fitZoomButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.toolTipText")); // NOI18N
|
||||
fitZoomButton.setFocusable(false);
|
||||
fitZoomButton.setHorizontalTextPosition(SwingConstants.CENTER);
|
||||
fitZoomButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.toolTipText")); // NOI18N
|
||||
fitZoomButton.setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||
fitZoomButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
@ -525,11 +538,25 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
|
||||
zoomLabel.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomLabel.text")); // NOI18N
|
||||
|
||||
clearVizButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/broom.png"))); // NOI18N
|
||||
clearVizButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.clearVizButton.text_1")); // NOI18N
|
||||
clearVizButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
clearVizButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jSeparator2.setOrientation(SwingConstants.VERTICAL);
|
||||
|
||||
GroupLayout toolbarLayout = new GroupLayout(toolbar);
|
||||
toolbar.setLayout(toolbarLayout);
|
||||
toolbarLayout.setHorizontalGroup(toolbarLayout.createParallelGroup(GroupLayout.LEADING)
|
||||
.add(toolbarLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.add(clearVizButton)
|
||||
.add(3, 3, 3)
|
||||
.add(jSeparator1, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE)
|
||||
.add(5, 5, 5)
|
||||
.add(jLabel1)
|
||||
.addPreferredGap(LayoutStyle.RELATED)
|
||||
.add(fastOrganicLayoutButton)
|
||||
@ -540,7 +567,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
.addPreferredGap(LayoutStyle.RELATED)
|
||||
.add(circleLayoutButton)
|
||||
.addPreferredGap(LayoutStyle.RELATED)
|
||||
.add(jSeparator1, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE)
|
||||
.add(jSeparator2, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.RELATED)
|
||||
.add(jLabel2)
|
||||
.addPreferredGap(LayoutStyle.RELATED)
|
||||
.add(zoomLabel)
|
||||
.addPreferredGap(LayoutStyle.RELATED)
|
||||
.add(zoomOutButton, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.RELATED)
|
||||
@ -549,11 +580,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
.add(zoomActualButton, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.RELATED)
|
||||
.add(fitZoomButton, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(jLabel2)
|
||||
.addPreferredGap(LayoutStyle.RELATED)
|
||||
.add(zoomLabel)
|
||||
.add(27, 27, 27))
|
||||
.addContainerGap(12, Short.MAX_VALUE))
|
||||
);
|
||||
toolbarLayout.setVerticalGroup(toolbarLayout.createParallelGroup(GroupLayout.LEADING)
|
||||
.add(toolbarLayout.createSequentialGroup()
|
||||
@ -570,7 +597,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
.add(zoomActualButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(fitZoomButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.add(jLabel2)
|
||||
.add(zoomLabel))
|
||||
.add(zoomLabel)
|
||||
.add(clearVizButton)
|
||||
.add(jSeparator2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.add(3, 3, 3))
|
||||
);
|
||||
|
||||
@ -613,6 +642,18 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
morph(hierarchicalLayout);
|
||||
}//GEN-LAST:event_hierarchyLayoutButtonActionPerformed
|
||||
|
||||
private void clearVizButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_clearVizButtonActionPerformed
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
graph.getModel().beginUpdate();
|
||||
pinnedAccountModel.clear();
|
||||
graph.clear();
|
||||
rebuildGraph();
|
||||
// Updates the display
|
||||
graph.getModel().endUpdate();
|
||||
setCursor(Cursor.getDefaultCursor());
|
||||
|
||||
}//GEN-LAST:event_clearVizButtonActionPerformed
|
||||
|
||||
private void applyOrganicLayout(int iterations) {
|
||||
organicLayout.setMaxIterations(iterations);
|
||||
morph(organicLayout);
|
||||
@ -653,7 +694,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
ModalDialogProgressIndicator progress = new ModalDialogProgressIndicator(windowAncestor, "Computing layout", new String[]{CANCEL}, CANCEL, cancelationListener);
|
||||
SwingWorker<Void, Void> morphWorker = new SwingWorker<Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground() throws Exception {
|
||||
protected Void doInBackground() {
|
||||
progress.start("Computing layout");
|
||||
layout.execute(graph.getDefaultParent());
|
||||
if (isCancelled()) {
|
||||
@ -695,12 +736,14 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private JPanel borderLayoutPanel;
|
||||
private JButton circleLayoutButton;
|
||||
private JButton clearVizButton;
|
||||
private JButton fastOrganicLayoutButton;
|
||||
private JButton fitZoomButton;
|
||||
private JButton hierarchyLayoutButton;
|
||||
private JLabel jLabel1;
|
||||
private JLabel jLabel2;
|
||||
private JToolBar.Separator jSeparator1;
|
||||
private JToolBar.Separator jSeparator2;
|
||||
private JTextArea jTextArea1;
|
||||
private JButton organicLayoutButton;
|
||||
private JPanel placeHolderPanel;
|
||||
@ -857,7 +900,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
progress.setCancelling("Cancelling...");
|
||||
cancellable.cancel(true);
|
||||
progress.finish();
|
||||
|
BIN
Core/src/org/sleuthkit/autopsy/communications/images/broom.png
Normal file
After Width: | Height: | Size: 784 B |
@ -525,7 +525,7 @@ public final class IngestJobSettings {
|
||||
* @return The file path.
|
||||
*/
|
||||
private String getModuleSettingsFilePath(IngestModuleFactory factory) {
|
||||
String fileName = factory.getClass().getCanonicalName() + IngestJobSettings.MODULE_SETTINGS_FILE_EXT;
|
||||
String fileName = FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) + IngestJobSettings.MODULE_SETTINGS_FILE_EXT;
|
||||
Path path = Paths.get(this.moduleSettingsFolderPath, fileName);
|
||||
return path.toAbsolutePath().toString();
|
||||
}
|
||||
@ -564,7 +564,7 @@ public final class IngestJobSettings {
|
||||
* @param settings The ingest job settings for the ingest module
|
||||
*/
|
||||
private void saveModuleSettings(IngestModuleFactory factory, IngestModuleIngestJobSettings settings) {
|
||||
String moduleSettingsFilePath = Paths.get(this.moduleSettingsFolderPath, FactoryClassNameNormalizer.normalize(factory.getClass().getCanonicalName()) + MODULE_SETTINGS_FILE_EXT).toString();
|
||||
String moduleSettingsFilePath = getModuleSettingsFilePath(factory);
|
||||
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(moduleSettingsFilePath))) {
|
||||
out.writeObject(settings);
|
||||
} catch (IOException ex) {
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018 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.timeline;
|
||||
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.lookup.ProxyLookup;
|
||||
|
||||
/**
|
||||
* Extension of ProxyLookup that exposes the ability to change the Lookups
|
||||
* delegated to.
|
||||
*
|
||||
*/
|
||||
final class ModifiableProxyLookup extends ProxyLookup {
|
||||
|
||||
ModifiableProxyLookup(final Lookup... lookups) {
|
||||
super(lookups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Lookups delegated to by this lookup.
|
||||
*
|
||||
* @param lookups The new Lookups to delegate to.
|
||||
*/
|
||||
public void setNewLookups(final Lookup... lookups) {
|
||||
setLookups(lookups);
|
||||
}
|
||||
}
|
@ -18,6 +18,11 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.timeline;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
@ -36,12 +41,14 @@ import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import static javax.swing.SwingUtilities.isDescendingFrom;
|
||||
import org.controlsfx.control.Notifications;
|
||||
import org.joda.time.Interval;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.explorer.ExplorerUtils;
|
||||
import static org.openide.explorer.ExplorerUtils.createLookup;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
@ -52,6 +59,7 @@ import org.openide.windows.TopComponent;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.actions.AddBookmarkTagAction;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
@ -84,22 +92,72 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
private static final Logger LOGGER = Logger.getLogger(TimeLineTopComponent.class.getName());
|
||||
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
private final DataContentPanel contentViewerPanel;
|
||||
private final DataContentExplorerPanel contentViewerPanel;
|
||||
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
private DataResultPanel dataResultPanel;
|
||||
private final DataResultPanel dataResultPanel;
|
||||
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
private final ExplorerManager em = new ExplorerManager();
|
||||
private final ExplorerManager explorerManager = new ExplorerManager();
|
||||
|
||||
private final TimeLineController controller;
|
||||
|
||||
/** Lookup that will be exposed through the (Global Actions Context) */
|
||||
private final ModifiableProxyLookup proxyLookup = new ModifiableProxyLookup();
|
||||
|
||||
private final PropertyChangeListener focusPropertyListener = new PropertyChangeListener() {
|
||||
/**
|
||||
* Listener that drives the result viewer or content viewer (depending on
|
||||
* view mode) according to the controller's selected event IDs
|
||||
* Listener that keeps the proxyLookup in sync with the focused area of
|
||||
* the UI.
|
||||
*
|
||||
* Since the embedded MessageContentViewer (attachments panel) inside
|
||||
* the DataContentPanel is not in its own TopComponenet, its selection
|
||||
* does not get proxied into the Global Actions Context (GAC)
|
||||
* automatically, and many of the available actions don't work on it.
|
||||
* Further, we can't put the selection from both the Result table and
|
||||
* the Attachments table in the GAC because they could bouth include
|
||||
* AbstractFiles, muddling the selection seen by the actions. Instead,
|
||||
* depending on where the focus is in the window, we want to put
|
||||
* different Content in the Global Actions Context to be picked up by,
|
||||
* e.g., the tagging actions. The best way I could figure to do this was
|
||||
* to listen to all focus events and swap out what is in the lookup
|
||||
* appropriately. An alternative to this would be to investigate using
|
||||
* the ContextAwareAction interface.
|
||||
*
|
||||
* @see org.sleuthkit.autopsy.communications.MessageBrowser for a
|
||||
* similar situation and a similar solution.
|
||||
*
|
||||
* @param focusEvent The focus change event.
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(final PropertyChangeEvent focusEvent) {
|
||||
if (focusEvent.getPropertyName().equalsIgnoreCase("focusOwner")) {
|
||||
final Component newFocusOwner = (Component) focusEvent.getNewValue();
|
||||
|
||||
if (newFocusOwner == null) {
|
||||
return;
|
||||
}
|
||||
if (isDescendingFrom(newFocusOwner, contentViewerPanel)) {
|
||||
//if the focus owner is within the MessageContentViewer (the attachments table)
|
||||
proxyLookup.setNewLookups(createLookup(contentViewerPanel.getExplorerManager(), getActionMap()));
|
||||
} else if (isDescendingFrom(newFocusOwner, TimeLineTopComponent.this)) {
|
||||
//... or if it is within the Results table.
|
||||
proxyLookup.setNewLookups(createLookup(explorerManager, getActionMap()));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@NbBundle.Messages({"TimelineTopComponent.selectedEventListener.errorMsg=There was a problem getting the content for the selected event."})
|
||||
private final InvalidationListener selectedEventsListener = new InvalidationListener() {
|
||||
/**
|
||||
* Listener that drives the result viewer or content viewer (depending
|
||||
* on view mode) according to the controller's selected event IDs
|
||||
*
|
||||
* @param observable Observable that was invalidated. Usually
|
||||
* irrelevant.
|
||||
*/
|
||||
@Override
|
||||
public void invalidated(Observable observable) {
|
||||
List<Long> selectedEventIDs = controller.getSelectedEventIDs();
|
||||
@ -118,10 +176,10 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
//set generic container node as root context
|
||||
em.setRootContext(new AbstractNode(children));
|
||||
explorerManager.setRootContext(new AbstractNode(children));
|
||||
try {
|
||||
//set selected nodes for actions
|
||||
em.setSelectedNodes(childArray);
|
||||
explorerManager.setSelectedNodes(childArray);
|
||||
} catch (PropertyVetoException ex) {
|
||||
//I don't know why this would ever happen.
|
||||
LOGGER.log(Level.SEVERE, "Selecting the event node was vetoed.", ex); // NON-NLS
|
||||
@ -172,7 +230,7 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
*/
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
splitYPane.remove(contentViewerPanel);
|
||||
if ((horizontalSplitPane.getParent() == splitYPane) == false) {
|
||||
if (horizontalSplitPane.getParent() != splitYPane) {
|
||||
splitYPane.setBottomComponent(horizontalSplitPane);
|
||||
horizontalSplitPane.setRightComponent(contentViewerPanel);
|
||||
}
|
||||
@ -197,7 +255,7 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
*/
|
||||
public TimeLineTopComponent(TimeLineController controller) {
|
||||
initComponents();
|
||||
associateLookup(ExplorerUtils.createLookup(em, getActionMap()));
|
||||
associateLookup(proxyLookup);
|
||||
setName(NbBundle.getMessage(TimeLineTopComponent.class, "CTL_TimeLineTopComponent"));
|
||||
|
||||
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(AddBookmarkTagAction.BOOKMARK_SHORTCUT, "addBookmarkTag"); //NON-NLS
|
||||
@ -206,7 +264,7 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
this.controller = controller;
|
||||
|
||||
//create linked result and content views
|
||||
contentViewerPanel = DataContentPanel.createInstance();
|
||||
contentViewerPanel = new DataContentExplorerPanel();
|
||||
dataResultPanel = DataResultPanel.createInstanceUninitialized("", "", Node.EMPTY, 0, contentViewerPanel);
|
||||
|
||||
//add them to bottom splitpane
|
||||
@ -214,6 +272,7 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
horizontalSplitPane.setRightComponent(contentViewerPanel);
|
||||
|
||||
dataResultPanel.open(); //get the explorermanager
|
||||
contentViewerPanel.initialize();
|
||||
|
||||
Platform.runLater(this::initFXComponents);
|
||||
|
||||
@ -224,6 +283,10 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
//Listen to ViewMode and adjust GUI componenets as needed.
|
||||
controller.viewModeProperty().addListener(viewMode -> syncViewMode());
|
||||
syncViewMode();
|
||||
|
||||
//add listener that maintains correct selection in the Global Actions Context
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||
.addPropertyChangeListener("focusOwner", focusPropertyListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -255,7 +318,7 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
final TabPane leftTabPane = new TabPane(filterTab, eventsTreeTab);
|
||||
VBox.setVgrow(leftTabPane, Priority.ALWAYS);
|
||||
controller.viewModeProperty().addListener(viewMode -> {
|
||||
if (controller.getViewMode().equals(ViewMode.DETAIL) == false) {
|
||||
if (controller.getViewMode() != ViewMode.DETAIL) {
|
||||
//if view mode is not details, switch back to the filter tab
|
||||
leftTabPane.getSelectionModel().select(filterTab);
|
||||
}
|
||||
@ -383,11 +446,22 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
public void componentOpened() {
|
||||
super.componentOpened();
|
||||
WindowManager.getDefault().setTopComponentFloating(this, true);
|
||||
|
||||
//add listener that maintains correct selection in the Global Actions Context
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||
.addPropertyChangeListener("focusOwner", focusPropertyListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void componentClosed() {
|
||||
super.componentClosed();
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||
.removePropertyChangeListener("focusOwner", focusPropertyListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExplorerManager getExplorerManager() {
|
||||
return em;
|
||||
return explorerManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -413,6 +487,52 @@ public final class TimeLineTopComponent extends TopComponent implements Explorer
|
||||
.withZone(TimeLineController.getJodaTimeZone())
|
||||
.toString(zonedFormatter);
|
||||
return Bundle.TimeLineResultView_startDateToEndDate_text(start, end);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Panel that wraps a DataContentPanel and implements
|
||||
* ExplorerManager.Provider. This allows the explorer manager found by the
|
||||
* DataContentPanel to be controlled easily.
|
||||
*
|
||||
* @see org.sleuthkit.autopsy.communications.MessageDataContent for another
|
||||
* solution to a very similar problem.
|
||||
*/
|
||||
final private static class DataContentExplorerPanel extends JPanel implements ExplorerManager.Provider, DataContent {
|
||||
|
||||
private final ExplorerManager explorerManager = new ExplorerManager();
|
||||
private final DataContentPanel wrapped;
|
||||
|
||||
private DataContentExplorerPanel() {
|
||||
super(new BorderLayout());
|
||||
wrapped = DataContentPanel.createInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExplorerManager getExplorerManager() {
|
||||
return explorerManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNode(Node selectedNode) {
|
||||
wrapped.setNode(selectedNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
wrapped.propertyChange(evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the contents of this panel for use. Specifically add the
|
||||
* wrapped DataContentPanel to the AWT/Swing containment hierarchy. This
|
||||
* will trigger the addNotify() method of the embeded Message
|
||||
* MessageContentViewer causing it to look for a ExplorerManager; it
|
||||
* should find the one provided by this DataContentExplorerPanel.
|
||||
*/
|
||||
private void initialize() {
|
||||
add(wrapped, BorderLayout.CENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ The following are some use cases for the Central Repository:
|
||||
- <b>Alerting When Previously Notable Properties Occur</b>
|
||||
- You can use the Central Repository to record which properties were associated with files and artifacts that were evidence (or notable). Once these properties have been tagged as notable they will be added to the Interesting Items section of the tree when seen again in any future cases.
|
||||
- <b>Storing Hash Sets</b>
|
||||
- You can create and import hash sets into the central repository instead of using local copies in the \ref hash_db_page "Hash Database module". These hash sets are functionally equivalent to local hash sets but can be shared among multiple analysts (when using a PostgreSQL central repository).
|
||||
- You can create and import hash sets into the central repository instead of using local copies in the \ref hash_db_page "Hash Lookup module". These hash sets are functionally equivalent to local hash sets but can be shared among multiple analysts (when using a PostgreSQL central repository).
|
||||
|
||||
\section cr_terms Terms and Concepts
|
||||
|
||||
@ -70,7 +70,7 @@ are saved to the database, so in a multi-user setting any changes will affect al
|
||||
|
||||
Descriptions of the property types:
|
||||
- <b>Files</b>
|
||||
- Files are correlated based on MD5 hash and file path and name. The Hash Database ingest module must be enabled.
|
||||
- Files are correlated based on MD5 hash and file path and name. The Hash Lookup ingest module must be enabled.
|
||||
- <b>Domains</b>
|
||||
- Domains are extracted from the various web artifacts, which primarily come from the Recent Activity module
|
||||
- <b>Email Addresses</b>
|
||||
@ -82,7 +82,7 @@ Descriptions of the property types:
|
||||
|
||||
\subsection cr_manage_orgs Manage Organizations
|
||||
|
||||
Organizations are stored in the central repository and contain contact information for the given organization. Organizations are used for Hash Databases saved in the central repository, and can also be associated with Autopsy cases.
|
||||
Organizations are stored in the central repository and contain contact information for the given organization. Organizations are used for Hash Sets saved in the central repository, and can also be associated with Autopsy cases.
|
||||
|
||||
\image html central_repo_orgs.png
|
||||
|
||||
@ -113,6 +113,10 @@ ingest to be added to the Interesting Artifacts list in that currently open case
|
||||
If a tag is accidentally added to a file or artifact, it can be removed though the context menu. This will remove its
|
||||
notable status in the Central Repository.
|
||||
|
||||
If you would like to prevent the Interesting Items from being created in a particular case, you can disable the flagging through the run time ingest properties. Note that this only disables the Interesting Item results - all files and artifacts are still added to the central repository.
|
||||
|
||||
\image html central_repo_disable_flagging.png
|
||||
|
||||
\section cr_viewing_results Viewing Results
|
||||
|
||||
Results from enabling a central repository and running the Correlation Engine Ingest Module can be seen in two places:
|
||||
|
@ -9,7 +9,6 @@ Autopsy supports four types of data sources:
|
||||
- Logical Files: Local files or folders. (see \ref ds_log)
|
||||
- Unallocated Space Image Files: Any type of file that does not contain a file system but you want to run through ingest (see \ref ds_unalloc)
|
||||
|
||||
|
||||
\section ds_add Adding a Data Source
|
||||
|
||||
You can add a data source in several ways:
|
||||
@ -51,6 +50,7 @@ Autopsy supports disk images in the following formats:
|
||||
- EnCase (For example: *.e01, *.e02, etc)
|
||||
- Virtual Machines (For example: *.vmdk, *.vhd)
|
||||
|
||||
\image html data_source_disk_image.png
|
||||
|
||||
To add a disk image:
|
||||
|
||||
@ -58,7 +58,7 @@ To add a disk image:
|
||||
-# Browse to the first file in the disk image. You need to specify only the first file and Autopsy will find the rest.
|
||||
-# Choose the timezone that the disk image came from. This is most important for when adding FAT file systems because it does not store timezone information and Autopsy will not know how to normalize to UTC.
|
||||
-# Choose to perform orphan file finding on FAT file systems. This can be a time intensive process because it will require that Autopsy look at each sector in the device.
|
||||
|
||||
-# Optionally choose the sector size. The Auto Detect mode will work correctly on the majority of images, but if adding the data source fails you may want to try the other sector sizes.
|
||||
|
||||
\section ds_local Adding a Local Disk
|
||||
|
||||
@ -74,10 +74,10 @@ There is an option to make a copy of the local disk as a VHD during analysis. Th
|
||||
|
||||
To add a local drive:
|
||||
-# Choose "Local Disk" from the data source types.
|
||||
-# Choose the device from the pull down list.
|
||||
-# Use the "Select Disk" button to open a dialog showing the local disks. This may take a minute to load. Then select the device from the list.
|
||||
-# Choose to perform orphan file finding. See comment in \ref ds_img about this setting.
|
||||
-# Choose whether to create a VHD copy of the local disk and whether to update the image path.
|
||||
|
||||
-# Optionally choose the sector size. The Auto Detect mode will work correctly on the majority of images, but if adding the data source fails you may want to try the other sector sizes.
|
||||
|
||||
\section ds_log Adding a Logical File
|
||||
|
||||
@ -92,11 +92,14 @@ Some things to note when doing this:
|
||||
|
||||
To add logical files:
|
||||
-# Choose "Logical Files" from the data source types.
|
||||
-# Leave the top combo box on "Local files and folders"
|
||||
-# Press the "Add" button and navigate to a folder or file to add. Choosing a folder will cause all of its contents (including sub-folders) to be added.
|
||||
-# Continue to press "Add" until all files and folders have been selected.
|
||||
|
||||
All of the files that you added in the panel will be grouped together into a single data source, called "LogicalFileSet" in the main UI.
|
||||
|
||||
There is also limited support for logical evidence (L01) files. To add one as a data source, select "Logical evidence file (L01)" in the top combo box and then browse to your file.
|
||||
|
||||
\section ds_unalloc Adding an Unallocated Space Image File
|
||||
|
||||
\image html unallocated_space_options.PNG
|
||||
|
@ -27,7 +27,7 @@ Search for all files with the selected MIME type. Multiple types can be used by
|
||||
\li Date:
|
||||
Search for all files and directory whose "date property" is within the date range given. The "date properties" are "Modified Date", "Accessed Date", "Changed Date", and "Created Date". You must also specify the timezone for the date given.
|
||||
\li Known Status:
|
||||
Search for all files and directory whose known status is recognized as either Unknown, Known, or Known Bad. For more on Known Status, see Hash Database Management.
|
||||
Search for all files and directory whose known status is recognized as either Unknown, Known, or Known Bad. For more on Known Status, see the \ref hash_db_page.
|
||||
To use any of these filters, check the box next to the category and click "Search" button to start the search process. The result will show up in the "Result Viewer".
|
||||
\li MD5
|
||||
Search for all files with the given MD5 hash.
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*! \page hash_db_page Hash Database Lookup Module
|
||||
/*! \page hash_db_page Hash Lookup Module
|
||||
|
||||
What Does It Do
|
||||
========
|
||||
|
||||
The Hash Database Lookup Module calculates MD5 hash values for files and looks up hash values in a database to determine if the file is notable, known (in general), or unknown.
|
||||
The Hash Lookup Module calculates MD5 hash values for files and looks up hash values in a database to determine if the file is notable, known (in general), or unknown.
|
||||
|
||||
|
||||
Configuration
|
||||
=======
|
||||
The Hash Database Management window is where you can set and update your hash database information. Hash databases are used to identify files that are 'known'.
|
||||
The Hash Sets tab on the Options panel is where you can set and update your hash set information. Hash sets are used to identify files that are 'known' or 'notable'.
|
||||
\li Known good files are those that can be safely ignored. This set of files frequently includes standard OS and application files. Ignoring such uninteresting-to-the-investigator files, can greatly reduce image analysis time.
|
||||
\li Notable (or known bad) files are those that should raise awareness. This set will vary depending on the type of investigation, but common examples include contraband images and malware.
|
||||
|
||||
\section adding_hashsets Importing Hashsets
|
||||
\section adding_hashsets Importing Hash Sets
|
||||
|
||||
To import an existing hashset, use the "Import Database" button on the Hash Databases options panel. This will bring up a dialog to import the file.
|
||||
To import an existing hash set, use the "Import Database" button on the Hash Sets options panel. This will bring up a dialog to import the file.
|
||||
|
||||
\image html hash_import.png
|
||||
|
||||
@ -31,35 +31,35 @@ To import an existing hashset, use the "Import Database" button on the Hash Data
|
||||
|
||||
<b>Name</b> - Display name of the hash set. One will be suggested based on the file name, but this can be changed.
|
||||
|
||||
<b>Version</b> - The version of the hashset can only be entered when importing the hashset into the central repository. Additionally, no version can be entered if the database is not read-only.
|
||||
<b>Version</b> - The version of the hash set can only be entered when importing the hash set into the central repository. Additionally, no version can be entered if the hash set is not read-only.
|
||||
|
||||
<b>Source Organization</b> - The organization can only be entered when importing the hash set into the central repository. See the section on \ref cr_manage_orgs "managing organizations" for more information.
|
||||
|
||||
<b>Type of database</b> - All entries in the hash set should either be "known" (can be safely ignored) or "notable" (could be indicators of suspicious behavior).
|
||||
|
||||
<b>Make database read-only</b> - The read-only setting is only active when importing the hashset into the central repository. A read-only database can not have new hashes added to it through either the Hash Database options panel or the context menu. For locally imported hashsets, whether they can be written to is dependent on the type of hashset. Autopsy format databases (*.kdb) can be edited, but all other types will be read-only.
|
||||
<b>Make database read-only</b> - The read-only setting is only active when importing the hash set into the central repository. A read-only database can not have new hashes added to it through either the Hash Sets options panel or the context menu. For locally imported hash sets, whether they can be written to is dependent on the type of hash set. Autopsy format databases (*.kdb) can be edited, but all other types will be read-only.
|
||||
|
||||
<b>Send ingest inbox message for each hit</b> - Determines whether a message is sent for each matching file. This can not be enabled for a "known" database.
|
||||
<b>Send ingest inbox message for each hit</b> - Determines whether a message is sent for each matching file. This can not be enabled for a "known" hash set.
|
||||
|
||||
\subsection hashset_indexing Indexing
|
||||
|
||||
After importing the hashset, you may have to index it before it can be used. For most hashset types, Autopsy needs an index of the hashset to actually use a hash database. It can create the index if you import only the hashset. Any hashsets that require an index will be displayed in red, and their "Index Status" will indicate that an index needs to be created. This is done simply by using the Index button.
|
||||
After importing the hash set, you may have to index it before it can be used. For most hash set types, Autopsy needs an index of the hash set to actually use a hash set. It can create the index if you import only the hash set. Any hash sets that require an index will be displayed in red, and their "Index Status" will indicate that an index needs to be created. This is done simply by using the Index button.
|
||||
|
||||
\image html hash_indexing.png
|
||||
|
||||
Autopsy uses the hash database management system from The Sleuth Kit. You can manually create an index using the 'hfind' command line tool or you can use Autopsy. If you attempt proceed without indexing a database, Autopsy will offer to automatically produce an index for you.
|
||||
You can also specify only the index file and not use the full hashset - the index file is sufficient to identify known files. This can save space. To do this, specify the .idx file from the Hash Database Management window.
|
||||
Autopsy uses the hash set management system from The Sleuth Kit. You can manually create an index using the 'hfind' command line tool or you can use Autopsy. If you attempt proceed without indexing a hash set, Autopsy will offer to automatically produce an index for you.
|
||||
You can also specify only the index file and not use the full hash set - the index file is sufficient to identify known files. This can save space. To do this, specify the .idx file from the Hash Sets option panel.
|
||||
|
||||
\section creating_hashsets Creating Hash sets
|
||||
|
||||
New hashsets can be created using the "New Database" button. The fields are mostly the same as the \ref adding_hashsets "import dialog" described above.
|
||||
New hash sets can be created using the "New Hash Set" button. The fields are mostly the same as the \ref adding_hashsets "import dialog" described above.
|
||||
|
||||
\image html hash_new_db.png
|
||||
|
||||
In this case, the Database Path is where the new database will be stored. If the central repository is being used then this field is not needed.
|
||||
|
||||
|
||||
\section using_hashsets Using Hashsets
|
||||
\section using_hashsets Using Hash Sets
|
||||
There is an \ref ingest_page "ingest module" that will hash the files and look them up in the hash sets. It will flag files that were in the notable hash set and those results will be shown in the Results tree of the \ref tree_viewer_page.
|
||||
Other ingest modules are able to use the known status of a file to decide if they should ignore the file or process it.
|
||||
You can also see the results in the \ref how_to_open_file_search "File Search" window. There is an option to choose the 'known status'. From here, you can do a search to see all 'notable' files. From here, you can also choose to ignore all 'known' files that were found in the NSRL. You can also see the status of the file in a column when the file is listed.
|
||||
@ -68,7 +68,7 @@ NIST NSRL
|
||||
------
|
||||
Autopsy can use the <A HREF="http://www.nsrl.nist.gov">NIST NSRL</A> to detect 'known files'. The NSRL contains hashes of 'known files' that may be good or bad depending on your perspective and investigation type. For example, the existence of a piece of financial software may be interesting to your investigation and that software could be in the NSRL. Therefore, Autopsy treats files that are found in the NSRL as simply 'known' and does not specify good or bad. Ingest modules have the option of ignoring files that were found in the NSRL.
|
||||
|
||||
To use the NSRL, you may download a pre-made index from <A HREF="http://sourceforge.net/projects/autopsy/files/NSRL/">http://sourceforge.net/projects/autopsy/files/NSRL</A>. Download the <b>NSRL-XYZm-autopsy.zip </b> (where 'XYZ' is the version number. As of this writing, it is 247) and unzip the file. Use the "Tools", "Options" menu and select the "Hash Database" tab. Click "Import Database" and browse to the location of the unzipped NSRL file. You can change the Hash Set Name if desired. Select the type of database desired, choosing "Send ingest inbox message for each hit" if desired, and then click "OK".
|
||||
To use the NSRL, you may download a pre-made index from <A HREF="http://sourceforge.net/projects/autopsy/files/NSRL/">http://sourceforge.net/projects/autopsy/files/NSRL</A>. Download the <b>NSRL-XYZm-autopsy.zip </b> (where 'XYZ' is the version number. As of this writing, it is 247) and unzip the file. Use the "Tools", "Options" menu and select the "Hash Sets" tab. Click "Import Database" and browse to the location of the unzipped NSRL file. You can change the Hash Set Name if desired. Select the type of database desired, choosing "Send ingest inbox message for each hit" if desired, and then click "OK".
|
||||
|
||||
<br>
|
||||
\image html nsrl_import_process.PNG
|
||||
|
BIN
docs/doxygen-user/images/central_repo_disable_flagging.png
Normal file
After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 30 KiB |
BIN
docs/doxygen-user/images/data_source_disk_image.png
Normal file
After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 68 KiB |
BIN
docs/doxygen-user/images/photo_rec_settings.PNG
Normal file
After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 430 KiB After Width: | Height: | Size: 431 KiB |
@ -39,7 +39,7 @@ There are two places to configure ingest modules. When you select the module nam
|
||||
|
||||
There may also be an "Advanced" button that is enabled in the lower corner. Pressing this button allows you to change global settings that are not specific to a single image. This advanced configuration panel can often be found in the "Tools", "Options" menu too.
|
||||
|
||||
As an example, the hash lookup module will allow you to enable or disable hash databases in the "run time" options panel, but requires you to go to the "Advanced" dialog to add or remove hash databases from the Autopsy configuration.
|
||||
As an example, the hash lookup module will allow you to enable or disable hash sets in the "run time" options panel, but requires you to go to the "Advanced" dialog to add or remove hash sets from the Autopsy configuration.
|
||||
|
||||
\section file_filters Custom File Filters
|
||||
|
||||
@ -47,7 +47,7 @@ The file filters panel can be opened from the ingest module selection panel or t
|
||||
|
||||
\image html ingest-file-filters.PNG
|
||||
|
||||
Each filter contains one or more rules for selecting files based on file name and/or path. All files will still be displayed in the tree view, but the ingest modules will only run on a subset. If we use the previous example and run the hash module, only files ending in .png will have their hash computed.
|
||||
Each filter contains one or more rules for selecting files based on a combination of file name, path, and how recently the file was modified. All files will still be displayed in the tree view, but the ingest modules will only run on a subset. If we use the previous example and run the hash module, only files ending in .png will have their hash computed.
|
||||
|
||||
\section ingest_profiles Using Ingest Profiles
|
||||
|
||||
|
@ -49,7 +49,7 @@ The user can also use the String Viewer first and try different script/language
|
||||
\image html keyword-search-configuration-dialog-general.PNG
|
||||
|
||||
### NIST NSRL Support
|
||||
The hash database ingest service can be configured to use the NIST NSRL hash database of known files. The keyword search advanced configuration dialog "General" tab contains an option to skip keyword indexing and search on files that have previously marked as "known" and uninteresting files. Selecting this option can greatly reduce size of the index and improve ingest performance. In most cases, user does not need to keyword search for "known" files.
|
||||
The hash lookup ingest service can be configured to use the NIST NSRL hash set of known files. The keyword search advanced configuration dialog "General" tab contains an option to skip keyword indexing and search on files that have previously marked as "known" and uninteresting files. Selecting this option can greatly reduce size of the index and improve ingest performance. In most cases, user does not need to keyword search for "known" files.
|
||||
|
||||
### Result update frequency during ingest
|
||||
To control how frequently searches are executed during ingest, the user can adjust the timing setting available in the keyword search advanced configuration dialog "General" tab. Setting the number of minutes lower will result in more frequent index updates and searches being executed and the user will be able to see results more in real-time. However, more frequent updates can affect the overall performance, especially on lower-end systems, and can potentially lengthen the overall time needed for the ingest to complete.
|
||||
|
@ -20,7 +20,11 @@ Select the checkbox in the Ingest Modules settings screen to enable the PhotoRec
|
||||
|
||||
Ingest Settings
|
||||
------
|
||||
There are no run-time settings for this module, but the global setting to "Process Unallocated Space" needs to be selected to make this work.
|
||||
The run-time setting for this module allows you to choose whether to keep corrupted files.
|
||||
|
||||
\image html photo_rec_settings.png
|
||||
|
||||
Also note that the "Run ingest modules on" selection needs to include unallocated space for this module to run.
|
||||
|
||||
Seeing Results
|
||||
------
|
||||
|
@ -25,7 +25,7 @@ Autopsy will start to analyze these data sources and add them to the case and th
|
||||
You will next be prompted to configure the Ingest Modules. Ingest modules will run in the background and perform specific tasks. The Ingest Modules analyze files in a prioritized order so that files in a user's directory are analyzed before files in other folders. Ingest modules can be developed by third-parties. The standard ingest modules included with Autopsy are:
|
||||
|
||||
- <strong>\subpage recent_activity_page</strong> extracts user activity as saved by web browsers and the OS. Also runs Regripper on the registry hive.
|
||||
- <strong>\subpage hash_db_page</strong> uses hash databases to ignore known files from the NIST NSRL and flag known bad files. Use the "Advanced" button to add and configure the hash databases to use during this process. You will get updates on known bad file hits as the ingest occurs. You can later add hash databases via the Tools -> Options menu in the main UI. You can download an index of the NIST NSRL from http://sourceforge.net/projects/autopsy/files/NSRL/
|
||||
- <strong>\subpage hash_db_page</strong> uses hash sets to ignore known files from the NIST NSRL and flag known bad files. Use the "Advanced" button to add and configure the hash sets to use during this process. You will get updates on known bad file hits as the ingest occurs. You can later add hash sets via the Tools -> Options menu in the main UI. You can download an index of the NIST NSRL from http://sourceforge.net/projects/autopsy/files/NSRL/
|
||||
- <strong>\subpage file_type_identification_page</strong> determines file types based on signatures and reports them based on MIME type. It stores the results in the Blackboard and many modules depend on this. It uses the Tika open source library. You can define your own custom file types in Tools, Options, File Types.
|
||||
- <strong>\subpage embedded_file_extractor_page</strong> opens ZIP, RAR, other archive formats, Doc, Docx, PPT, PPTX, XLS, and XLSX and sends the derived files from those files back through the ingest pipeline for analysis.
|
||||
- <strong>\subpage EXIF_parser_page</strong> extracts EXIF information from JPEG files and posts the results into the tree in the main UI.
|
||||
@ -37,7 +37,7 @@ You will next be prompted to configure the Ingest Modules. Ingest modules will r
|
||||
- <strong>\subpage interesting_files_identifier_page</strong> searches for files and directories based on user-specified rules in Tools, Options, Interesting Files. It works as a "File Alerting Module". It generates messages in the inbox when specified files are found.
|
||||
- <strong>\subpage photorec_carver_page</strong> carves files from unallocated space and sends them through the file processing chain.
|
||||
|
||||
When you select a module, you will have the option to change its settings. For example, you can configure which keyword search lists to use during ingest and which hash databases to use. Refer to the individual module help for details on configuring each module.
|
||||
When you select a module, you will have the option to change its settings. For example, you can configure which keyword search lists to use during ingest and which hash sets to use. Refer to the individual module help for details on configuring each module.
|
||||
|
||||
While ingest modules are running in the background, you will see a progress bar in the lower right. You can use the GUI to review incoming results and perform other tasks while ingesting at the same time.
|
||||
|
||||
|
@ -105,7 +105,7 @@ Filters / Events
|
||||
This area allows the user to apply filters to limit what events are shown in the visualization. When the Details View is active, a tab in this area also enables navigating the visualization by event descriptions ( see the Details View section for more on this)
|
||||
|
||||
|
||||
When the __Hide Known Files__ filter is active, files with known hashes will not be included in any way in the rest of the timeline tool (except for the Histogram which shows all events). In order for this filter to work, the Hash Lookup ingest module must have been run with a Known hash database enabled.
|
||||
When the __Hide Known Files__ filter is active, files with known hashes will not be included in any way in the rest of the timeline tool (except for the Histogram which shows all events). In order for this filter to work, the Hash Lookup ingest module must have been run with a Known hash set enabled.
|
||||
|
||||
When the __Text Filter__ is active, only events with descriptions containing the supplied string as a substring will be shown. Note: this filter users the full description in its search even if not displayed.
|
||||
|
||||
|
@ -58,6 +58,7 @@
|
||||
<!-- Disabled because we have lots of undocumented fields -->
|
||||
<property name="fieldCommentRequirement" value="Ignored"/>
|
||||
<!-- Disabled because we don't require comments on overrides of public fields -->
|
||||
<property name="protectedMethodCommentRequirement" value="Ignored"/>
|
||||
<property name="publicMethodCommentRequirement" value="Ignored"/>
|
||||
<!--<property name="methodWithOverrideCommentRequirement" value="Unwanted"/>-->
|
||||
</properties>
|
||||
@ -243,7 +244,7 @@
|
||||
<rule ref="rulesets/java/optimizations.xml/AvoidArrayLoops"/>
|
||||
<rule ref="rulesets/java/optimizations.xml/UnnecessaryWrapperObjectCreation"/>
|
||||
<rule ref="rulesets/java/optimizations.xml/AddEmptyString"/>
|
||||
<rule ref="rulesets/java/optimizations.xml/RedundantFieldInitializer"/>
|
||||
<!--<rule ref="rulesets/java/optimizations.xml/RedundantFieldInitializer"/>-->
|
||||
<rule ref="rulesets/java/optimizations.xml/PrematureDeclaration"/>
|
||||
<rule ref="rulesets/java/strictexception.xml/SignatureDeclareThrowsException"/>
|
||||
<rule ref="rulesets/java/strictexception.xml/AvoidCatchingThrowable"/>
|
||||
|