merge from 6631

This commit is contained in:
Greg DiCristofaro
2020-07-30 12:18:39 -04:00
36 changed files with 1350 additions and 255 deletions
@@ -22,7 +22,6 @@ import java.util.Map;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JLabel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.DataSource;
@@ -75,6 +74,7 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
rightAlignedRenderer.setHorizontalAlignment(JLabel.RIGHT);
initComponents();
fileCountsByCategoryTable.getTableHeader().setReorderingAllowed(false);
artifactCountsTable.getTableHeader().setReorderingAllowed(false);
setDataSource(null);
}
@@ -110,11 +110,11 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
* @param artifactDataModel The artifact type data model.
*/
private void updateCountsTableData(Object[][] fileCategoryDataModel, Object[][] artifactDataModel) {
fileCountsByCategoryTable.setModel(new DefaultTableModel(fileCategoryDataModel, FILE_BY_CATEGORY_COLUMN_HEADERS));
fileCountsByCategoryTable.setModel(new NonEditableTableModel(fileCategoryDataModel, FILE_BY_CATEGORY_COLUMN_HEADERS));
fileCountsByCategoryTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
fileCountsByCategoryTable.getColumnModel().getColumn(0).setPreferredWidth(130);
artifactCountsTable.setModel(new DefaultTableModel(artifactDataModel, ARTIFACT_COUNTS_COLUMN_HEADERS));
artifactCountsTable.setModel(new NonEditableTableModel(artifactDataModel, ARTIFACT_COUNTS_COLUMN_HEADERS));
artifactCountsTable.getColumnModel().getColumn(0).setPreferredWidth(230);
artifactCountsTable.getColumnModel().getColumn(1).setCellRenderer(rightAlignedRenderer);
@@ -230,7 +230,6 @@ class DataSourceSummaryCountsPanel extends javax.swing.JPanel {
org.openide.awt.Mnemonics.setLocalizedText(resultsByTypeLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryCountsPanel.class, "DataSourceSummaryCountsPanel.resultsByTypeLabel.text")); // NOI18N
artifactCountsTable.setAutoCreateRowSorter(true);
artifactCountsScrollPane.setViewportView(artifactCountsTable);
fileTypePiePanel.setPreferredSize(new java.awt.Dimension(400, 300));
@@ -0,0 +1,36 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
import javax.swing.table.DefaultTableModel;
/**
* A Table model where cells are not editable.
*/
class NonEditableTableModel extends DefaultTableModel {
NonEditableTableModel(Object[][] data, Object[] columnNames) {
super(data, columnNames);
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
}
@@ -305,7 +305,7 @@ public final class CentralRepoAccount {
normalizedAccountIdentifier = accountIdentifier.toLowerCase().trim();
}
} catch (CorrelationAttributeNormalizationException ex) {
throw new InvalidAccountIDException("Failed to normalize the account idenitier.", ex);
throw new InvalidAccountIDException("Failed to normalize the account idenitier " + accountIdentifier, ex);
}
return normalizedAccountIdentifier;
}
@@ -185,11 +185,11 @@ public class CorrelationAttributeUtil {
}
}
} catch (CorrelationAttributeNormalizationException ex) {
logger.log(Level.SEVERE, String.format("Error normalizing correlation attribute (%s)", artifact), ex); // NON-NLS
logger.log(Level.WARNING, String.format("Error normalizing correlation attribute (%s)", artifact), ex); // NON-NLS
return correlationAttrs;
}
catch (InvalidAccountIDException ex) {
logger.log(Level.SEVERE, String.format("Invalid account identifier (%s)", artifact), ex); // NON-NLS
logger.log(Level.WARNING, String.format("Invalid account identifier (artifactID: %d)", artifact.getId())); // NON-NLS
return correlationAttrs;
}
catch (CentralRepoException ex) {
@@ -65,8 +65,10 @@ abstract class CVTFilterRefresher implements RefreshThrottler.Refresher {
try (SleuthkitCase.CaseDbQuery dbQuery = skCase.executeQuery("SELECT MAX(date_time) as end, MIN(date_time) as start from account_relationships")) {
// ResultSet is closed by CasDBQuery
ResultSet rs = dbQuery.getResultSet();
rs.next();
startTime = rs.getInt("start"); // NON-NLS
endTime = rs.getInt("end"); // NON-NLS
}
// Get the devices with CVT artifacts
List<Integer> deviceObjIds = new ArrayList<>();
@@ -73,5 +73,5 @@ SummaryViewer.referencesLabel.text=Communication References:
SummaryViewer.referencesDataLabel.text=<reference count>
SummaryViewer.contactsLabel.text=Book Entries:
SummaryViewer.accountCountry.text=<account country>
SummaryViewer.fileRefPane.border.title=File Referernce(s) in Current Case
SummaryViewer.fileRefPane.border.title=File References in Current Case
SummaryViewer.selectAccountFileRefLabel.text=<Select a single account to see File References>
@@ -22,6 +22,8 @@ import com.google.common.eventbus.Subscribe;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.JSplitPane;
@@ -47,14 +49,12 @@ public final class DiscoveryTopComponent extends TopComponent {
private static final long serialVersionUID = 1L;
private static final String PREFERRED_ID = "Discovery"; // NON-NLS
private static final int ANIMATION_INCREMENT = 30;
private volatile static int resultsAreaSize = 250;
private final GroupListPanel groupListPanel;
private final DetailsPanel detailsPanel;
private final ResultsPanel resultsPanel;
private int dividerLocation = -1;
private static final int ANIMATION_INCREMENT = 30;
private static final int RESULTS_AREA_SMALL_SIZE = 250;
private SwingAnimator animator = null;
/**
@@ -78,6 +78,19 @@ public final class DiscoveryTopComponent extends TopComponent {
}
});
rightSplitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equalsIgnoreCase(JSplitPane.DIVIDER_LOCATION_PROPERTY)) {
//Only change the saved location when it was a manual change by the user and not the animation or the window opening initially
if ((animator == null || !animator.isRunning()) && evt.getNewValue() instanceof Integer
&& ((int) evt.getNewValue() + 5) < (rightSplitPane.getHeight() - rightSplitPane.getDividerSize())) {
resultsAreaSize = (int) evt.getNewValue();
}
}
}
});
}
/**
@@ -130,6 +143,7 @@ public final class DiscoveryTopComponent extends TopComponent {
@Override
protected void componentClosed() {
DiscoveryDialog.getDiscoveryDialogInstance().cancelSearch();
DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent());
DiscoveryEventUtils.getDiscoveryEventBus().unregister(this);
DiscoveryEventUtils.getDiscoveryEventBus().unregister(groupListPanel);
DiscoveryEventUtils.getDiscoveryEventBus().unregister(resultsPanel);
@@ -245,6 +259,7 @@ public final class DiscoveryTopComponent extends TopComponent {
void handleDetailsVisibleEvent(DiscoveryEventUtils.DetailsVisibleEvent detailsVisibleEvent) {
if (animator != null && animator.isRunning()) {
animator.stop();
animator = null;
}
dividerLocation = rightSplitPane.getDividerLocation();
if (detailsVisibleEvent.isShowDetailsArea()) {
@@ -316,8 +331,9 @@ public final class DiscoveryTopComponent extends TopComponent {
@Override
public boolean hasTerminated() {
if (dividerLocation != JSplitPane.UNDEFINED_CONDITION && dividerLocation < RESULTS_AREA_SMALL_SIZE) {
dividerLocation = RESULTS_AREA_SMALL_SIZE;
if (dividerLocation != JSplitPane.UNDEFINED_CONDITION && dividerLocation < resultsAreaSize) {
dividerLocation = resultsAreaSize;
animator = null;
return true;
}
return false;
@@ -340,6 +356,7 @@ public final class DiscoveryTopComponent extends TopComponent {
public boolean hasTerminated() {
if (dividerLocation > rightSplitPane.getHeight() || dividerLocation == JSplitPane.UNDEFINED_CONDITION) {
dividerLocation = rightSplitPane.getHeight();
animator = null;
return true;
}
return false;
@@ -362,8 +379,9 @@ public final class DiscoveryTopComponent extends TopComponent {
@Override
public void paintComponent(Graphics g) {
if ((dividerLocation == JSplitPane.UNDEFINED_CONDITION) || (dividerLocation <= rightSplitPane.getHeight() && dividerLocation >= RESULTS_AREA_SMALL_SIZE)) {
rightSplitPane.setDividerLocation(dividerLocation);
if (animator != null && animator.isRunning() && (dividerLocation == JSplitPane.UNDEFINED_CONDITION
|| (dividerLocation <= getHeight() && dividerLocation >= resultsAreaSize))) {
setDividerLocation(dividerLocation);
}
super.paintComponent(g);
}
@@ -3,7 +3,7 @@
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[700, 200]"/>
<Dimension value="[300, 60]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[700, 700]"/>
@@ -315,7 +315,7 @@
<Container class="javax.swing.JPanel" name="resultsViewerPanel">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 160]"/>
<Dimension value="[0, 60]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[700, 700]"/>
@@ -376,7 +376,7 @@ final class ResultsPanel extends javax.swing.JPanel {
javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
resultsViewerPanel = new javax.swing.JPanel();
setMinimumSize(new java.awt.Dimension(700, 200));
setMinimumSize(new java.awt.Dimension(300, 60));
setPreferredSize(new java.awt.Dimension(700, 700));
setLayout(new java.awt.BorderLayout());
@@ -533,7 +533,7 @@ final class ResultsPanel extends javax.swing.JPanel {
add(pagingPanel, java.awt.BorderLayout.PAGE_START);
resultsViewerPanel.setMinimumSize(new java.awt.Dimension(0, 160));
resultsViewerPanel.setMinimumSize(new java.awt.Dimension(0, 60));
resultsViewerPanel.setPreferredSize(new java.awt.Dimension(700, 700));
resultsViewerPanel.setLayout(new java.awt.BorderLayout());
add(resultsViewerPanel, java.awt.BorderLayout.CENTER);
@@ -501,9 +501,9 @@ class GeoFilterPanel extends javax.swing.JPanel {
DataSource dataSource, BlackboardArtifact.ARTIFACT_TYPE artifactType) throws TskCoreException {
long count = 0;
String queryStr
= "SELECT count(DISTINCT artifact_id) AS count FROM"
= "SELECT count(DISTINCT artIds) AS count FROM"
+ " ("
+ " SELECT * FROM blackboard_artifacts as arts"
+ " SELECT arts.artifact_id as artIds, * FROM blackboard_artifacts as arts"
+ " INNER JOIN blackboard_attributes as attrs"
+ " ON attrs.artifact_id = arts.artifact_id"
+ " WHERE arts.artifact_type_id = " + artifactType.getTypeID()
@@ -516,7 +516,7 @@ class GeoFilterPanel extends javax.swing.JPanel {
+ " or attrs.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_TRACKPOINTS.getTypeID()
+ " or attrs.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_WAYPOINTS.getTypeID()
+ " )"
+ " )";
+ " ) as innerTable";
try (SleuthkitCase.CaseDbQuery queryResult = sleuthkitCase.executeQuery(queryStr);
ResultSet resultSet = queryResult.getResultSet()) {
if (resultSet.next()) {
@@ -201,21 +201,32 @@ public final class CaseUcoReportModule implements GeneralReportModule {
Set<Long> dataSourceIds = dataSources.stream()
.map((datasource) -> datasource.getId())
.collect(Collectors.toSet());
logger.log(Level.INFO, "Writing all artifacts to the CASE-UCO report. "
+ "Keyword hits will be skipped as they can't be represented"
+ " in CASE format.");
// Write all standard artifacts that are contained within the
// selected data sources.
for (ARTIFACT_TYPE artType : currentCase.getSleuthkitCase().getBlackboardArtifactTypesInUse()) {
if(artType.equals(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT)) {
// Keyword hits cannot be represented in CASE.
continue;
}
for (BlackboardArtifact artifact : currentCase.getSleuthkitCase().getBlackboardArtifacts(artType)) {
if (dataSourceIds.contains(artifact.getDataSource().getId())) {
try {
for (JsonElement element : exporter.exportBlackboardArtifact(artifact)) {
gson.toJson(element, reportWriter);
}
} catch (ContentNotExportableException | BlackboardJsonAttrUtil.InvalidJsonException ex) {
logger.log(Level.WARNING, String.format("Unable to export blackboard artifact (id: %d) to CASE/UCO. "
} catch (ContentNotExportableException ex) {
logger.log(Level.INFO, String.format("Unable to export blackboard artifact (id: %d, type: %d) to CASE/UCO. "
+ "The artifact type is either not supported or the artifact instance does not have any "
+ "exportable attributes.", artifact.getId()));
+ "exportable attributes.", artifact.getId(), artType.getTypeID()));
} catch (BlackboardJsonAttrUtil.InvalidJsonException ex) {
logger.log(Level.WARNING, String.format("Artifact instance (id: %d, type: %d) contained a "
+ "malformed json attribute.", artifact.getId(), artType.getTypeID()), ex);
}
}
}