From 90ae935c005a6702302c4801f1e7fcae2b6fceac Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 11 Jun 2021 14:31:03 -0400 Subject: [PATCH 01/16] use analysis result for unique path --- .../datamodel/BlackboardArtifactNode.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 1068c72973..f048a84663 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -80,6 +80,7 @@ import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR; import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; import org.sleuthkit.datamodel.AnalysisResult; +import org.sleuthkit.datamodel.BlackboardArtifact.Category; import org.sleuthkit.datamodel.Score; /** @@ -109,17 +110,6 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Tue, 15 Jun 2021 19:42:49 -0400 Subject: [PATCH 02/16] weak listeners for hosts and persons --- Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java | 5 +++-- Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java index 1f349fdfc4..d736eaa0e9 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java @@ -189,6 +189,8 @@ public class HostNode extends DisplayableItemNode { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(hostChangePcl, null); /* * Get the host name or 'unknown host' if null. @@ -247,8 +249,7 @@ public class HostNode extends DisplayableItemNode { host == null ? Lookups.fixed(displayName) : Lookups.fixed(host, displayName)); hostId = host == null ? null : host.getHostId(); - Case.addEventTypeSubscriber(EnumSet.of(Case.Events.HOSTS_UPDATED), - WeakListeners.propertyChange(hostChangePcl, this)); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.HOSTS_UPDATED), weakPcl); super.setName(displayName); super.setDisplayName(displayName); this.setIconBaseWithExtension(ICON_PATH); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java index 06d52b8662..73db7648dd 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/PersonNode.java @@ -173,6 +173,8 @@ public class PersonNode extends DisplayableItemNode { } } }; + + private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(personChangePcl, null); /** * Gets the display name for this person or "Unknown Persons". @@ -210,8 +212,7 @@ public class PersonNode extends DisplayableItemNode { this.setIconBaseWithExtension(ICON_PATH); this.person = person; this.personId = person == null ? null : person.getPersonId(); - Case.addEventTypeSubscriber(EnumSet.of(Case.Events.PERSONS_UPDATED), - WeakListeners.propertyChange(personChangePcl, this)); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.PERSONS_UPDATED), weakPcl); } @Override From 22bad47df0e1cdc06af6a23e806ba6d084e57f23 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 16 Jun 2021 09:51:42 -0400 Subject: [PATCH 03/16] 7630 make report wizard larger with split pane --- .../infrastructure/ReportVisualPanel1.form | 207 +++++++++++------- .../infrastructure/ReportVisualPanel1.java | 69 ++++-- .../infrastructure/ReportVisualPanel2.form | 2 +- .../infrastructure/ReportVisualPanel2.java | 2 +- 4 files changed, 186 insertions(+), 94 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.form b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.form index 7728350704..57ea5ec153 100644 --- a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.form +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.form @@ -3,7 +3,7 @@
- + @@ -24,13 +24,11 @@ - - - - - - - + + + + + @@ -42,14 +40,7 @@ - - - - - - - - + @@ -63,78 +54,140 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.java index e98f0b7984..3fd85e4c17 100644 --- a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.java @@ -271,16 +271,37 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { private void initComponents() { reportModulesLabel = new javax.swing.JLabel(); + javax.swing.JSplitPane modulesSplitPane = new javax.swing.JSplitPane(); + javax.swing.JPanel detailsPanel = new javax.swing.JPanel(); configurationPanel = new javax.swing.JPanel(); descriptionScrollPane = new javax.swing.JScrollPane(); descriptionTextPane = new javax.swing.JTextPane(); modulesScrollPane = new javax.swing.JScrollPane(); modulesJList = new javax.swing.JList<>(); - setPreferredSize(new java.awt.Dimension(650, 250)); + setPreferredSize(new java.awt.Dimension(834, 374)); org.openide.awt.Mnemonics.setLocalizedText(reportModulesLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.reportModulesLabel.text")); // NOI18N + //Make border on split pane invisible to maintain previous style + modulesSplitPane.setUI(new javax.swing.plaf.basic.BasicSplitPaneUI() { + @Override + public javax.swing.plaf.basic.BasicSplitPaneDivider createDefaultDivider() + { + return new javax.swing.plaf.basic.BasicSplitPaneDivider(this) { + @Override + public void paint(java.awt.Graphics g) + { + super.paint(g); + setBorder(null); + } + }; + } + }); + modulesSplitPane.setBorder(null); + modulesSplitPane.setDividerSize(8); + modulesSplitPane.setResizeWeight(0.5); + configurationPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(125, 125, 125))); configurationPanel.setOpaque(false); @@ -288,11 +309,11 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { configurationPanel.setLayout(configurationPanelLayout); configurationPanelLayout.setHorizontalGroup( configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 432, Short.MAX_VALUE) + .addGap(0, 545, Short.MAX_VALUE) ); configurationPanelLayout.setVerticalGroup( configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 168, Short.MAX_VALUE) + .addGap(0, 340, Short.MAX_VALUE) ); descriptionScrollPane.setBorder(null); @@ -302,6 +323,29 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { descriptionTextPane.setOpaque(false); descriptionScrollPane.setViewportView(descriptionTextPane); + javax.swing.GroupLayout detailsPanelLayout = new javax.swing.GroupLayout(detailsPanel); + detailsPanel.setLayout(detailsPanelLayout); + detailsPanelLayout.setHorizontalGroup( + detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(detailsPanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(descriptionScrollPane)) + .addGap(0, 0, 0)) + ); + detailsPanelLayout.setVerticalGroup( + detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(detailsPanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + + modulesSplitPane.setRightComponent(detailsPanel); + modulesJList.setBackground(new java.awt.Color(240, 240, 240)); modulesJList.setModel(new javax.swing.AbstractListModel() { ReportModule[] modules = {}; @@ -311,6 +355,8 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { modulesJList.setOpaque(false); modulesScrollPane.setViewportView(modulesJList); + modulesSplitPane.setLeftComponent(modulesScrollPane); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -318,12 +364,10 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(reportModulesLabel) - .addComponent(modulesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 190, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(descriptionScrollPane)) + .addGroup(layout.createSequentialGroup() + .addComponent(reportModulesLabel) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(modulesSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 814, Short.MAX_VALUE)) .addContainerGap()) ); layout.setVerticalGroup( @@ -332,12 +376,7 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { .addContainerGap() .addComponent(reportModulesLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 208, Short.MAX_VALUE)) + .addComponent(modulesSplitPane) .addContainerGap()) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel2.form b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel2.form index b54495fb20..bad6a7a7fa 100644 --- a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel2.form +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel2.form @@ -7,7 +7,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel2.java b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel2.java index a596eb6c38..5243f2fe63 100644 --- a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel2.java +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel2.java @@ -311,7 +311,7 @@ final class ReportVisualPanel2 extends JPanel { advancedButton = new javax.swing.JButton(); allTaggedResultsRadioButton = new javax.swing.JRadioButton(); - setPreferredSize(new java.awt.Dimension(650, 275)); + setPreferredSize(new java.awt.Dimension(834, 374)); optionsButtonGroup.add(specificTaggedResultsRadioButton); org.openide.awt.Mnemonics.setLocalizedText(specificTaggedResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.specificTaggedResultsRadioButton.text")); // NOI18N From 022642b7c9e3e14e289859b48772726aa8bf72d5 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 17 Jun 2021 09:57:28 -0400 Subject: [PATCH 04/16] 7630 fix split pane border --- .../infrastructure/ReportVisualPanel1.form | 12 +++++----- .../infrastructure/ReportVisualPanel1.java | 23 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.form b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.form index 57ea5ec153..4337e14246 100644 --- a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.form +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.form @@ -28,7 +28,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -84,11 +84,11 @@ - + - + @@ -122,12 +122,12 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.java b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.java index 3fd85e4c17..5c1dcc38ac 100644 --- a/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.java +++ b/Core/src/org/sleuthkit/autopsy/report/infrastructure/ReportVisualPanel1.java @@ -36,6 +36,7 @@ import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; +import javax.swing.border.Border; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.openide.DialogDisplayer; @@ -286,16 +287,14 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { //Make border on split pane invisible to maintain previous style modulesSplitPane.setUI(new javax.swing.plaf.basic.BasicSplitPaneUI() { @Override - public javax.swing.plaf.basic.BasicSplitPaneDivider createDefaultDivider() - { - return new javax.swing.plaf.basic.BasicSplitPaneDivider(this) { + public javax.swing.plaf.basic.BasicSplitPaneDivider createDefaultDivider() { + javax.swing.plaf.basic.BasicSplitPaneDivider divider = new javax.swing.plaf.basic.BasicSplitPaneDivider(this) { @Override - public void paint(java.awt.Graphics g) - { - super.paint(g); - setBorder(null); + public void setBorder(Border border){ + //do nothing so border is not visible } }; + return divider; } }); modulesSplitPane.setBorder(null); @@ -309,11 +308,11 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { configurationPanel.setLayout(configurationPanelLayout); configurationPanelLayout.setHorizontalGroup( configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 545, Short.MAX_VALUE) + .addGap(0, 546, Short.MAX_VALUE) ); configurationPanelLayout.setVerticalGroup( configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 340, Short.MAX_VALUE) + .addGap(0, 290, Short.MAX_VALUE) ); descriptionScrollPane.setBorder(null); @@ -330,8 +329,8 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { .addGroup(detailsPanelLayout.createSequentialGroup() .addGap(0, 0, 0) .addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(descriptionScrollPane)) + .addComponent(descriptionScrollPane) + .addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(0, 0, 0)) ); detailsPanelLayout.setVerticalGroup( @@ -367,7 +366,7 @@ final class ReportVisualPanel1 extends JPanel implements ListSelectionListener { .addGroup(layout.createSequentialGroup() .addComponent(reportModulesLabel) .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(modulesSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 814, Short.MAX_VALUE)) + .addComponent(modulesSplitPane)) .addContainerGap()) ); layout.setVerticalGroup( From 86a35cdd3fb8160eac44a515b33f12e9fcefeb05 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 17 Jun 2021 10:01:30 -0400 Subject: [PATCH 05/16] Copy DataArtifacts and AnalysisResults into the portable case --- .../PortableCaseReportModule.java | 67 ++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java b/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java index f8dbebe224..4494d1dd5b 100644 --- a/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java +++ b/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java @@ -62,6 +62,7 @@ import org.sleuthkit.autopsy.report.ReportProgressPanel; import org.sleuthkit.caseuco.CaseUcoExporter; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.Blackboard.BlackboardException; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifactTag; @@ -69,12 +70,14 @@ import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.CaseDbAccessManager; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentTag; +import org.sleuthkit.datamodel.DataArtifact; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.FileSystem; import org.sleuthkit.datamodel.Host; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.LocalFilesDataSource; import org.sleuthkit.datamodel.Pool; +import org.sleuthkit.datamodel.Score; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction; import org.sleuthkit.datamodel.TagName; @@ -392,8 +395,8 @@ public class PortableCaseReportModule implements ReportModule { // Copy interesting files and results if (!setNames.isEmpty()) { try { - List interestingFiles = currentCase.getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT); - for (BlackboardArtifact art : interestingFiles) { + List interestingFiles = currentCase.getSleuthkitCase().getBlackboard().getAnalysisResultsByType(BlackboardArtifact.Type.TSK_INTERESTING_FILE_HIT.getTypeID()); + for (AnalysisResult art : interestingFiles) { // Check for cancellation if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) { handleCancellation(progressPanel); @@ -411,8 +414,8 @@ public class PortableCaseReportModule implements ReportModule { } try { - List interestingResults = currentCase.getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT); - for (BlackboardArtifact art : interestingResults) { + List interestingResults = currentCase.getSleuthkitCase().getBlackboard().getAnalysisResultsByType(BlackboardArtifact.Type.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()); + for (AnalysisResult art : interestingResults) { // Check for cancellation if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) { handleCancellation(progressPanel); @@ -936,9 +939,6 @@ public class PortableCaseReportModule implements ReportModule { String.join(",", oldAssociatedAttribute.getSources()), newAssociatedArtifact.getArtifactID())); } - // Create the new artifact - int newArtifactTypeId = getNewArtifactTypeId(artifactToCopy); - BlackboardArtifact newArtifact = portableSkCase.newBlackboardArtifact(newArtifactTypeId, newContentId); List oldAttrs = artifactToCopy.getAttributes(); // Copy over each attribute, making sure the type is in the new case. @@ -977,8 +977,57 @@ public class PortableCaseReportModule implements ReportModule { throw new TskCoreException("Unexpected attribute value type found: " + oldAttr.getValueType().getLabel()); // NON-NLS } } - - newArtifact.addAttributes(newAttrs); + // Create the new artifact + int newArtifactTypeId = getNewArtifactTypeId(artifactToCopy); + BlackboardArtifact.Type newArtifactType = portableSkCase.getArtifactType(newArtifactTypeId); + BlackboardArtifact newArtifact; + + // First, check if the artifact being copied is an AnalysisResult or a DataArtifact. If it + // is neither, attempt to reload it as the appropriate subclass. + if (!((artifactToCopy instanceof AnalysisResult) || (artifactToCopy instanceof DataArtifact))) { + try { + if (newArtifactType.getCategory().equals(BlackboardArtifact.Category.ANALYSIS_RESULT)) { + AnalysisResult ar = currentCase.getSleuthkitCase().getBlackboard().getAnalysisResultById(artifactToCopy.getId()); + if (ar != null) { + artifactToCopy = ar; + } + } else { + DataArtifact da = currentCase.getSleuthkitCase().getBlackboard().getDataArtifactById(artifactToCopy.getId()); + if (da != null) { + artifactToCopy = da; + } + } + } catch (TskCoreException ex) { + // If the lookup failed, just use the orginal BlackboardArtifact + } + } + + try { + if (artifactToCopy instanceof AnalysisResult) { + AnalysisResult analysisResultToCopy = (AnalysisResult) artifactToCopy; + newArtifact = portableSkCase.getBlackboard().newAnalysisResult(newArtifactType, newContentId, + newIdToContent.get(newContentId).getDataSource().getId(), analysisResultToCopy.getScore(), + analysisResultToCopy.getConclusion(), analysisResultToCopy.getConfiguration(), + analysisResultToCopy.getJustification(), newAttrs).getAnalysisResult(); + } else if (artifactToCopy instanceof DataArtifact) { + DataArtifact dataArtifactToCopy = (DataArtifact) artifactToCopy; + newArtifact = portableSkCase.getBlackboard().newDataArtifact(newArtifactType, newContentId, + newIdToContent.get(newContentId).getDataSource().getId(), + newAttrs, dataArtifactToCopy.getOsAccountObjectId().orElse(null)); + } else { + if (newArtifactType.getCategory().equals(BlackboardArtifact.Category.ANALYSIS_RESULT)) { + newArtifact = portableSkCase.getBlackboard().newAnalysisResult(newArtifactType, newContentId, + newIdToContent.get(newContentId).getDataSource().getId(), Score.SCORE_NONE, + null, null, null, newAttrs).getAnalysisResult(); + } else { + newArtifact = portableSkCase.getBlackboard().newDataArtifact(newArtifactType, newContentId, + newIdToContent.get(newContentId).getDataSource().getId(), + newAttrs, null); + } + } + } catch (BlackboardException ex) { + throw new TskCoreException("Error copying artifact with ID: " + artifactToCopy.getId()); + } oldArtifactIdToNewArtifact.put(artifactToCopy.getArtifactID(), newArtifact); return newArtifact; From 5a853bf6e717cfd9d7cff7e8215b2fe9f1c32126 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Thu, 17 Jun 2021 14:40:01 -0400 Subject: [PATCH 06/16] 7655 don't set stale data for disabled viewer --- .../textcontentviewer/TextContentViewerPanel.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextContentViewerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextContentViewerPanel.java index 7c80d606fd..62062cbc95 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextContentViewerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextContentViewerPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -79,9 +79,9 @@ public class TextContentViewerPanel extends javax.swing.JPanel implements DataCo } /** - * Determine whether the content viewer which displays this panel isSupported. - * This panel is supported if any of the TextViewer's displayed in it are - * supported. + * Determine whether the content viewer which displays this panel + * isSupported. This panel is supported if any of the TextViewer's displayed + * in it are supported. * * @param node * @@ -213,7 +213,7 @@ public class TextContentViewerPanel extends javax.swing.JPanel implements DataCo // Get and set current selected tab int currentTab = pane.getSelectedIndex(); - if (currentTab != -1) { + if (currentTab != -1 && pane.isEnabledAt(currentTab)) { UpdateWrapper dcv = textViewers.get(currentTab); if (dcv.isOutdated()) { // change the cursor to "waiting cursor" for this operation From 4b76e26f2b84adff51de28521ad567bebab00cb7 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 17 Jun 2021 15:37:32 -0400 Subject: [PATCH 07/16] Made performance changes to improve the opening delay --- .../contentviewer/OtherOccurrencesPanel.form | 2 -- .../contentviewer/OtherOccurrencesPanel.java | 32 +++++++++++++------ .../contentviewers/MediaViewImagePanel.java | 27 +++++++++++----- .../org/sleuthkit/autopsy/core/Installer.java | 9 ++++++ .../autopsy/coreutils/ImageUtils.java | 2 +- 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.form index 237bfe4ce8..13284ecec9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.form @@ -34,8 +34,6 @@ - - diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.java index c4d0bf0e0a..db5f5c1990 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.java @@ -35,6 +35,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; import java.util.logging.Level; import javax.swing.JFileChooser; import javax.swing.JMenuItem; @@ -71,7 +74,6 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { private static final CorrelationCaseWrapper NO_ARTIFACTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noArtifacts()); private static final CorrelationCaseWrapper NO_RESULTS_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_noResultsFound()); - private static final CorrelationCaseWrapper LOADING_CASE = new CorrelationCaseWrapper(Bundle.OtherOccurrencesPanel_table_loadingResults()); private static final Logger logger = Logger.getLogger(OtherOccurrencesPanel.class.getName()); private static final long serialVersionUID = 1L; private final OtherOccurrencesFilesTableModel filesTableModel; @@ -84,6 +86,9 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { private AbstractFile file = null; private SwingWorker worker; + + private final FutureTask futureFileChooser = new FutureTask<>(JFileChooser::new); + private JFileChooser CSVFileChooser; /** * Creates new form OtherOccurrencesPanel @@ -93,9 +98,11 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { this.casesTableModel = new OtherOccurrencesCasesTableModel(); this.dataSourcesTableModel = new OtherOccurrencesDataSourcesTableModel(); this.correlationAttributes = new ArrayList<>(); - occurrencePanel = new OccurrencePanel(); initComponents(); customizeComponents(); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(futureFileChooser); } private void customizeComponents() { @@ -245,6 +252,15 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { private void saveToCSV() throws NoCurrentCaseException { if (casesTableModel.getRowCount() > 0) { + + if(CSVFileChooser == null) { + try { + CSVFileChooser = futureFileChooser.get(); + } catch (InterruptedException | ExecutionException ex) { + Exceptions.printStackTrace(ex); + } + } + Calendar now = Calendar.getInstance(); String fileName = String.format("%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_data_sources.csv", now); CSVFileChooser.setCurrentDirectory(new File(Case.getCurrentCaseThrows().getExportDirectory())); @@ -258,8 +274,8 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { if (!selectedFile.getName().endsWith(".csv")) { // NON-NLS selectedFile = new File(selectedFile.toString() + ".csv"); // NON-NLS } - CSVWorker worker = new CSVWorker(selectedFile, file, dataSourceName, deviceId, Collections.unmodifiableCollection(correlationAttributes)); - worker.execute(); + CSVWorker csvWorker = new CSVWorker(selectedFile, file, dataSourceName, deviceId, Collections.unmodifiableCollection(correlationAttributes)); + csvWorker.execute(); } } } @@ -685,7 +701,6 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { exportToCSVMenuItem = new javax.swing.JMenuItem(); showCaseDetailsMenuItem = new javax.swing.JMenuItem(); showCommonalityMenuItem = new javax.swing.JMenuItem(); - CSVFileChooser = new javax.swing.JFileChooser(); tableContainerPanel = new javax.swing.JPanel(); tablesViewerSplitPane = new javax.swing.JSplitPane(); caseDatasourceFileSplitPane = new javax.swing.JSplitPane(); @@ -704,12 +719,12 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); rightClickPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() { - public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) { - rightClickPopupMenuPopupMenuWillBecomeVisible(evt); + public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) { } public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) { } - public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) { + public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) { + rightClickPopupMenuPopupMenuWillBecomeVisible(evt); } }); @@ -857,7 +872,6 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JFileChooser CSVFileChooser; private javax.swing.JSplitPane caseDatasourceFileSplitPane; private javax.swing.JSplitPane caseDatasourceSplitPane; private javax.swing.JScrollPane caseScrollPane; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaViewImagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaViewImagePanel.java index 06b0a42fb7..591bed7ff3 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaViewImagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaViewImagePanel.java @@ -34,6 +34,9 @@ import java.util.Collections; import java.util.List; import static java.util.Objects.nonNull; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; import java.util.logging.Level; import java.util.stream.Collectors; import javafx.application.Platform; @@ -69,6 +72,7 @@ import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.apache.commons.io.FilenameUtils; import org.controlsfx.control.MaskerPane; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.actions.GetTagNameAndCommentDialog; import org.sleuthkit.autopsy.actions.GetTagNameAndCommentDialog.TagNameAndComment; @@ -150,7 +154,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final JMenuItem exportTagsMenuItem; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - private final JFileChooser exportChooser; + private JFileChooser exportChooser; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private final JFXPanel fxPanel; @@ -189,10 +193,8 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan @ThreadConfined(type = ThreadConfined.ThreadType.JFX) private Task readImageFileTask; private volatile ImageTransforms imageTransforms; - - static { - ImageIO.scanForPlugins(); - } + + private final FutureTask futureFileChooser = new FutureTask<>(JFileChooser::new); /** * Constructs a media image file viewer implemented as a Swing panel that @@ -210,9 +212,9 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan initComponents(); imageTransforms = new ImageTransforms(0, 0, true); - - exportChooser = new JFileChooser(); - exportChooser.setDialogTitle(Bundle.MediaViewImagePanel_fileChooserTitle()); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(futureFileChooser); //Build popupMenu when Tags Menu button is pressed. imageTaggingOptions = new JPopupMenu(); @@ -1043,6 +1045,15 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan final AbstractFile file = imageFile; tagsGroup.clearFocus(); SwingUtilities.invokeLater(() -> { + + if(exportChooser == null) { + try { + exportChooser = futureFileChooser.get(); + } catch (InterruptedException | ExecutionException ex) { + Exceptions.printStackTrace(ex); + } + } + exportChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); //Always base chooser location to export folder exportChooser.setCurrentDirectory(new File(Case.getCurrentCase().getExportDirectory())); diff --git a/Core/src/org/sleuthkit/autopsy/core/Installer.java b/Core/src/org/sleuthkit/autopsy/core/Installer.java index 5bd649e8cb..7411377733 100644 --- a/Core/src/org/sleuthkit/autopsy/core/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/core/Installer.java @@ -33,6 +33,7 @@ import java.util.logging.Handler; import java.util.logging.Level; import javafx.application.Platform; import javafx.embed.swing.JFXPanel; +import javax.imageio.ImageIO; import net.sf.sevenzipjbinding.SevenZip; import net.sf.sevenzipjbinding.SevenZipNativeInitializationException; import org.apache.commons.io.FileUtils; @@ -44,6 +45,7 @@ import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.actions.IngestRunningCheck; import org.sleuthkit.autopsy.casemodule.Case; import static org.sleuthkit.autopsy.core.UserPreferences.SETTINGS_PROPERTIES; +import org.sleuthkit.autopsy.corelibs.OpenCvLoader; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.ModuleSettings; @@ -66,6 +68,13 @@ public class Installer extends ModuleInstall { static { loadDynLibraries(); + + // This call was moved from MediaViewImagePanel so that it is + // not called during top level component construction. + ImageIO.scanForPlugins(); + + // This will cause OpenCvLoader to load its library instead of + OpenCvLoader.openCvIsLoaded(); } private static void loadDynLibraries() { diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java index 6ae521de1e..8d9c3a02b9 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java @@ -194,7 +194,7 @@ public class ImageUtils { public static SortedSet getSupportedImageMimeTypes() { return Collections.unmodifiableSortedSet(SUPPORTED_IMAGE_MIME_TYPES); } - + /** * Get the default thumbnail, which is the icon for a file. Used when we can * not generate a content based thumbnail. From 35ef6b6dfe59d71611cfbbabb13690f86756378e Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 17 Jun 2021 16:01:10 -0400 Subject: [PATCH 08/16] Copy os accounts into portable case --- .../PortableCaseReportModule.java | 104 +++++++++++++++++- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java b/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java index 4494d1dd5b..12412aae20 100644 --- a/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java +++ b/Core/src/org/sleuthkit/autopsy/report/modules/portablecase/PortableCaseReportModule.java @@ -76,6 +76,11 @@ import org.sleuthkit.datamodel.FileSystem; import org.sleuthkit.datamodel.Host; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.LocalFilesDataSource; +import org.sleuthkit.datamodel.OsAccount; +import org.sleuthkit.datamodel.OsAccountManager; +import org.sleuthkit.datamodel.OsAccountManager.NotUserSIDException; +import org.sleuthkit.datamodel.OsAccountRealm; +import org.sleuthkit.datamodel.OsAccountRealmManager; import org.sleuthkit.datamodel.Pool; import org.sleuthkit.datamodel.Score; import org.sleuthkit.datamodel.SleuthkitCase; @@ -135,6 +140,12 @@ public class PortableCaseReportModule implements ReportModule { // Map of old artifact ID to new artifact private final Map oldArtifactIdToNewArtifact = new HashMap<>(); + + // Map of old OS account id to new OS account id + private final Map oldOsAccountIdToNewOsAccountId = new HashMap<>(); + + // Map of old OS account realm id to new OS account ream id + private final Map oldRealmIdToNewRealm = new HashMap<>(); public PortableCaseReportModule() { } @@ -979,7 +990,7 @@ public class PortableCaseReportModule implements ReportModule { } // Create the new artifact int newArtifactTypeId = getNewArtifactTypeId(artifactToCopy); - BlackboardArtifact.Type newArtifactType = portableSkCase.getArtifactType(newArtifactTypeId); + BlackboardArtifact.Type newArtifactType = portableSkCase.getBlackboard().getArtifactType(newArtifactTypeId); BlackboardArtifact newArtifact; // First, check if the artifact being copied is an AnalysisResult or a DataArtifact. If it @@ -1011,9 +1022,14 @@ public class PortableCaseReportModule implements ReportModule { analysisResultToCopy.getJustification(), newAttrs).getAnalysisResult(); } else if (artifactToCopy instanceof DataArtifact) { DataArtifact dataArtifactToCopy = (DataArtifact) artifactToCopy; + Long newOsAccountId = null; + if (dataArtifactToCopy.getOsAccountObjectId().isPresent()) { + copyOsAccount(dataArtifactToCopy.getOsAccountObjectId().get()); + newOsAccountId = oldOsAccountIdToNewOsAccountId.get((dataArtifactToCopy.getOsAccountObjectId().get())); + } newArtifact = portableSkCase.getBlackboard().newDataArtifact(newArtifactType, newContentId, newIdToContent.get(newContentId).getDataSource().getId(), - newAttrs, dataArtifactToCopy.getOsAccountObjectId().orElse(null)); + newAttrs, newOsAccountId); } else { if (newArtifactType.getCategory().equals(BlackboardArtifact.Category.ANALYSIS_RESULT)) { newArtifact = portableSkCase.getBlackboard().newAnalysisResult(newArtifactType, newContentId, @@ -1137,6 +1153,14 @@ public class PortableCaseReportModule implements ReportModule { newHost = portableSkCase.getHostManager().newHost(oldHost.getName()); } + // Copy the associated OS account (if needed) before beginning transaction. + if (content instanceof AbstractFile) { + AbstractFile file = (AbstractFile) content; + if (file.getOsAccountObjectId().isPresent()) { + copyOsAccount(file.getOsAccountObjectId().get()); + } + } + CaseDbTransaction trans = portableSkCase.beginTransaction(); try { if (content instanceof Image) { @@ -1189,10 +1213,16 @@ public class PortableCaseReportModule implements ReportModule { // Construct the relative path to the copied file String relativePath = FILE_FOLDER_NAME + File.separator + exportSubFolder + File.separator + fileName; + Long newOsAccountId = null; + if (abstractFile.getOsAccountObjectId().isPresent()) { + newOsAccountId = oldOsAccountIdToNewOsAccountId.get(abstractFile.getOsAccountObjectId().get()); + } + newContent = portableSkCase.addLocalFile(abstractFile.getName(), relativePath, abstractFile.getSize(), abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getMtime(), abstractFile.getMd5Hash(), abstractFile.getSha256Hash(), abstractFile.getKnown(), abstractFile.getMIMEType(), - true, TskData.EncodingType.NONE, + true, TskData.EncodingType.NONE, + newOsAccountId, abstractFile.getOwnerUid().orElse(null), newParent, trans); } catch (IOException ex) { throw new TskCoreException("Error copying file " + abstractFile.getName() + " with original obj ID " @@ -1215,6 +1245,72 @@ public class PortableCaseReportModule implements ReportModule { newIdToContent.put(newContent.getId(), newContent); return oldIdToNewContent.get(content.getId()).getId(); } + + /** + * Copy an OS Account to the new case and add it to the oldOsAccountIdToNewOsAccountId map. + * Will also copy the associated realm. + * + * @param oldOsAccountId The OS account id in the current case. + */ + private void copyOsAccount(Long oldOsAccountId) throws TskCoreException { + // If it has already been copied, we're done. + if (oldOsAccountIdToNewOsAccountId.containsKey(oldOsAccountId)) { + return; + } + + // Load the OS account from the current case. + OsAccountManager oldOsAcctManager = currentCase.getSleuthkitCase().getOsAccountManager(); + OsAccount oldOsAccount = oldOsAcctManager.getOsAccountByObjectId(oldOsAccountId); + + // Load the realm associated with the OS account. + OsAccountRealmManager oldRealmManager = currentCase.getSleuthkitCase().getOsAccountRealmManager(); + OsAccountRealm oldRealm = oldRealmManager.getRealmByRealmId(oldOsAccount.getRealmId()); + + // Copy the realm to the portable case if necessary. + if (!oldRealmIdToNewRealm.containsKey(oldOsAccount.getRealmId())) { + OsAccountRealmManager newRealmManager = portableSkCase.getOsAccountRealmManager(); + + Host host = null; + if (oldRealm.getScopeHost().isPresent()) { + host = oldRealm.getScopeHost().get(); + } else { + if (oldRealm.getScope().equals(OsAccountRealm.RealmScope.DOMAIN)) { + // This is a workaround to get around needing a new method for copying the realm. + // The host won't be stored since it's a domain-scoped realm. + List hosts = portableSkCase.getHostManager().getAllHosts(); + if (hosts.isEmpty()) { + throw new TskCoreException("Failed to copy OsAccountRealm with ID=" + oldOsAccount.getRealmId() + " because there are no hosts in the case"); + } + host = hosts.get(0); + } else { + throw new TskCoreException("Failed to copy OsAccountRealm with ID=" + oldOsAccount.getRealmId() + " because it is non-domain scoped but has no scope host"); + } + } + + // We currently only support one realm name. + String realmName = null; + List names = oldRealm.getRealmNames(); + if (!names.isEmpty()) { + realmName = names.get(0); + } + + try { + OsAccountRealm newRealm = newRealmManager.newWindowsRealm(oldRealm.getRealmAddr().orElse(null), realmName, host, oldRealm.getScope()); + oldRealmIdToNewRealm.put(oldOsAccount.getRealmId(), newRealm); + } catch (NotUserSIDException ex) { + throw new TskCoreException("Failed to copy OsAccountRealm with ID=" + oldOsAccount.getRealmId(), ex); + } + } + + OsAccountManager newOsAcctManager = portableSkCase.getOsAccountManager(); + try { + OsAccount newOsAccount = newOsAcctManager.newWindowsOsAccount(oldOsAccount.getAddr().orElse(null), + oldOsAccount.getLoginName().orElse(null), oldRealmIdToNewRealm.get(oldOsAccount.getRealmId())); + oldOsAccountIdToNewOsAccountId.put(oldOsAccountId, newOsAccount.getId()); + } catch (NotUserSIDException ex) { + throw new TskCoreException("Failed to copy OsAccount with ID=" + oldOsAccount.getId(), ex); + } + } /** * Copy path ID attribute to new case along with the referenced file. @@ -1393,6 +1489,8 @@ public class PortableCaseReportModule implements ReportModule { oldArtTypeIdToNewArtTypeId.clear(); oldAttrTypeIdToNewAttrType.clear(); oldArtifactIdToNewArtifact.clear(); + oldOsAccountIdToNewOsAccountId.clear(); + oldRealmIdToNewRealm.clear(); closePortableCaseDatabase(); From 54e56b9bc2f9901aafb0b2b15df1ccd91820ec34 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 17 Jun 2021 16:04:35 -0400 Subject: [PATCH 09/16] Tweaked exception handling --- .../contentviewer/OtherOccurrencesPanel.java | 12 ++++++++---- .../autopsy/contentviewers/MediaViewImagePanel.java | 8 ++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.java index db5f5c1990..81fac1ebd6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/OtherOccurrencesPanel.java @@ -49,7 +49,6 @@ import javax.swing.SwingWorker; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.TableModel; import javax.swing.table.TableRowSorter; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -87,6 +86,8 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { private SwingWorker worker; + // Initializing the JFileChooser in a thread to prevent a block on the EDT + // see https://stackoverflow.com/questions/49792375/jfilechooser-is-very-slow-when-using-windows-look-and-feel private final FutureTask futureFileChooser = new FutureTask<>(JFileChooser::new); private JFileChooser CSVFileChooser; @@ -254,11 +255,14 @@ public final class OtherOccurrencesPanel extends javax.swing.JPanel { if (casesTableModel.getRowCount() > 0) { if(CSVFileChooser == null) { - try { + try{ CSVFileChooser = futureFileChooser.get(); } catch (InterruptedException | ExecutionException ex) { - Exceptions.printStackTrace(ex); - } + // If something happened with the thread try and + // initalized the chooser now + logger.log(Level.WARNING, "A failure occurred in the JFileChooser background thread"); + CSVFileChooser = new JFileChooser(); + } } Calendar now = Calendar.getInstance(); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaViewImagePanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaViewImagePanel.java index 591bed7ff3..177c397c78 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaViewImagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaViewImagePanel.java @@ -72,7 +72,6 @@ import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.apache.commons.io.FilenameUtils; import org.controlsfx.control.MaskerPane; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.actions.GetTagNameAndCommentDialog; import org.sleuthkit.autopsy.actions.GetTagNameAndCommentDialog.TagNameAndComment; @@ -194,6 +193,8 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan private Task readImageFileTask; private volatile ImageTransforms imageTransforms; + // Initializing the JFileChooser in a thread to prevent a block on the EDT + // see https://stackoverflow.com/questions/49792375/jfilechooser-is-very-slow-when-using-windows-look-and-feel private final FutureTask futureFileChooser = new FutureTask<>(JFileChooser::new); /** @@ -1050,7 +1051,10 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan try { exportChooser = futureFileChooser.get(); } catch (InterruptedException | ExecutionException ex) { - Exceptions.printStackTrace(ex); + // If something happened with the thread try and + // initalized the chooser now + logger.log(Level.WARNING, "A failure occurred in the JFileChooser background thread"); + exportChooser = new JFileChooser(); } } From d461f5a3cf16199c185e22df69a10b4ca537fb45 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 17 Jun 2021 16:16:17 -0400 Subject: [PATCH 10/16] Added wait cursor --- Core/src/org/sleuthkit/autopsy/casemodule/Case.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 19d70deb62..40e7dab750 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -22,6 +22,7 @@ import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils; import com.google.common.annotations.Beta; import com.google.common.eventbus.Subscribe; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.awt.Cursor; import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData; import java.awt.Frame; import java.awt.event.ActionEvent; @@ -1324,12 +1325,14 @@ public class Case { * opened via the DirectoryTreeTopComponent 'propertyChange()' * method on a DATA_SOURCE_ADDED event. */ + mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if (hasData) { CoreComponentControl.openCoreWindows(); } else { //ensure that the DirectoryTreeTopComponent is open so that it's listener can open the core windows including making it visible. DirectoryTreeTopComponent.findInstance(); } + mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); /* * Reset the main window title to: From ca86d364eafb28ab8549bc3975d8fa410a7cc2e6 Mon Sep 17 00:00:00 2001 From: apriestman Date: Fri, 18 Jun 2021 08:29:28 -0400 Subject: [PATCH 11/16] Fix typo --- Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java index bd3671e44b..112ea3523c 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java @@ -150,7 +150,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer { ContentViewerHtmlStyles.getTextClassName(), EscapeUtil.escapeHtml(key), ContentViewerHtmlStyles.getTextClassName(), - EscapeUtil.escapeHtml(key) + EscapeUtil.escapeHtml(value) )); } From ca16df609cd23d27d03907c7019be85a143ef041 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 18 Jun 2021 13:11:33 -0400 Subject: [PATCH 12/16] 7748 handle cancellation of IngestJobInfoPanel cancellation --- .../org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java index 5161a544ca..89b696c041 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.java @@ -26,6 +26,7 @@ import java.util.Date; import java.util.EnumSet; import java.util.List; import java.util.Set; +import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JOptionPane; @@ -167,6 +168,8 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel { } } catch (InterruptedException | ExecutionException ex) { logger.log(Level.WARNING, "Error getting results from Ingest Job Info Panel's refresh worker", ex); + } catch (CancellationException ignored){ + logger.log(Level.INFO, "The refreshing of the IngestJobInfoPanel was cancelled"); } } }; From bff3e9bb4f698107766eb95ee6cafd1efd351597 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 18 Jun 2021 13:31:51 -0400 Subject: [PATCH 13/16] 7669 simplify isSupported methods of othercases and annotation content viewers --- .../DataContentViewerOtherCases.java | 9 ++++----- .../AnnotationsContentViewer.java | 20 +------------------ 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index c44b4e2479..cbb34d9448 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -90,13 +90,12 @@ public final class DataContentViewerOtherCases extends JPanel implements DataCon public boolean isSupported(Node node) { // Is supported if one of the following is true: - // - The central repo is enabled and the node has correlatable content - // (either through the MD5 hash of the associated file or through a BlackboardArtifact) + // - The central repo is enabled and the node is not null // - The central repo is disabled and the backing file has a valid MD5 hash - AbstractFile file = OtherOccurrences.getAbstractFileFromNode(node); - if (CentralRepository.isEnabled()) { - return !OtherOccurrences.getCorrelationAttributesFromNode(node, file).isEmpty(); + if (CentralRepository.isEnabled() && node != null) { + return true; } else { + AbstractFile file = OtherOccurrences.getAbstractFileFromNode(node); return file != null && file.getSize() > 0 && ((file.getMd5Hash() != null) && (!file.getMd5Hash().isEmpty())); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java index aad1fe79a8..53acf3a024 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java @@ -130,25 +130,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data @Override public boolean isSupported(Node node) { - BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); - - try { - if (artifact != null) { - if (artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID()) != null) { - return true; - } - } else { - if (node.getLookup().lookup(AbstractFile.class) != null) { - return true; - } - } - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, String.format( - "Exception while trying to retrieve a Content instance from the BlackboardArtifact '%s' (id=%d).", - artifact.getDisplayName(), artifact.getArtifactID()), ex); - } - - return false; + return node.getLookup().lookup(AbstractFile.class) != null; } @Override From 0efd53c3a9556d4ddf200ee8aeeca0cd2b779f02 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 18 Jun 2021 13:34:35 -0400 Subject: [PATCH 14/16] 7669 handle null case better --- .../contentviewer/DataContentViewerOtherCases.java | 3 ++- .../autopsy/contentviewers/AnnotationsContentViewer.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index cbb34d9448..501203babc 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -94,12 +94,13 @@ public final class DataContentViewerOtherCases extends JPanel implements DataCon // - The central repo is disabled and the backing file has a valid MD5 hash if (CentralRepository.isEnabled() && node != null) { return true; - } else { + } else if (node != null){ AbstractFile file = OtherOccurrences.getAbstractFileFromNode(node); return file != null && file.getSize() > 0 && ((file.getMd5Hash() != null) && (!file.getMd5Hash().isEmpty())); } + return false; } @Override diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java index 53acf3a024..b61abfceee 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/AnnotationsContentViewer.java @@ -130,7 +130,7 @@ public class AnnotationsContentViewer extends javax.swing.JPanel implements Data @Override public boolean isSupported(Node node) { - return node.getLookup().lookup(AbstractFile.class) != null; + return node != null && node.getLookup().lookup(AbstractFile.class) != null; } @Override From 1afacd0e7b14e577ebc92a8cb1e9d40667d1070b Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 18 Jun 2021 14:44:09 -0400 Subject: [PATCH 15/16] move getType to constructor --- .../datamodel/BlackboardArtifactNode.java | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index f048a84663..f0168936c1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -119,6 +119,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Fri, 18 Jun 2021 16:06:08 -0400 Subject: [PATCH 16/16] move to separate method --- .../datamodel/BlackboardArtifactNode.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index f0168936c1..e3bad44705 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -228,14 +228,7 @@ public class BlackboardArtifactNode extends AbstractContentNode