4621 new queries and population of new counts for Files tab

This commit is contained in:
William Schaefer 2019-01-25 14:41:29 -05:00
parent 7edecf0c48
commit 1a85d5c3e3
5 changed files with 130 additions and 55 deletions

View File

@ -39,7 +39,6 @@ import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
* Panel which allows viewing and selecting of Data Sources and some of their * Panel which allows viewing and selecting of Data Sources and some of their
* related information. * related information.
@ -124,10 +123,11 @@ final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerMana
*/ */
private List<DataSourceSummary> getDataSourceSummaryList(Map<Long, String> usageMap, Map<Long, Long> fileCountsMap) { private List<DataSourceSummary> getDataSourceSummaryList(Map<Long, String> usageMap, Map<Long, Long> fileCountsMap) {
List<DataSourceSummary> summaryList = new ArrayList<>(); List<DataSourceSummary> summaryList = new ArrayList<>();
final Map<Long, Long> artifactCountsMap = DataSourceInfoUtilities.getCountsOfArtifacts();
final Map<Long, Long> tagCountsMap = DataSourceInfoUtilities.getCountsOfTags();
try { try {
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
final Map<Long, Long> artifactCountsMap = DataSourceInfoUtilities.getCountsOfArtifacts(skCase);
final Map<Long, Long> tagCountsMap = DataSourceInfoUtilities.getCountsOfTags(skCase);
for (DataSource dataSource : skCase.getDataSources()) { for (DataSource dataSource : skCase.getDataSources()) {
summaryList.add(new DataSourceSummary(dataSource, usageMap.get(dataSource.getId()), summaryList.add(new DataSourceSummary(dataSource, usageMap.get(dataSource.getId()),
fileCountsMap.get(dataSource.getId()), artifactCountsMap.get(dataSource.getId()), tagCountsMap.get(dataSource.getId()))); fileCountsMap.get(dataSource.getId()), artifactCountsMap.get(dataSource.getId()), tagCountsMap.get(dataSource.getId())));

View File

@ -49,8 +49,9 @@ class DataSourceInfoUtilities {
* comma seperated list of values of data source usage types * comma seperated list of values of data source usage types
* expected to be in the datasource * expected to be in the datasource
*/ */
static Map<Long, String> getDataSourceTypes(SleuthkitCase skCase) { static Map<Long, String> getDataSourceTypes() {
try { try {
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
List<BlackboardArtifact> listOfArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE); List<BlackboardArtifact> listOfArtifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE);
Map<Long, String> typeMap = new HashMap<>(); Map<Long, String> typeMap = new HashMap<>();
for (BlackboardArtifact typeArtifact : listOfArtifacts) { for (BlackboardArtifact typeArtifact : listOfArtifacts) {
@ -67,7 +68,7 @@ class DataSourceInfoUtilities {
} }
} }
return typeMap; return typeMap;
} catch (TskCoreException ex) { } catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Unable to get types of files for all datasources, providing empty results", ex); logger.log(Level.WARNING, "Unable to get types of files for all datasources, providing empty results", ex);
return Collections.emptyMap(); return Collections.emptyMap();
} }
@ -83,16 +84,14 @@ class DataSourceInfoUtilities {
* files in the datasource, will only contain entries for * files in the datasource, will only contain entries for
* datasources which have at least 1 file * datasources which have at least 1 file
*/ */
static Map<Long, Long> getCountsOfFiles(SleuthkitCase skCase) { static Map<Long, Long> getCountsOfFiles() {
try { try {
DataSourceCountsCallback callback = new DataSourceCountsCallback();
final String countFilesQuery = "data_source_obj_id, COUNT(*) AS count" final String countFilesQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType() + " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue() + " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS + " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
skCase.getCaseDbAccessManager().select(countFilesQuery, callback); return getCountsMap(countFilesQuery);
return callback.getMapOfCounts(); } catch (TskCoreException | NoCurrentCaseException ex) {
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex); logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
return Collections.emptyMap(); return Collections.emptyMap();
} }
@ -108,15 +107,13 @@ class DataSourceInfoUtilities {
* artifacts in the datasource, will only contain entries for * artifacts in the datasource, will only contain entries for
* datasources which have at least 1 artifact * datasources which have at least 1 artifact
*/ */
static Map<Long, Long> getCountsOfArtifacts(SleuthkitCase skCase) { static Map<Long, Long> getCountsOfArtifacts() {
try { try {
DataSourceCountsCallback callback = new DataSourceCountsCallback();
final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS count" final String countArtifactsQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID() + " FROM blackboard_artifacts WHERE review_status_id !=" + BlackboardArtifact.ReviewStatus.REJECTED.getID()
+ " GROUP BY data_source_obj_id"; //NON-NLS + " GROUP BY data_source_obj_id"; //NON-NLS
skCase.getCaseDbAccessManager().select(countArtifactsQuery, callback); return getCountsMap(countArtifactsQuery);
return callback.getMapOfCounts(); } catch (TskCoreException | NoCurrentCaseException ex) {
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex); logger.log(Level.WARNING, "Unable to get counts of artifacts for all datasources, providing empty results", ex);
return Collections.emptyMap(); return Collections.emptyMap();
} }
@ -133,25 +130,22 @@ class DataSourceInfoUtilities {
* tags which have been applied in the datasource, will only contain * tags which have been applied in the datasource, will only contain
* entries for datasources which have at least 1 item tagged. * entries for datasources which have at least 1 item tagged.
*/ */
static Map<Long, Long> getCountsOfTags(SleuthkitCase skCase) { static Map<Long, Long> getCountsOfTags() {
try { try {
DataSourceCountsCallback fileCountcallback = new DataSourceCountsCallback();
final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS count" final String countFileTagsQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM content_tags as content_tags, tsk_files as tsk_files" + " FROM content_tags as content_tags, tsk_files as tsk_files"
+ " WHERE content_tags.obj_id = tsk_files.obj_id" + " WHERE content_tags.obj_id = tsk_files.obj_id"
+ " GROUP BY data_source_obj_id"; //NON-NLS + " GROUP BY data_source_obj_id"; //NON-NLS
skCase.getCaseDbAccessManager().select(countFileTagsQuery, fileCountcallback); //new hashmap so it can be modifiable
Map<Long, Long> tagCountMap = new HashMap<>(fileCountcallback.getMapOfCounts()); Map<Long, Long> tagCountMap = new HashMap<>(getCountsMap(countFileTagsQuery));
DataSourceCountsCallback artifactCountcallback = new DataSourceCountsCallback();
final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS count" final String countArtifactTagsQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts" + " FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts"
+ " WHERE artifact_tags.artifact_id = arts.artifact_id" + " WHERE artifact_tags.artifact_id = arts.artifact_id"
+ " GROUP BY data_source_obj_id"; //NON-NLS + " GROUP BY data_source_obj_id"; //NON-NLS
skCase.getCaseDbAccessManager().select(countArtifactTagsQuery, artifactCountcallback);
//combine the results from the count artifact tags query into the copy of the mapped results from the count file tags query //combine the results from the count artifact tags query into the copy of the mapped results from the count file tags query
artifactCountcallback.getMapOfCounts().forEach((key, value) -> tagCountMap.merge(key, value, (value1, value2) -> value1 + value2)); getCountsMap(countArtifactTagsQuery).forEach((key, value) -> tagCountMap.merge(key, value, (value1, value2) -> value1 + value2));
return tagCountMap; return tagCountMap;
} catch (TskCoreException ex) { } catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex); logger.log(Level.WARNING, "Unable to get counts of tags for all datasources, providing empty results", ex);
return Collections.emptyMap(); return Collections.emptyMap();
} }
@ -199,7 +193,7 @@ class DataSourceInfoUtilities {
* specified mime types in the current case for the specified data * specified mime types in the current case for the specified data
* source, null if no count was retrieved * source, null if no count was retrieved
*/ */
static Long getCountOfFiles(DataSource currentDataSource, Set<String> setOfMimeTypes) { static Long getCountOfFilesForMimeTypes(DataSource currentDataSource, Set<String> setOfMimeTypes) {
if (currentDataSource != null) { if (currentDataSource != null) {
try { try {
String inClause = String.join("', '", setOfMimeTypes); String inClause = String.join("', '", setOfMimeTypes);
@ -217,6 +211,84 @@ class DataSourceInfoUtilities {
return null; return null;
} }
/**
* Get a map containing the number of files in each data source in the
* current case.
*
* @param skCase the current SluethkitCase
*
* @return Collection which maps datasource id to a count for the number of
* files in the datasource, will only contain entries for
* datasources which have at least 1 file
*/
static Map<Long, Long> getCountsOfUnallocatedFiles() {
try {
final String countUnallocatedFilesQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
+ " AND dir_flags=" + TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue()
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
return getCountsMap(countUnallocatedFilesQuery);
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
return Collections.emptyMap();
}
}
/**
* Get a map containing the number of files in each data source in the
* current case.
*
* @param skCase the current SluethkitCase
*
* @return Collection which maps datasource id to a count for the number of
* files in the datasource, will only contain entries for
* datasources which have at least 1 file
*/
static Map<Long, Long> getCountsOfDirectories() {
try {
final String countDirectoriesQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM tsk_files WHERE type<>" + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
+ " AND meta_type=" + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
return getCountsMap(countDirectoriesQuery);
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
return Collections.emptyMap();
}
}
/**
* Get a map containing the number of files in each data source in the
* current case.
*
* @param skCase the current SluethkitCase
*
* @return Collection which maps datasource id to a count for the number of
* files in the datasource, will only contain entries for
* datasources which have at least 1 file
*/
static Map<Long, Long> getCountsOfSlackFiles() {
try {
final String countSlackFilesQuery = "data_source_obj_id, COUNT(*) AS count"
+ " FROM tsk_files WHERE type=" + TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType()
+ " AND dir_type<>" + TskData.TSK_FS_NAME_TYPE_ENUM.VIRT_DIR.getValue()
+ " AND name<>'' GROUP BY data_source_obj_id"; //NON-NLS
return getCountsMap(countSlackFilesQuery);
} catch (TskCoreException | NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Unable to get counts of files for all datasources, providing empty results", ex);
return Collections.emptyMap();
}
}
private static Map<Long, Long> getCountsMap(String query) throws TskCoreException, NoCurrentCaseException {
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
DataSourceSingleCountCallback callback = new DataSourceSingleCountCallback();
skCase.getCaseDbAccessManager().select(query, callback);
return callback.getMapOfCounts();
}
private DataSourceInfoUtilities() { private DataSourceInfoUtilities() {
} }
} }

View File

@ -32,9 +32,9 @@ import org.sleuthkit.datamodel.CaseDbAccessManager;
* selects data_source_obj_id and count(*) with a group by data_source_obj_id * selects data_source_obj_id and count(*) with a group by data_source_obj_id
* clause. * clause.
*/ */
class DataSourceCountsCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback { class DataSourceSingleCountCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
private static final Logger logger = Logger.getLogger(DataSourceCountsCallback.class.getName()); private static final Logger logger = Logger.getLogger(DataSourceSingleCountCallback.class.getName());
private Map<Long, Long> dataSourceObjIdCounts = new HashMap<>(); private Map<Long, Long> dataSourceObjIdCounts = new HashMap<>();
@Override @Override

View File

@ -19,18 +19,13 @@
package org.sleuthkit.autopsy.casemodule.datasourceSummary; package org.sleuthkit.autopsy.casemodule.datasourceSummary;
import java.awt.Frame; import java.awt.Frame;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.SleuthkitCase;
/** /**
* Dialog for displaying the Data Sources Summary information * Dialog for displaying the Data Sources Summary information
@ -55,15 +50,8 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
}) })
DataSourceSummaryDialog(Frame owner) { DataSourceSummaryDialog(Frame owner) {
super(owner, Bundle.DataSourceSummaryPanel_window_title(), true); super(owner, Bundle.DataSourceSummaryPanel_window_title(), true);
Map<Long, String> usageMap = new HashMap<>(); Map<Long, String> usageMap = DataSourceInfoUtilities.getDataSourceTypes();
Map<Long, Long> fileCountsMap = new HashMap<>(); Map<Long, Long> fileCountsMap = DataSourceInfoUtilities.getCountsOfFiles();
try {
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
usageMap = DataSourceInfoUtilities.getDataSourceTypes(skCase);
fileCountsMap = DataSourceInfoUtilities.getCountsOfFiles(skCase);
} catch (NoCurrentCaseException ex) {
logger.log(Level.WARNING, "Unable to data source usage information", ex);
}
filesPanel = new DataSourceSummaryFilesPanel(fileCountsMap); filesPanel = new DataSourceSummaryFilesPanel(fileCountsMap);
detailsPanel = new DataSourceSummaryDetailsPanel(usageMap); detailsPanel = new DataSourceSummaryDetailsPanel(usageMap);
dataSourcesPanel = new DataSourceBrowser(usageMap, fileCountsMap); dataSourcesPanel = new DataSourceBrowser(usageMap, fileCountsMap);

View File

@ -37,12 +37,19 @@ public class DataSourceSummaryFilesPanel extends javax.swing.JPanel {
private FilesByMimeTypeTableModel filesByMimeTypeTableModel = new FilesByMimeTypeTableModel(null); private FilesByMimeTypeTableModel filesByMimeTypeTableModel = new FilesByMimeTypeTableModel(null);
private FilesByCategoryTableModel filesByCategoryTableModel = new FilesByCategoryTableModel(null); private FilesByCategoryTableModel filesByCategoryTableModel = new FilesByCategoryTableModel(null);
private static final Logger logger = Logger.getLogger(DataSourceSummaryFilesPanel.class.getName()); private static final Logger logger = Logger.getLogger(DataSourceSummaryFilesPanel.class.getName());
private final Map<Long, Long> fileCountsMap; private final Map<Long, Long> allFilesCountsMap;
private final Map<Long, Long> slackFilesCountsMap;
private final Map<Long, Long> directoriesCountsMap;
private final Map<Long, Long> unallocatedFilesCountsMap;
/** /**
* Creates new form DataSourceSummaryFilesPanel * Creates new form DataSourceSummaryFilesPanel
*/ */
public DataSourceSummaryFilesPanel(Map<Long, Long> fileCountsMap) { public DataSourceSummaryFilesPanel(Map<Long, Long> fileCountsMap) {
this.fileCountsMap = fileCountsMap; this.allFilesCountsMap = fileCountsMap;
this.slackFilesCountsMap = DataSourceInfoUtilities.getCountsOfSlackFiles();
this.directoriesCountsMap = DataSourceInfoUtilities.getCountsOfDirectories();
this.unallocatedFilesCountsMap = DataSourceInfoUtilities.getCountsOfUnallocatedFiles();
initComponents(); initComponents();
fileCountsByMimeTypeTable.getTableHeader().setReorderingAllowed(false); fileCountsByMimeTypeTable.getTableHeader().setReorderingAllowed(false);
} }
@ -195,15 +202,15 @@ public class DataSourceSummaryFilesPanel extends javax.swing.JPanel {
} else if (columnIndex == 1) { } else if (columnIndex == 1) {
switch (rowIndex) { switch (rowIndex) {
case 0: case 0:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes()); return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.IMAGE.getMediaTypes());
case 1: case 1:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes()); return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.VIDEO.getMediaTypes());
case 2: case 2:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes()); return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.AUDIO.getMediaTypes());
case 3: case 3:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.DOCUMENTS.getMediaTypes()); return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.DOCUMENTS.getMediaTypes());
case 4: case 4:
return DataSourceInfoUtilities.getCountOfFiles(currentDataSource, FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes()); return DataSourceInfoUtilities.getCountOfFilesForMimeTypes(currentDataSource, FileTypeUtils.FileTypeCategory.EXECUTABLE.getMediaTypes());
default: default:
break; break;
} }
@ -281,15 +288,23 @@ public class DataSourceSummaryFilesPanel extends javax.swing.JPanel {
} else if (columnIndex == 1) { } else if (columnIndex == 1) {
switch (rowIndex) { switch (rowIndex) {
case 0: case 0:
return fileCountsMap.get(currentDataSource.getId()) == null ? 0 : fileCountsMap.get(currentDataSource.getId()); return allFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : allFilesCountsMap.get(currentDataSource.getId());
case 1: case 1:
Long unallocatedFilesCount = unallocatedFilesCountsMap.get(currentDataSource.getId());
Long allFilesCount = allFilesCountsMap.get(currentDataSource.getId());
if (allFilesCount == null) {
return 0; return 0;
} else if (unallocatedFilesCount == null) {
return allFilesCount;
} else {
return allFilesCount - unallocatedFilesCount;
}
case 2: case 2:
return 0; return unallocatedFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : unallocatedFilesCountsMap.get(currentDataSource.getId());
case 3: case 3:
return 0; return slackFilesCountsMap.get(currentDataSource.getId()) == null ? 0 : slackFilesCountsMap.get(currentDataSource.getId());
case 4: case 4:
return 0; return directoriesCountsMap.get(currentDataSource.getId()) == null ? 0 : directoriesCountsMap.get(currentDataSource.getId());
default: default:
break; break;
} }