From 183c34eb67240f0704003d2a7452bac52b090457 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 18 Sep 2017 16:59:06 -0400 Subject: [PATCH 01/29] 2740 File System Details now viewable through table context menu --- .../autopsy/datamodel/DirectoryNode.java | 2 + .../sleuthkit/autopsy/datamodel/FileNode.java | 2 + .../autopsy/datamodel/SlackFileNode.java | 3 +- .../autopsy/directorytree/Bundle.properties | 1 - .../directorytree/Bundle_ja.properties | 1 - .../FileSystemDetailsAction.java | 67 ++ .../directorytree/FileSystemDetailsPanel.form | 753 ++++++++---------- .../directorytree/FileSystemDetailsPanel.java | 127 ++- 8 files changed, 476 insertions(+), 480 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java index 68aeb01e8c..c480247035 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java @@ -30,6 +30,7 @@ import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.ExtractAction; +import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; @@ -82,6 +83,7 @@ public class DirectoryNode extends AbstractFsContentNode { for (Action a : super.getActions(true)) { actionsList.add(a); } + actionsList.add(new FileSystemDetailsAction(content)); if (!getDirectoryBrowseMode()) { actionsList.add(new ViewContextAction( NbBundle.getMessage(this.getClass(), "DirectoryNode.getActions.viewFileInDir.text"), this)); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java index 5190d59a87..cc66c5e9bf 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java @@ -32,6 +32,7 @@ import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; +import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; @@ -147,6 +148,7 @@ public class FileNode extends AbstractFsContentNode { public Action[] getActions(boolean context) { List actionsList = new ArrayList<>(); actionsList.addAll(Arrays.asList(super.getActions(true))); + actionsList.add(new FileSystemDetailsAction(content)); if (!this.getDirectoryBrowseMode()) { actionsList.add(new ViewContextAction(Bundle.FileNode_getActions_viewFileInDir_text(), this)); actionsList.add(null); // Creates an item separator diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/SlackFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SlackFileNode.java index 742b75ddcb..deaf9cfc3e 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/SlackFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SlackFileNode.java @@ -29,6 +29,7 @@ import org.sleuthkit.autopsy.actions.AddContentTagAction; import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.directorytree.ExtractAction; +import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; import org.sleuthkit.datamodel.AbstractFile; @@ -77,7 +78,7 @@ public class SlackFileNode extends AbstractFsContentNode { for (Action a : super.getActions(true)) { actionsList.add(a); } - + actionsList.add(new FileSystemDetailsAction(content)); if (!this.getDirectoryBrowseMode()) { actionsList.add(new ViewContextAction(NbBundle.getMessage(this.getClass(), "SlackFileNode.viewFileInDir.text"), this.content)); actionsList.add(null); // creates a menu separator diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties index c382e012b7..1243a04294 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties @@ -14,7 +14,6 @@ FileSystemDetailsPanel.blockCountValue.text=... FileSystemDetailsPanel.rootInumValue.text=... FileSystemDetailsPanel.firstInumValue.text=... FileSystemDetailsPanel.lastInumValue.text=... -FileSystemDetailsPanel.jLabel1.text=Detailed File Information FileSystemDetailsPanel.volumeIDLabel.text=Volume ID: FileSystemDetailsPanel.blockSizeLabel.text=Block Size: FileSystemDetailsPanel.blockCountLabel.text=Block Count: diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties index 8ddb1552a2..c26e601051 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties @@ -14,7 +14,6 @@ FileSystemDetailsPanel.blockCountValue.text=... FileSystemDetailsPanel.rootInumValue.text=... FileSystemDetailsPanel.firstInumValue.text=... FileSystemDetailsPanel.lastInumValue.text=... -FileSystemDetailsPanel.jLabel1.text=\u30d5\u30a1\u30a4\u30eb\u8a73\u7d30\u60c5\u5831 FileSystemDetailsPanel.volumeIDLabel.text=\u30dc\u30ea\u30e5\u30fc\u30e0ID\uff1a FileSystemDetailsPanel.blockSizeLabel.text=\u30d6\u30ed\u30c3\u30af\u30b5\u30a4\u30ba\uff1a FileSystemDetailsPanel.blockCountLabel.text=\u30d6\u30ed\u30c3\u30af\u6570\uff1a diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java new file mode 100644 index 0000000000..cb7ab3de05 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java @@ -0,0 +1,67 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.directorytree; + +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.AbstractAction; +import javax.swing.JDialog; +import javax.swing.JFrame; +import org.openide.util.NbBundle; +import org.openide.windows.WindowManager; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.FsContent; + +/** + * + * @author wschaefer + */ +public class FileSystemDetailsAction extends AbstractAction { + + final Content fsContent; + + @NbBundle.Messages({"FileSystemDetailsAction.title.text=File System Details"}) + public FileSystemDetailsAction(Content content) { + super(Bundle.FileSystemDetailsAction_title_text()); + fsContent = content; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (fsContent instanceof FsContent) { + FileSystemDetailsDialog fsDetailsDialog = new FileSystemDetailsDialog(); + fsDetailsDialog.display((FsContent) fsContent); + } + } + + private final class FileSystemDetailsDialog extends JDialog implements ActionListener { + + private FileSystemDetailsDialog() { + super((JFrame) WindowManager.getDefault().getMainWindow(), + Bundle.FileSystemDetailsAction_title_text(), + false); + } + + private void display(FsContent content) { + FileSystemDetailsPanel fsPanel = new FileSystemDetailsPanel(content); + fsPanel.setOKButtonActionListener(this); + setContentPane(fsPanel); + pack(); + Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); + setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2); + setVisible(true); + } + + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form index 0b460a54c4..b5eeee1b1f 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form @@ -19,12 +19,12 @@ - - + + - - + + @@ -35,10 +35,10 @@ - - + + - + @@ -51,427 +51,364 @@ - + - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + + + + - + - - - - - - - - - - + + + + - + + + + + + + + + + + + + + + + + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java index c751014552..7efbf9abe0 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java @@ -18,15 +18,20 @@ */ package org.sleuthkit.autopsy.directorytree; -import java.awt.*; import java.awt.event.ActionListener; +import org.openide.util.Exceptions; +import org.sleuthkit.datamodel.FileSystem; +import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.TskCoreException; /** * This is the form / panel to show the File System Details. * * @author jantonius */ -class FileSystemDetailsPanel extends javax.swing.JPanel { +final class FileSystemDetailsPanel extends javax.swing.JPanel { + + private static final long serialVersionUID = 1L; /** * Creates new form FileSystemDetailsPanel @@ -35,6 +40,24 @@ class FileSystemDetailsPanel extends javax.swing.JPanel { initComponents(); } + FileSystemDetailsPanel(FsContent content) { + initComponents(); + try { + FileSystem fSystem = content.getFileSystem(); + setFileSystemTypeValue(fSystem.getFsType().toString()); + setImageOffsetValue(Long.toString(fSystem.getImageOffset())); + setVolumeIDValue(Long.toString(fSystem.getId())); + setBlockSizeValue(Long.toString(fSystem.getBlock_size())); + setBlockCountValue(Long.toString(fSystem.getBlock_count())); + setRootInumValue(Long.toString(fSystem.getRoot_inum())); + setFirstInumValue(Long.toString(fSystem.getFirst_inum())); + setLastInumValue(Long.toString(fSystem.getLastInum())); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + + } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -45,7 +68,6 @@ class FileSystemDetailsPanel extends javax.swing.JPanel { private void initComponents() { OKButton = new javax.swing.JButton(); - jSplitPane1 = new javax.swing.JSplitPane(); genInfoPanel = new javax.swing.JPanel(); fsTypeLabel = new javax.swing.JLabel(); imgOffsetLabel = new javax.swing.JLabel(); @@ -67,14 +89,9 @@ class FileSystemDetailsPanel extends javax.swing.JPanel { jSeparator1 = new javax.swing.JSeparator(); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); - detailInfoPanel = new javax.swing.JPanel(); - jLabel1 = new javax.swing.JLabel(); OKButton.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.OKButton.text")); // NOI18N - jSplitPane1.setDividerLocation(180); - jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - genInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); genInfoPanel.setPreferredSize(new java.awt.Dimension(815, 170)); @@ -142,45 +159,47 @@ class FileSystemDetailsPanel extends javax.swing.JPanel { genInfoPanelLayout.setHorizontalGroup( genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createSequentialGroup() - .addGap(95, 95, 95) + .addGap(10, 10, 10) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(fsTypeLabel) .addComponent(imgOffsetLabel) .addComponent(volumeIDLabel) .addComponent(blockSizeLabel)) - .addGap(108, 108, 108) - .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(genInfoLabel) + .addGap(10, 10, 10) + .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(genInfoPanelLayout.createSequentialGroup() - .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(blockSizeValue) - .addComponent(volumeIDValue) - .addComponent(imgOffsetValue) - .addComponent(fsTypeValue)) - .addGap(31, 31, 31) - .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel2) - .addComponent(jLabel3)) - .addGap(33, 33, 33) + .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(genInfoPanelLayout.createSequentialGroup() + .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(blockSizeValue, javax.swing.GroupLayout.DEFAULT_SIZE, 112, Short.MAX_VALUE) + .addComponent(imgOffsetValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel3))) + .addComponent(volumeIDValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(fsTypeValue, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(10, 10, 10) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(31, 31, 31) + .addGap(10, 10, 10) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(blockCountLabel) .addComponent(rootInumLabel) .addComponent(firstInumLabel) - .addComponent(lastInumLabel)) - .addGap(111, 111, 111) - .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lastInumValue) - .addComponent(firstInumValue) - .addComponent(rootInumValue) - .addComponent(blockCountValue)))) - .addGap(245, 245, 245)) + .addComponent(lastInumLabel))) + .addComponent(genInfoLabel)) + .addGap(10, 10, 10) + .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(blockCountValue, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE) + .addComponent(rootInumValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(firstInumValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lastInumValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); genInfoPanelLayout.setVerticalGroup( genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, genInfoPanelLayout.createSequentialGroup() - .addContainerGap(23, Short.MAX_VALUE) + .addContainerGap(19, Short.MAX_VALUE) .addComponent(genInfoLabel) .addGap(18, 18, 18) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -222,57 +241,30 @@ class FileSystemDetailsPanel extends javax.swing.JPanel { .addComponent(firstInumLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(lastInumLabel))) - .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)) + .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 96, Short.MAX_VALUE)) .addContainerGap()) ); - jSplitPane1.setTopComponent(genInfoPanel); - - detailInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - detailInfoPanel.setPreferredSize(new java.awt.Dimension(516, 293)); - - jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD, 18)); - jLabel1.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.jLabel1.text")); // NOI18N - - javax.swing.GroupLayout detailInfoPanelLayout = new javax.swing.GroupLayout(detailInfoPanel); - detailInfoPanel.setLayout(detailInfoPanelLayout); - detailInfoPanelLayout.setHorizontalGroup( - detailInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, detailInfoPanelLayout.createSequentialGroup() - .addContainerGap(278, Short.MAX_VALUE) - .addComponent(jLabel1) - .addGap(276, 276, 276)) - ); - detailInfoPanelLayout.setVerticalGroup( - detailInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(detailInfoPanelLayout.createSequentialGroup() - .addGap(23, 23, 23) - .addComponent(jLabel1) - .addContainerGap(235, Short.MAX_VALUE)) - ); - - jSplitPane1.setRightComponent(detailInfoPanel); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(367, 367, 367) - .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 786, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(genInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 534, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addGap(222, 222, 222) + .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) + .addComponent(genInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(OKButton) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -364,7 +356,6 @@ class FileSystemDetailsPanel extends javax.swing.JPanel { private javax.swing.JLabel blockCountValue; private javax.swing.JLabel blockSizeLabel; private javax.swing.JLabel blockSizeValue; - private javax.swing.JPanel detailInfoPanel; private javax.swing.JLabel firstInumLabel; private javax.swing.JLabel firstInumValue; private javax.swing.JLabel fsTypeLabel; @@ -373,11 +364,9 @@ class FileSystemDetailsPanel extends javax.swing.JPanel { private javax.swing.JPanel genInfoPanel; private javax.swing.JLabel imgOffsetLabel; private javax.swing.JLabel imgOffsetValue; - private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JSeparator jSeparator1; - private javax.swing.JSplitPane jSplitPane1; private javax.swing.JLabel lastInumLabel; private javax.swing.JLabel lastInumValue; private javax.swing.JLabel rootInumLabel; From f8433ba2384fd62841fb0d185ea68146e6746c46 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 19 Sep 2017 11:15:27 -0400 Subject: [PATCH 02/29] 2740 moved adding of action up to parent class of all implementations --- .../autopsy/datamodel/AbstractFsContentNode.java | 13 +++++++++++++ .../sleuthkit/autopsy/datamodel/DirectoryNode.java | 2 -- .../org/sleuthkit/autopsy/datamodel/FileNode.java | 3 +-- .../sleuthkit/autopsy/datamodel/SlackFileNode.java | 2 -- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index b8a6807c24..0d48250e2b 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -18,11 +18,16 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import javax.swing.Action; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction; import org.sleuthkit.datamodel.AbstractFile; /** @@ -60,6 +65,14 @@ public abstract class AbstractFsContentNode extends Abst return directoryBrowseMode; } + @Override + public Action[] getActions(boolean context) { + List actionsList = new ArrayList<>(); + actionsList.addAll(Arrays.asList(super.getActions(true))); + actionsList.add(new FileSystemDetailsAction(content)); + return actionsList.toArray(new Action[actionsList.size()]); + } + @Override protected Sheet createSheet() { Sheet s = super.createSheet(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java index c480247035..68aeb01e8c 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java @@ -30,7 +30,6 @@ import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.ExtractAction; -import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; @@ -83,7 +82,6 @@ public class DirectoryNode extends AbstractFsContentNode { for (Action a : super.getActions(true)) { actionsList.add(a); } - actionsList.add(new FileSystemDetailsAction(content)); if (!getDirectoryBrowseMode()) { actionsList.add(new ViewContextAction( NbBundle.getMessage(this.getClass(), "DirectoryNode.getActions.viewFileInDir.text"), this)); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java index cc66c5e9bf..39c1464e3c 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileNode.java @@ -32,7 +32,6 @@ import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; -import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction; import org.sleuthkit.autopsy.directorytree.HashSearchAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; @@ -148,7 +147,7 @@ public class FileNode extends AbstractFsContentNode { public Action[] getActions(boolean context) { List actionsList = new ArrayList<>(); actionsList.addAll(Arrays.asList(super.getActions(true))); - actionsList.add(new FileSystemDetailsAction(content)); + if (!this.getDirectoryBrowseMode()) { actionsList.add(new ViewContextAction(Bundle.FileNode_getActions_viewFileInDir_text(), this)); actionsList.add(null); // Creates an item separator diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/SlackFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SlackFileNode.java index deaf9cfc3e..60d3912a84 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/SlackFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SlackFileNode.java @@ -29,7 +29,6 @@ import org.sleuthkit.autopsy.actions.AddContentTagAction; import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.directorytree.ExtractAction; -import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; import org.sleuthkit.datamodel.AbstractFile; @@ -78,7 +77,6 @@ public class SlackFileNode extends AbstractFsContentNode { for (Action a : super.getActions(true)) { actionsList.add(a); } - actionsList.add(new FileSystemDetailsAction(content)); if (!this.getDirectoryBrowseMode()) { actionsList.add(new ViewContextAction(NbBundle.getMessage(this.getClass(), "SlackFileNode.viewFileInDir.text"), this.content)); actionsList.add(null); // creates a menu separator From 01f724bcee1db8d9785d44758ac7445fbbe27a66 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 20 Sep 2017 13:56:17 -0400 Subject: [PATCH 03/29] 2740 File system details box clean up --- .../autopsy/directorytree/Bundle.properties | 1 - .../directorytree/Bundle_ja.properties | 1 - .../FileSystemDetailsAction.java | 22 +++++-- .../directorytree/FileSystemDetailsPanel.form | 63 +++++++------------ .../directorytree/FileSystemDetailsPanel.java | 54 +++++++--------- 5 files changed, 61 insertions(+), 80 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties index 1243a04294..aa8f1f3a90 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle.properties @@ -3,7 +3,6 @@ HINT_DirectoryTreeTopComponent=This is a DirectoryTree window OpenIDE-Module-Name=DirectoryTree FileSystemDetailsPanel.imgOffsetLabel.text=Image Offset: FileSystemDetailsPanel.fsTypeLabel.text=FileSystem Type: -FileSystemDetailsPanel.genInfoLabel.text=General File Information FileSystemDetailsPanel.jLabel2.text=bytes FileSystemDetailsPanel.jLabel3.text=bytes FileSystemDetailsPanel.fsTypeValue.text=... diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties index c26e601051..2fb64c5bea 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/directorytree/Bundle_ja.properties @@ -3,7 +3,6 @@ HINT_DirectoryTreeTopComponent=\u3053\u308c\u306f\u30c7\u30a3\u30ec\u30af\u30c8\ OpenIDE-Module-Name=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30c4\u30ea\u30fc FileSystemDetailsPanel.imgOffsetLabel.text=\u30a4\u30e1\u30fc\u30b8\u30aa\u30d5\u30bb\u30c3\u30c8\uff1a FileSystemDetailsPanel.fsTypeLabel.text=\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u30bf\u30a4\u30d7\uff1a -FileSystemDetailsPanel.genInfoLabel.text=\u30d5\u30a1\u30a4\u30eb\u4e00\u822c\u60c5\u5831 FileSystemDetailsPanel.jLabel2.text=\u30d0\u30a4\u30c8 FileSystemDetailsPanel.jLabel3.text=\u30d0\u30a4\u30c8 FileSystemDetailsPanel.fsTypeValue.text=... diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java index cb7ab3de05..1f3fd2bf7b 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.directorytree; @@ -18,8 +31,7 @@ import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.FsContent; /** - * - * @author wschaefer + * Action which opens a dialog containing the FileSystemDetailsPanel. */ public class FileSystemDetailsAction extends AbstractAction { diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form index b5eeee1b1f..fc323af4c7 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form @@ -23,7 +23,7 @@ - + @@ -35,8 +35,8 @@ - - + + @@ -75,34 +75,29 @@ - + - - - - - - - - - - - - - + + - - - + - - - - + + - + + + + + + + + + + + @@ -118,9 +113,7 @@ - - - + @@ -168,7 +161,7 @@ - + @@ -368,18 +361,6 @@ - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java index 7efbf9abe0..6705f6579c 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011 Basis Technology Corp. + * Copyright 2011-2017 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -85,7 +85,6 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { rootInumValue = new javax.swing.JLabel(); firstInumValue = new javax.swing.JLabel(); lastInumValue = new javax.swing.JLabel(); - genInfoLabel = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JSeparator(); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); @@ -143,9 +142,6 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { lastInumValue.setFont(lastInumValue.getFont().deriveFont(lastInumValue.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); lastInumValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.lastInumValue.text")); // NOI18N - genInfoLabel.setFont(genInfoLabel.getFont().deriveFont(genInfoLabel.getFont().getStyle() | java.awt.Font.BOLD, 18)); - genInfoLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.genInfoLabel.text")); // NOI18N - jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL); jLabel2.setFont(jLabel2.getFont().deriveFont(jLabel2.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); @@ -166,28 +162,25 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { .addComponent(volumeIDLabel) .addComponent(blockSizeLabel)) .addGap(10, 10, 10) - .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(genInfoPanelLayout.createSequentialGroup() .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addGroup(genInfoPanelLayout.createSequentialGroup() - .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(blockSizeValue, javax.swing.GroupLayout.DEFAULT_SIZE, 112, Short.MAX_VALUE) - .addComponent(imgOffsetValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel2) - .addComponent(jLabel3))) - .addComponent(volumeIDValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(fsTypeValue, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(10, 10, 10) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(10, 10, 10) + .addComponent(blockSizeValue, javax.swing.GroupLayout.DEFAULT_SIZE, 112, Short.MAX_VALUE) + .addComponent(imgOffsetValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(blockCountLabel) - .addComponent(rootInumLabel) - .addComponent(firstInumLabel) - .addComponent(lastInumLabel))) - .addComponent(genInfoLabel)) + .addComponent(jLabel2) + .addComponent(jLabel3))) + .addComponent(volumeIDValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(fsTypeValue, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(10, 10, 10) + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(blockCountLabel) + .addComponent(rootInumLabel) + .addComponent(firstInumLabel) + .addComponent(lastInumLabel)) .addGap(10, 10, 10) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(blockCountValue, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE) @@ -199,9 +192,7 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { genInfoPanelLayout.setVerticalGroup( genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, genInfoPanelLayout.createSequentialGroup() - .addContainerGap(19, Short.MAX_VALUE) - .addComponent(genInfoLabel) - .addGap(18, 18, 18) + .addGap(10, 10, 10) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -241,7 +232,7 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { .addComponent(firstInumLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(lastInumLabel))) - .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 96, Short.MAX_VALUE)) + .addComponent(jSeparator1)) .addContainerGap()) ); @@ -255,7 +246,7 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { .addContainerGap() .addComponent(genInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 534, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() - .addGap(222, 222, 222) + .addGap(221, 221, 221) .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -263,8 +254,8 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(genInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(genInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(OKButton) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -360,7 +351,6 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { private javax.swing.JLabel firstInumValue; private javax.swing.JLabel fsTypeLabel; private javax.swing.JLabel fsTypeValue; - private javax.swing.JLabel genInfoLabel; private javax.swing.JPanel genInfoPanel; private javax.swing.JLabel imgOffsetLabel; private javax.swing.JLabel imgOffsetValue; From e4b477c50e7e46076e9fc3fe11be9a1591877b02 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 21 Sep 2017 11:16:09 -0400 Subject: [PATCH 04/29] 2740 file system details action now occurs off of volume nodes --- .../datamodel/AbstractFsContentNode.java | 13 -------- .../autopsy/datamodel/VolumeNode.java | 3 +- .../DirectoryTreeFilterNode.java | 23 +++++++------ .../FileSystemDetailsAction.java | 33 ++++++++++++------- .../directorytree/FileSystemDetailsPanel.java | 15 +++++---- 5 files changed, 45 insertions(+), 42 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index 0d48250e2b..b8a6807c24 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -18,16 +18,11 @@ */ package org.sleuthkit.autopsy.datamodel; -import java.util.ArrayList; -import java.util.Arrays; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; -import javax.swing.Action; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction; import org.sleuthkit.datamodel.AbstractFile; /** @@ -65,14 +60,6 @@ public abstract class AbstractFsContentNode extends Abst return directoryBrowseMode; } - @Override - public Action[] getActions(boolean context) { - List actionsList = new ArrayList<>(); - actionsList.addAll(Arrays.asList(super.getActions(true))); - actionsList.add(new FileSystemDetailsAction(content)); - return actionsList.toArray(new Action[actionsList.size()]); - } - @Override protected Sheet createSheet() { Sheet s = super.createSheet(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java index ee5a5713a3..62230a5422 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java @@ -36,6 +36,7 @@ import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.VirtualDirectory; import org.sleuthkit.datamodel.Volume; +import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction; /** * This class is used to represent the "Node" for the volume. Its child is the @@ -139,7 +140,7 @@ public class VolumeNode extends AbstractContentNode { for (Action a : super.getActions(true)) { actionsList.add(a); } - + actionsList.add(new FileSystemDetailsAction(content)); actionsList.add(new NewWindowViewAction( NbBundle.getMessage(this.getClass(), "VolumeNode.getActions.viewInNewWin.text"), this)); actionsList.addAll(ExplorerNodeActionVisitor.getActions(content)); diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java index a515fe17de..045447a7f8 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java @@ -42,6 +42,7 @@ import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.VirtualDirectory; +import org.sleuthkit.datamodel.Volume; /** * A node filter (decorator) that sets the actions for a node in the tree view @@ -78,9 +79,10 @@ class DirectoryTreeFilterNode extends FilterNode { public String getDisplayName() { final Node orig = getOriginal(); String name = orig.getDisplayName(); + if (orig instanceof AbstractContentNode) { AbstractFile file = getLookup().lookup(AbstractFile.class); - if ((file != null) && (false == (orig instanceof BlackboardArtifactNode)) ){ + if ((file != null) && (false == (orig instanceof BlackboardArtifactNode))) { try { int numVisibleChildren = getVisibleChildCount(file); @@ -94,14 +96,13 @@ class DirectoryTreeFilterNode extends FilterNode { } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error getting children count to display for file: " + file, ex); //NON-NLS } - } - else if (orig instanceof BlackboardArtifactNode) { - BlackboardArtifact artifact = ((BlackboardArtifactNode) orig).getArtifact(); + } else if (orig instanceof BlackboardArtifactNode) { + BlackboardArtifact artifact = ((BlackboardArtifactNode) orig).getArtifact(); try { int numAttachments = artifact.getChildrenCount(); name = name + " \u200E(\u200E" + numAttachments + ")\u200E"; //NON-NLS } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error getting chidlren count for atifact: " + artifact, ex); //NON-NLS + logger.log(Level.SEVERE, "Error getting chidlren count for atifact: " + artifact, ex); //NON-NLS } } } @@ -134,18 +135,17 @@ class DirectoryTreeFilterNode extends FilterNode { || (purgeSlackFiles && childFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)) { numVisibleChildren--; } - } else if(child instanceof BlackboardArtifact){ + } else if (child instanceof BlackboardArtifact) { BlackboardArtifact bba = (BlackboardArtifact) child; - + // Only message type artifacts are displayed in the tree - if((bba.getArtifactTypeID() != ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) - && (bba.getArtifactTypeID() != ARTIFACT_TYPE.TSK_MESSAGE.getTypeID())){ + if ((bba.getArtifactTypeID() != ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) + && (bba.getArtifactTypeID() != ARTIFACT_TYPE.TSK_MESSAGE.getTypeID())) { numVisibleChildren--; } } } } - return numVisibleChildren; } @@ -163,6 +163,9 @@ class DirectoryTreeFilterNode extends FilterNode { List actions = new ArrayList<>(); final Content content = this.getLookup().lookup(Content.class); if (content != null) { + if (content instanceof Volume) { + actions.add(new FileSystemDetailsAction((Volume) content)); + } actions.addAll(ExplorerNodeActionVisitor.getActions(content)); Directory dir = this.getLookup().lookup(Directory.class); diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java index 1f3fd2bf7b..ff9b00e9af 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsAction.java @@ -22,44 +22,55 @@ import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.JDialog; import javax.swing.JFrame; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; -import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.Volume; +import org.sleuthkit.datamodel.TskCoreException; /** * Action which opens a dialog containing the FileSystemDetailsPanel. */ -public class FileSystemDetailsAction extends AbstractAction { - - final Content fsContent; +final public class FileSystemDetailsAction extends AbstractAction { + private static final Logger logger = Logger.getLogger(FileSystemDetailsPanel.class.getName()); + final Volume fsContent; @NbBundle.Messages({"FileSystemDetailsAction.title.text=File System Details"}) - public FileSystemDetailsAction(Content content) { + public FileSystemDetailsAction(Volume content) { super(Bundle.FileSystemDetailsAction_title_text()); + enabled = false; fsContent = content; + try { + if (!fsContent.getFileSystems().isEmpty()) { + enabled = true; + } + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Unable to create FileSystemDetailsAction", ex); + } } @Override public void actionPerformed(ActionEvent e) { - if (fsContent instanceof FsContent) { - FileSystemDetailsDialog fsDetailsDialog = new FileSystemDetailsDialog(); - fsDetailsDialog.display((FsContent) fsContent); - } + FileSystemDetailsDialog fsDetailsDialog = new FileSystemDetailsDialog(); + fsDetailsDialog.display(fsContent); + } private final class FileSystemDetailsDialog extends JDialog implements ActionListener { + private static final long serialVersionUID = 1L; + private FileSystemDetailsDialog() { super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.FileSystemDetailsAction_title_text(), false); } - private void display(FsContent content) { + private void display(Volume content) { FileSystemDetailsPanel fsPanel = new FileSystemDetailsPanel(content); fsPanel.setOKButtonActionListener(this); setContentPane(fsPanel); diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java index 6705f6579c..8b8dab1d87 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java @@ -19,9 +19,10 @@ package org.sleuthkit.autopsy.directorytree; import java.awt.event.ActionListener; -import org.openide.util.Exceptions; +import java.util.logging.Level; +import java.util.logging.Logger; import org.sleuthkit.datamodel.FileSystem; -import org.sleuthkit.datamodel.FsContent; +import org.sleuthkit.datamodel.Volume; import org.sleuthkit.datamodel.TskCoreException; /** @@ -30,7 +31,7 @@ import org.sleuthkit.datamodel.TskCoreException; * @author jantonius */ final class FileSystemDetailsPanel extends javax.swing.JPanel { - + private static final Logger logger = Logger.getLogger(FileSystemDetailsPanel.class.getName()); private static final long serialVersionUID = 1L; /** @@ -40,10 +41,10 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { initComponents(); } - FileSystemDetailsPanel(FsContent content) { + FileSystemDetailsPanel(Volume content) { initComponents(); try { - FileSystem fSystem = content.getFileSystem(); + FileSystem fSystem = content.getFileSystems().get(0); //Autopsy currently only supports one file system per Volume setFileSystemTypeValue(fSystem.getFsType().toString()); setImageOffsetValue(Long.toString(fSystem.getImageOffset())); setVolumeIDValue(Long.toString(fSystem.getId())); @@ -52,8 +53,8 @@ final class FileSystemDetailsPanel extends javax.swing.JPanel { setRootInumValue(Long.toString(fSystem.getRoot_inum())); setFirstInumValue(Long.toString(fSystem.getFirst_inum())); setLastInumValue(Long.toString(fSystem.getLastInum())); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); + } catch (TskCoreException|ArrayIndexOutOfBoundsException ex) { + logger.log(Level.SEVERE, "Unable to construct FileSystemDetailsPanel",ex); } } From 5d037a403c7f5124c8f5af1670224b53cc7002c3 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 21 Sep 2017 12:46:56 -0400 Subject: [PATCH 05/29] 2740 added Properties action to directory tree node context menu --- .../autopsy/directorytree/DirectoryTreeFilterNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java index 045447a7f8..5ff69ba29a 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.directorytree; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.logging.Level; @@ -161,6 +162,7 @@ class DirectoryTreeFilterNode extends FilterNode { @Override public Action[] getActions(boolean context) { List actions = new ArrayList<>(); + actions.addAll(Arrays.asList(super.getActions(true))); final Content content = this.getLookup().lookup(Content.class); if (content != null) { if (content instanceof Volume) { From 2174f2c0409d155ec9964e46391276b9301b278f Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 21 Sep 2017 17:15:59 -0400 Subject: [PATCH 06/29] 2740 moved Properties context action adding to after null content check --- .../autopsy/directorytree/DirectoryTreeFilterNode.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java index 5ff69ba29a..a1bd1d9116 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java @@ -162,9 +162,10 @@ class DirectoryTreeFilterNode extends FilterNode { @Override public Action[] getActions(boolean context) { List actions = new ArrayList<>(); - actions.addAll(Arrays.asList(super.getActions(true))); + final Content content = this.getLookup().lookup(Content.class); if (content != null) { + actions.addAll(Arrays.asList(super.getActions(true))); if (content instanceof Volume) { actions.add(new FileSystemDetailsAction((Volume) content)); } From e0e1c3dce4ea89f23943229683a451a4f3704ae4 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 22 Sep 2017 13:42:24 -0400 Subject: [PATCH 07/29] 3081 correct reset of recent central repo artifacts --- .../eventlisteners/IngestEventsListener.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index cdedd03c83..430b9c07a9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -51,7 +51,7 @@ public class IngestEventsListener { private static final Logger LOGGER = Logger.getLogger(EamArtifact.class.getName()); - final Collection addedCeArtifactTrackerSet = new LinkedHashSet<>(); + final Collection recentlyAddedCeArtifacts = new LinkedHashSet<>(); private static int ceModuleInstanceCount = 0; private final PropertyChangeListener pcl1 = new IngestModuleEventListener(); private final PropertyChangeListener pcl2 = new IngestJobEventListener(); @@ -139,7 +139,7 @@ public class IngestEventsListener { for (EamArtifact eamArtifact : convertedArtifacts) { try { // Only do something with this artifact if it's unique within the job - if (addedCeArtifactTrackerSet.add(eamArtifact.toString())) { + if (recentlyAddedCeArtifacts.add(eamArtifact.toString())) { // Was it previously marked as bad? // query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad". // if gettKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case, @@ -180,10 +180,10 @@ public class IngestEventsListener { switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) { case DATA_SOURCE_ANALYSIS_COMPLETED: { // clear the tracker to reduce memory usage - // @@@ This isnt' entirely accurate to do here. We could have multiple - // ingest jobs at the same time - addedCeArtifactTrackerSet.clear(); - + if (getCeModuleInstanceCount() == 0) { + recentlyAddedCeArtifacts.clear(); + } + //else another instance of the Correlation Engine Module is still being run. } // DATA_SOURCE_ANALYSIS_COMPLETED break; } From 61cdebf9eff06931b4d8e3acde80683c7f4e01cb Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sat, 23 Sep 2017 21:51:23 +0200 Subject: [PATCH 08/29] remove null checks --- .../autopsy/keywordsearch/AccountsText.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java index ac94008115..20f8105751 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java @@ -228,14 +228,10 @@ class AccountsText implements IndexedText { //add both the canonical form and the form in the text as accountNumbers to highlight. BlackboardAttribute attribute = artifact.getAttribute(TSK_KEYWORD); - if (attribute != null) { - this.accountNumbers.add(attribute.getValueString()); - } + this.accountNumbers.add(attribute.getValueString()); attribute = artifact.getAttribute(TSK_CARD_NUMBER); - if (attribute != null) { - this.accountNumbers.add(attribute.getValueString()); - } - + this.accountNumbers.add(attribute.getValueString()); + //if the chunk id is present just use that. Optional chunkID = Optional.ofNullable(artifact.getAttribute(TSK_KEYWORD_SEARCH_DOCUMENT_ID)) @@ -323,7 +319,7 @@ class AccountsText implements IndexedText { // extracted content (minus highlight tags) is HTML-escaped return "
" + highlightedText + "
"; //NON-NLS } catch (Exception ex) { - logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + this.solrObjectId + ", chunkID " + this.currentPage , ex); //NON-NLS + logger.log(Level.SEVERE, "Error getting highlighted text for Solr doc id " + this.solrObjectId + ", chunkID " + this.currentPage, ex); //NON-NLS return Bundle.AccountsText_getMarkup_queryFailedMsg(); } } From e7cc636e17ea891ea2c95ccb7314baf065f36780 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Sun, 24 Sep 2017 21:17:39 +0200 Subject: [PATCH 09/29] cleanup in AccountsText --- .../autopsy/keywordsearch/AccountsText.java | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java index 20f8105751..365655103b 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java @@ -55,6 +55,8 @@ class AccountsText implements IndexedText { private static final Logger logger = Logger.getLogger(AccountsText.class.getName()); private static final boolean DEBUG = (Version.getBuildType() == Version.Type.DEVELOPMENT); + private static final String CCN_REGEX = "(%?)(B?)([0-9][ \\-]*?){12,19}(\\^?)"; + private static final String HIGHLIGHT_PRE = ""; //NON-NLS private static final String ANCHOR_NAME_PREFIX = AccountsText.class.getName() + "_"; @@ -80,23 +82,24 @@ class AccountsText implements IndexedText { private int numberPagesForFile = 0; private Integer currentPage = 0; - /* + /** * map from page/chunk to number of hits. value is 0 if not yet known. */ private final TreeMap numberOfHitsPerPage = new TreeMap<>(); - /* + + /** * set of pages, used for iterating back and forth. Only stores pages with * hits */ private final Set pages = numberOfHitsPerPage.keySet(); - /* + + /** * map from page/chunk number to current hit on that page. */ private final HashMap currentHitPerPage = new HashMap<>(); AccountsText(long objectID, BlackboardArtifact artifact) { this(objectID, Arrays.asList(artifact)); - } @NbBundle.Messages({ @@ -201,11 +204,7 @@ class AccountsText implements IndexedText { @Override public int currentItem() { - if (this.currentHitPerPage.containsKey(currentPage)) { - return currentHitPerPage.get(currentPage); - } else { - return 0; - } + currentHitPerPage.getOrDefault(currentPage, 0); } /** @@ -261,10 +260,11 @@ class AccountsText implements IndexedText { isPageInfoLoaded = true; } - private static final String CCN_REGEX = "(%?)(B?)([0-9][ \\-]*?){12,19}(\\^?)"; /** * Load the paging info from the QueryResults object. + * + * @param hits The QueryResults to load the paging info from. */ synchronized private void loadPageInfoFromHits(QueryResults hits) { //organize the hits by page, filter as needed @@ -370,9 +370,6 @@ class AccountsText implements IndexedText { @Override public int getNumberHits() { - if (!this.numberOfHitsPerPage.containsKey(this.currentPage)) { - return 0; - } - return this.numberOfHitsPerPage.get(this.currentPage); + return numberOfHitsPerPage.getOrDefault(currentPage, 0); } } From e65ef996fdd98824b346f5b08f32952d1fef0554 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 25 Sep 2017 10:01:28 +0200 Subject: [PATCH 10/29] fix a bug and do some cleanup --- .../autopsy/keywordsearch/AccountsText.java | 3 +- .../autopsy/keywordsearch/RegexQuery.java | 102 +++++++++++------- 2 files changed, 64 insertions(+), 41 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java index 365655103b..e5f17cef12 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/AccountsText.java @@ -204,7 +204,7 @@ class AccountsText implements IndexedText { @Override public int currentItem() { - currentHitPerPage.getOrDefault(currentPage, 0); + return currentHitPerPage.getOrDefault(currentPage, 0); } /** @@ -244,6 +244,7 @@ class AccountsText implements IndexedText { } else { //otherwise we need to do a query to figure out the paging. needsQuery = true; + // we can't break the for loop here because we need to accumulate all the accountNumbers } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index d905d9caed..f2445940f6 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -240,7 +240,6 @@ final class RegexQuery implements KeywordSearchQuery { int offset = 0; while (hitMatcher.find(offset)) { - StringBuilder snippet = new StringBuilder(); // If the location of the hit is beyond this chunk (i.e. it // exists in the overlap region), we skip the hit. It will @@ -273,41 +272,46 @@ final class RegexQuery implements KeywordSearchQuery { hit = hit.replaceAll("[^0-9]$", ""); } - switch (originalKeyword.getArtifactAttributeType()) { - case TSK_EMAIL: - /* - * Reduce false positives by eliminating email - * address hits that are either too short or are not - * for valid top level domains. - */ - if (hit.length() >= MIN_EMAIL_ADDR_LENGTH - && DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) { - addHit(content, snippet, hitMatcher, hit, hits, docId); - } + ATTRIBUTE_TYPE artifactAttributeType = originalKeyword.getArtifactAttributeType(); - break; - case TSK_CARD_NUMBER: - /* - * If searching for credit card account numbers, do - * extra validation on the term and discard it if it - * does not pass. - */ - Matcher ccnMatcher = CREDIT_CARD_NUM_PATTERN.matcher(hit); - - for (int rLength = hit.length(); rLength >= 12; rLength--) { - ccnMatcher.region(0, rLength); - if (ccnMatcher.find()) { - final String group = ccnMatcher.group("ccn"); - if (CREDIT_CARD_VALIDATOR.isValidCCN(group)) { - addHit(content, snippet, hitMatcher, hit, hits, docId); - }; + if (artifactAttributeType == null) { + hits.add(createHit(content, hitMatcher, hit, docId)); + } else { + switch (artifactAttributeType) { + case TSK_EMAIL: + /* + * Reduce false positives by eliminating email + * address hits that are either too short or are + * not for valid top level domains. + */ + if (hit.length() >= MIN_EMAIL_ADDR_LENGTH + && DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) { + hits.add(createHit(content, hitMatcher, hit, docId)); } - } - break; - default: - addHit(content, snippet, hitMatcher, hit, hits, docId); + break; + case TSK_CARD_NUMBER: + /* + * If searching for credit card account numbers, + * do extra validation on the term and discard + * it if it does not pass. + */ + Matcher ccnMatcher = CREDIT_CARD_NUM_PATTERN.matcher(hit); + for (int rLength = hit.length(); rLength >= 12; rLength--) { + ccnMatcher.region(0, rLength); + if (ccnMatcher.find()) { + final String group = ccnMatcher.group("ccn"); + if (CREDIT_CARD_VALIDATOR.isValidCCN(group)) { + hits.add(createHit(content, hitMatcher, hit, docId)); + }; + } + } + + break; + default: + hits.add(createHit(content, hitMatcher, hit, docId)); + } } } @@ -328,19 +332,37 @@ final class RegexQuery implements KeywordSearchQuery { return hits; } - private void addHit(String content, StringBuilder snippet, Matcher hitMatcher, String hit, List hits, final String docId) throws TskCoreException { - /** - * Get the snippet from the document if keyword search is configured to - * use snippets. - */ + /** + * Create a KeywordHit from the given information. + * + * + * @param content + * @param hitMatcher + * @param hit + * @param docId + * + * @return + * + * @throws TskCoreException + */ + private KeywordHit createHit(String content, Matcher hitMatcher, String hit, final String docId) throws TskCoreException { + + // Get the snippet from the document. int maxIndex = content.length() - 1; - snippet.append(content.substring(Integer.max(0, hitMatcher.start() - 20), Integer.max(0, hitMatcher.start()))); + StringBuilder snippet = new StringBuilder( + content.substring( + Integer.max(0, hitMatcher.start() - 20), + Integer.max(0, hitMatcher.start()) + )); snippet.appendCodePoint(171); snippet.append(hit); snippet.appendCodePoint(171); - snippet.append(content.substring(Integer.min(maxIndex, hitMatcher.end()), Integer.min(maxIndex, hitMatcher.end() + 20))); + snippet.append(content.substring( + Integer.min(maxIndex, hitMatcher.end()), + Integer.min(maxIndex, hitMatcher.end() + 20) + )); - hits.add(new KeywordHit(docId, snippet.toString(), hit)); + return new KeywordHit(docId, snippet.toString(), hit); } @Override From 798118ccdb8d39378ecf045d343d3b4ab22e6342 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 25 Sep 2017 11:21:13 +0200 Subject: [PATCH 11/29] factor away createHit --- .../autopsy/keywordsearch/RegexQuery.java | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index f2445940f6..63b6d426dc 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -275,7 +275,7 @@ final class RegexQuery implements KeywordSearchQuery { ATTRIBUTE_TYPE artifactAttributeType = originalKeyword.getArtifactAttributeType(); if (artifactAttributeType == null) { - hits.add(createHit(content, hitMatcher, hit, docId)); + hits.add(new KeywordHit(docId, makeSnippet(content, hitMatcher, hit), hit)); } else { switch (artifactAttributeType) { case TSK_EMAIL: @@ -286,7 +286,7 @@ final class RegexQuery implements KeywordSearchQuery { */ if (hit.length() >= MIN_EMAIL_ADDR_LENGTH && DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) { - hits.add(createHit(content, hitMatcher, hit, docId)); + hits.add(new KeywordHit(docId, makeSnippet(content, hitMatcher, hit), hit)); } break; @@ -303,14 +303,15 @@ final class RegexQuery implements KeywordSearchQuery { if (ccnMatcher.find()) { final String group = ccnMatcher.group("ccn"); if (CREDIT_CARD_VALIDATOR.isValidCCN(group)) { - hits.add(createHit(content, hitMatcher, hit, docId)); + hits.add(new KeywordHit(docId, makeSnippet(content, hitMatcher, hit), hit)); }; } } break; default: - hits.add(createHit(content, hitMatcher, hit, docId)); + hits.add(new KeywordHit(docId, makeSnippet(content, hitMatcher, hit), hit)); + break; } } } @@ -332,21 +333,7 @@ final class RegexQuery implements KeywordSearchQuery { return hits; } - /** - * Create a KeywordHit from the given information. - * - * - * @param content - * @param hitMatcher - * @param hit - * @param docId - * - * @return - * - * @throws TskCoreException - */ - private KeywordHit createHit(String content, Matcher hitMatcher, String hit, final String docId) throws TskCoreException { - + static private String makeSnippet(String content, Matcher hitMatcher, String hit) { // Get the snippet from the document. int maxIndex = content.length() - 1; StringBuilder snippet = new StringBuilder( @@ -361,8 +348,7 @@ final class RegexQuery implements KeywordSearchQuery { Integer.min(maxIndex, hitMatcher.end()), Integer.min(maxIndex, hitMatcher.end() + 20) )); - - return new KeywordHit(docId, snippet.toString(), hit); + return snippet.toString(); } @Override From bc591661b3dfc3aeca9352d1d1476b17641258a1 Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 25 Sep 2017 12:03:58 +0200 Subject: [PATCH 12/29] some more cleanup/refactoring --- .../autopsy/keywordsearch/RegexQuery.java | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java index 63b6d426dc..fc3147df27 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java @@ -88,6 +88,7 @@ final class RegexQuery implements KeywordSearchQuery { private static final CreditCardValidator CREDIT_CARD_VALIDATOR = new CreditCardValidator(); private static final int MAX_RESULTS_PER_CURSOR_MARK = 512; private static final int MIN_EMAIL_ADDR_LENGTH = 8; + private static final String SNIPPET_DELIMITER = String.valueOf(Character.toChars(171)); private final List filters = new ArrayList<>(); private final KeywordList keywordList; @@ -150,7 +151,7 @@ final class RegexQuery implements KeywordSearchQuery { final Server solrServer = KeywordSearch.getServer(); SolrQuery solrQuery = new SolrQuery(); - /** + /* * The provided regular expression may include wildcards at the * beginning and/or end. These wildcards are used to indicate that the * user wants to find hits for the regex that are embedded within other @@ -333,22 +334,28 @@ final class RegexQuery implements KeywordSearchQuery { return hits; } - static private String makeSnippet(String content, Matcher hitMatcher, String hit) { + /** + * Make a snippet from the given content that has the given hit plus some + * surrounding context. + * + * @param content The content to extract the snippet from. + * + * @param hitMatcher The Matcher that has the start/end info for where the + * hit is in the content. + * @param hit The actual hit in the content. + * + * @return A snippet extracted from content that contains hit plus some + * surrounding context. + */ + private String makeSnippet(String content, Matcher hitMatcher, String hit) { // Get the snippet from the document. int maxIndex = content.length() - 1; - StringBuilder snippet = new StringBuilder( - content.substring( - Integer.max(0, hitMatcher.start() - 20), - Integer.max(0, hitMatcher.start()) - )); - snippet.appendCodePoint(171); - snippet.append(hit); - snippet.appendCodePoint(171); - snippet.append(content.substring( - Integer.min(maxIndex, hitMatcher.end()), - Integer.min(maxIndex, hitMatcher.end() + 20) - )); - return snippet.toString(); + final int end = hitMatcher.end(); + final int start = hitMatcher.start(); + + return content.substring(Integer.max(0, start - 20), Integer.max(0, start)) + + SNIPPET_DELIMITER + hit + SNIPPET_DELIMITER + + content.substring(Integer.min(maxIndex, end), Integer.min(maxIndex, end + 20)); } @Override @@ -563,7 +570,7 @@ final class RegexQuery implements KeywordSearchQuery { */ static private void addAttributeIfNotAlreadyCaptured(Map attributeMap, ATTRIBUTE_TYPE attrType, String groupName, Matcher matcher) { BlackboardAttribute.Type type = new BlackboardAttribute.Type(attrType); - attributeMap.computeIfAbsent(type, (BlackboardAttribute.Type t) -> { + attributeMap.computeIfAbsent(type, t -> { String value = matcher.group(groupName); if (attrType.equals(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)) { attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_KEYWORD), @@ -572,8 +579,9 @@ final class RegexQuery implements KeywordSearchQuery { } if (StringUtils.isNotBlank(value)) { return new BlackboardAttribute(attrType, MODULE_NAME, value); + } else { + return null; } - return null; }); } } From f9b29afb0fb063d4c4a3d598ba51399f26db708a Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 25 Sep 2017 11:18:47 -0400 Subject: [PATCH 13/29] 3061 changed runIngestmodules from callableSystemAction to abstractAction to avoid exeption --- .../RunIngestModulesAction.java | 50 +++++++------------ 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java b/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java index 7a1e6fa4db..ec5888712f 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java @@ -23,13 +23,12 @@ import java.awt.event.ActionEvent; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JOptionPane; import org.openide.DialogDisplayer; import org.openide.WizardDescriptor; -import org.openide.util.HelpCtx; import org.openide.util.NbBundle.Messages; -import org.openide.util.actions.CallableSystemAction; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestManager; @@ -41,7 +40,7 @@ import org.sleuthkit.datamodel.Directory; * When the data source is pressed, it should open the wizard for ingest * modules. */ -public final class RunIngestModulesAction extends CallableSystemAction { +public final class RunIngestModulesAction extends AbstractAction { @Messages("RunIngestModulesAction.name=Run Ingest Modules") private static final long serialVersionUID = 1L; @@ -51,6 +50,21 @@ public final class RunIngestModulesAction extends CallableSystemAction { * used instead of this wizard and is retained for backwards compatibility. */ private static final String EXECUTION_CONTEXT = "org.sleuthkit.autopsy.ingest.RunIngestModulesDialog"; + /** + * Display any warnings that the ingestJobSettings have. + * + * @param ingestJobSettings + */ + private static void showWarnings(IngestJobSettings ingestJobSettings) { + List warnings = ingestJobSettings.getWarnings(); + if (warnings.isEmpty() == false) { + StringBuilder warningMessage = new StringBuilder(1024); + for (String warning : warnings) { + warningMessage.append(warning).append("\n"); + } + JOptionPane.showMessageDialog(null, warningMessage.toString()); + } + } private final List dataSources = new ArrayList<>(); private final IngestJobSettings.IngestType ingestType; @@ -103,35 +117,9 @@ public final class RunIngestModulesAction extends CallableSystemAction { } } - /** - * Display any warnings that the ingestJobSettings have. - * - * @param ingestJobSettings - */ - private static void showWarnings(IngestJobSettings ingestJobSettings) { - List warnings = ingestJobSettings.getWarnings(); - if (warnings.isEmpty() == false) { - StringBuilder warningMessage = new StringBuilder(1024); - for (String warning : warnings) { - warningMessage.append(warning).append("\n"); - } - JOptionPane.showMessageDialog(null, warningMessage.toString()); - } - } @Override - public void performAction() { - actionPerformed(null); + public Object clone() throws CloneNotSupportedException { + return super.clone(); //To change body of generated methods, choose Tools | Templates. } - - @Override - public String getName() { - return Bundle.RunIngestModulesAction_name(); - } - - @Override - public HelpCtx getHelpCtx() { - return HelpCtx.DEFAULT_HELP; - } - } From dde230d88a43aad969d7ff907d3da65a5cfbe916 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 25 Sep 2017 15:27:40 -0400 Subject: [PATCH 14/29] 2740 removed adding of individual actions in DirectoryTreeFilterNode --- .../DirectoryTreeFilterNode.java | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java index a1bd1d9116..c9070015f2 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java @@ -166,33 +166,6 @@ class DirectoryTreeFilterNode extends FilterNode { final Content content = this.getLookup().lookup(Content.class); if (content != null) { actions.addAll(Arrays.asList(super.getActions(true))); - if (content instanceof Volume) { - actions.add(new FileSystemDetailsAction((Volume) content)); - } - actions.addAll(ExplorerNodeActionVisitor.getActions(content)); - - Directory dir = this.getLookup().lookup(Directory.class); - if (dir != null) { - actions.add(ExtractAction.getInstance()); - actions.add(new RunIngestModulesAction(dir)); - } - - final Image img = this.getLookup().lookup(Image.class); - final VirtualDirectory virtualDirectory = this.getLookup().lookup(VirtualDirectory.class); - boolean isRootVD = false; - if (virtualDirectory != null) { - try { - if (virtualDirectory.getParent() == null) { - isRootVD = true; - } - } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Error determining the parent of the virtual directory", ex); // NON-NLS - } - } - if (img != null || isRootVD) { - actions.add(new FileSearchAction(NbBundle.getMessage(this.getClass(), "DirectoryTreeFilterNode.action.openFileSrcByAttr.text"))); - actions.add(new RunIngestModulesAction(Collections.singletonList(content))); - } } actions.add(collapseAllAction); return actions.toArray(new Action[actions.size()]); From a6c76a1100bb32e9f9623b83dc52edb1e3c6980e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Mon, 25 Sep 2017 21:09:15 +0200 Subject: [PATCH 15/29] validate that ccn lengths match BINs --- CoreLibs/ivy.xml | 2 +- CoreLibs/nbproject/project.properties | 4 +- CoreLibs/nbproject/project.xml | 4 +- KeywordSearch/ivy.xml | 2 + KeywordSearch/nbproject/project.properties | 2 +- KeywordSearch/nbproject/project.xml | 8 +- .../keywordsearch/CreditCardValidator.java | 82 +++++++++++++++++++ .../CreditCardValidatorTest.java | 14 ++++ 8 files changed, 107 insertions(+), 11 deletions(-) diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index bfd9112f9e..24634d90f1 100755 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -16,7 +16,7 @@ - + diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index 13a62b62ee..da8749c100 100755 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -24,7 +24,7 @@ file.reference.dom4j-1.6.1.jar=release/modules/ext/dom4j-1.6.1.jar file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.1_spec-1.0.jar file.reference.gson-1.4.jar=release/modules/ext/gson-1.4.jar file.reference.gstreamer-java-1.5.jar=release/modules/ext/gstreamer-java-1.5.jar -file.reference.guava-19.0.jar=release/modules/ext/guava-19.0.jar +file.reference.guava-21.0.jar=release/modules/ext/guava-21.0.jar file.reference.imageio-bmp-3.2.jar=release/modules/ext/imageio-bmp-3.2.jar file.reference.imageio-core-3.2.jar=release/modules/ext/imageio-core-3.2.jar file.reference.imageio-icns-3.2.jar=release/modules/ext/imageio-icns-3.2.jar @@ -78,7 +78,6 @@ javadoc.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-javado javadoc.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-javadoc.jar javadoc.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-javadoc.jar javadoc.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-javadoc.jar -javadoc.reference.guava-19.0.jar=release/modules/ext/guava-19.0-javadoc.jar javadoc.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-javadoc.jar javadoc.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-javadoc.jar javadoc.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-javadoc.jar @@ -87,7 +86,6 @@ source.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-sources source.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-sources.jar source.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-sources.jar source.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-sources.jar -source.reference.guava-19.0.jar=release/modules/ext/guava-19.0-sources.jar source.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-sources.jar source.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-sources.jar source.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-sources.jar diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index 6fcef46ccd..f3c852d11c 100755 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -848,8 +848,8 @@ release/modules/ext/slf4j-simple-1.6.1.jar - ext/guava-19.0.jar - release/modules/ext/guava-19.0.jar + ext/guava-21.0.jar + release/modules/ext/guava-21.0.jar ext/commons-io-2.5.jar diff --git a/KeywordSearch/ivy.xml b/KeywordSearch/ivy.xml index 3ceb4e6378..6f810feddc 100755 --- a/KeywordSearch/ivy.xml +++ b/KeywordSearch/ivy.xml @@ -14,6 +14,8 @@ + + diff --git a/KeywordSearch/nbproject/project.properties b/KeywordSearch/nbproject/project.properties index 5aa1b716e0..07273eea69 100755 --- a/KeywordSearch/nbproject/project.properties +++ b/KeywordSearch/nbproject/project.properties @@ -42,7 +42,7 @@ file.reference.fontbox-2.0.3.jar=release/modules/ext/fontbox-2.0.3.jar file.reference.geoapi-3.0.0.jar=release/modules/ext/geoapi-3.0.0.jar file.reference.grib-4.5.5.jar=release/modules/ext/grib-4.5.5.jar file.reference.gson-2.2.4.jar=release/modules/ext/gson-2.2.4.jar -file.reference.guava-17.0.jar=release/modules/ext/guava-17.0.jar +file.reference.guava-21.0.jar=release/modules/ext/guava-21.0.jar file.reference.hamcrest-core-1.3.jar=release/modules/ext/hamcrest-core-1.3.jar file.reference.httpclient-4.3.1.jar=release/modules/ext/httpclient-4.3.1.jar file.reference.httpcore-4.3.jar=release/modules/ext/httpcore-4.3.jar diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml index d375e76868..8a5e7213e0 100755 --- a/KeywordSearch/nbproject/project.xml +++ b/KeywordSearch/nbproject/project.xml @@ -213,10 +213,6 @@ ext/slf4j-api-1.7.12.jar release/modules/ext/slf4j-api-1.7.12.jar - - ext/guava-17.0.jar - release/modules/ext/guava-17.0.jar - ext/opennlp-maxent-3.0.3.jar release/modules/ext/opennlp-maxent-3.0.3.jar @@ -677,6 +673,10 @@ ext/sis-storage-0.6.jar release/modules/ext/sis-storage-0.6.jar + + ext/guava-21.0.jar + ext/guava-21.0.jar + ext/jcip-annotations-1.0.jar release/modules/ext/jcip-annotations-1.0.jar diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidator.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidator.java index baa8c17c44..2b49e7ff9d 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidator.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidator.java @@ -19,6 +19,11 @@ package org.sleuthkit.autopsy.keywordsearch; import com.google.common.base.CharMatcher; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Range; +import com.google.common.collect.RangeMap; +import com.google.common.collect.TreeRangeMap; +import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit; @@ -42,6 +47,73 @@ final class CreditCardValidator { private static final LuhnCheckDigit CREDIT_CARD_NUM_LUHN_CHECK = new LuhnCheckDigit(); + /** + * map from ccn IIN to allowed lengths + */ + static private final RangeMap> allowedLengths = TreeRangeMap.create(); + private static final ImmutableSet Set12to19 = ImmutableSet.of(12, 13, 14, 15, 16, 17, 18, 19); + private static final ImmutableSet Set14to19 = ImmutableSet.of(14, 15, 16, 17, 18, 19); + private static final ImmutableSet Set16to19 = ImmutableSet.of(16, 17, 18, 29); + + static { + //amex + allowedLengths.put(Range.closedOpen(34000000, 35000000), ImmutableSet.of(15)); + allowedLengths.put(Range.closedOpen(37000000, 38000000), ImmutableSet.of(15)); + + //visa + allowedLengths.put(Range.closedOpen(40000000, 50000000), Set12to19); + + //visa electron + allowedLengths.put(Range.closedOpen(40260000, 40270000), ImmutableSet.of(16)); + allowedLengths.put(Range.closedOpen(41750000, 41750100), ImmutableSet.of(16)); + allowedLengths.put(Range.closedOpen(44050000, 44060000), ImmutableSet.of(16)); + allowedLengths.put(Range.closedOpen(45080000, 45090000), ImmutableSet.of(16)); + allowedLengths.put(Range.closedOpen(48440000, 48450000), ImmutableSet.of(16)); + allowedLengths.put(Range.closedOpen(49130000, 49140000), ImmutableSet.of(16)); + allowedLengths.put(Range.closedOpen(49170000, 49180000), ImmutableSet.of(16)); + + //China UnionPay + allowedLengths.put(Range.closedOpen(62000000, 63000000), Set16to19); + + //MasterCard + allowedLengths.put(Range.closedOpen(51000000, 56000000), ImmutableSet.of(16)); + allowedLengths.put(Range.closedOpen(22210000, 27210000), ImmutableSet.of(16)); + + //Verve, these over lap with discover + allowedLengths.put(Range.closedOpen(50609900, 50619900), ImmutableSet.of(16, 19)); + allowedLengths.put(Range.closedOpen(65000200, 65002700), ImmutableSet.of(16, 19)); + + //Maestro + allowedLengths.put(Range.closedOpen(50000000, 50100000), Set12to19); + allowedLengths.put(Range.closedOpen(56000000, 59000000), Set12to19); + allowedLengths.put(Range.closedOpen(60000000, 70000000), Set12to19); + allowedLengths.put(Range.closedOpen(63900000, 63910000), Set12to19); + allowedLengths.put(Range.closedOpen(67000000, 68000000), Set12to19); + + //Diners Club International (processed by discover + allowedLengths.put(Range.closedOpen(30000000, 30600000), Set16to19); + allowedLengths.put(Range.closedOpen(30950000, 30960000), Set16to19); + allowedLengths.put(Range.closedOpen(36000000, 37000000), Set14to19); + allowedLengths.put(Range.closedOpen(38000000, 40000000), Set16to19); + + //Diners Club USA & Canada (MasterCard co brand) + allowedLengths.put(Range.closedOpen(54000000, 56000000), Set14to19); + + //Discover + allowedLengths.put(Range.closedOpen(60110000, 60120000), Set16to19); + allowedLengths.put(Range.closedOpen(62212600, 62292600), Set16to19); + allowedLengths.put(Range.closedOpen(64400000, 66000000), Set16to19); + + //JCB //process by discover + allowedLengths.put(Range.closedOpen(35280000, 35900000), Set16to19); + + //Dankort + allowedLengths.put(Range.closedOpen(50190000, 50200000), Set16to19); + + //InterPayment + allowedLengths.put(Range.closedOpen(63600000, 63700000), Set16to19); + } + /** * Does the given string represent a valid credit card number? It must have * no separators, or only '-', or only ' '. Checks digit grouping for @@ -79,6 +151,10 @@ final class CreditCardValidator { splitCCN = new String[]{cannonicalCCN}; } + if (false == lengthMatchesBin(cannonicalCCN)) { + return false; + } + // validate digit grouping for 15, 16, and 19 digit cards switch (cannonicalCCN.length()) { case 15: @@ -105,6 +181,12 @@ final class CreditCardValidator { return CREDIT_CARD_NUM_LUHN_CHECK.isValid(cannonicalCCN); } + private boolean lengthMatchesBin(String cannonicalCCN) { + String BIN = cannonicalCCN.substring(0, 8); + final Set lengthsForBIN = allowedLengths.get(Integer.valueOf(BIN)); + return null == lengthsForBIN || lengthsForBIN.contains(cannonicalCCN.length()); + } + static private boolean isValidOtherDigitGrouping(String[] splitCCN) { if (splitCCN.length == 1) { return true; diff --git a/KeywordSearch/test/unit/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidatorTest.java b/KeywordSearch/test/unit/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidatorTest.java index 637be8b3ae..fd7a56c39b 100644 --- a/KeywordSearch/test/unit/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidatorTest.java +++ b/KeywordSearch/test/unit/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidatorTest.java @@ -46,6 +46,18 @@ public class CreditCardValidatorTest { public void tearDown() { } + @Test + public void testLengthMatchesBin(){ + System.out.println("lengthMatchesBin"); + CreditCardValidator validator = new CreditCardValidator(); + + //amex must be 15 + assertEquals(true, validator.isValidCCN("3431 136294 58529")); + assertEquals(false, validator.isValidCCN("3431-136294-5850")); + assertEquals(false, validator.isValidCCN("34311362945850")); + assertEquals(false, validator.isValidCCN("3431 1362 9458 5034")); + } + /** * Test of isValidCCN method, of class CreditCardValidator. */ @@ -187,4 +199,6 @@ public class CreditCardValidatorTest { assertEquals(false, CreditCardValidator.isValidCCN("123 456789031")); //grouping assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031")); //separators } + + } From 339f42e2b2d8863e6aeec55933b772ab9d80405a Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Mon, 25 Sep 2017 15:50:45 -0400 Subject: [PATCH 16/29] 3061 make clone method for RunIngestModulesAction throw exception to prevent use --- .../ingest/runIngestModuleWizard/RunIngestModulesAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java b/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java index ec5888712f..2f15a74c64 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/runIngestModuleWizard/RunIngestModulesAction.java @@ -120,6 +120,6 @@ public final class RunIngestModulesAction extends AbstractAction { @Override public Object clone() throws CloneNotSupportedException { - return super.clone(); //To change body of generated methods, choose Tools | Templates. + throw new CloneNotSupportedException("Clone is not supported for the RunIngestModulesAction"); } } From a132d6962c8f514999e89d40d3b4ea4c39e473d0 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Mon, 25 Sep 2017 17:16:00 -0400 Subject: [PATCH 17/29] refactor. Removed some methods and reduced scope. Renamed case --- .../actions/EamCaseEditDetailsDialog.java | 6 +- .../DataContentViewerOtherCases.java | 12 +-- ...DataContentViewerOtherCasesTableModel.java | 12 +-- .../datamodel/AbstractSqlEamDb.java | 93 ++++++++++--------- .../CorrelationAttributeInstance.java | 81 ++++++---------- .../{EamCase.java => CorrelationCase.java} | 41 ++++---- .../datamodel/CorrelationDataSource.java | 9 +- .../datamodel/EamArtifactUtil.java | 4 +- .../centralrepository/datamodel/EamDb.java | 14 +-- .../datamodel/SqliteEamDb.java | 32 +++---- .../eventlisteners/CaseEventListener.java | 8 +- .../ingestmodule/IngestModule.java | 12 +-- 12 files changed, 148 insertions(+), 176 deletions(-) rename Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/{EamCase.java => CorrelationCase.java} (90%) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.java index c00f0583d8..d647c12d9b 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/actions/EamCaseEditDetailsDialog.java @@ -36,7 +36,7 @@ import javax.swing.event.DocumentListener; import org.openide.util.NbBundle.Messages; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization; @@ -48,7 +48,7 @@ import org.sleuthkit.autopsy.centralrepository.optionspanel.AddNewOrganizationDi public class EamCaseEditDetailsDialog extends JDialog { private final static Logger LOGGER = Logger.getLogger(EamCaseEditDetailsDialog.class.getName()); - private EamCase eamCase; + private CorrelationCase eamCase; private EamDb dbManager; private Boolean contentChanged = false; private final Collection textBoxes = new ArrayList<>(); @@ -69,7 +69,7 @@ public class EamCaseEditDetailsDialog extends JDialog { try { this.dbManager = EamDb.getInstance(); - this.eamCase = this.dbManager.getCaseDetails(Case.getCurrentCase().getName()); + this.eamCase = this.dbManager.getCaseByUUID(Case.getCurrentCase().getName()); if(this.eamCase == null){ this.eamCase = dbManager.newCase(Case.getCurrentCase()); } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index ac71624da7..0a42433215 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -50,7 +50,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance; import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import org.sleuthkit.autopsy.centralrepository.datamodel.EamGlobalFileInstance; import org.sleuthkit.datamodel.AbstractFile; @@ -167,7 +167,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D EamDb dbManager = EamDb.getInstance(); int selectedRowModelIdx = otherCasesTable.convertRowIndexToModel(selectedRowViewIdx); CorrelationAttribute eamArtifact = (CorrelationAttribute) tableModel.getRow(selectedRowModelIdx); - EamCase eamCasePartial = eamArtifact.getInstances().get(0).getEamCase(); + CorrelationCase eamCasePartial = eamArtifact.getInstances().get(0).getCorrelationCase(); if (eamCasePartial == null) { JOptionPane.showConfirmDialog(showCaseDetailsMenuItem, Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetailsReference(), @@ -177,7 +177,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D } caseDisplayName = eamCasePartial.getDisplayName(); // query case details - EamCase eamCase = dbManager.getCaseDetails(eamCasePartial.getCaseUUID()); + CorrelationCase eamCase = dbManager.getCaseByUUID(eamCasePartial.getCaseUUID()); if (eamCase == null) { JOptionPane.showConfirmDialog(showCaseDetailsMenuItem, Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(), @@ -421,9 +421,9 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D try { EamDb dbManager = EamDb.getInstance(); Collection artifactInstances = dbManager.getArtifactInstancesByTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).stream() - .filter(artifactInstance -> !artifactInstance.getEamCase().getCaseUUID().equals(caseUUID) - || !artifactInstance.getEamDataSource().getName().equals(dataSourceName) - || !artifactInstance.getEamDataSource().getDeviceID().equals(deviceId)) + .filter(artifactInstance -> !artifactInstance.getCorrelationCase().getCaseUUID().equals(caseUUID) + || !artifactInstance.getCorrelationDataSource().getName().equals(dataSourceName) + || !artifactInstance.getCorrelationDataSource().getDeviceID().equals(deviceId)) .collect(Collectors.toList()); return artifactInstances; } catch (EamDbException ex) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java index b27b6880d6..68d15a6fe5 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java @@ -133,18 +133,18 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { switch (colId) { case CASE_NAME: - if (null != eamArtifactInstance.getEamCase()) { - value = eamArtifactInstance.getEamCase().getDisplayName(); + if (null != eamArtifactInstance.getCorrelationCase()) { + value = eamArtifactInstance.getCorrelationCase().getDisplayName(); } break; case DEVICE: - if (null != eamArtifactInstance.getEamDataSource()) { - value = eamArtifactInstance.getEamDataSource().getDeviceID(); + if (null != eamArtifactInstance.getCorrelationDataSource()) { + value = eamArtifactInstance.getCorrelationDataSource().getDeviceID(); } break; case DATA_SOURCE: - if (null != eamArtifactInstance.getEamDataSource()) { - value = eamArtifactInstance.getEamDataSource().getName(); + if (null != eamArtifactInstance.getCorrelationDataSource()) { + value = eamArtifactInstance.getCorrelationDataSource().getName(); } break; case FILE_PATH: diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java index accd263d57..67015dc12e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/AbstractSqlEamDb.java @@ -198,7 +198,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * @param eamCase The case to add */ @Override - public void newCase(EamCase eamCase) throws EamDbException { + public void newCase(CorrelationCase eamCase) throws EamDbException { Connection conn = connect(); PreparedStatement preparedStatement = null; @@ -259,12 +259,12 @@ public abstract class AbstractSqlEamDb implements EamDb { * @param case The case to add */ @Override - public EamCase newCase(Case autopsyCase) throws EamDbException{ + public CorrelationCase newCase(Case autopsyCase) throws EamDbException{ if(autopsyCase == null){ throw new EamDbException("Case is null"); } - EamCase curCeCase = new EamCase( + CorrelationCase curCeCase = new CorrelationCase( -1, autopsyCase.getName(), // unique case ID EamOrganization.getDefault(), @@ -285,7 +285,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * @param eamCase The case to update */ @Override - public void updateCase(EamCase eamCase) throws EamDbException { + public void updateCase(CorrelationCase eamCase) throws EamDbException { Connection conn = connect(); PreparedStatement preparedStatement = null; @@ -349,10 +349,12 @@ public abstract class AbstractSqlEamDb implements EamDb { * @return The retrieved case */ @Override - public EamCase getCaseDetails(String caseUUID) throws EamDbException { + public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException { + // @@@ We should have a cache here... + Connection conn = connect(); - EamCase eamCaseResult = null; + CorrelationCase eamCaseResult = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; @@ -386,11 +388,11 @@ public abstract class AbstractSqlEamDb implements EamDb { * @return List of cases */ @Override - public List getCases() throws EamDbException { + public List getCases() throws EamDbException { Connection conn = connect(); - List cases = new ArrayList<>(); - EamCase eamCaseResult; + List cases = new ArrayList<>(); + CorrelationCase eamCaseResult; PreparedStatement preparedStatement = null; ResultSet resultSet = null; @@ -450,27 +452,27 @@ public abstract class AbstractSqlEamDb implements EamDb { * * @param eamDataSource the data source to update */ - @Override - public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException { - Connection conn = connect(); - - PreparedStatement preparedStatement = null; - String sql = "UPDATE data_sources SET name=? WHERE device_id=?"; - - try { - preparedStatement = conn.prepareStatement(sql); - - preparedStatement.setString(1, eamDataSource.getName()); - preparedStatement.setString(2, eamDataSource.getDeviceID()); - - preparedStatement.executeUpdate(); - } catch (SQLException ex) { - throw new EamDbException("Error updating case.", ex); // NON-NLS - } finally { - EamDbUtil.closePreparedStatement(preparedStatement); - EamDbUtil.closeConnection(conn); - } - } +// @Override +// public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException { +// Connection conn = connect(); +// BC: This needs to be updated because device_id is not unique. Query needs to also use case_id +// PreparedStatement preparedStatement = null; +// String sql = "UPDATE data_sources SET name=? WHERE device_id=?"; +// +// try { +// preparedStatement = conn.prepareStatement(sql); +// +// preparedStatement.setString(1, eamDataSource.getName()); +// preparedStatement.setString(2, eamDataSource.getDeviceID()); +// +// preparedStatement.executeUpdate(); +// } catch (SQLException ex) { +// throw new EamDbException("Error updating case.", ex); // NON-NLS +// } finally { +// EamDbUtil.closePreparedStatement(preparedStatement); +// EamDbUtil.closeConnection(conn); +// } +// } /** * Retrieves Data Source details based on data source device ID @@ -568,8 +570,8 @@ public abstract class AbstractSqlEamDb implements EamDb { preparedStatement = conn.prepareStatement(sql.toString()); for (CorrelationAttributeInstance eamInstance : eamInstances) { if(! eamArtifact.getCorrelationValue().isEmpty()){ - preparedStatement.setString(1, eamInstance.getEamCase().getCaseUUID()); - preparedStatement.setString(2, eamInstance.getEamDataSource().getDeviceID()); + preparedStatement.setString(1, eamInstance.getCorrelationCase().getCaseUUID()); + preparedStatement.setString(2, eamInstance.getCorrelationDataSource().getDeviceID()); preparedStatement.setString(3, eamArtifact.getCorrelationValue()); preparedStatement.setString(4, eamInstance.getFilePath()); preparedStatement.setByte(5, eamInstance.getKnownStatus().getFileKnownValue()); @@ -928,8 +930,8 @@ public abstract class AbstractSqlEamDb implements EamDb { for (CorrelationAttributeInstance eamInstance : eamInstances) { if(! eamArtifact.getCorrelationValue().isEmpty()){ - bulkPs.setString(1, eamInstance.getEamCase().getCaseUUID()); - bulkPs.setString(2, eamInstance.getEamDataSource().getDeviceID()); + bulkPs.setString(1, eamInstance.getCorrelationCase().getCaseUUID()); + bulkPs.setString(2, eamInstance.getCorrelationDataSource().getDeviceID()); bulkPs.setString(3, eamArtifact.getCorrelationValue()); bulkPs.setString(4, eamInstance.getFilePath()); bulkPs.setByte(5, eamInstance.getKnownStatus().getFileKnownValue()); @@ -962,7 +964,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * Executes a bulk insert of the cases */ @Override - public void bulkInsertCases(List cases) throws EamDbException { + public void bulkInsertCases(List cases) throws EamDbException { Connection conn = connect(); if (cases.isEmpty()) { @@ -978,7 +980,7 @@ public abstract class AbstractSqlEamDb implements EamDb { + getConflictClause(); bulkPs = conn.prepareStatement(sql); - for (EamCase eamCase : cases) { + for (CorrelationCase eamCase : cases) { bulkPs.setString(1, eamCase.getCaseUUID()); if (null == eamCase.getOrg()) { bulkPs.setNull(2, Types.INTEGER); @@ -1075,8 +1077,8 @@ public abstract class AbstractSqlEamDb implements EamDb { try { preparedQuery = conn.prepareStatement(sqlQuery.toString()); - preparedQuery.setString(1, eamInstance.getEamCase().getCaseUUID()); - preparedQuery.setString(2, eamInstance.getEamDataSource().getDeviceID()); + preparedQuery.setString(1, eamInstance.getCorrelationCase().getCaseUUID()); + preparedQuery.setString(2, eamInstance.getCorrelationDataSource().getDeviceID()); preparedQuery.setString(3, eamArtifact.getCorrelationValue()); preparedQuery.setString(4, eamInstance.getFilePath()); resultSet = preparedQuery.executeQuery(); @@ -1103,12 +1105,12 @@ public abstract class AbstractSqlEamDb implements EamDb { // in the database, but we don't expect the user to be tagging large numbers // of items (that didn't have the CE ingest module run on them) at once. - if(null == getCaseDetails(eamInstance.getEamCase().getCaseUUID())){ - newCase(eamInstance.getEamCase()); + if(null == getCaseByUUID(eamInstance.getCorrelationCase().getCaseUUID())){ + newCase(eamInstance.getCorrelationCase()); } - if (null == getDataSourceDetails(eamInstance.getEamDataSource().getDeviceID())) { - newDataSource(eamInstance.getEamDataSource()); + if (null == getDataSourceDetails(eamInstance.getCorrelationDataSource().getDeviceID())) { + newDataSource(eamInstance.getCorrelationDataSource()); } eamArtifact.getInstances().get(0).setKnownStatus(knownStatus); @@ -1836,7 +1838,7 @@ public abstract class AbstractSqlEamDb implements EamDb { * * @throws SQLException when an expected column name is not in the resultSet */ - private EamCase getEamCaseFromResultSet(ResultSet resultSet) throws SQLException { + private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet) throws SQLException { if (null == resultSet) { return null; } @@ -1853,8 +1855,7 @@ public abstract class AbstractSqlEamDb implements EamDb { resultSet.getString("poc_phone")); } - EamCase eamCase = new EamCase(resultSet.getString("case_uid"), resultSet.getString("case_name")); - eamCase.setID(resultSet.getInt("case_id")); + CorrelationCase eamCase = new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")); eamCase.setOrg(eamOrg); eamCase.setCreationDate(resultSet.getString("creation_date")); eamCase.setCaseNumber(resultSet.getString("case_number")); @@ -1911,7 +1912,7 @@ public abstract class AbstractSqlEamDb implements EamDb { return null; } CorrelationAttributeInstance eamArtifactInstance = new CorrelationAttributeInstance( - new EamCase(resultSet.getString("case_uid"), resultSet.getString("case_name")), + new CorrelationCase(resultSet.getString("case_uid"), resultSet.getString("case_name")), new CorrelationDataSource(-1, resultSet.getString("device_id"), resultSet.getString("name")), resultSet.getString("file_path"), resultSet.getString("comment"), diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java index e6f2aab4b2..7db48d28db 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java @@ -53,52 +53,52 @@ public class CorrelationAttributeInstance implements Serializable { private static final long serialVersionUID = 1L; - private String ID; - private EamCase eamCase; - private CorrelationDataSource eamDataSource; + private int ID; + private CorrelationCase correlationCase; + private CorrelationDataSource correlationDataSource; private String filePath; private String comment; private TskData.FileKnown knownStatus; private GlobalStatus globalStatus; public CorrelationAttributeInstance( - EamCase eamCase, + CorrelationCase eamCase, CorrelationDataSource eamDataSource ) { - this("", eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); + this(-1, eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); } public CorrelationAttributeInstance( - EamCase eamCase, + CorrelationCase eamCase, CorrelationDataSource eamDataSource, String filePath ) { - this("", eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); + this(-1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); } public CorrelationAttributeInstance( - EamCase eamCase, + CorrelationCase eamCase, CorrelationDataSource eamDataSource, String filePath, String comment ) { - this("", eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); + this(-1, eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN, GlobalStatus.LOCAL); } public CorrelationAttributeInstance( - EamCase eamCase, + CorrelationCase eamCase, CorrelationDataSource eamDataSource, String filePath, String comment, TskData.FileKnown knownStatus, GlobalStatus globalStatus ) { - this("", eamCase, eamDataSource, filePath, comment, knownStatus, globalStatus); + this(-1, eamCase, eamDataSource, filePath, comment, knownStatus, globalStatus); } public CorrelationAttributeInstance( - String ID, - EamCase eamCase, + int ID, + CorrelationCase eamCase, CorrelationDataSource eamDataSource, String filePath, String comment, @@ -106,8 +106,8 @@ public class CorrelationAttributeInstance implements Serializable { GlobalStatus globalStatus ) { this.ID = ID; - this.eamCase = eamCase; - this.eamDataSource = eamDataSource; + this.correlationCase = eamCase; + this.correlationDataSource = eamDataSource; // Lower case paths to normalize paths and improve correlation results, if this causes significant issues on case-sensitive file systems, remove this.filePath = filePath.toLowerCase(); this.comment = comment; @@ -116,9 +116,9 @@ public class CorrelationAttributeInstance implements Serializable { } public Boolean equals(CorrelationAttributeInstance otherInstance) { - return ((this.getID().equals(otherInstance.getID())) - && (this.getEamCase().equals(otherInstance.getEamCase())) - && (this.getEamDataSource().equals(otherInstance.getEamDataSource())) + return ((this.getID() == otherInstance.getID()) + && (this.getCorrelationCase().equals(otherInstance.getCorrelationCase())) + && (this.getCorrelationDataSource().equals(otherInstance.getCorrelationDataSource())) && (this.getFilePath().equals(otherInstance.getFilePath())) && (this.getGlobalStatus().equals(otherInstance.getGlobalStatus())) && (this.getKnownStatus().equals(otherInstance.getKnownStatus())) @@ -128,8 +128,8 @@ public class CorrelationAttributeInstance implements Serializable { @Override public String toString() { return this.getID() - + this.getEamCase().getCaseUUID() - + this.getEamDataSource().getName() + + this.getCorrelationCase().getCaseUUID() + + this.getCorrelationDataSource().getName() + this.getFilePath() + this.getGlobalStatus() + this.getKnownStatus() @@ -137,45 +137,24 @@ public class CorrelationAttributeInstance implements Serializable { } /** - * @return the ID + * @return the database ID */ - public String getID() { + int getID() { return ID; } - /** - * @param ID the ID to set - */ - public void setID(String ID) { - this.ID = ID; - } - /** * @return the eamCase */ - public EamCase getEamCase() { - return eamCase; - } - - /** - * @param eamCase the eamCase to set - */ - public void setEamCase(EamCase eamCase) { - this.eamCase = eamCase; + public CorrelationCase getCorrelationCase() { + return correlationCase; } /** * @return the eamDataSource */ - public CorrelationDataSource getEamDataSource() { - return eamDataSource; - } - - /** - * @param eamDataSource the eamDataSource to set - */ - public void setEamDataSource(CorrelationDataSource eamDataSource) { - this.eamDataSource = eamDataSource; + public CorrelationDataSource getCorrelationDataSource() { + return correlationDataSource; } /** @@ -185,14 +164,6 @@ public class CorrelationAttributeInstance implements Serializable { return filePath; } - /** - * @param filePath the filePath to set - */ - public void setFilePath(String filePath) { - // Lower case paths to normalize paths and improve correlation results, if this causes significant issues on case-sensitive file systems, remove - this.filePath = filePath.toLowerCase(); - } - /** * @return the comment */ diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamCase.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationCase.java similarity index 90% rename from Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamCase.java rename to Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationCase.java index d9df632109..466c73a7ee 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamCase.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationCase.java @@ -29,13 +29,13 @@ import org.openide.util.NbBundle.Messages; * Used to store info about a case. * */ -public class EamCase implements Serializable { +public class CorrelationCase implements Serializable { private static long serialVersionUID = 1L; private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)"); - private int ID; - private String caseUUID; + private int databaseId; + private String caseUUID; // globally unique private EamOrganization org; private String displayName; private String creationDate; @@ -45,11 +45,20 @@ public class EamCase implements Serializable { private String examinerPhone; private String notes; - public EamCase(String caseUUID, String displayName) { + /** + * + * @param caseUUID Globally unique identifier + * @param displayName + */ + public CorrelationCase(String caseUUID, String displayName) { this(-1, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null); } + + CorrelationCase(int ID, String caseUUID, String displayName) { + this(ID, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null); + } - public EamCase(int ID, + public CorrelationCase(int ID, String caseUUID, EamOrganization org, String displayName, @@ -59,7 +68,7 @@ public class EamCase implements Serializable { String examinerEmail, String examinerPhone, String notes) { - this.ID = ID; + this.databaseId = ID; this.caseUUID = caseUUID; this.org = org; this.displayName = displayName; @@ -149,18 +158,13 @@ public class EamCase implements Serializable { } /** - * @return the ID + * @return the database ID for the case or -1 if it is unknown (or not in the DB) */ - public int getID() { - return ID; + int getID() { + // @@@ Should probably have some lazy logic here to lead the ID from the DB if it is -1 + return databaseId; } - /** - * @param ID the ID to set - */ - public void setID(int ID) { - this.ID = ID; - } /** * @return the caseUUID @@ -169,12 +173,6 @@ public class EamCase implements Serializable { return caseUUID; } - /** - * @param caseUUID the caseUUID to set - */ - public void setCaseUUID(String caseUUID) { - this.caseUUID = caseUUID; - } /** * @return the org @@ -287,5 +285,4 @@ public class EamCase implements Serializable { public void setNotes(String notes) { this.notes = notes; } - } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java index 9b7480bee7..54b069b2a4 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationDataSource.java @@ -34,7 +34,7 @@ public class CorrelationDataSource implements Serializable { private static final long serialVersionUID = 1L; private final int dataSourceId; //< Id in the central repo - private final String deviceID; + private final String deviceID; //< Unique to its associated case (not necessarily globally unique) private final String name; @@ -73,7 +73,7 @@ public class CorrelationDataSource implements Serializable { public String toString() { StringBuilder str = new StringBuilder(); str.append("("); - str.append("ID=").append(Integer.toString(getDataSourceID())); + str.append("ID=").append(Integer.toString(getID())); str.append(",deviceID=").append(getDeviceID()); str.append(",name=").append(getName()); str.append(")"); @@ -81,13 +81,16 @@ public class CorrelationDataSource implements Serializable { } /** + * Get the database row ID + * * @return the ID */ - public int getDataSourceID() { + int getID() { return dataSourceId; } /** + * Get the device ID that is unique to the case * @return the deviceID */ public String getDeviceID() { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java index 11523150a3..f8033b6269 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java @@ -97,7 +97,7 @@ public class EamArtifactUtil { // make an instance for the BB source file CorrelationAttributeInstance eamInstance = new CorrelationAttributeInstance( - new EamCase(currentCase.getName(), currentCase.getDisplayName()), + new CorrelationCase(currentCase.getName(), currentCase.getDisplayName()), CorrelationDataSource.fromTSKDataSource(bbSourceFile.getDataSource()), bbSourceFile.getParentPath() + bbSourceFile.getName(), "", @@ -245,7 +245,7 @@ public class EamArtifactUtil { CorrelationAttribute.Type filesType = EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); eamArtifact = new CorrelationAttribute(filesType, af.getMd5Hash()); CorrelationAttributeInstance cei = new CorrelationAttributeInstance( - new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()), + new CorrelationCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()), CorrelationDataSource.fromTSKDataSource(af.getDataSource()), af.getParentPath() + af.getName(), comment, diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java index d3addef488..ccabea41c1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamDb.java @@ -147,21 +147,21 @@ public interface EamDb { * * @param eamCase The case to add */ - void newCase(EamCase eamCase) throws EamDbException; + void newCase(CorrelationCase eamCase) throws EamDbException; /** * Creates new Case in the database from the given case * * @param case The case to add */ - EamCase newCase(Case autopsyCase) throws EamDbException; + CorrelationCase newCase(Case autopsyCase) throws EamDbException; /** * Updates an existing Case in the database * * @param eamCase The case to update */ - void updateCase(EamCase eamCase) throws EamDbException; + void updateCase(CorrelationCase eamCase) throws EamDbException; /** * Retrieves Case details based on Case UUID @@ -170,14 +170,14 @@ public interface EamDb { * * @return The retrieved case */ - EamCase getCaseDetails(String caseUUID) throws EamDbException; + CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException; /** * Retrieves cases that are in DB. * * @return List of cases */ - List getCases() throws EamDbException; + List getCases() throws EamDbException; /** * Creates new Data Source in the database @@ -191,7 +191,7 @@ public interface EamDb { * * @param eamDataSource the data source to update */ - void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException; + //void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException; /** * Retrieves Data Source details based on data source device ID @@ -312,7 +312,7 @@ public interface EamDb { /** * Executes a bulk insert of the cases */ - void bulkInsertCases(List cases) throws EamDbException; + void bulkInsertCases(List cases) throws EamDbException; /** * Sets an eamArtifact instance to the given known status. If eamArtifact diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java index 536fe5e5aa..616a72caad 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteEamDb.java @@ -271,7 +271,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @param case The case to add */ @Override - public EamCase newCase(Case autopsyCase) throws EamDbException { + public CorrelationCase newCase(Case autopsyCase) throws EamDbException { try{ acquireExclusiveLock(); return super.newCase(autopsyCase); @@ -288,7 +288,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @param eamCase The case to add */ @Override - public void newCase(EamCase eamCase) throws EamDbException { + public void newCase(CorrelationCase eamCase) throws EamDbException { try{ acquireExclusiveLock(); super.newCase(eamCase); @@ -303,7 +303,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @param eamCase The case to update */ @Override - public void updateCase(EamCase eamCase) throws EamDbException { + public void updateCase(CorrelationCase eamCase) throws EamDbException { try{ acquireExclusiveLock(); super.updateCase(eamCase); @@ -320,10 +320,10 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @return The retrieved case */ @Override - public EamCase getCaseDetails(String caseUUID) throws EamDbException { + public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException { try{ acquireSharedLock(); - return super.getCaseDetails(caseUUID); + return super.getCaseByUUID(caseUUID); } finally { releaseSharedLock(); } @@ -335,7 +335,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { * @return List of cases */ @Override - public List getCases() throws EamDbException { + public List getCases() throws EamDbException { try{ acquireSharedLock(); return super.getCases(); @@ -364,15 +364,15 @@ public class SqliteEamDb extends AbstractSqlEamDb { * * @param eamDataSource the data source to update */ - @Override - public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException { - try{ - acquireExclusiveLock(); - super.updateDataSource(eamDataSource); - } finally { - releaseExclusiveLock(); - } - } +// @Override +// public void updateDataSource(CorrelationDataSource eamDataSource) throws EamDbException { +// try{ +// acquireExclusiveLock(); +// super.updateDataSource(eamDataSource); +// } finally { +// releaseExclusiveLock(); +// } +// } /** * Retrieves Data Source details based on data source device ID @@ -561,7 +561,7 @@ public class SqliteEamDb extends AbstractSqlEamDb { * Executes a bulk insert of the cases */ @Override - public void bulkInsertCases(List cases) throws EamDbException { + public void bulkInsertCases(List cases) throws EamDbException { try{ acquireExclusiveLock(); super.bulkInsertCases(cases); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index d7ac0f290c..dc67b526aa 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -34,7 +34,7 @@ import org.sleuthkit.autopsy.casemodule.services.TagsManager; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttribute; import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; @@ -277,7 +277,7 @@ public class CaseEventListener implements PropertyChangeListener { LOGGER.log(Level.SEVERE, "Error adding tag.", ex); // NON-NLS } - EamCase curCeCase = new EamCase( + CorrelationCase curCeCase = new CorrelationCase( -1, curCase.getName(), // unique case ID EamOrganization.getDefault(), @@ -296,7 +296,7 @@ public class CaseEventListener implements PropertyChangeListener { try { // NOTE: Cannot determine if the opened case is a new case or a reopened case, // so check for existing name in DB and insert if missing. - EamCase existingCase = dbManager.getCaseDetails(curCeCase.getCaseUUID()); + CorrelationCase existingCase = dbManager.getCaseByUUID(curCeCase.getCaseUUID()); if (null == existingCase) { dbManager.newCase(curCeCase); @@ -319,7 +319,7 @@ public class CaseEventListener implements PropertyChangeListener { String newName = (String)evt.getNewValue(); try { // See if the case is in the database. If it is, update the display name. - EamCase existingCase = dbManager.getCaseDetails(Case.getCurrentCase().getName()); + CorrelationCase existingCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName()); if (null != existingCase) { existingCase.setDisplayName(newName); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index 518ac55a1a..4136f0a717 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -18,7 +18,7 @@ */ package org.sleuthkit.autopsy.centralrepository.ingestmodule; -import org.sleuthkit.autopsy.centralrepository.datamodel.EamCase; +import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import java.util.List; import java.util.logging.Level; @@ -64,7 +64,7 @@ class IngestModule implements FileIngestModule { private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter(); private static final IngestModuleReferenceCounter warningMsgRefCounter = new IngestModuleReferenceCounter(); private long jobId; - private EamCase eamCase; + private CorrelationCase eamCase; private CorrelationDataSource eamDataSource; private Blackboard blackboard; private CorrelationAttribute.Type filesType; @@ -216,7 +216,7 @@ class IngestModule implements FileIngestModule { throw new IngestModuleException("Cannot run on a multi-user case with a SQLite central repository."); // NON-NLS } jobId = context.getJobId(); - eamCase = new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()); + eamCase = new CorrelationCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()); try { eamDataSource = CorrelationDataSource.fromTSKDataSource(context.getDataSource()); @@ -256,9 +256,9 @@ class IngestModule implements FileIngestModule { } // ensure we have this case defined in the EAM DB - EamCase existingCase; + CorrelationCase existingCase; Case curCase = Case.getCurrentCase(); - EamCase curCeCase = new EamCase( + CorrelationCase curCeCase = new CorrelationCase( -1, curCase.getName(), // unique case ID EamOrganization.getDefault(), @@ -270,7 +270,7 @@ class IngestModule implements FileIngestModule { null, null); try { - existingCase = dbManager.getCaseDetails(curCeCase.getCaseUUID()); + existingCase = dbManager.getCaseByUUID(curCeCase.getCaseUUID()); if (existingCase == null) { dbManager.newCase(curCeCase); } From 83336abc618ba6428fe64c5054fa7f53e8b20b0f Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 26 Sep 2017 13:21:19 +0200 Subject: [PATCH 18/29] expanded unit tests --- .../keywordsearch/CreditCardValidator.java | 2 +- .../CreditCardValidatorTest.java | 186 ++++++++++-------- 2 files changed, 109 insertions(+), 79 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidator.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidator.java index 2b49e7ff9d..20c4d64152 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidator.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidator.java @@ -181,7 +181,7 @@ final class CreditCardValidator { return CREDIT_CARD_NUM_LUHN_CHECK.isValid(cannonicalCCN); } - private boolean lengthMatchesBin(String cannonicalCCN) { + static private boolean lengthMatchesBin(String cannonicalCCN) { String BIN = cannonicalCCN.substring(0, 8); final Set lengthsForBIN = allowedLengths.get(Integer.valueOf(BIN)); return null == lengthsForBIN || lengthsForBIN.contains(cannonicalCCN.length()); diff --git a/KeywordSearch/test/unit/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidatorTest.java b/KeywordSearch/test/unit/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidatorTest.java index fd7a56c39b..e59b2b98f3 100644 --- a/KeywordSearch/test/unit/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidatorTest.java +++ b/KeywordSearch/test/unit/src/org/sleuthkit/autopsy/keywordsearch/CreditCardValidatorTest.java @@ -46,18 +46,50 @@ public class CreditCardValidatorTest { public void tearDown() { } - @Test - public void testLengthMatchesBin(){ - System.out.println("lengthMatchesBin"); - CreditCardValidator validator = new CreditCardValidator(); + @Test + public void testLengthMatchesBin() { + System.out.println("lengthMatchesBin"); //amex must be 15 - assertEquals(true, validator.isValidCCN("3431 136294 58529")); - assertEquals(false, validator.isValidCCN("3431-136294-5850")); - assertEquals(false, validator.isValidCCN("34311362945850")); - assertEquals(false, validator.isValidCCN("3431 1362 9458 5034")); + assertEquals(true, CreditCardValidator.isValidCCN("3431 136294 58529")); + assertEquals(false, CreditCardValidator.isValidCCN("3431-136294-5850")); //too short + assertEquals(false, CreditCardValidator.isValidCCN("34311362945850"));// too short + assertEquals(false, CreditCardValidator.isValidCCN("3431 1362 9458 5034")); //too long + + //verve 16 or 19 + assertEquals(false, CreditCardValidator.isValidCCN("506099002418342")); // 15 too short + assertEquals(true, CreditCardValidator.isValidCCN("5060990024183426")); //16 + assertEquals(false, CreditCardValidator.isValidCCN("50609900241834267")); // 17 + assertEquals(false, CreditCardValidator.isValidCCN("506099002418342675")); //18 + assertEquals(true, CreditCardValidator.isValidCCN("5060990024183426759")); //19 + assertEquals(false, CreditCardValidator.isValidCCN("50609900241834267591")); //20 + + //visa (theoretically 12-19 digits) + assertEquals(false, CreditCardValidator.isValidCCN("4000 0000 000")); //11 visa + assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002")); //12 visa + assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2")); //13 visa + assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 26")); //14 visa + assertEquals(false, CreditCardValidator.isValidCCN("4000 0000 0002 267")); //15 visa + assertEquals(true, CreditCardValidator.isValidCCN("4000 000000 02267")); //15 visa //is this right to enforce grouping? + assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2675")); //16 visa + assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2675 9")); //17 visa + assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2675 91")); //18 visa + assertEquals(true, CreditCardValidator.isValidCCN("4000 0000 0002 2675 918")); //19 visa + assertEquals(false, CreditCardValidator.isValidCCN("4000 0000 0002 2675 9183")); //20 visa + + //vs visa electron (only 16 digits (?)) + assertEquals(false, CreditCardValidator.isValidCCN("4026 1200 006")); //11 visa electron + assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065")); //12 visa electron + assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9")); //13 visa electron + assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 91")); //14 visa electron + assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 918")); //15 visa electron + assertEquals(true, CreditCardValidator.isValidCCN("4026 0000 0065 9187")); //16 visa electron + assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9187 0")); //17 visa electron + assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9183 00")); //18 visa electron + assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9183 000")); //19 visa electron + assertEquals(false, CreditCardValidator.isValidCCN("4026 0000 0065 9183 0000")); //20 visa electron } - + /** * Test of isValidCCN method, of class CreditCardValidator. */ @@ -66,15 +98,15 @@ public class CreditCardValidatorTest { System.out.println("isValidCCN"); //rules for separators and grouping for 16 digits - assertEquals(true, CreditCardValidator.isValidCCN("1234567890318342"));// dashes - assertEquals(true, CreditCardValidator.isValidCCN("1234-5678-9031-8342"));// dashes - assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8342"));// or spaces - - assertEquals(false, CreditCardValidator.isValidCCN("1234567890318341"));// luhn - assertEquals(false, CreditCardValidator.isValidCCN("1234-5678-9031 8342")); //only one seperator - assertEquals(false, CreditCardValidator.isValidCCN("1234-5678-90-318342")); //only four groups of four - assertEquals(false, CreditCardValidator.isValidCCN("1234 5678 90 318342")); //only four groups of four - assertEquals(false, CreditCardValidator.isValidCCN("1-2-3-4-5-6-7-8-9-0-3-1-8-3-4-2")); //only four groups of four + assertEquals(true, CreditCardValidator.isValidCCN("1234567890318342"));// dashes + assertEquals(true, CreditCardValidator.isValidCCN("1234-5678-9031-8342"));// dashes + assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8342"));// or spaces + + assertEquals(false, CreditCardValidator.isValidCCN("1234567890318341"));// luhn + assertEquals(false, CreditCardValidator.isValidCCN("1234-5678-9031 8342")); //only one seperator + assertEquals(false, CreditCardValidator.isValidCCN("1234-5678-90-318342")); //only four groups of four + assertEquals(false, CreditCardValidator.isValidCCN("1234 5678 90 318342")); //only four groups of four + assertEquals(false, CreditCardValidator.isValidCCN("1-2-3-4-5-6-7-8-9-0-3-1-8-3-4-2")); //only four groups of four } @Test @@ -83,23 +115,23 @@ public class CreditCardValidatorTest { //amex are fifteen digits, and grouped 4 6 5 //amex cards that strart with 34 - assertEquals(true, CreditCardValidator.isValidCCN("3431 136294 58529")); - assertEquals(true, CreditCardValidator.isValidCCN("3431-136294-58529")); - assertEquals(true, CreditCardValidator.isValidCCN("343113629458529")); - - assertEquals(false, CreditCardValidator.isValidCCN("343113629458528")); //luhn - assertEquals(false, CreditCardValidator.isValidCCN("3431 13629458 529")); //grouping - assertEquals(false, CreditCardValidator.isValidCCN("3431 136294-58529")); //separators + assertEquals(true, CreditCardValidator.isValidCCN("3431 136294 58529")); + assertEquals(true, CreditCardValidator.isValidCCN("3431-136294-58529")); + assertEquals(true, CreditCardValidator.isValidCCN("343113629458529")); + + assertEquals(false, CreditCardValidator.isValidCCN("343113629458528")); //luhn + assertEquals(false, CreditCardValidator.isValidCCN("3431 13629458 529")); //grouping + assertEquals(false, CreditCardValidator.isValidCCN("3431 136294-58529")); //separators //amex cards that start with 37 - assertEquals(true, CreditCardValidator.isValidCCN("377585291285489")); - assertEquals(true, CreditCardValidator.isValidCCN("3775-852912-85489")); - assertEquals(true, CreditCardValidator.isValidCCN("3775 852912 85489")); - - assertEquals(false, CreditCardValidator.isValidCCN("377585291285488")); //luhn - assertEquals(false, CreditCardValidator.isValidCCN("3775-852912 85489")); //separator - assertEquals(false, CreditCardValidator.isValidCCN("37-7585-29-1285489")); //grouping - assertEquals(false, CreditCardValidator.isValidCCN("377585 29128548 9")); //grouping + assertEquals(true, CreditCardValidator.isValidCCN("377585291285489")); + assertEquals(true, CreditCardValidator.isValidCCN("3775-852912-85489")); + assertEquals(true, CreditCardValidator.isValidCCN("3775 852912 85489")); + + assertEquals(false, CreditCardValidator.isValidCCN("377585291285488")); //luhn + assertEquals(false, CreditCardValidator.isValidCCN("3775-852912 85489")); //separator + assertEquals(false, CreditCardValidator.isValidCCN("37-7585-29-1285489")); //grouping + assertEquals(false, CreditCardValidator.isValidCCN("377585 29128548 9")); //grouping //UATP are also 15 digits, start with 1 and are typically 4-5-6 // assertEquals(true, CreditCardValidator.isValidCCN("1409 56201 545229")); @@ -113,92 +145,90 @@ public class CreditCardValidatorTest { public void testIsValidCCN19() { System.out.println("isValidCCN"); //nineteen digit (visa) cards 4-4-4-4-3 - assertEquals(true, CreditCardValidator.isValidCCN("4539747947839518654")); - assertEquals(true, CreditCardValidator.isValidCCN("4539-7479-4783-9518-654")); - assertEquals(true, CreditCardValidator.isValidCCN("4539 7479 4783 9518 654")); + assertEquals(true, CreditCardValidator.isValidCCN("4539747947839518654")); + assertEquals(true, CreditCardValidator.isValidCCN("4539-7479-4783-9518-654")); + assertEquals(true, CreditCardValidator.isValidCCN("4539 7479 4783 9518 654")); - assertEquals(false, CreditCardValidator.isValidCCN("4539747947839518653")); //luhn - assertEquals(false, CreditCardValidator.isValidCCN("4539-7479 4783 9518 654")); //separators - assertEquals(false, CreditCardValidator.isValidCCN("45374 79 4783 9518 654")); //grouping + assertEquals(false, CreditCardValidator.isValidCCN("4539747947839518653")); //luhn + assertEquals(false, CreditCardValidator.isValidCCN("4539-7479 4783 9518 654")); //separators + assertEquals(false, CreditCardValidator.isValidCCN("45374 79 4783 9518 654")); //grouping //nineteen digit China UnionPay is 19 digits 6-13 (or 4-4-4-4) beging 62 - assertEquals(true, CreditCardValidator.isValidCCN("6239747947839518659")); - assertEquals(true, CreditCardValidator.isValidCCN("623974 7947839518659")); - assertEquals(true, CreditCardValidator.isValidCCN("623974-7947839518659")); + assertEquals(true, CreditCardValidator.isValidCCN("6239747947839518659")); + assertEquals(true, CreditCardValidator.isValidCCN("623974 7947839518659")); + assertEquals(true, CreditCardValidator.isValidCCN("623974-7947839518659")); /* - * China UnionPay may not use luhn ??? - * + * China UnionPay may not use luhn ??? * * https://stackoverflow.com/questions/7863058/does-the-luhn-algorithm-work-for-all-mainstream-credit-cards-discover-visa-m */ - assertEquals(false, CreditCardValidator.isValidCCN("6239747947839518658")); //luhn - assertEquals(false, CreditCardValidator.isValidCCN("623974-79478395 18659")); //separators - assertEquals(false, CreditCardValidator.isValidCCN("62397-47947839518659")); //grouping + assertEquals(false, CreditCardValidator.isValidCCN("6239747947839518658")); //luhn + assertEquals(false, CreditCardValidator.isValidCCN("623974-79478395 18659")); //separators + assertEquals(false, CreditCardValidator.isValidCCN("62397-47947839518659")); //grouping } @Test public void testIsValidCCN18() { System.out.println("isValidCCN"); - assertEquals(true, CreditCardValidator.isValidCCN("123456789031834267")); - assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8342 67")); - assertEquals(true, CreditCardValidator.isValidCCN("1234-56789031834-267")); + assertEquals(true, CreditCardValidator.isValidCCN("123456789031834267")); + assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8342 67")); + assertEquals(true, CreditCardValidator.isValidCCN("1234-56789031834-267")); - assertEquals(false, CreditCardValidator.isValidCCN("123456789031834266")); //luhn - assertEquals(false, CreditCardValidator.isValidCCN("123 456789031834267")); //grouping - assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031834267")); //separators + assertEquals(false, CreditCardValidator.isValidCCN("123456789031834266")); //luhn + assertEquals(false, CreditCardValidator.isValidCCN("123 456789031834267")); //grouping + assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031834267")); //separators } @Test public void testIsValidCCN17() { System.out.println("isValidCCN"); - assertEquals(true, CreditCardValidator.isValidCCN("12345678903183426")); - assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8342 6")); - assertEquals(true, CreditCardValidator.isValidCCN("1234-56789031834-26")); + assertEquals(true, CreditCardValidator.isValidCCN("12345678903183426")); + assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8342 6")); + assertEquals(true, CreditCardValidator.isValidCCN("1234-56789031834-26")); - assertEquals(false, CreditCardValidator.isValidCCN("12345678903183425"));//luhn - assertEquals(false, CreditCardValidator.isValidCCN("123 45678903183426")); //grouping - assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 03183426")); //separators + assertEquals(false, CreditCardValidator.isValidCCN("12345678903183425"));//luhn + assertEquals(false, CreditCardValidator.isValidCCN("123 45678903183426")); //grouping + assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 03183426")); //separators } @Test public void testIsValidCCN14() { System.out.println("isValidCCN"); - assertEquals(true, CreditCardValidator.isValidCCN("12345678903183")); - assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 83")); - assertEquals(true, CreditCardValidator.isValidCCN("1234-5678903183")); + assertEquals(true, CreditCardValidator.isValidCCN("12345678903183")); + assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 83")); + assertEquals(true, CreditCardValidator.isValidCCN("1234-5678903183")); - assertEquals(false, CreditCardValidator.isValidCCN("12345678903182"));//luhn - assertEquals(false, CreditCardValidator.isValidCCN("123 45678903183")); //grouping - assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 03183")); //separators + assertEquals(false, CreditCardValidator.isValidCCN("12345678903182"));//luhn + assertEquals(false, CreditCardValidator.isValidCCN("123 45678903183")); //grouping + assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 03183")); //separators } @Test public void testIsValidCCN13() { System.out.println("isValidCCN"); - assertEquals(true, CreditCardValidator.isValidCCN("1234567890318")); - assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8")); - assertEquals(true, CreditCardValidator.isValidCCN("1234-567890318")); + assertEquals(true, CreditCardValidator.isValidCCN("1234567890318")); + assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031 8")); + assertEquals(true, CreditCardValidator.isValidCCN("1234-567890318")); - assertEquals(false, CreditCardValidator.isValidCCN("1234567890317"));//luhn - assertEquals(false, CreditCardValidator.isValidCCN("123 4567890318")); //grouping - assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 0318")); //separators + assertEquals(false, CreditCardValidator.isValidCCN("1234567890317"));//luhn + assertEquals(false, CreditCardValidator.isValidCCN("123 4567890318")); //grouping + assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 0318")); //separators } @Test public void testIsValidCCN12() { System.out.println("isValidCCN"); - assertEquals(true, CreditCardValidator.isValidCCN("123456789031")); - assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031")); - assertEquals(true, CreditCardValidator.isValidCCN("1234-56789031")); + assertEquals(true, CreditCardValidator.isValidCCN("123456789031")); + assertEquals(true, CreditCardValidator.isValidCCN("1234 5678 9031")); + assertEquals(true, CreditCardValidator.isValidCCN("1234-56789031")); - assertEquals(false, CreditCardValidator.isValidCCN("123456789030")); //luhn - assertEquals(false, CreditCardValidator.isValidCCN("123 456789031")); //grouping - assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031")); //separators + assertEquals(false, CreditCardValidator.isValidCCN("123456789030")); //luhn + assertEquals(false, CreditCardValidator.isValidCCN("123 456789031")); //grouping + assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031")); //separators } - } From 332c11648668bbc50b5969c69a98bd11cf44f20e Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 26 Sep 2017 13:38:52 +0200 Subject: [PATCH 19/29] revert unneeded upgrade to guava 19 --- CoreLibs/ivy.xml | 2 +- CoreLibs/nbproject/project.properties | 4 +++- CoreLibs/nbproject/project.xml | 4 ++-- KeywordSearch/ivy.xml | 2 -- KeywordSearch/nbproject/project.properties | 2 +- KeywordSearch/nbproject/project.xml | 8 ++++---- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index 24634d90f1..bfd9112f9e 100755 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -16,7 +16,7 @@ - + diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index da8749c100..13a62b62ee 100755 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -24,7 +24,7 @@ file.reference.dom4j-1.6.1.jar=release/modules/ext/dom4j-1.6.1.jar file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.1_spec-1.0.jar file.reference.gson-1.4.jar=release/modules/ext/gson-1.4.jar file.reference.gstreamer-java-1.5.jar=release/modules/ext/gstreamer-java-1.5.jar -file.reference.guava-21.0.jar=release/modules/ext/guava-21.0.jar +file.reference.guava-19.0.jar=release/modules/ext/guava-19.0.jar file.reference.imageio-bmp-3.2.jar=release/modules/ext/imageio-bmp-3.2.jar file.reference.imageio-core-3.2.jar=release/modules/ext/imageio-core-3.2.jar file.reference.imageio-icns-3.2.jar=release/modules/ext/imageio-icns-3.2.jar @@ -78,6 +78,7 @@ javadoc.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-javado javadoc.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-javadoc.jar javadoc.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-javadoc.jar javadoc.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-javadoc.jar +javadoc.reference.guava-19.0.jar=release/modules/ext/guava-19.0-javadoc.jar javadoc.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-javadoc.jar javadoc.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-javadoc.jar javadoc.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-javadoc.jar @@ -86,6 +87,7 @@ source.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-sources source.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-sources.jar source.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-sources.jar source.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-sources.jar +source.reference.guava-19.0.jar=release/modules/ext/guava-19.0-sources.jar source.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-sources.jar source.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-sources.jar source.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-sources.jar diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index f3c852d11c..6fcef46ccd 100755 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -848,8 +848,8 @@ release/modules/ext/slf4j-simple-1.6.1.jar - ext/guava-21.0.jar - release/modules/ext/guava-21.0.jar + ext/guava-19.0.jar + release/modules/ext/guava-19.0.jar ext/commons-io-2.5.jar diff --git a/KeywordSearch/ivy.xml b/KeywordSearch/ivy.xml index 6f810feddc..3ceb4e6378 100755 --- a/KeywordSearch/ivy.xml +++ b/KeywordSearch/ivy.xml @@ -14,8 +14,6 @@ - - diff --git a/KeywordSearch/nbproject/project.properties b/KeywordSearch/nbproject/project.properties index 07273eea69..5aa1b716e0 100755 --- a/KeywordSearch/nbproject/project.properties +++ b/KeywordSearch/nbproject/project.properties @@ -42,7 +42,7 @@ file.reference.fontbox-2.0.3.jar=release/modules/ext/fontbox-2.0.3.jar file.reference.geoapi-3.0.0.jar=release/modules/ext/geoapi-3.0.0.jar file.reference.grib-4.5.5.jar=release/modules/ext/grib-4.5.5.jar file.reference.gson-2.2.4.jar=release/modules/ext/gson-2.2.4.jar -file.reference.guava-21.0.jar=release/modules/ext/guava-21.0.jar +file.reference.guava-17.0.jar=release/modules/ext/guava-17.0.jar file.reference.hamcrest-core-1.3.jar=release/modules/ext/hamcrest-core-1.3.jar file.reference.httpclient-4.3.1.jar=release/modules/ext/httpclient-4.3.1.jar file.reference.httpcore-4.3.jar=release/modules/ext/httpcore-4.3.jar diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml index 8a5e7213e0..d375e76868 100755 --- a/KeywordSearch/nbproject/project.xml +++ b/KeywordSearch/nbproject/project.xml @@ -213,6 +213,10 @@ ext/slf4j-api-1.7.12.jar release/modules/ext/slf4j-api-1.7.12.jar + + ext/guava-17.0.jar + release/modules/ext/guava-17.0.jar + ext/opennlp-maxent-3.0.3.jar release/modules/ext/opennlp-maxent-3.0.3.jar @@ -673,10 +677,6 @@ ext/sis-storage-0.6.jar release/modules/ext/sis-storage-0.6.jar - - ext/guava-21.0.jar - ext/guava-21.0.jar - ext/jcip-annotations-1.0.jar release/modules/ext/jcip-annotations-1.0.jar From f813f6036c6c4003f7fb1076131e38e80d4824d9 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Tue, 26 Sep 2017 13:53:15 -0400 Subject: [PATCH 20/29] Allow carved files in the central repo --- .../datamodel/EamArtifactUtil.java | 23 ++++++++++++++----- .../ingestmodule/IngestModule.java | 10 ++------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java index 7e3c7881be..d53e1b480b 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java @@ -229,12 +229,7 @@ public class EamArtifactUtil { final AbstractFile af = (AbstractFile) content; - if ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) - || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) - || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK) - || (af.getKnown() == TskData.FileKnown.KNOWN) - || (af.isDir() == true) - || (!af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC))) { + if ( ! isValidCentralRepoFile(af)) { return null; } @@ -263,4 +258,20 @@ public class EamArtifactUtil { return null; } } + + /** + * Check whether the given abstract file should be processed for + * the central repository. + * @param af The file to test + * @return true if the file should be added to the central repo, false otherwise + */ + public static boolean isValidCentralRepoFile(AbstractFile af){ + if(af == null) return false; + return (false == ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) + || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) + || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK) + || (af.getKnown() == TskData.FileKnown.KNOWN) + || (af.isDir() == true) + || ((af.getType() != TskData.TSK_DB_FILES_TYPE_ENUM.CARVED) && !af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)))); + } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java index 518ac55a1a..d9d6683c69 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/IngestModule.java @@ -23,7 +23,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException; import java.util.List; import java.util.logging.Level; import java.util.stream.Collectors; -import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.casemodule.Case; @@ -41,6 +40,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationDataSource; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb; import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbPlatformEnum; +import org.sleuthkit.autopsy.centralrepository.datamodel.EamArtifactUtil; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -49,7 +49,6 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.EamOrganization; import org.sleuthkit.autopsy.centralrepository.eventlisteners.IngestEventsListener; -import org.sleuthkit.datamodel.TskDataException; /** * Ingest module for inserting entries into the Central Repository database on @@ -83,12 +82,7 @@ class IngestModule implements FileIngestModule { blackboard = Case.getCurrentCase().getServices().getBlackboard(); - if ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) - || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) - || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK) - || (af.getKnown() == TskData.FileKnown.KNOWN) - || (af.isDir() == true) - || (!af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC))) { + if (! EamArtifactUtil.isValidCentralRepoFile(af)) { return ProcessResult.OK; } From ae4e0052f18afcf4c8510b3d18d63b4cd85947ee Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Tue, 26 Sep 2017 14:38:13 -0400 Subject: [PATCH 21/29] Refactor test --- .../datamodel/EamArtifactUtil.java | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java index d53e1b480b..f198eaf62f 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/EamArtifactUtil.java @@ -266,12 +266,30 @@ public class EamArtifactUtil { * @return true if the file should be added to the central repo, false otherwise */ public static boolean isValidCentralRepoFile(AbstractFile af){ - if(af == null) return false; - return (false == ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) - || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) - || (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK) - || (af.getKnown() == TskData.FileKnown.KNOWN) - || (af.isDir() == true) - || ((af.getType() != TskData.TSK_DB_FILES_TYPE_ENUM.CARVED) && !af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC)))); + if(af == null){ + return false; + } + + if(af.getKnown() == TskData.FileKnown.KNOWN){ + return false; + } + + switch (af.getType()){ + case UNALLOC_BLOCKS: + case UNUSED_BLOCKS: + case SLACK: + case VIRTUAL_DIR: + case LOCAL_DIR: + return false; + case CARVED: + case DERIVED: + case LOCAL: + return true; + case FS: + return af.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC); + default: + LOGGER.log(Level.WARNING, "Unexpected file type {0}", af.getType().getName()); + return false; + } } } From b34f4ad955ec1858a1cd751ebd07e69b6e8258d7 Mon Sep 17 00:00:00 2001 From: esaunders Date: Tue, 26 Sep 2017 14:40:30 -0400 Subject: [PATCH 22/29] Fix for completed jobs always being in error. --- .../autoingest/AutoIngestJob.java | 9 +++--- .../autoingest/AutoIngestManager.java | 32 ++++++++++--------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJob.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJob.java index b43b00d3fd..5e9bfbd26c 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJob.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJob.java @@ -208,13 +208,14 @@ public final class AutoIngestJob implements Comparable, Serializa * is set when the stage is set. * * @param newStage The processing stage. + * @param stageStartDate The date and time this stage started. */ - synchronized void setProcessingStage(Stage newStage) { + synchronized void setProcessingStage(Stage newStage, Date stageStartDate) { if (Stage.CANCELLING == this.stage && Stage.COMPLETED != newStage) { return; } this.stage = newStage; - this.stageStartDate = Date.from(Instant.now()); + this.stageStartDate = stageStartDate; } /** @@ -319,7 +320,7 @@ public final class AutoIngestJob implements Comparable, Serializa * Cancels the job. */ synchronized void cancel() { - setProcessingStage(Stage.CANCELLING); + setProcessingStage(Stage.CANCELLING, Date.from(Instant.now())); cancelled = true; errorsOccurred = true; if (null != dataSourceProcessor) { @@ -347,7 +348,7 @@ public final class AutoIngestJob implements Comparable, Serializa * the job. */ synchronized void setCompleted() { - setProcessingStage(Stage.COMPLETED); + setProcessingStage(Stage.COMPLETED, Date.from(Instant.now())); completed = true; } diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index bb9e68c610..5d59f01027 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -849,7 +849,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang if (null != ingestJob) { IngestJob.DataSourceIngestModuleHandle moduleHandle = ingestJob.getSnapshot().runningDataSourceIngestModule(); if (null != moduleHandle) { - currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING_MODULE); + currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING_MODULE, Date.from(Instant.now())); moduleHandle.cancel(); SYS_LOGGER.log(Level.INFO, "Cancelling {0} module for manifest {1}", new Object[]{moduleHandle.displayName(), currentJob.getManifest().getFilePath()}); } @@ -1297,10 +1297,12 @@ public final class AutoIngestManager extends Observable implements PropertyChang AutoIngestJob job = new AutoIngestJob(manifest); job.setCaseDirectoryPath(caseDirectoryPath); job.setProcessingStatus(AutoIngestJob.ProcessingStatus.COMPLETED); - job.setProcessingStage(AutoIngestJob.Stage.COMPLETED); + job.setProcessingStage(AutoIngestJob.Stage.COMPLETED, nodeData.getCompletedDate()); job.setCompletedDate(nodeData.getCompletedDate()); - job.setErrorsOccurred(true); - newCompletedJobsList.add(new AutoIngestJob(nodeData)); + job.setErrorsOccurred(nodeData.getErrorsOccurred()); + job.setPriority(nodeData.getPriority()); + job.setNumberOfCrashes(nodeData.getNumberOfCrashes()); + newCompletedJobsList.add(job); /* * Try to upgrade/update the coordination service node data for @@ -1868,7 +1870,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang Path manifestPath = currentJob.getManifest().getFilePath(); SYS_LOGGER.log(Level.INFO, "Started processing of {0}", manifestPath); currentJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.PROCESSING); - currentJob.setProcessingStage(AutoIngestJob.Stage.STARTING); + currentJob.setProcessingStage(AutoIngestJob.Stage.STARTING, Date.from(Instant.now())); currentJob.setProcessingHostName(AutoIngestManager.LOCAL_HOST_NAME); updateCoordinationServiceNode(currentJob); setChanged(); @@ -1990,7 +1992,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang if (AutoIngestUserPreferences.getSharedConfigEnabled()) { Path manifestPath = currentJob.getManifest().getFilePath(); SYS_LOGGER.log(Level.INFO, "Downloading shared configuration for {0}", manifestPath); - currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG); + currentJob.setProcessingStage(AutoIngestJob.Stage.UPDATING_SHARED_CONFIG, Date.from(Instant.now())); new SharedConfiguration().downloadConfiguration(); } } @@ -2008,7 +2010,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang private void verifyRequiredSevicesAreRunning() throws ServicesMonitorException, DatabaseServerDownException, KeywordSearchServerDownException { Path manifestPath = currentJob.getManifest().getFilePath(); SYS_LOGGER.log(Level.INFO, "Checking services availability for {0}", manifestPath); - currentJob.setProcessingStage(AutoIngestJob.Stage.CHECKING_SERVICES); + currentJob.setProcessingStage(AutoIngestJob.Stage.CHECKING_SERVICES, Date.from(Instant.now())); if (!isServiceUp(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString())) { throw new DatabaseServerDownException("Case database server is down"); } @@ -2055,7 +2057,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang Manifest manifest = currentJob.getManifest(); String caseName = manifest.getCaseName(); SYS_LOGGER.log(Level.INFO, "Opening case {0} for {1}", new Object[]{caseName, manifest.getFilePath()}); - currentJob.setProcessingStage(AutoIngestJob.Stage.OPENING_CASE); + currentJob.setProcessingStage(AutoIngestJob.Stage.OPENING_CASE, Date.from(Instant.now())); /* * Acquire and hold a case name lock so that only one node at as * time can scan the output directory at a time. This prevents @@ -2168,7 +2170,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang DataSource dataSource = identifyDataSource(caseForJob); if (null == dataSource) { - currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED); + currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED, Date.from(Instant.now())); return; } @@ -2178,7 +2180,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang runDataSourceProcessor(caseForJob, dataSource); if (dataSource.getContent().isEmpty()) { - currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED); + currentJob.setProcessingStage(AutoIngestJob.Stage.COMPLETED, Date.from(Instant.now())); return; } @@ -2223,7 +2225,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang Manifest manifest = currentJob.getManifest(); Path manifestPath = manifest.getFilePath(); SYS_LOGGER.log(Level.INFO, "Identifying data source for {0} ", manifestPath); - currentJob.setProcessingStage(AutoIngestJob.Stage.IDENTIFYING_DATA_SOURCE); + currentJob.setProcessingStage(AutoIngestJob.Stage.IDENTIFYING_DATA_SOURCE, Date.from(Instant.now())); Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); Path dataSourcePath = manifest.getDataSourcePath(); @@ -2259,7 +2261,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang Manifest manifest = currentJob.getManifest(); Path manifestPath = manifest.getFilePath(); SYS_LOGGER.log(Level.INFO, "Adding data source for {0} ", manifestPath); - currentJob.setProcessingStage(AutoIngestJob.Stage.ADDING_DATA_SOURCE); + currentJob.setProcessingStage(AutoIngestJob.Stage.ADDING_DATA_SOURCE, Date.from(Instant.now())); UUID taskId = UUID.randomUUID(); DataSourceProcessorCallback callBack = new AddDataSourceCallback(caseForJob, dataSource, taskId); DataSourceProcessorProgressMonitor progressMonitor = new DoNothingDSPProgressMonitor(); @@ -2424,7 +2426,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang Manifest manifest = currentJob.getManifest(); Path manifestPath = manifest.getFilePath(); SYS_LOGGER.log(Level.INFO, "Starting ingest modules analysis for {0} ", manifestPath); - currentJob.setProcessingStage(AutoIngestJob.Stage.ANALYZING_DATA_SOURCE); + currentJob.setProcessingStage(AutoIngestJob.Stage.ANALYZING_DATA_SOURCE, Date.from(Instant.now())); Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); IngestJobEventListener ingestJobEventListener = new IngestJobEventListener(); @@ -2460,7 +2462,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang } jobLogger.logAnalysisCompleted(); } else { - currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING); + currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING, Date.from(Instant.now())); currentJob.setErrorsOccurred(true); AutoIngestAlertFile.create(caseDirectoryPath); // Do this first, it is more important than the case log jobLogger.logAnalysisCancelled(); @@ -2523,7 +2525,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang Manifest manifest = currentJob.getManifest(); Path manifestPath = manifest.getFilePath(); SYS_LOGGER.log(Level.INFO, "Exporting files for {0}", manifestPath); - currentJob.setProcessingStage(AutoIngestJob.Stage.EXPORTING_FILES); + currentJob.setProcessingStage(AutoIngestJob.Stage.EXPORTING_FILES, Date.from(Instant.now())); Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, manifest.getDataSourceFileName(), caseDirectoryPath); try { From 08eb9c98247a32a3ff24aebe4147a922f610a4e9 Mon Sep 17 00:00:00 2001 From: esaunders Date: Tue, 26 Sep 2017 15:03:48 -0400 Subject: [PATCH 23/29] Add comment explaining the use of the manifest to create the AutoIngestJob. --- .../autoingest/AutoIngestManager.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index 359f270af0..6e12b98403 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -1294,14 +1294,25 @@ public final class AutoIngestManager extends Observable implements PropertyChang private void addCompletedJob(Manifest manifest, AutoIngestJobNodeData nodeData) throws CoordinationServiceException, InterruptedException { Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName()); if (null != caseDirectoryPath) { + /** + * We use the manifest rather than the nodeData here to create + * a new AutoIngestJob instance because the AutoIngestJob + * constructor that takes a nodeData expects the nodeData to + * have fields that do not exist in earlier versions. + */ AutoIngestJob job = new AutoIngestJob(manifest); - job.setCaseDirectoryPath(caseDirectoryPath); - job.setProcessingStatus(AutoIngestJob.ProcessingStatus.COMPLETED); - job.setProcessingStage(AutoIngestJob.Stage.COMPLETED, nodeData.getCompletedDate()); + /** + * Update the job with the fields that exist in all versions + * of the nodeData. + */ job.setCompletedDate(nodeData.getCompletedDate()); job.setErrorsOccurred(nodeData.getErrorsOccurred()); job.setPriority(nodeData.getPriority()); job.setNumberOfCrashes(nodeData.getNumberOfCrashes()); + job.setProcessingStage(AutoIngestJob.Stage.COMPLETED, nodeData.getCompletedDate()); + + job.setCaseDirectoryPath(caseDirectoryPath); + job.setProcessingStatus(AutoIngestJob.ProcessingStatus.COMPLETED); newCompletedJobsList.add(job); /* From deddb0f58cc86f20bd9cfb5efe4026a73f0c9451 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Tue, 26 Sep 2017 15:10:45 -0400 Subject: [PATCH 24/29] Use name of "known" column to determine color instead of index --- .../DataContentViewerOtherCasesTableCellRenderer.java | 3 ++- .../contentviewer/DataContentViewerOtherCasesTableModel.java | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableCellRenderer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableCellRenderer.java index 0c2968fe6b..699c8755f1 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableCellRenderer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableCellRenderer.java @@ -49,7 +49,8 @@ public class DataContentViewerOtherCasesTableCellRenderer implements TableCellRe foreground = Color.WHITE; background = Color.BLUE; } else { - String known_status = (String) table.getModel().getValueAt(row, 5); + String known_status = (String) table.getModel().getValueAt(row, + table.getColumn(DataContentViewerOtherCasesTableModel.TableColumns.KNOWN.columnName()).getModelIndex()); if (known_status.equals(TskData.FileKnown.BAD.getName())) { foreground = Color.WHITE; background = Color.RED; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java index b27b6880d6..e3829987d6 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCasesTableModel.java @@ -40,9 +40,8 @@ public class DataContentViewerOtherCasesTableModel extends AbstractTableModel { "DataContentViewerOtherCasesTableModel.known=Known", "DataContentViewerOtherCasesTableModel.comment=Comment", "DataContentViewerOtherCasesTableModel.noData=No Data.",}) - private enum TableColumns { + enum TableColumns { // Ordering here determines displayed column order in Content Viewer. - // If order is changed, update the CellRenderer to ensure correct row coloring. CASE_NAME(Bundle.DataContentViewerOtherCasesTableModel_case(), 75), DATA_SOURCE(Bundle.DataContentViewerOtherCasesTableModel_dataSource(), 75), TYPE(Bundle.DataContentViewerOtherCasesTableModel_type(), 40), From f7aa83524be14d4720b4cc8afd6267bbf5e752fd Mon Sep 17 00:00:00 2001 From: esaunders Date: Tue, 26 Sep 2017 17:41:38 -0400 Subject: [PATCH 25/29] Change job state when the user decides to reprocess a job. --- .../experimental/autoingest/AutoIngestManager.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index 6e12b98403..a180efcc83 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -652,9 +652,14 @@ public final class AutoIngestManager extends Observable implements PropertyChang */ if (null != completedJob && !completedJob.getCaseDirectoryPath().toString().isEmpty()) { try { + /** + * We reset the status, completion date and processing stage + * but we keep the original priority. + */ completedJob.setErrorsOccurred(false); completedJob.setCompletedDate(new Date(0)); - completedJob.setPriority(DEFAULT_JOB_PRIORITY); + completedJob.setProcessingStatus(PENDING); + completedJob.setProcessingStage(AutoIngestJob.Stage.PENDING, Date.from(Instant.now())); updateCoordinationServiceNode(completedJob); pendingJobs.add(completedJob); } catch (CoordinationServiceException ex) { @@ -1224,7 +1229,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang /* * Update the coordination service node for the job. If - * this fails, leave the recovery to anoterh host. + * this fails, leave the recovery to another host. */ try { updateCoordinationServiceNode(job); From 8c13265611ba8f361ff914c04a3c51ffe74b98c6 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Tue, 26 Sep 2017 23:51:49 -0400 Subject: [PATCH 26/29] Revised one of the ViewContextAction constructors. --- .../sleuthkit/autopsy/directorytree/ViewContextAction.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index f237243dd0..a1aa1c9a0f 100755 --- a/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -72,8 +72,8 @@ public class ViewContextAction extends AbstractAction { */ public ViewContextAction(String displayName, BlackboardArtifactNode artifactNode) { super(displayName); - this.content = artifactNode.getLookup().lookup(Content.class); - if (content instanceof AbstractFile) { + this.content = artifactNode.getLookup().lookup(AbstractFile.class); + if(this.content != null) { AbstractFile file = (AbstractFile) content; if ((TskData.FileKnown.KNOWN == file.getKnown() && UserPreferences.hideKnownFilesInDataSourcesTree()) || (TskData.TSK_DB_FILES_TYPE_ENUM.SLACK == file.getType() && UserPreferences.hideSlackFilesInDataSourcesTree())) { From f9501ff7703089fcbc6e8e969bfe78d1ed1f5d3c Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Wed, 27 Sep 2017 09:49:17 -0400 Subject: [PATCH 27/29] Added check for pre-existing job in completed table. --- .../autopsy/experimental/autoingest/AutoIngestManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index a180efcc83..8b519891f1 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -343,6 +343,10 @@ public final class AutoIngestManager extends Observable implements PropertyChang hostNamesToRunningJobs.remove(hostName); if (event.shouldRetry() == false) { synchronized (jobsLock) { + AutoIngestJob job = event.getJob(); + if(completedJobs.contains(job)) { + completedJobs.remove(job); + } completedJobs.add(event.getJob()); } } From 02ae502d25022d9ca47868bd53f55bf3d39a1c47 Mon Sep 17 00:00:00 2001 From: Ann Priestman Date: Wed, 27 Sep 2017 11:31:36 -0400 Subject: [PATCH 28/29] Update central repo doc --- docs/doxygen-user/central_repo.dox | 8 ++++---- .../images/central_repo_content_viewer.png | Bin 12948 -> 12953 bytes 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/doxygen-user/central_repo.dox b/docs/doxygen-user/central_repo.dox index 74bf0dde4c..811b363674 100644 --- a/docs/doxygen-user/central_repo.dox +++ b/docs/doxygen-user/central_repo.dox @@ -138,7 +138,7 @@ The \ref content_viewer_page panel is where previous instances of properties are If at least one other case or data source has been ingested with this module enabled, there is a potential that data will be displayed in the Other Occurrences content viewer. Note that the Correlation Engine Ingest Module does not have to have been run on the current data source to see correlated files from other cases/data sources. If the selected file or artifact is associated by one of the supported Correlation Types, to one or more file(s) or artifact(s) in the database, the associated files/artifacts will be displayed. Note: the Content Viewer will display ALL associated files and artifacts available in the database. It ignores the user's enabled/disabled Correlation Properties. -By default, the rows in the content viewer will have background colors to indicate if they are known to be of interest. Files/artifacts that are notable will have a Red background, unknown will have Yellow background, and known will have a White background. +By default, the rows in the content viewer will have background colors to indicate if they are known to be of interest. Files/artifacts that are notable will have a Red background, all others will have a White background. \image html central_repo_content_viewer.png @@ -149,7 +149,7 @@ This menu has several options. -# Select All -# Export Selected Rows to CSV -# Show Case Details --# Show Commonality Details +-# Show Frequency Select All @@ -177,9 +177,9 @@ details will include: These details would have been entered by the examiner of the selected case, by visiting the Case -> Central Repository Case Properties menu, when that case was open. -Show Commonality Details +Show Frequency -The concept of Commonality simply means, how common is the selected file. The value is the percentage of case/data source tuples that have the selected file or artifact. +This shows how common the selected file is. The value is the percentage of case/data source tuples that have the selected file or artifact. \subsection cr_interesting_items Interesting Items diff --git a/docs/doxygen-user/images/central_repo_content_viewer.png b/docs/doxygen-user/images/central_repo_content_viewer.png index 7f79baaf93adfa30bf48c4775f0ec1650eef1e9a..5be52c5e65a8795d479ff627824bb6f6fe8b03d8 100644 GIT binary patch literal 12953 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 From 261a8d950f45a0cb1da590b11628eea940f79844 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 27 Sep 2017 13:33:08 -0400 Subject: [PATCH 29/29] Fix bug in AutoIngestJobNodeData ctor --- .../autopsy/experimental/autoingest/AutoIngestJobNodeData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java index 3544e9ef49..4dbedf644e 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJobNodeData.java @@ -84,7 +84,7 @@ final class AutoIngestJobNodeData { AutoIngestJobNodeData(AutoIngestJob job) { setProcessingStatus(job.getProcessingStatus()); setPriority(job.getPriority()); - setNumberOfCrashes(numberOfCrashes); // RJCTODO + setNumberOfCrashes(job.getNumberOfCrashes()); setCompletedDate(job.getCompletedDate()); setErrorsOccurred(job.getErrorsOccurred()); this.version = CURRENT_VERSION;